void ASTVisitor.Accept(NodeInfix value) { Accept(value); }
internal void Accept(NodeInfix infix) { infix.left.Visit(this); infix.right.Visit(this); builder.currentLineNumber = infix.left.EndLine; builder.OpInfix(infix.op); }
private Node Factor(Node left, uint minp = 0) { // Here we have two options: // - There's an operator, and it's precedence is >= the current precedence. // - There's an identifier, and the current precedence >= the default precedence. // In either of these cases, the token must be on the same line as the expression. while (TokensRemain && ((Check(OPERATOR) && Laye.GetOperatorPrecedence(Current.image) >= minp) || ( Check(IDENTIFIER) && Laye.defaultOperatorPrecedence >= minp)) && Current.location.line == left.EndLine) { // We know it's either an operator OR a method name, determine which: var isOp = Check(OPERATOR); // Save the token and location, as well. var token = Current; // Skip past this token, time to finish this infix expression. Advance(); // Get an expression without checking infix. Node right = PrimaryExpression(); // End of file? if (right == null) { // TODO error } // Make sure we don't have a semi colon. else { // get our precedence var thisPrec = isOp ? Laye.GetOperatorPrecedence(token.image) : Laye.defaultOperatorPrecedence; // Basically we do the same as above // This time the precedence must be GREATER, but not equal. while (TokensRemain && ((Check(OPERATOR) && Laye.GetOperatorPrecedence(Current.image) > thisPrec) || ( Check(IDENTIFIER) && Laye.defaultOperatorPrecedence > thisPrec)) && Current.location.line == right.EndLine) { // Our right side is now the result of the infix operation. right = Factor(right, Current.type == OPERATOR ? Laye.GetOperatorPrecedence(Current.image) : Laye.defaultOperatorPrecedence); } } // Even if we hit an error, let's return some valid data! if (isOp) left = new NodeInfix(left, right, token.image); else left = new NodeInvoke(new NodeFieldIndex(left, token.image), new List<Node>() { right }); } return left; }