protected virtual List <CodeErrorException> TypeCheckBinaryOperator(BinaryOperatorTree op) { List <CodeErrorException> errors = new List <CodeErrorException>(); switch (op.Operator) { case Operator.Addition: case Operator.Subtraction: case Operator.Multiplication: case Operator.Division: case Operator.Power: break; default: errors.Add( new CodeErrorException( op.Token.Line, op.Token.StartPosition, op.Token.EndPosition, string.Format( "Type-checker does not support binary operator '{0}'", op.Token.Value ) ) ); break; } // typecheck expressions errors.AddRange(TypeCheckExpression(op.LeftHandSide)); errors.AddRange(TypeCheckExpression(op.RightHandSide)); return(errors); }
private SyntaxTree ParseMathExpression(int level) { SyntaxTree tree = ParseTerm(0); Operator op; while (true) { // if next token is not an operator bail out if (!TryResolveOperator(CurrentToken.TokenType, false, out op)) { break; } // if next token is not a binary operator bail out if (GetOperatorAryness(op) != Aryness.Binary) { break; } // if next operator precedence is less than existing level, bail out if (!(GetPrecedenceLevel(op) >= level)) { break; } BinaryOperatorTree opTree = new BinaryOperatorTree(CurrentToken); opTree.Operator = op; Match(CurrentToken.TokenType); // parse the right hand side of the expression int operatorPrecedence = GetPrecedenceLevel(op); int newPrecedenceLevel = operatorPrecedence; if (GetOperatorAssociativity(op) == Associativity.Left) { newPrecedenceLevel = newPrecedenceLevel + 1; } SyntaxTree rightHandTree = ParseExpression(newPrecedenceLevel); // set the left hand-side to the existing tree, right-hand side to new parsed tree opTree.LeftHandSide = tree; opTree.RightHandSide = rightHandTree; // set main xpression tree to the new operator tree tree = opTree; } return(tree); }
protected virtual string EmitBinaryOperator(BinaryOperatorTree op) { string code = string.Empty; switch (op.Operator) { case Operator.MemberSelection: code = string.Format( "{0}.{1}", EmitExpression(op.LeftHandSide), op.RightHandSide.Token.Value ); break; case Operator.Power: code = string.Format( "Math.Pow({0},{1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.Multiplication: code = string.Format( "({0})*({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.Division: code = string.Format( "({0})/({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.Modulus: code = string.Format( "({0})%({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.Addition: code = string.Format( "({0}) + ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.Subtraction: code = string.Format( "({0}) - ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.LessThan: code = string.Format( "({0}) < ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.GreaterThan: code = string.Format( "({0}) > ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.LessThanEqualTo: code = string.Format( "({0}) <= ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.GreaterThanEqualTo: code = string.Format( "({0}) >= ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.Equality: code = string.Format( "({0}) == ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.Inequality: code = string.Format( "({0}) != ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.And: code = string.Format( "({0}) && ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; case Operator.Or: code = string.Format( "({0}) || ({1})", EmitExpression(op.LeftHandSide), EmitExpression(op.RightHandSide) ); break; default: throw new InternalCompilerException( string.Format("Could not generate code for binary operator: {0}", op.Operator) ); } return(code); }