private ExprAst ParseAddSubstract() { var lhs = ParseMulDiv(); while (true) { Func <double, double, double> op = null; if (_tokenizer.Token == Token.Plus) { op = (a, b) => a + b; } else if (_tokenizer.Token == Token.Minus) { op = (a, b) => a - b; } if (op == null) { return(lhs); } _tokenizer.NextToken(); var rhs = ParseMulDiv(); lhs = new BinaryExprAST(lhs, rhs, op); } }
protected internal virtual ExprAST VisitBinaryExprAST(BinaryExprAST node) { this.Visit(node.Lhs); this.Visit(node.Rhs); return node; }
protected internal virtual ExprAST VisitBinaryExprAST(BinaryExprAST node) { this.Visit(node.Lhs); this.Visit(node.Rhs); return(node); }
protected internal override void VisitAST(BinaryExprAST node) { // for convenience, convert both of the LHS and RHS type explicitly var ty = (TypeKind) Math.Max((int) node.Lhs.RetType, (int) node.Rhs.RetType); this.Visit(node.Lhs); GenCode.Add(Ins.Conv(node.Lhs.RetType,ty)); this.Visit(node.Rhs); GenCode.Add(Ins.Conv(node.Rhs.RetType, ty)); var code = node.NodeType switch { ASTType.Add => Ins.Add(ty), ASTType.Subtract => Ins.Sub(ty), ASTType.Multiply => Ins.Mul(ty), ASTType.Divide => Ins.Div(ty), ASTType.Modulo => Ins.Mod(), ASTType.Equal => Ins.Equ(ty), ASTType.NotEqual => Ins.Neq(ty), ASTType.LessThan => Ins.Les(ty), ASTType.LessEqual => Ins.Leq(ty), ASTType.GreaterThan => Ins.Grt(ty), ASTType.GreaterEqual => Ins.Geq(ty), ASTType.And => Ins.And(), ASTType.Or => Ins.Or(), _ => throw new NotImplementedException() }; GenCode.Add(code); }
private static ASTNode ParseBinaryOperation(ASTNode leftNode) { if (curTok.token != Tokens.Token.OP) { ConsoleHelper.WriteErrorAST("Expected 'op'", curTok.y, curTok.x); } string oldOp = curTok.subString; int oldPriority = opPriority[oldOp]; ASTNode rightMember; GetNextToken(); if (curTok.token == Tokens.Token.PARENTHESIS_L) { rightMember = ParseParenthesis(); GetNextToken(); } else { rightMember = MemberBinOperation(); } if (rightMember == null) { ConsoleHelper.WriteErrorAST("Expected 'identificator'", curTok.y, curTok.x); } ASTNode binaryExpr; if (curTok.token == Tokens.Token.OP) { string newOp = curTok.subString; int newPriority = opPriority[newOp]; if (oldPriority > newPriority) { binaryExpr = new BinaryExprAST(oldOp, leftNode, rightMember, new Point(curTok.y, curTok.x)); return(ParseBinaryOperation(binaryExpr)); } else { Point point = new Point(curTok.y, curTok.x); ASTNode rightNode = ParseBinaryOperation(rightMember); binaryExpr = new BinaryExprAST(oldOp, leftNode, rightNode, point); return(binaryExpr); } } return(new BinaryExprAST(oldOp, leftNode, rightMember, new Point(curTok.y, curTok.x))); }
private ExprAst ParseMulDiv() { var lhs = ParseUnary(); while (true) { Func <double, double, double> op = null; if (_tokenizer.Token == Token.Pow) { op = Math.Pow; } if (_tokenizer.Token == Token.YRoot) { op = CalcMath.YRoot; } if (_tokenizer.Token == Token.Mul) { op = (a, b) => a * b; } else if (_tokenizer.Token == Token.Div) { op = (a, b) => a / b; } if (op == null) { return(lhs); } _tokenizer.NextToken(); var rhs = ParseUnary(); lhs = new BinaryExprAST(lhs, rhs, op); } }
protected override ExprAST VisitBinaryExprAST(BinaryExprAST node) { this.Visit(node.Lhs); this.Visit(node.Rhs); LLVMValueRef r = this.valueStack.Pop(); LLVMValueRef l = this.valueStack.Pop(); LLVMValueRef n; switch (node.NodeType) { case ExprType.AddExpr: n = LLVM.BuildFAdd(this.builder, l, r, "addtmp"); break; case ExprType.SubtractExpr: n = LLVM.BuildFSub(this.builder, l, r, "subtmp"); break; case ExprType.MultiplyExpr: n = LLVM.BuildFMul(this.builder, l, r, "multmp"); break; case ExprType.LessThanExpr: // Convert bool 0/1 to double 0.0 or 1.0 n = LLVM.BuildUIToFP(this.builder, LLVM.BuildFCmp(this.builder, LLVMRealPredicate.LLVMRealULT, l, r, "cmptmp"), LLVM.DoubleType(), "booltmp"); break; default: throw new Exception("invalid binary operator"); } this.valueStack.Push(n); return(node); }
private static ASTNode MemberBoolBinOperation(bool isAndOp = false) { GetNextToken(); switch (curTok.token) { case Tokens.Token.BOOL: return(new BoolAST(curTok.subString, new Point(curTok.y, curTok.x))); case Tokens.Token.STRING: case Tokens.Token.CHAR: case Tokens.Token.INT_VALUE: case Tokens.Token.DOUBLE_VALUE: case Tokens.Token.X16_VALUE: case Tokens.Token.X8_VALUE: case Tokens.Token.X2_VALUE: case Tokens.Token.ID: ASTNode leftNode = MemberBinOperation(); ASTNode leftNodeExp; if (curTok.token == Tokens.Token.OP) { leftNodeExp = ParseBinaryOperation(leftNode); } else { leftNodeExp = leftNode; } if (curTok.token == Tokens.Token.BOOL_OP) { string op = curTok.subString; GetNextToken(); ASTNode rightNodeExp = MemberBinOperation(); if (rightNodeExp == null) { ConsoleHelper.WriteErrorAST("Expected 'x'", curTok.y, curTok.x); } if (isAndOp) { ASTNode nodeExprLeft = new BinaryExprAST(op, leftNodeExp, rightNodeExp, new Point(curTok.y, curTok.x)); ASTNode boolNode = new BoolAST(nodeExprLeft, new Point(curTok.y, curTok.x)); return(boolNode); } string opBool; if (curTok.token == Tokens.Token.BOOL_OP_AND) { opBool = curTok.subString; ASTNode nodeExprLeft = new BinaryExprAST(op, leftNodeExp, rightNodeExp, new Point(curTok.y, curTok.x)); ASTNode boolNode = new BoolAST(nodeExprLeft, new Point(curTok.y, curTok.x)); ASTNode nodeExpRight = new BinaryExprAST(opBool, boolNode, MemberBoolBinOperation(true), new Point(curTok.y, curTok.x)); ASTNode nodeBool; while (curTok.token != Tokens.Token.PARENTHESIS_R) { string boolor = curTok.subString; ASTNode memberBoolOr = MemberBoolBinOperation(curTok.token == Tokens.Token.BOOL_OP_AND); nodeExpRight = new BinaryExprAST(boolor, memberBoolOr, nodeExpRight, new Point(curTok.y, curTok.x)); } nodeBool = nodeExpRight; return(new BoolAST(nodeBool, new Point(curTok.y, curTok.x))); } else if (curTok.token == Tokens.Token.BOOL_OP_OR) { opBool = curTok.subString; ASTNode nodeExprLeft = new BinaryExprAST(op, leftNodeExp, rightNodeExp, new Point(curTok.y, curTok.x)); ASTNode boolNode = new BoolAST(nodeExprLeft, new Point(curTok.y, curTok.x)); ASTNode nodeExpRight = new BinaryExprAST(opBool, boolNode, MemberBoolBinOperation(), new Point(curTok.y, curTok.x)); return(new BoolAST(nodeExpRight, new Point(curTok.y, curTok.x))); } else { ASTNode nodeExpr = new BinaryExprAST(op, leftNodeExp, rightNodeExp, new Point(curTok.y, curTok.x)); return(new BoolAST(nodeExpr, new Point(curTok.y, curTok.x))); } } ConsoleHelper.WriteErrorAST("Expected 'boolean'", curTok.y, curTok.x); return(null); case Tokens.Token.PARENTHESIS_L: return(ParseParenthesis()); default: ConsoleHelper.WriteErrorAST("Impossible token in this area", curTok.y, curTok.x); break; } return(null); }
// binoprhs // ::= ('+' primary)* private ExprAST ParseBinOpRHS(int exprPrec, ExprAST lhs) { // If this is a binop, find its precedence. while (true) { int tokPrec = this.scanner.GetTokPrecedence(); // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done. if (tokPrec < exprPrec) { return lhs; } // Okay, we know this is a binop. int binOp = this.scanner.CurrentToken; this.scanner.GetNextToken(); // eat binop // Parse the primary expression after the binary operator. ExprAST rhs = this.ParsePrimary(); if (rhs == null) { return null; } // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int nextPrec = this.scanner.GetTokPrecedence(); if (tokPrec < nextPrec) { rhs = this.ParseBinOpRHS(tokPrec + 1, rhs); if (rhs == null) { return null; } } // Merge LHS/RHS. lhs = new BinaryExprAST((char)binOp, lhs, rhs); } }