override public void Visit(AST_binary_operator binary_operator) { binary_operator.LeftOperand.Accept(this); Variable left = this.Value.Copy(); binary_operator.RightOperand.Accept(this); Variable right = this.Value.Copy(); switch (left.Type) { case AST_type.AST_type_kind.bool_type: EvaluateBooleanBinaryOperator(binary_operator, left, right); break; case AST_type.AST_type_kind.int_type: EvaluateIntegerBinaryOperator(binary_operator, left, right); break; case AST_type.AST_type_kind.string_type: EvaluateStringBinaryOperator(binary_operator, left, right); break; default: break; } }
private void EvaluateIntegerBinaryOperator(AST_binary_operator binary_operator, Variable left, Variable right) { switch (binary_operator.Kind) { case AST_binary_operator.OperatorKind.Equal: this.value.Set(left.IntValue == right.IntValue); break; case AST_binary_operator.OperatorKind.Less: this.value.Set(left.IntValue < right.IntValue); break; case AST_binary_operator.OperatorKind.Plus: this.value.Set(left.IntValue + right.IntValue); break; case AST_binary_operator.OperatorKind.Minus: this.value.Set(left.IntValue - right.IntValue); break; case AST_binary_operator.OperatorKind.Asterisk: this.value.Set(left.IntValue * right.IntValue); break; case AST_binary_operator.OperatorKind.Slash: this.value.Set(left.IntValue / right.IntValue); break; default: break; } }
public virtual void Visit(AST_binary_operator binary_operator) { IncrementDepth(); binary_operator.LeftOperand.Accept(this); binary_operator.RightOperand.Accept(this); DecrementDepth(); }
private AST_binary_operator Parse_binary_operator(TokenKind followSet) { IncrementDepth(); AST_binary_operator binary_operator; Token t = GetNextToken(); DebugPrint("op " + t.Lexeme); AST_binary_operator.OperatorKind kind; switch (t.Kind) { case Plus: kind = AST_binary_operator.OperatorKind.Plus; break; case Minus: kind = AST_binary_operator.OperatorKind.Minus; break; case Asterisk: kind = AST_binary_operator.OperatorKind.Asterisk; break; case Slash: kind = AST_binary_operator.OperatorKind.Slash; break; case Less: kind = AST_binary_operator.OperatorKind.Less; break; case Equal: kind = AST_binary_operator.OperatorKind.Equal; break; case Ampersand: kind = AST_binary_operator.OperatorKind.Ampersand; break; default: Error("Binary operator expected.", t); kind = AST_binary_operator.OperatorKind.Plus; SkipUntilFollow(followSet); break; } binary_operator = new AST_binary_operator(kind); binary_operator.Row = t.Row; binary_operator.Column = t.Column; DecrementDepth(); return(binary_operator); }
private void EvaluateBooleanBinaryOperator(AST_binary_operator binary_operator, Variable left, Variable right) { switch (binary_operator.Kind) { case AST_binary_operator.OperatorKind.Ampersand: this.value.Set(left.BoolValue & right.BoolValue); break; case AST_binary_operator.OperatorKind.Equal: this.value.Set(left.BoolValue == right.BoolValue); break; default: break; } }
private AST_expression Parse_expression(TokenKind followSet) { IncrementDepth(); DebugPrint("expr"); AST_expression expression; Token t = LookAheadToken(); switch (t.Kind) { case Exclamation: expression = Parse_unary_operator_operand(followSet); break; default: if (isMemberOf(t.Kind, FirstSet_operand)) { AST_operand left_operand = Parse_operand(followSet | BinaryOperators); if (IsBinaryOperator(LookAheadToken().Kind)) { AST_binary_operator binary_operator = Parse_binary_operator(followSet); AST_operand right_operand = Parse_operand(followSet); binary_operator.SetLeft(left_operand); binary_operator.SetRight(right_operand); expression = binary_operator; } else { expression = left_operand; } } else { Error("Expression expected. '" + t.ToString() + "' does not start an expression.", t); expression = new ASTDummy_operand(); SkipUntilFollow(followSet); } break; } DecrementDepth(); return(expression); }
private void EvaluateStringBinaryOperator(AST_binary_operator binary_operator, Variable left, Variable right) { switch (binary_operator.Kind) { case AST_binary_operator.OperatorKind.Equal: this.value.Set(left.StringValue.Equals(right.StringValue)); break; case AST_binary_operator.OperatorKind.Less: this.value.Set(left.StringValue.CompareTo(right.StringValue) < 0); break; case AST_binary_operator.OperatorKind.Plus: this.value.Set(string.Concat(left.StringValue, right.StringValue)); break; default: break; } }
override public void Visit(AST_binary_operator binary_operator) { base.Visit(binary_operator); if (binary_operator.LeftOperand.DataType != binary_operator.RightOperand.DataType) { Error("Left and right operands of binary operator must be of same type.", binary_operator); } else { AST_type.AST_type_kind t = binary_operator.LeftOperand.DataType; switch (binary_operator.Kind) { case Ampersand: if (t != bool_type) { Error("Binary operator '&' requires bool operands.", binary_operator); } break; case Asterisk: if (t != int_type) { Error("Binary operator '*' requires int operands.", binary_operator); } break; case Equal: // All types accepted break; case Less: // All types accepted break; case Minus: if (t != int_type) { Error("Binary operator '-' requires int operands.", binary_operator); } break; case Plus: if (t == bool_type) { Error("Binary operator '+' requires int or string operands.", binary_operator); } break; case Slash: if (t != int_type) { Error("Binary operator '/' requires int operands.", binary_operator); } break; default: break; } } switch (binary_operator.Kind) { case Equal: case Less: case Ampersand: binary_operator.DataType = bool_type; break; default: binary_operator.DataType = binary_operator.LeftOperand.DataType; break; } }