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); } }
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."); } } }