|
@@ -60,31 +60,50 @@ GETTER -> get ORIGIN .
|
|
GETCALL -> comma COMMAND | .
|
|
GETCALL -> comma COMMAND | .
|
|
ORIGIN -> word | SETTER | GETTER .
|
|
ORIGIN -> word | SETTER | GETTER .
|
|
|
|
|
|
-Note that the Muesli syntax description below is not strictly LL(1),
|
|
|
|
-notably the optional operator after a getter, but the recursive descent parser
|
|
|
|
-can parse it correctly.
|
|
|
|
|
|
|
|
-PROGRAM -> STATEMENTS.
|
|
|
|
-CLOSED -> BLOCK | LIST | PARENTHESIS .
|
|
|
|
|
|
+Or, new syntax with operators for command chains at the top level,
|
|
|
|
+for easier shunting the operator into commands:
|
|
|
|
+
|
|
|
|
+PROGRAM -> STATEMENTS .
|
|
STATEMENTS -> STATEMENT STATEMENTS | .
|
|
STATEMENTS -> STATEMENT STATEMENTS | .
|
|
-STATEMENT -> CLOSED | EXPRESSION eos | eos .
|
|
|
|
-COMMAND -> WORDVALUE DETAILS .
|
|
|
|
-DETAILS -> OPERATION | PARAMETERS .
|
|
|
|
-OPT_OPER -> OPERATION | .
|
|
|
|
-OPERATION -> operator COMMAND .
|
|
|
|
-PARAMETERS -> PARAMETER PARAMETERS | .
|
|
|
|
-PARAMETER -> WORDVALUE | GETTER | SETTER | CLOSED .
|
|
|
|
-EXPRESSION -> COMMAND | GETTER | SETTER.
|
|
|
|
-PARENTHESIS -> openparen EXPRESSION closeparen .
|
|
|
|
|
|
+STATEMENT -> BLOCK | CHAIN eos | eos .
|
|
|
|
+CHAIN -> COMMAND LINKS .
|
|
|
|
+LINKS -> LINK LINKS | .
|
|
|
|
+LINK -> operator COMMAND .
|
|
|
|
+COMMAND -> DIRECT | INDIRECT | LITERAL .
|
|
|
|
+DIRECT -> NAME PARAMETERS .
|
|
|
|
+INDIRECT -> SUBSTITUTION PARAMETERS .
|
|
|
|
+PARAMETER -> NAME | LITERAL | SUBSTITUTION | BLOCK .
|
|
|
|
+SUBSTITUTION -> PARENTHESIS | GETTER | SETTER | LIST .
|
|
|
|
+PARENTHESIS -> openparen CHAIN closeparen .
|
|
BLOCK -> openblock STATEMENTS closeblock .
|
|
BLOCK -> openblock STATEMENTS closeblock .
|
|
LIST -> openlist PARAMETERS closelist .
|
|
LIST -> openlist PARAMETERS closelist .
|
|
-VALUE -> string | int | float | symbol | type .
|
|
|
|
-WORDVALUE -> word | VALUE.
|
|
|
|
-SETTER -> set TARGET .
|
|
|
|
-TARGET -> word PARAMETER | GETTER PARAMETER .
|
|
|
|
-GETTER -> get ORIGIN OPT_OPER .
|
|
|
|
-GETCALL -> comma COMMAND | .
|
|
|
|
-ORIGIN -> word | SETTER | GETTER .
|
|
|
|
|
|
+LITERAL -> string | int | float | true | false | nil .
|
|
|
|
+NAME -> word | type | symbol .
|
|
|
|
+SETTER -> set PARAMETER PARAMETER .
|
|
|
|
+GETTER -> get PARAMETER .
|
|
|
|
+
|
|
|
|
+semantics:
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+- A muesli program consists of statements.
|
|
|
|
+- A statement is either a block, or a command chain terminated by eos, or just an eos .
|
|
|
|
+- A command chain consists of commands chained together with operators.
|
|
|
|
+- A command may be a direct command, an indirect command, or a literal value.
|
|
|
|
+- A () parenthesis gets substituted inline anywhere it occurs, also in the
|
|
|
|
+ beginning of a command.
|
|
|
|
+- A bracketed list [ elem1 elem2 ... ] is syntactic sugar for (list elem1 elem 2)
|
|
|
|
+- A dollar getter $varname is syntactic sugar for (get varname)
|
|
|
|
+- A equals setter =varname value is syntactic sugar for (set varname value)
|
|
|
|
+- Therefore, parenthesis, lists, getters and setters are allowed anywhere,
|
|
|
|
+ also in the beginning of the command with substitution semantics.
|
|
|
|
+- If a command starts with a substitution, it is an indirect command. The
|
|
|
|
+ substitution is evaluated and it's value is looked up as the command name.
|
|
|
|
+ In case the result is not a name, this is a run time error.
|
|
|
|
+ In case the result is a list, each value of the list is executed as a command
|
|
|
|
+ with the same parameters.
|
|
|
|
+- A literal evaluate to itself.
|
|
|
|
+- A name also evaluates as itself but is specific for direct commands.
|
|
|
|
|
|
|
|
|
|
*
|
|
*
|
|
@@ -212,8 +231,6 @@ func AstKindForToken(token Token) AstKind {
|
|
return AstKindValue
|
|
return AstKindValue
|
|
case TokenKindWord:
|
|
case TokenKindWord:
|
|
return AstKindWord
|
|
return AstKindWord
|
|
- case TokenKindOperator:
|
|
|
|
- return AstKindWord
|
|
|
|
case TokenKindType:
|
|
case TokenKindType:
|
|
return AstKindType
|
|
return AstKindType
|
|
default:
|
|
default:
|
|
@@ -399,11 +416,7 @@ func (parser *Parser) ParseSet() *Ast {
|
|
ast := NewAstWithToken(AstKindSet, set)
|
|
ast := NewAstWithToken(AstKindSet, set)
|
|
target := parser.ParseTarget()
|
|
target := parser.ParseTarget()
|
|
ast.AppendChild(target)
|
|
ast.AppendChild(target)
|
|
- if parser.NextIs(TokenKindOperator) {
|
|
|
|
- ast = parser.ParseOperator(ast)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return ast
|
|
|
|
|
|
+ return ast
|
|
}
|
|
}
|
|
|
|
|
|
func (parser *Parser) ParseGet() *Ast {
|
|
func (parser *Parser) ParseGet() *Ast {
|
|
@@ -413,35 +426,15 @@ func (parser *Parser) ParseGet() *Ast {
|
|
ast := NewAstWithToken(AstKindGet, get)
|
|
ast := NewAstWithToken(AstKindGet, get)
|
|
target := parser.ParseOrigin()
|
|
target := parser.ParseOrigin()
|
|
ast.AppendChild(target)
|
|
ast.AppendChild(target)
|
|
- if parser.NextIs(TokenKindOperator) {
|
|
|
|
- ast = parser.ParseOperator(ast)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
return ast
|
|
return ast
|
|
}
|
|
}
|
|
|
|
|
|
-func (parser *Parser) ParseOperator(operand *Ast) *Ast {
|
|
|
|
- parser.LogDebug("ParseOperator: %s\n", parser.current.String())
|
|
|
|
-
|
|
|
|
- operator := parser.Require(TokenKindOperator)
|
|
|
|
- arguments := parser.ParseArguments(operand)
|
|
|
|
- command := NewAstWithToken(AstKindCommand, operator)
|
|
|
|
- command.AppendChild(arguments)
|
|
|
|
- return command
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
func (parser *Parser) ParseCommand() *Ast {
|
|
func (parser *Parser) ParseCommand() *Ast {
|
|
parser.LogDebug("ParseCommand: %s\n", parser.current.String())
|
|
parser.LogDebug("ParseCommand: %s\n", parser.current.String())
|
|
|
|
|
|
- wordvalue := parser.ParseWordValue()
|
|
|
|
-
|
|
|
|
- // operator command
|
|
|
|
- if parser.NextIs(TokenKindOperator) {
|
|
|
|
- return parser.ParseOperator(wordvalue)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- arguments := parser.ParseArguments()
|
|
|
|
- command := NewAstWithToken(AstKindCommand, wordvalue.Token())
|
|
|
|
|
|
+ word := parser.Require(TokenKindWord, TokenKindType)
|
|
|
|
+ arguments := parser.ParseArguments()
|
|
|
|
+ command := NewAstWithToken(AstKindCommand, word)
|
|
command.AppendChild(arguments)
|
|
command.AppendChild(arguments)
|
|
return command
|
|
return command
|
|
}
|
|
}
|