Example #1
0
        Exp parseCall()
        {
            //report("parseCall");
            List <Exp> exps = new List <Exp>();

            while (tape.Current.Kind == TokenKind.Ident || tape.Current.Kind == TokenKind.LBS || TokenKindHelper.IsLiteral(tape.Current.Kind))//|| CurrentKind == TokenKind.RBS
            {
                Exp term = parseChain();
                exps.Add(term);
            }
            if (exps.Count == 2 && (exps[0] is ExpType) && (exps[1] is ExpBracket))
            {
                ExpNew expNew = new ExpNew();
                expNew.TypeExp    = (exps[0] as ExpType);
                expNew.BracketExp = (exps[1] as ExpBracket);
                return(expNew);
            }
            else if (exps.Count == 0)
            {
                return(null);
            }
            else if (exps.Count == 1 && !(exps[0] is ExpProcNamePart))
            {
                return(exps[0]);
            }
            else
            {
                ExpCall callExp = new ExpCall();
                callExp.Elements = exps;
                return(callExp);
            }
        }
Example #2
0
        public Exp Parse(IEnumerable <object> elements, ContextExp context, bool isAssignTo)
        {
            this.ExpContext = context;
            this.IsAssignTo = isAssignTo;

            object[] objs    = parser.ParseItems(elements, context, this.IsAssignTo);
            int      objSize = objs.Length;

            if (objSize == 0)
            {
                return(null);
            }
            else if (objSize == 1)
            {
                return(Parse1(objs[0]));
            }
            else if (objSize == 2 && (objs[0] is ExpTypeBase) && IsArg(objs[1]))
            {
                return(ParseToExpNew((ExpTypeBase)objs[0], (Exp)objs[1]));
            }
            else
            {
                ExpCall callExp = new ExpCall(this.ExpContext, objs.Select(p => (Exp)p));
                return(callExp.Analy());
            }
        }
        private TreeExp BuildExpression(Expression expression)
        {
            switch (expression)
            {
            case Identifier id:
            {
                // TODO instance stuff
                if (env.ContainsKey(id.Name))
                {
                    return(new ExpTemp(env[id.Name]));
                }
                else if (parEnv.ContainsKey(id.Name))
                {
                    return(new ExpParam(parEnv[id.Name].Number));
                }
                else if (instanceVariables.ContainsKey(id.Name))
                {
                    int index = -1;
                    for (int i = 0; i < vshit.RawClass[currentClass].Length; i++)
                    {
                        if (vshit.RawClass[currentClass][i] == id.Name)
                        {
                            index = i;
                        }
                    }
                    if (index < 0)
                    {
                        throw new Exception("Instance Variable not found");
                    }
                    return(new ExpMem(new ExpBinOp(ExpBinOp.Op.PLUS, new ExpParam(0), new ExpBinOp(ExpBinOp.Op.MUL, new ExpConst(index), new ExpConst(WORDSIZE)))));
                }
                else
                {
                    throw new Exception("Could not find id in environment");
                }
            }

            case And and:
            {
                Label labelT = new Label();
                Label labelF = new Label();
                Label exit   = new Label();

                ExpTemp leftT  = new ExpTemp(new Temp());
                ExpTemp rightT = new ExpTemp(new Temp());

                return(new ExpESeq(new StmSeq(new List <TreeStm>()
                    {
                        new StmCJump(StmCJump.Relation.EQ, BuildExpression(and.Left), new ExpConst(1),
                                     labelT, labelF), new StmLabel(labelT), new StmMove(rightT, BuildExpression(and.Right)), new StmMove(leftT, new ExpConst(1)), new StmJump(new ExpName(exit), new List <Label> {
                            exit
                        }),
                        new StmLabel(labelF), new StmMove(rightT, new ExpConst(0)), new StmMove(leftT, new ExpConst(0)), new StmLabel(exit)
                    }), new ExpBinOp(ExpBinOp.Op.AND, leftT, rightT)));
            }

            case Plus plus:
            {
                return(new ExpBinOp(ExpBinOp.Op.PLUS, BuildExpression(plus.Left), BuildExpression(plus.Right)));
            }

            case Minus minus:
            {
                return(new ExpBinOp(ExpBinOp.Op.MINUS, BuildExpression(minus.Left), BuildExpression(minus.Right)));
            }

            case Times times:
            {
                return(new ExpBinOp(ExpBinOp.Op.MUL, BuildExpression(times.Left), BuildExpression(times.Right)));
            }

            case Division division:
            {
                return(new ExpBinOp(ExpBinOp.Op.DIV, BuildExpression(division.Left), BuildExpression(division.Right)));
            }

            case LessThan lt:
            {
                Label ltrue  = new Label();
                Label lfalse = new Label();
                Temp  temp   = new Temp();

                return(new ExpESeq(new StmSeq(new List <TreeStm>()
                    {
                        new StmMove(new ExpTemp(temp), new ExpConst(0)),
                        new StmCJump(StmCJump.Relation.LT, BuildExpression(lt.Left), BuildExpression(lt.Right), ltrue, lfalse),
                        new StmLabel(ltrue), new StmMove(new ExpTemp(temp), new ExpConst(1)), new StmLabel(lfalse)
                    }), new ExpTemp(temp)));
            }

            case GreaterThan gt:
            {
                throw new Exception("Not implemented");         // i dont care TODO
            }

            case ArrayAccess arrAcc:
            {
                ExpMem lengthMem = new ExpMem(BuildExpression(arrAcc.Index));

                Label   ltrue1     = new Label();
                Label   lfalse1    = new Label();
                Label   labelExit1 = new Label();
                ExpTemp test1      = new ExpTemp(new Temp());

                Label   ltrue2     = new Label();
                Label   lfalse2    = new Label();
                Label   labelExit2 = new Label();
                ExpTemp test2      = new ExpTemp(new Temp());

                Label   allTrue  = new Label();
                Label   allFalse = new Label();
                ExpTemp allTest  = new ExpTemp(new Temp());

                ExpConst trueConst  = new ExpConst(1);
                ExpConst falseConst = new ExpConst(0);

                ExpTemp result = new ExpTemp(new Temp());
                ExpCall error  = new ExpCall(new ExpName(RAISE), new List <TreeExp>()
                    {
                        new ExpConst(1)
                    });
                ExpMem positiveResult = new ExpMem(new ExpBinOp(ExpBinOp.Op.PLUS, BuildExpression(arrAcc.Index), new ExpBinOp(ExpBinOp.Op.MUL, new ExpConst(WORDSIZE), new ExpBinOp(ExpBinOp.Op.PLUS, BuildExpression(arrAcc.Val), new ExpConst(1)))));

                Label labelExit = new Label();

                // TODO überprüfen, ob sich der wert in den Arraygrenzen befindet sonst L_Raise callen
                return(new ExpESeq(new StmSeq(new List <TreeStm>()
                    {
                        new StmCJump(StmCJump.Relation.EQ, new ExpBinOp(ExpBinOp.Op.AND,
                                                                        new ExpESeq(new StmSeq(new List <TreeStm>()
                        {
                            new StmCJump(StmCJump.Relation.LT, BuildExpression(arrAcc.Val), lengthMem, ltrue1, lfalse1), new StmLabel(ltrue1), new StmMove(test1, trueConst), new StmJump(new ExpName(labelExit1), new List <Label>()
                            {
                                labelExit1
                            }), new StmLabel(lfalse1), new StmMove(test1, falseConst), new StmLabel(labelExit1)
                        }), test1),
                                                                        new ExpESeq(new StmSeq(new List <TreeStm>()
                        {
                            new StmCJump(StmCJump.Relation.GE, BuildExpression(arrAcc.Val), falseConst, ltrue2, lfalse2), new StmLabel(ltrue2), new StmMove(test2, trueConst), new StmJump(new ExpName(labelExit2), new List <Label>()
                            {
                                labelExit2
                            }), new StmLabel(lfalse2), new StmMove(test2, falseConst), new StmLabel(labelExit2)
                        }), test2)
                                                                        ), new ExpConst(1), allTrue, allFalse), new StmLabel(allTrue), new StmMove(result, positiveResult), new StmJump(new ExpName(labelExit), new List <Label>()
                        {
                            labelExit
                        }), new StmLabel(allFalse), new StmMove(result, error), new StmLabel(labelExit)
                    }), result));

                //return new ExpMem(new ExpBinOp(ExpBinOp.Op.PLUS, BuildExpression(arrAcc.Index), new ExpBinOp(ExpBinOp.Op.MUL, new ExpConst(WORDSIZE), new ExpBinOp(ExpBinOp.Op.PLUS, BuildExpression(arrAcc.Val), new ExpConst(1)))));
            }

            case ArrayLength arrlength:
            {
                return(new ExpMem(BuildExpression(arrlength.Exp)));
            }

            case MethodCall call:
            {
                List <TreeExp> parameters = new List <TreeExp>();

                if (call.Exp is This)
                {
                    parameters.Add(new ExpParam(0));
                }
                else
                {
                    parameters.Add(BuildExpression(call.Exp));
                }

                foreach (var parameter in call.Parameters)
                {
                    parameters.Add(BuildExpression(parameter));
                }

                return(new ExpCall(new ExpName(new Label(call.EnhancedName)), parameters));
            }

            case Read read:
            {
                //TODO
                throw new Exception("Not implemented");
            }

            case IntegerLit integerLit:
            {
                return(new ExpConst(integerLit.Val));
            }

            case BooleanLit booleanLit:
            {
                int val;
                val = booleanLit.Val ? 1 : 0;
                return(new ExpConst(val));
            }

            case This t:
            {
                return(new ExpParam(0));
            }

            case ArrayInstantiation arrayInst:
            {
                Temp temptemp = new Temp();
                return(new ExpESeq(new StmSeq(new List <TreeStm> {
                        new StmMove(new ExpTemp(temptemp), new ExpCall(new ExpName(HALLOC), new List <TreeExp> {
                            new ExpBinOp(ExpBinOp.Op.MUL, new ExpBinOp(ExpBinOp.Op.PLUS, BuildExpression(arrayInst.Length), new ExpConst(1)), new ExpConst(WORDSIZE))
                        })), new StmMove(new ExpMem(new ExpTemp(temptemp)), BuildExpression(arrayInst.Length))
                    }), new ExpTemp(temptemp)));
            }

            case ObjectInstantiation objInst:
            {
                return(new ExpCall(new ExpName(HALLOC), new List <TreeExp> {
                        new ExpConst((vshit.RawClass[objInst.ObjectId].Length) * WORDSIZE)
                    }));
            }

            case Not not:
            {
                return(new ExpBinOp(ExpBinOp.Op.MINUS, new ExpConst(1), BuildExpression(not.Exp)));
            }

            case Parent par:
            {
                return(BuildExpression(par.Exp));
            }

            default:
            {
                throw new Exception("Your expression is weird.");
            }
            }
        }