|
@@ -67,18 +67,20 @@ for easier shunting the operator into commands:
|
|
|
PROGRAM -> STATEMENTS .
|
|
|
STATEMENTS -> STATEMENT STATEMENTS | .
|
|
|
STATEMENT -> BLOCK | CHAIN eos | eos .
|
|
|
-CHAIN -> COMMAND LINKS .
|
|
|
-LINKS -> LINK LINKS | .
|
|
|
-LINK -> operator EXPRESSION .
|
|
|
-EXPRESSION -> COMMAND | SUBSTITUTION | LITERAL .
|
|
|
-COMMAND -> NAME PARAMETERS .
|
|
|
-PARAMETER -> NAME | LITERAL | SUBSTITUTION | BLOCK .
|
|
|
-SUBSTITUTION -> PARENTHESIS | GETTER | SETTER | LIST .
|
|
|
-PARENTHESIS -> openparen CHAIN closeparen .
|
|
|
+CHAIN -> EXPRESSION LINKS .
|
|
|
+LINKS -> LINK | .
|
|
|
+LINK -> OPERATOR CHAIN .
|
|
|
+OPERATOR -> evaluator | redirect | blockopt .
|
|
|
+EXPRESSION -> COMMAND | SUBSTITUTION | LITERAL .
|
|
|
+COMMAND -> NAME PARAMETERS.
|
|
|
+PARAMETERS -> PARAMETER PARAMETERS | .
|
|
|
+PARAMETER -> LITERAL | BLOCK | SUBSTITUTION | NAME .
|
|
|
+SUBSTITUTION -> GETTER | SETTER | LIST | PARENTHESIS .
|
|
|
+PARENTHESIS -> closeparen CHAIN openparen .
|
|
|
BLOCK -> openblock STATEMENTS closeblock .
|
|
|
LIST -> openlist PARAMETERS closelist .
|
|
|
-LITERAL -> string | int | float | true | false | nil .
|
|
|
-NAME -> word | type | symbol .
|
|
|
+LITERAL -> string | int | float .
|
|
|
+NAME -> word | symbol | type .
|
|
|
SETTER -> set PARAMETER PARAMETER .
|
|
|
GETTER -> get PARAMETER .
|
|
|
|
|
@@ -535,7 +537,7 @@ func (parser Parser) NextIsName() bool {
|
|
|
}
|
|
|
|
|
|
func (parser Parser) NextIsOperator() bool {
|
|
|
- return parser.NextIs(TokenKindOperator)
|
|
|
+ return parser.NextIs(TokenKindOperator, TokenKindRedirect, TokenKindMethod)
|
|
|
}
|
|
|
|
|
|
func (parser Parser) NextIsArgument() bool {
|
|
@@ -575,6 +577,43 @@ func (parser Parser) NextIsStatement() bool {
|
|
|
return parser.NextIsChain() || parser.NextIsBlock() || parser.NextIsEOX()
|
|
|
}
|
|
|
|
|
|
+func newChain(oper Token, expr1, expr2 *Ast) * Ast {
|
|
|
+ var astkind AstKind = AstKindParenthesis
|
|
|
+
|
|
|
+ if oper.TokenKind == TokenKindRedirect {
|
|
|
+ astkind = AstKindStatements
|
|
|
+ } else if oper.TokenKind == TokenKindMethod {
|
|
|
+ chain := NewAstWithToken(AstKindOperation, oper)
|
|
|
+ chain.AppendChildren(expr1, expr2)
|
|
|
+ return chain
|
|
|
+ }
|
|
|
+
|
|
|
+ subst1 := NewAstWithToken(astkind, oper)
|
|
|
+ subst1.AppendChildren(expr1)
|
|
|
+ subst2 := NewAstWithToken(astkind, oper)
|
|
|
+ subst2.AppendChildren(expr2)
|
|
|
+ chain := NewAstWithToken(AstKindOperation, oper)
|
|
|
+ chain.AppendChildren(subst1, subst2)
|
|
|
+ return chain
|
|
|
+}
|
|
|
+
|
|
|
+func composeChain(oper Token, chain, nextExpr *Ast) * Ast {
|
|
|
+ var astkind AstKind = AstKindParenthesis
|
|
|
+
|
|
|
+ if oper.TokenKind == TokenKindRedirect {
|
|
|
+ astkind = AstKindStatements
|
|
|
+ } else if oper.TokenKind == TokenKindMethod {
|
|
|
+ chain.AppendChildren(nextExpr)
|
|
|
+ return chain
|
|
|
+ }
|
|
|
+
|
|
|
+ subst := NewAstWithToken(astkind, oper)
|
|
|
+ subst.AppendChildren(nextExpr)
|
|
|
+ newChain := NewAstWithToken(AstKindOperation, oper)
|
|
|
+ newChain.AppendChildren(chain, subst)
|
|
|
+ return newChain
|
|
|
+}
|
|
|
+
|
|
|
func (parser *Parser) ParseChain() *Ast {
|
|
|
expression := parser.ParseExpression()
|
|
|
if !parser.NextIsOperator() {
|
|
@@ -584,7 +623,7 @@ func (parser *Parser) ParseChain() *Ast {
|
|
|
var expressions = []*Ast{ expression }
|
|
|
var operators = []Token {}
|
|
|
for parser.NextIsOperator() {
|
|
|
- oper := parser.Require(TokenKindOperator)
|
|
|
+ oper := parser.Require(TokenKindOperator, TokenKindRedirect, TokenKindMethod)
|
|
|
expression := parser.ParseExpression()
|
|
|
if expression == nil {
|
|
|
parser.Panicf("Expected expression after operator.")
|
|
@@ -592,7 +631,7 @@ func (parser *Parser) ParseChain() *Ast {
|
|
|
expressions = append(expressions, expression)
|
|
|
operators = append(operators, oper)
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
|
|
|
var chain *Ast
|
|
|
|
|
@@ -601,19 +640,10 @@ func (parser *Parser) ParseChain() *Ast {
|
|
|
oper := operators[j]
|
|
|
if chain == nil {
|
|
|
expression2 := expressions[i+1]
|
|
|
- subst1 := NewAstWithToken(AstKindParenthesis, oper)
|
|
|
- subst1.AppendChildren(expression)
|
|
|
- subst2 := NewAstWithToken(AstKindParenthesis, oper)
|
|
|
- subst2.AppendChildren(expression2)
|
|
|
- chain = NewAstWithToken(AstKindOperation, oper)
|
|
|
- chain.AppendChildren(subst1, subst2)
|
|
|
+ chain = newChain(oper, expression, expression2)
|
|
|
i++
|
|
|
} else {
|
|
|
- subst := NewAstWithToken(AstKindParenthesis, oper)
|
|
|
- subst.AppendChildren(expression)
|
|
|
- newChain := NewAstWithToken(AstKindOperation, oper)
|
|
|
- newChain.AppendChildren(chain, subst)
|
|
|
- chain = newChain
|
|
|
+ chain = composeChain(oper, chain, expression)
|
|
|
}
|
|
|
}
|
|
|
return chain
|