Exemple #1
0
        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);
            }
        }
Exemple #2
0
        protected internal virtual ExprAST VisitBinaryExprAST(BinaryExprAST node)
        {
            this.Visit(node.Lhs);
            this.Visit(node.Rhs);

            return node;
        }
Exemple #3
0
        protected internal virtual ExprAST VisitBinaryExprAST(BinaryExprAST node)
        {
            this.Visit(node.Lhs);
            this.Visit(node.Rhs);

            return(node);
        }
Exemple #4
0
        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)));
        }
Exemple #6
0
        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);
        }
Exemple #9
0
        // 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);
            }
        }