/// <summary> /// Parses the statements in the function body /// recursively and calls other statemetents as needed /// </summary> private void ParseStatementExpression() { Token t = _scanner.GetToken(); var identfiers = new Stack<Expr>(); var operators = new Stack<Expr>(); var functionParameters = new Stack<Expr>(); bool foundLeftParen = false; bool functionHasParameters = false; while (!t.IdentiferName.Equals(constants.SEMICOLON)) { if (t.isOperator) { if (t.IdentiferName.Equals(constants.LPAREN)) { foundLeftParen = true; } if (operators.Count > 0) { OperatorPrecedenceTable.ShiftReduceEval sre = OperatorPrecedenceTable.IdOperation.Validate(operators.Peek().GetToken(), t); switch (sre) { case OperatorPrecedenceTable.ShiftReduceEval.Shift: { if (t.IdentiferName.Equals(constants.RPAREN)) { foundLeftParen = false; functionHasParameters = false; var parameterList = new List<Expr>(); while (functionParameters.Count > 0) { parameterList.Add(functionParameters.Pop()); } if (operators.Peek().GetToken().IdentiferName.Equals(constants.LPAREN)) { operators.Pop(); } else { throw new NireExecutionException("mismatched parens"); } var funcCall = new FunctionCallExpression(identfiers.Pop().GetToken(), parameterList); identfiers.Push(funcCall); break; } operators.Push(new OperatorExpression(t)); break; } case OperatorPrecedenceTable.ShiftReduceEval.Reduce: { Expr operation = operators.Pop(); var oe = new OperatorExpression(operation.GetToken()); if (identfiers.Count < 2) { throw new NireException(); } Expr rvalue = identfiers.Pop(); Expr lvalue = identfiers.Pop(); switch (operation.GetToken().Kind) { case ByteCodeIdentifiers.TokenCode.Equal: { var ae = new AssignmentExpr(oe, lvalue, rvalue); if (ae.IsValidBinaryExpression()) { identfiers.Push(ae); } break; } case ByteCodeIdentifiers.TokenCode.Multiply: case ByteCodeIdentifiers.TokenCode.Divide: case ByteCodeIdentifiers.TokenCode.EqualEqual: case ByteCodeIdentifiers.TokenCode.Plus: case ByteCodeIdentifiers.TokenCode.Minus: { var boe = new ArithmeticBinaryExpr(oe, lvalue, rvalue); if (boe.IsValidBinaryExpression()) { identfiers.Push(boe); } break; } } if (t.Kind != ByteCodeIdentifiers.TokenCode.SemiColon && t.Kind != ByteCodeIdentifiers.TokenCode.LParen && t.Kind != ByteCodeIdentifiers.TokenCode.RParen) { operators.Push(new OperatorExpression(t)); } break; } } } else { if (t.Kind != ByteCodeIdentifiers.TokenCode.RParen) { operators.Push(new OperatorExpression(t)); } } } else { if (foundLeftParen) { functionHasParameters = true; } if (functionHasParameters) { if (!t.Value.Equals(constants.COMMA)) { var ie = new IdentifierExpression(t); var symbolTable = SymbolTable.CreateInstance(); if (!symbolTable.IsTokenDefinedInScope(_expressionScopeStack.Peek(), ie)) { functionParameters.Push(new IdentifierExpression(t)); } } } else { identfiers.Push(DetermineNextToken(t)); } } t = _scanner.GetToken(); } ConstructAst(operators, identfiers); }
internal AssignmentExpr(OperatorExpression operation, Expr left, Expr right) : base(operation, left, right) { }
internal BinaryOperatorExpression( OperatorExpression operation, Expr left, Expr right) : this() { this.left = left; this.right = right; this.operation = operation; }
internal ArithmeticBinaryExpr(OperatorExpression operation, Expr left, Expr right) : base(operation, left, right) { }
internal BinaryOperatorExpression(OperatorExpression operation) : base() { this.operation = operation; }