// <parexpression> ::= <LPAR> <expression> <RPAR> // Note that ParExpression turns scanners IgnoreWhitespace private ASTAnyExpression ExpectParExpression() { ASTAnyExpression operand = null; this.Scanner.IgnoreWhitespace = true; this.Expect(TokenType.LPAR); operand = ExpectExpression(); this.Scanner.IgnoreWhitespace = false; this.Expect(TokenType.RPAR); return operand; }
// <expression> ::= <term> ( <addop> <term> )* private ASTAnyExpression ExpectExpression() { ASTAnyExpression expression = this.ExpectTerm(); while (this.Scanner.CurrentToken == TokenType.PLUS || this.Scanner.CurrentToken == TokenType.MINUS) { ASTBinaryExpression binary = new ASTBinaryExpression(); binary.Left = expression; binary.Operator = this.ExpectAddOperator(); binary.Right = this.ExpectTerm(); expression = binary; } return expression; }
// <operand> ::= [ <expression> | <parexpression> ] private ASTAnyExpression ExpectOperand() { ASTAnyExpression operand = null; if (this.Scanner.CurrentToken == TokenType.LPAR) { operand = this.ExpectParExpression(); } else if (this.Scanner.CurrentToken == TokenType.ID || this.Scanner.CurrentToken == TokenType.INTEGER || this.Scanner.CurrentToken == TokenType.MINUS || this.Scanner.CurrentToken == TokenType.PLUS) { operand = this.ExpectExpression(); } return operand; }
// <term> ::= <signedfactor> ( <mulop> <factor> )* private ASTAnyExpression ExpectTerm() { ASTAnyExpression expression = this.ExpectSignedFactor(); while (this.Scanner.CurrentToken == TokenType.OCTOTHORPE || this.Scanner.CurrentToken == TokenType.FWDSLASH || this.Scanner.CurrentToken == TokenType.BCKSLASH || this.Scanner.CurrentToken == TokenType.CARRET) { ASTBinaryExpression binary = new ASTBinaryExpression(); binary.Left = expression; binary.Operator = this.ExpectMulOperator(); binary.Right = this.ExpectFactor(); expression = binary; } return expression; }
// <factor> ::= <literal> | <call> | <LPAR> <expression> <RPAR> private ASTAnyExpression ExpectFactor() { ASTAnyExpression expression = null; switch (this.Scanner.CurrentToken) { case TokenType.INTEGER: expression = this.ExpectLiteral(); break; case TokenType.ID: expression = this.ExpectCall(); break; case TokenType.LPAR: this.Expect(TokenType.LPAR); expression = ExpectExpression(); this.Expect(TokenType.RPAR); break; default: throw new ParserException(this, @"ID or INTEGER or LPAR "); } return expression; }
private CodeObjectCreateExpression CreateConstructorCallExpression(Type verbType, IList <ASTAnyExpression> operands) { CodeObjectCreateExpression constructorCall = new CodeObjectCreateExpression(); constructorCall.CreateType = new CodeTypeReference(verbType); // TODO: Figure out something with first foreach (var ctorParam in verbType.GetConstructors().First().GetParameters()) { if (operands.Count > ctorParam.Position && operands[ctorParam.Position] != null) { ASTAnyExpression operand = operands[ctorParam.Position]; if (ctorParam.ParameterType == typeof(IDoubleOperand)) { if (operand is ASTLiteral) { // Operand is a constant ASTLiteral literalOperand = (operand as ASTLiteral); if (literalOperand.LiteralType == LiteralType.Double) { constructorCall.Parameters.Add(GenerationUtils.ConctructCtorNumberParameter((double)literalOperand.Value)); } else { throw new CompilerException("Only double operands supported for the moment: " + operand.GetType().Name); } } else { // Operand is an expression string parameterMethodName = String.Format("Verb{0}_Operand{1}", this.verbNo, ctorParam.Position + 1); // Visit expression CodeExpression operandExpression = (CodeExpression)operand.Accept(this); // Construct method for operand this.CreateOperandMethod(parameterMethodName, operandExpression); // Add method delegate as constructor parameter constructorCall.Parameters.Add(GenerationUtils.ConctructCtorDelegateParameter(parameterMethodName)); } } else if (ctorParam.ParameterType == typeof(LiteralOperand)) { if (operand is ASTLValue) { string literal = (operand as ASTLValue).Id; constructorCall.Parameters.Add(GenerationUtils.ConstructCtorLiteralParameter(literal)); } else { throw new CompilerException("Wrong AST node for Literal operand: " + operand.GetType().Name); } } else { throw new CompilerException("Not supported parameter type: " + ctorParam.ParameterType.Name); } } else { // Set null for null operand and for remaining operands constructorCall.Parameters.Add(new CodePrimitiveExpression(null)); } } return(constructorCall); }