// Parse multiply/divide operations private INode ParseMultiplyDivide() { // Parse the left hand side var lhs = ParseUnary(); while (_tokensSequence.Current.Type == TokenType.Multiply || _tokensSequence.Current.Type == TokenType.Divide) { Func <double, double, double> op; if (_tokensSequence.Current.Type == TokenType.Multiply) { op = (a, b) => a * b; } else { op = (a, b) => a / b; } // Skip the operator _tokensSequence.MoveNext(); // Parse the right hand side of the expression var rhs = ParseUnary(); lhs = new BinaryOperationNode(lhs, rhs, op); } return(lhs); }
void BinaryOperationVisit(BinaryOperationNode node) { VariableManager.PushVariableCounter(); int t1 = VariableManager.IncrementVariableCounter(); VariableManager.PushVariableCounter(); node.LeftOperand.Accept(this); VariableManager.PopVariableCounter(); int t2 = VariableManager.IncrementVariableCounter(); VariableManager.PushVariableCounter(); node.RightOperand.Accept(this); VariableManager.PopVariableCounter(); VariableManager.PopVariableCounter(); if (node.LeftOperand.StaticType.Text == "String" && node.Symbol == "=") { IC.Add(new BinaryOperation(VariableManager.PeekVariableCounter(), t1, t2, "=:=")); return; } IC.Add(new BinaryOperation(VariableManager.PeekVariableCounter(), t1, t2, node.Symbol)); }
public void Accept(BinaryOperationNode node) { switch (node.BinaryOperation) { case BinaryOperation.Assignment: node.Right.Visit(this); // var = val if (node.Left is IdentifierNode) { string identifier = ((IdentifierNode)node.Left).Identifier; // Locals are lowercase HassiumWarning.EnforceCasing(module, node.Left.SourceLocation, identifier, HassiumCasingType.Lower); if (table.Scopes.Count == 2) { table.AddGlobalSymbol(identifier); } if (table.ContainsGlobalSymbol(identifier)) { emit(node.SourceLocation, InstructionType.StoreGlobal, identifier); emit(node.SourceLocation, InstructionType.LoadGlobal, identifier); } else { table.HandleSymbol(identifier); emit(node.SourceLocation, InstructionType.StoreLocal, table.GetSymbol(identifier)); emit(node.SourceLocation, InstructionType.LoadLocal, table.GetSymbol(identifier)); } } // var.attrib = val else if (node.Left is AttributeAccessNode) { AttributeAccessNode accessor = node.Left as AttributeAccessNode; accessor.Left.Visit(this); emit(node.SourceLocation, InstructionType.StoreAttribute, accessor.Right); accessor.Left.Visit(this); } // var [index] = val else if (node.Left is IterableAccessNode) { IterableAccessNode access = node.Left as IterableAccessNode; access.Index.Visit(this); access.Target.Visit(this); emit(node.SourceLocation, InstructionType.StoreIterableElement); } break; case BinaryOperation.Swap: emit(node.SourceLocation, InstructionType.Push, table.GetSymbol(((IdentifierNode)node.Left).Identifier)); emit(node.SourceLocation, InstructionType.Swap, table.GetSymbol(((IdentifierNode)node.Right).Identifier)); break; default: node.VisitChildren(this); emit(node.SourceLocation, InstructionType.BinaryOperation, (int)node.BinaryOperation); break; } }
private string GetExpression(BinaryOperationNode binOp, IDictionary <IFixing, string> fixingRefs) { var leftExpression = GetExpressionBase(binOp.Left, fixingRefs); var rightExpression = GetExpressionBase(binOp.Right, fixingRefs); return("(" + leftExpression + ")" + binOp.OpSymbol + "(" + rightExpression + ")"); }
private AstNode LogicalExpression() { var node = Comparison(); var token = Scanner.State.CurrentToken; while (_logicalExpressionOperators.Contains(token.Type)) { token = Scanner.State.CurrentToken; if (token.Type == TokenType.Or) { var line = Match(TokenType.Or); node = new BinaryOperationNode(node, BinaryOperationType.Or, Comparison()) { Line = line }; } else if (token.Type == TokenType.And) { var line = Match(TokenType.And); node = new BinaryOperationNode(node, BinaryOperationType.And, Comparison()) { Line = line }; } } return(node); }
private AstNode Term() { var node = Factor(); var token = Scanner.State.CurrentToken; while (_termOperators.Contains(token.Type)) { token = Scanner.State.CurrentToken; if (token.Type == TokenType.Multiply) { var line = Match(TokenType.Multiply); node = new BinaryOperationNode(node, BinaryOperationType.Multiply, Factor()) { Line = line }; } else if (token.Type == TokenType.Divide) { var line = Match(TokenType.Divide); node = new BinaryOperationNode(node, BinaryOperationType.Divide, Factor()) { Line = line }; } else if (token.Type == TokenType.BitwiseAnd) { var line = Match(TokenType.BitwiseAnd); node = new BinaryOperationNode(node, BinaryOperationType.BitwiseAnd, Factor()) { Line = line }; } else if (token.Type == TokenType.BitwiseOr) { var line = Match(TokenType.BitwiseOr); node = new BinaryOperationNode(node, BinaryOperationType.BitwiseOr, Factor()) { Line = line }; } else if (token.Type == TokenType.BitwiseXor) { var line = Match(TokenType.BitwiseXor); node = new BinaryOperationNode(node, BinaryOperationType.BitwiseXor, Factor()) { Line = line }; } else if (token.Type == TokenType.Modulo) { var line = Match(TokenType.Modulo); node = new BinaryOperationNode(node, BinaryOperationType.Modulo, Factor()) { Line = line }; } } return(node); }
/// <summary> /// Resolves Multiplication and division in PEMDAS order, let <see cref="ParseUnary"/> resolve negatives and such expresions /// </summary> /// <returns></returns> private static Node ParseMultiplyDivide() { Node lhs = ParseUnary(); while (true) { Func <int, int, int> op = null; switch (_tokenizer.CurrentToken) { case Token.Mul: { op = (a, b) => a * b; break; } case Token.Div: { op = (a, b) => a / b; break; } } if (op == null) { return(lhs); } _tokenizer.NextToken(); Node rhs = ParseUnary(); lhs = new BinaryOperationNode(lhs, rhs, op); } }
private AstNode Expression() { var node = Term(); var token = Scanner.State.CurrentToken; while (_expressionOperators.Contains(token.Type)) { token = Scanner.State.CurrentToken; if (token.Type == TokenType.Plus) { var line = Match(TokenType.Plus); node = new BinaryOperationNode(node, BinaryOperationType.Plus, Term()) { Line = line }; } else if (token.Type == TokenType.Minus) { var line = Match(TokenType.Minus); node = new BinaryOperationNode(node, BinaryOperationType.Minus, Term()) { Line = line }; } else if (token.Type == TokenType.ShiftLeft) { var line = Match(TokenType.ShiftLeft); node = new BinaryOperationNode(node, BinaryOperationType.ShiftLeft, Term()) { Line = line }; } else if (token.Type == TokenType.ShiftRight) { var line = Match(TokenType.ShiftRight); node = new BinaryOperationNode(node, BinaryOperationType.ShiftRight, Term()) { Line = line }; } else if (token.Type == TokenType.Or) { var line = Match(TokenType.Or); node = new BinaryOperationNode(node, BinaryOperationType.Or, Term()) { Line = line }; } else if (token.Type == TokenType.And) { var line = Match(TokenType.And); node = new BinaryOperationNode(node, BinaryOperationType.And, Term()) { Line = line }; } } return(node); }
private object Visit(BinaryOperationNode node) { bool isLeftInteger = node.LeftChild.Data.Type == TokenType.Integer; bool isRightInteger = node.RightChild.Data.Type == TokenType.Integer; switch (node.Data.Type) { case TokenType.Add: return((isLeftInteger ? (int)Visit(node.LeftChild) : (double)Visit(node.LeftChild)) + (isRightInteger ? (int)Visit(node.RightChild) : (double)Visit(node.RightChild))); case TokenType.Sub: return((isLeftInteger ? (int)Visit(node.LeftChild) : (double)Visit(node.LeftChild)) - (isRightInteger ? (int)Visit(node.RightChild) : (double)Visit(node.RightChild))); case TokenType.Mult: return((isLeftInteger ? (int)Visit(node.LeftChild) : (double)Visit(node.LeftChild)) * (isRightInteger ? (int)Visit(node.RightChild) : (double)Visit(node.RightChild))); case TokenType.Div: return((int)Visit(node.LeftChild) / (int)Visit(node.RightChild)); case TokenType.FloatDiv: return((double)Visit(node.LeftChild) / (double)Visit(node.RightChild)); default: throw new InvalidOperationException($"Token type {node.Data.Type} not expected for binary operations."); } }
private AstNode Comparison() { var node = Expression(); var token = Scanner.State.CurrentToken; if (token.Type == TokenType.CompareLessThan) { var line = Match(TokenType.CompareLessThan); node = new BinaryOperationNode(node, BinaryOperationType.Less, Expression()) { Line = line }; } else if (token.Type == TokenType.CompareGreaterThan) { var line = Match(TokenType.CompareGreaterThan); node = new BinaryOperationNode(node, BinaryOperationType.Greater, Expression()) { Line = line }; } else if (token.Type == TokenType.CompareLessOrEqualTo) { var line = Match(TokenType.CompareLessOrEqualTo); node = new BinaryOperationNode(node, BinaryOperationType.LessOrEqual, Expression()) { Line = line }; } else if (token.Type == TokenType.CompareGreaterOrEqualTo) { var line = Match(TokenType.CompareGreaterOrEqualTo); node = new BinaryOperationNode(node, BinaryOperationType.GreaterOrEqual, Expression()) { Line = line }; } else if (token.Type == TokenType.CompareEqual) { var line = Match(TokenType.CompareEqual); node = new BinaryOperationNode(node, BinaryOperationType.Equal, Expression()) { Line = line }; } else if (token.Type == TokenType.CompareNotEqual) { var line = Match(TokenType.CompareNotEqual); node = new BinaryOperationNode(node, BinaryOperationType.NotEqual, Expression()) { Line = line }; } return(node); }
private AstNode parseAnd() { AstNode left = parseBitshift(); while (acceptToken(TokenType.Operation, "&")) { left = new BinaryOperationNode(Location, BinaryOperation.BitwiseAnd, left, parseAnd()); } return(left); }
private AstNode parseXor() { AstNode left = parseAnd(); while (acceptToken(TokenType.Operation, "^")) { left = new BinaryOperationNode(Location, BinaryOperation.Xor, left, parseXor()); } return(left); }
private AstNode parseLogicalAnd() { AstNode left = parseEquality(); while (acceptToken(TokenType.Operation, "&&")) { left = new BinaryOperationNode(Location, BinaryOperation.LogicalAnd, left, parseLogicalAnd()); } return(left); }
/// <summary> /// 二元操作符 /// </summary> /// <param name="node"></param> public void Visit(BinaryOperationNode node) { var builder = new StringBuilder(); builder.Append("二元操作符:"); Console.WriteLine(builder.ToString()); Visit((Object)node.OperandA); Console.Write(node.OperationType); Visit((Object)node.OperandB); }
private AstNode parseLogicalOr() { var location = this.location; AstNode left = parseLogicalAnd(); while (acceptToken(TokenType.Operation, "||")) { left = new BinaryOperationNode(location, BinaryOperation.LogicalOr, left, parseLogicalOr()); } return(left); }
private AstNode parseXor() { var location = this.location; AstNode left = parseAnd(); while (acceptToken(TokenType.Operation, "^")) { left = new BinaryOperationNode(location, BinaryOperation.BitwiseXor, left, parseXor()); } return(left); }
public void InspectBinaryOperationNode() { AstNode left = MakeToken(TokenType.Number, "6"); Token op = MakeToken(TokenType.TimesSign, "*"); AstNode right = MakeToken(TokenType.Number, "9"); AstNode node = new BinaryOperationNode(left, op, right); Assert.That(node.Inspect(), Is.EqualTo( "BinaryOperationNode\r\n" + " LeftNode: Number |6|\r\n" + " OperatorNode: TimesSign |*|\r\n" + " RightNode: Number |9|")); }
public void ParseRuleSetsParentReferences() { BinaryOperationNode top = (BinaryOperationNode)_parser.ParseRule(RuleType.Expression); Assert.That(top.LeftNode.ParentNode, Is.SameAs(top), "Top.Left"); Assert.That(top.OperatorNode.ParentNode, Is.SameAs(top), "Top.Operator"); Assert.That(top.RightNode.ParentNode, Is.SameAs(top), "Top.Right"); BinaryOperationNode left = (BinaryOperationNode)top.LeftNode; Assert.That(left.LeftNode.ParentNode, Is.SameAs(left), "Left.Left"); Assert.That(left.OperatorNode.ParentNode, Is.SameAs(left), "Left.Operator"); Assert.That(left.RightNode.ParentNode, Is.SameAs(left), "Left.Right"); }
public override void VisitBinaryOperationNode(BinaryOperationNode node) { if (node.OperatorNode.Type == TokenType.ColonEquals) { base.VisitBinaryOperationNode(node); //base.Visit(node.RightNode); //AddCode(((Token)node.LeftNode).Text); //AddCode(" = "); //base.Visit(node.RightNode); } else { base.VisitBinaryOperationNode(node); } }
public override void Init(Irony.Parsing.ParsingContext context, Irony.Parsing.ParseTreeNode treeNode) { base.Init(context, treeNode); AddChild("deref", treeNode.ChildNodes[0]); var expressionNode = new BinaryOperationNode(); expressionNode.SetOp("+"); expressionNode.ChildNodes.Add(Child(0)); //offset expressionNode.ChildNodes.Add(Child(1)); //base pointer baseNode = Child(1); ChildNodes.Clear(); ChildNodes.Add(expressionNode); }
private TreeNode <Token> ParseTerm() { var result = ParseFactor(); var ops = new List <TokenType> { TokenType.Mult, TokenType.Div, TokenType.FloatDiv }; while (ops.Contains(Current.Type)) { var token = Current; Eat(TokenType.Mult, TokenType.Div, TokenType.FloatDiv); result = new BinaryOperationNode(token, result, ParseFactor()); } return(result); }
public void InspectNestedBinaryOperationNodes() { AstNode leftLeft = MakeToken(TokenType.Number, "2"); Token leftOp = MakeToken(TokenType.TimesSign, "*"); AstNode leftRight = MakeToken(TokenType.Number, "3"); Token op = MakeToken(TokenType.TimesSign, "*"); AstNode right = MakeToken(TokenType.Number, "9"); AstNode left = new BinaryOperationNode(leftLeft, leftOp, leftRight); AstNode node = new BinaryOperationNode(left, op, right); Assert.That(node.Inspect(), Is.EqualTo( "BinaryOperationNode\r\n" + " LeftNode: BinaryOperationNode\r\n" + " LeftNode: Number |2|\r\n" + " OperatorNode: TimesSign |*|\r\n" + " RightNode: Number |3|\r\n" + " OperatorNode: TimesSign |*|\r\n" + " RightNode: Number |9|")); }
private SyntaxNode ParseBinaryExpression(int parentPrecedence = 0) { SyntaxNode left = ParseUnaryOrParenthesisOrValue(); while (true) { var precedence = _tokens.Current.Kind.GetBinaryOperationPrecedence(); if (!_tokens.Current.Kind.IsInTokenGroup(SyntaxTokenGroup.Binary) || precedence <= parentPrecedence) { break; } var op = _tokens.GetAndMoveNext(); var right = ParseBinaryExpression(precedence); left = BinaryOperationNode.Create(left, op, right); } return(left); }
private TreeNode <Token> ParseExpression() { var result = ParseTerm(); var ops = new List <TokenType> { TokenType.Add, TokenType.Sub }; while (ops.Contains(Current.Type)) { var token = Current; Eat(TokenType.Add, TokenType.Sub); result = new BinaryOperationNode(token, result, ParseTerm()); } return(result); }
public SyntaxNode constructSyntaxNode(VisualNode e) { Debug.Log("Id of currentl constructing node is " + e.ID); SyntaxNode node = SyntaxNodeFactory.produce(e.ID); if (node is BlockNode) { if (node is IfNode) { //It should still retain while if is while IfNode ifBlock = (IfNode)node; BinaryOperationNode conditionalStatement = new BinaryOperationNode(); //Set it's attributes with fields in the operationVisual BlockVisual block = (BlockVisual)e; BinaryOperationVisual condition = (BinaryOperationVisual)block.condition; if (condition == null) { //Throw an exception } convertBinaryOperation((BinaryOperationNode)conditionalStatement, (BinaryOperationVisual)condition); ifBlock.SetCondition(conditionalStatement); } } else if (e is BinaryOperationVisual) { if (node is BinaryOperationNode) { convertBinaryOperation((BinaryOperationNode)node, (BinaryOperationVisual)e); } } //It should hold all it's changes. return(node); }
public override DynValue Visit(BinaryOperationNode binaryOperationNode) { var left = Visit(binaryOperationNode.LeftOperand); var right = Visit(binaryOperationNode.RightOperand); switch (binaryOperationNode.Type) { case BinaryOperationType.Plus: return(Addition(left, right, binaryOperationNode)); case BinaryOperationType.Minus: return(Subtraction(left, right, binaryOperationNode)); case BinaryOperationType.Multiply: if (left.Type == DynValueType.Number) { return(Multiplication(right, left, binaryOperationNode)); } else { return(Multiplication(left, right, binaryOperationNode)); } case BinaryOperationType.Divide: return(Division(left, right, binaryOperationNode)); case BinaryOperationType.Modulo: return(Modulus(left, right, binaryOperationNode)); case BinaryOperationType.ShiftLeft: return(ShiftLeft(left, right, binaryOperationNode)); case BinaryOperationType.ShiftRight: return(ShiftRight(left, right, binaryOperationNode)); case BinaryOperationType.BitwiseAnd: return(BitwiseAnd(left, right, binaryOperationNode)); case BinaryOperationType.BitwiseOr: return(BitwiseOr(left, right, binaryOperationNode)); case BinaryOperationType.BitwiseXor: return(BitwiseXor(left, right, binaryOperationNode)); case BinaryOperationType.Less: return(CompareLess(left, right, binaryOperationNode)); case BinaryOperationType.Greater: return(CompareGreater(left, right, binaryOperationNode)); case BinaryOperationType.LessOrEqual: return(CompareLessOrEqual(left, right, binaryOperationNode)); case BinaryOperationType.GreaterOrEqual: return(CompareGreaterOrEqual(left, right, binaryOperationNode)); case BinaryOperationType.NotEqual: return(CompareNotEqual(left, right, binaryOperationNode)); case BinaryOperationType.Equal: return(CompareEqual(left, right, binaryOperationNode)); case BinaryOperationType.And: return(LogicalAnd(left, right)); case BinaryOperationType.Or: return(LogicalOr(left, right)); default: throw new RuntimeException("Unknown binary operation.", binaryOperationNode.Line); } }
public void Accept(BinaryOperationNode node) { if (node.BinaryOperation != BinaryOperation.Assignment) { node.Right.Visit(this); node.Left.Visit(this); append("pop a"); append("pop b"); } switch (node.BinaryOperation) { case BinaryOperation.Assignment: node.Right.Visit(this); if (node.Left is IdentifierNode) { storeLocal(node.Left.SourceLocation, ((IdentifierNode)node.Left).Identifier, "b"); append("push b"); } else if (node.Left is IndexerNode) { append("pop c"); var indexer = node.Left as IndexerNode; indexer.Index.Visit(this); if (indexer.Target is IdentifierNode) { indexer.Target.Visit(this); } append("pop a"); append("pop b"); append("add a, b"); append("stob a, c"); append("push c"); } else if (node.Left is StaticAttributeAccessNode) { append("pop b"); string left = ((StaticAttributeAccessNode)node.Left).Left; string right = ((StaticAttributeAccessNode)node.Left).Right; Struct struct_ = structs[left]; if (!struct_.IsStatic) { throw new CompilerException(node.SourceLocation, "Static reference to non-static struct {0}!", left); } int location = BP_INITIAL + table.GetGlobalOffset(node.SourceLocation, left, true) + struct_.GetOffset(right); append("li a, {0}", location); switch (struct_.GetSize(right)) { case 1: append("stob a, b"); break; case 2: append("stow a, b"); break; } append("push b"); } break; case BinaryOperation.Addition: append("add a, b"); append("push a"); break; case BinaryOperation.Subtraction: append("sub a, b"); append("push a"); break; case BinaryOperation.Multiplication: append("mul a, b"); append("push a"); break; case BinaryOperation.Division: append("div a, b"); append("push a"); break; case BinaryOperation.Modulus: append("mod a, b"); append("push a"); break; case BinaryOperation.BitshiftLeft: append("shil a, b"); append("push a"); break; case BinaryOperation.BitshiftRight: append("shir a, b"); append("push a"); break; case BinaryOperation.BitwiseAnd: append("and a, b"); append("push a"); break; case BinaryOperation.BitwiseOr: append("or a, b"); append("push a"); break; case BinaryOperation.Xor: append("xor a, b"); append("push a"); break; case BinaryOperation.LogicalAnd: append("and a, b"); append("neqi a, 0"); append("push a"); break; case BinaryOperation.LogicalOr: append("or a, b"); append("neqi a, 0"); append("push a"); break; case BinaryOperation.Equality: append("eq a, b"); append("push a"); break; case BinaryOperation.Inequality: append("neq a, b"); append("push a"); break; case BinaryOperation.Greater: append("gt a, b"); append("push a"); break; case BinaryOperation.GreaterOrEqual: append("gte a, b"); append("push a"); break; case BinaryOperation.Lesser: append("lt a, b"); append("push a"); break; case BinaryOperation.LesserOrEqual: append("lte a, b"); append("push a"); break; } }
public virtual void VisitBinaryOperationNode(BinaryOperationNode node) { Visit(node.LeftNode); Visit(node.OperatorNode); Visit(node.RightNode); }
public override DynValue Visit(BinaryOperationNode binaryOperationNode) { var left = Visit(binaryOperationNode.LeftOperand); var right = Visit(binaryOperationNode.RightOperand); switch (binaryOperationNode.Type) { case BinaryOperationType.Plus: if (left.Type == DynValueType.String) { return(new DynValue(left.String + right.String)); } else { return(new DynValue(left.Number + right.Number)); } case BinaryOperationType.Minus: return(new DynValue(left.Number - right.Number)); case BinaryOperationType.Multiply: return(new DynValue(left.Number * right.Number)); case BinaryOperationType.Divide: return(new DynValue(left.Number / right.Number)); case BinaryOperationType.ShiftLeft: { if (left.Type != DynValueType.Number || right.Type != DynValueType.Number) { throw new RuntimeException("Attempt of left shift operation on a non-numerical value.", binaryOperationNode.Line); } if (left.Number % 1 != 0 || right.Number % 1 != 0) { throw new RuntimeException("'<<' operation is only allowed on integers.", binaryOperationNode.Line); } return(new DynValue((int)left.Number << (int)right.Number)); } case BinaryOperationType.ShiftRight: { if (left.Type != DynValueType.Number || right.Type != DynValueType.Number) { throw new RuntimeException("Attempt of right shift operation on a non-numerical value.", binaryOperationNode.Line); } if (left.Number % 1 != 0 || right.Number % 1 != 0) { throw new RuntimeException("'>>' operation is only allowed on integers.", binaryOperationNode.Line); } return(new DynValue((int)left.Number >> (int)right.Number)); } case BinaryOperationType.Nand: { if (left.Type != DynValueType.Number || right.Type != DynValueType.Number) { throw new RuntimeException("Attempt of NAND operation on a non-numerical value.", binaryOperationNode.Line); } if (left.Number % 1 != 0 || right.Number % 1 != 0) { throw new RuntimeException("NAND operation is only allowed on integers.", binaryOperationNode.Line); } return(new DynValue(~((int)left.Number & (int)right.Number))); } case BinaryOperationType.Modulo: return(new DynValue(left.Number % right.Number)); case BinaryOperationType.Less: if (left.Type == DynValueType.Number) { if (left.Number < right.Number) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else if (left.Type == DynValueType.String) { if (left.String.Length < right.String.Length) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else { throw new RuntimeException("'<' operator is only allowed on numbers and strings.", binaryOperationNode.Line); } case BinaryOperationType.Greater: if (left.Type == DynValueType.Number) { if (left.Number > right.Number) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else if (left.Type == DynValueType.String) { if (left.String.Length > right.String.Length) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else { throw new RuntimeException("'>' operator is only allowed on numbers and strings.", binaryOperationNode.Line); } case BinaryOperationType.LessOrEqual: if (left.Type == DynValueType.Number) { if (left.Number <= right.Number) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else if (left.Type == DynValueType.String) { if (left.String.Length <= right.String.Length) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else { throw new RuntimeException("'<=' operator is only allowed on numbers and strings.", binaryOperationNode.Line); } case BinaryOperationType.GreaterOrEqual: if (left.Type == DynValueType.Number) { if (left.Number >= right.Number) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else if (left.Type == DynValueType.String) { if (left.String.Length >= right.String.Length) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else { throw new RuntimeException("'>=' operator is only allowed on numbers and strings.", binaryOperationNode.Line); } case BinaryOperationType.NotEqual: if (left.Type == DynValueType.Number) { if (left.Number != right.Number) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else if (left.Type == DynValueType.String) { if (left.String.Length != right.String.Length && right.String != left.String) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else { throw new RuntimeException("'!=' operator is only allowed on numbers and strings.", binaryOperationNode.Line); } case BinaryOperationType.Equal: if (left.Type != right.Type) { throw new RuntimeException("Only values of the same type can be compared.", binaryOperationNode.Line); } if (left.Type == DynValueType.Number) { if (left.Number == right.Number) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else if (left.Type == DynValueType.String) { if (left.String.Length == right.String.Length && right.String == left.String) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else { throw new RuntimeException("'==' operator is only allowed on numbers and strings.", binaryOperationNode.Line); } case BinaryOperationType.And: if (left.Type == DynValueType.Number) { if (left.Number != 0 && right.Number != 0) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else { throw new RuntimeException("'and' operator is only allowed on numbers.", binaryOperationNode.Line); } case BinaryOperationType.Or: if (left.Type == DynValueType.Number) { if (left.Number != 0 || right.Number != 0) { return(new DynValue(1)); } else { return(new DynValue(0)); } } else { throw new RuntimeException("'or' operator is only allowed on numbers.", binaryOperationNode.Line); } default: throw new RuntimeException("Unknown binary operation.", binaryOperationNode.Line); } }
public abstract DynValue Visit(BinaryOperationNode binaryOperationNode);
public void Visit(Node node) { if (node is ArgumentsListNode) { VisitSubnodes(node); } else if (node is BinaryOperationNode) { BinaryOperationNode binop = (BinaryOperationNode)node; if (binop.BinaryOperation == BinaryOperation.Assignment) { if (binop.Left is IdentifierNode) { IdentifierNode ident = (IdentifierNode)binop.Left; if (!symbolTable.IsSymbolDefined(ident.Name)) { symbolTable.AddSymbol(ident.Name); } } } VisitSubnodes(node); } else if (node is ClassDeclarationNode) { throw new System.Exception("Can't define an class inside of an function."); } else if (node is CodeBlock) { VisitSubnodes(node); } else if (node is EnumDeclarationNode) { symbolTable.AddSymbol(((EnumDeclarationNode)node).Name); } else if (node is ExpressionNode) { VisitSubnodes(node); } else if (node is ForNode) { VisitSubnodes(node); } else if (node is FunctionCallNode) { VisitSubnodes(node); } else if (node is FunctionDeclarationNode) { throw new System.Exception("Can't define an function inside of an function."); } else if (node is GetAttributeNode) { VisitSubnodes(node); } else if (node is IfNode) { VisitSubnodes(node); } else if (node is IndexerNode) { VisitSubnodes(node); } else if (node is ReturnNode) { VisitSubnodes(node); } else if (node is ScopeNode) { symbolTable.BeginScope(); VisitSubnodes(node); symbolTable.EndScope(); } else if (node is FunctionDeclarationNode) { throw new System.Exception("Using statement is not valid inside function body."); } else if (node is WhileNode) { VisitSubnodes(node); } }
public static string InvalidUseOfOperator(BinaryOperationNode node, TypeInfo leftOperand, TypeInfo rightOperand) { return($"({node.Line}, {node.Column}) - Semantic Error:" + $" El operador '{node.Symbol}' no se puede aplicar a tipos '{leftOperand.Text}' y '{rightOperand.Text}'." ); }