public static void EmitIf(IfStatement ifst, List<ILInstuction> il) { ILDummy end = new ILDummy(); end.Line = GetLabel(); foreach (var ic in ifst.Clauses) { ILBranch branch = new ILBranch(); ILDummy blockBegin = new ILDummy(); ILDummy blockEnd = new ILDummy(); branch.Line = GetLabel(); blockBegin.Line = GetLabel(); blockEnd.Line = GetLabel(); ILGoto gotoEnd = new ILGoto(end.Line); gotoEnd.Line = GetLabel(); branch.SuccessJump = blockBegin.Line; branch.FailJump = blockEnd.Line; branch.Condition = ConstructILExpression(ic.Condition); il.Add(branch); il.Add(blockBegin); EmitStatementList(ic.Statements, il); il.Add(gotoEnd); il.Add(blockEnd); } if (ifst.AlternativeStatements != null) { EmitStatementList(ifst.AlternativeStatements, il); } il.Add(end); }
public static void _EmitWhileDo(WhileDoStatement wd, List<ILInstuction> il) { var begin = new ILDummy(); begin.Line = GetLabel(); il.Add(begin); var condtitionVariable = _EmitExpression(wd.Condition, il); CurrentFunction.AddLocal(condtitionVariable, wd.Condition.ResultType); var conditionIl = new ILBranch(); conditionIl.Condition = _constructVariableAccess(condtitionVariable); il.Add(conditionIl); var bodyBegin = new ILDummy(); bodyBegin.Line = GetLabel(); var bodyEnd = new ILDummy(); bodyEnd.Line = GetLabel(); il.Add(bodyBegin); _EmitStatementList(wd.Statements, il); var gotoBeginIl = new ILGoto(begin.Line); il.Add(gotoBeginIl); il.Add(bodyEnd); conditionIl.FailJump = bodyEnd.Line; conditionIl.SuccessJump = bodyBegin.Line;; }
public static void _EmitIf(IfStatement ifst, List<ILInstuction> il) { ILDummy end = new ILDummy(); end.Line = GetLabel(); foreach (var ic in ifst.Clauses) { ILBranch branch = new ILBranch(); ILDummy blockBegin = new ILDummy(); ILDummy blockEnd = new ILDummy(); branch.Line = GetLabel(); blockBegin.Line = GetLabel(); blockEnd.Line = GetLabel(); ILGoto gotoEnd = new ILGoto(end.Line); gotoEnd.Line = GetLabel(); branch.SuccessJump = blockBegin.Line; branch.FailJump = blockEnd.Line; var ifConditionVariable = _EmitExpression(ic.Condition, il); CurrentFunction.AddLocal(ifConditionVariable, ic.Condition.ResultType); branch.Condition = _constructVariableAccess(ifConditionVariable); il.Add(branch); il.Add(blockBegin); _EmitStatementList(ic.Statements, il); il.Add(gotoEnd); il.Add(blockEnd); } if (ifst.AlternativeStatements != null) { _EmitStatementList(ifst.AlternativeStatements, il); } il.Add(end); }
public static string _EmitExpression(Expression expr, List<ILInstuction> il) { if (expr.IsLeaf) { //Variable access if (expr.LeafType == ExpressionLeafType.VariableAccess) { CurrentFunction.AddLocal(expr.Value.ToString(), expr.ResultType); return expr.Value.ToString(); } else if (expr.LeafType == ExpressionLeafType.Constant) { var resultVariable = GetVariableName(); object c; if (expr.ResultType == VariableType.IntType) c = expr.IntValue; else if (expr.ResultType == VariableType.BoolType) c = expr.BoolValue; else c = expr.Value; var ilExpr = _constructAssignExpressionToConst(resultVariable, c); il.Add(ilExpr); //ilExpr.OriginalType = expr.ResultType; CurrentFunction.AddLocal(resultVariable, expr.ResultType); return resultVariable; } else if (expr.LeafType == ExpressionLeafType.FunctionCall) { var ilExpr = new ILExpression(); ilExpr.Type = ILExpressionType.FunctionCall; ilExpr.Const = expr.Value; ilExpr.VAList = new List<ILExpression>(); foreach (var expression in expr.VAList) { var parameterVariable = _EmitExpression(expression, il); ilExpr.VAList.Add(_constructVariableAccess(parameterVariable)); } ilExpr.Function = FindFunction((string)ilExpr.Const, expr.VAList); //TODO: Add support for void functions; //ilExpr.OriginalType = expr.ResultType; if (ilExpr.Function.IsVoidReturn) { il.Add(ilExpr); return "void"; } else { var resultVariable = GetVariableName(); var resultExpr = _constructAssignExpression(resultVariable, ilExpr); il.Add(resultExpr); CurrentFunction.AddLocal(resultVariable, expr.ResultType); return resultVariable; } } else if (expr.LeafType == ExpressionLeafType.ArrayLength) { var leftOp = _EmitExpression(expr.LeftNode, il); var ilExpr = new ILExpression(); ilExpr.Type = ILExpressionType.ArrayLength; ilExpr.LeftNode = _constructVariableAccess(leftOp); var resultVariable = GetVariableName(); var resultExpr = _constructAssignExpression(resultVariable, ilExpr); il.Add(resultExpr); //resultExpr.OriginalType = expr.ResultType; CurrentFunction.AddLocal(resultVariable, expr.ResultType); return resultVariable; } else if (expr.LeafType == ExpressionLeafType.ArrayAlloc) { var leftOp = _EmitExpression(expr.LeftNode, il); var ilExpr = new ILExpression(); ilExpr.Type = ILExpressionType.Alloc; ilExpr.OriginalType = expr.ResultType; ilExpr.LeftNode = _constructVariableAccess(leftOp); var resultVariable = GetVariableName(); var resultExpr = _constructAssignExpression(resultVariable, ilExpr); il.Add(resultExpr); CurrentFunction.AddLocal(resultVariable, expr.ResultType); return resultVariable; } } else { if (expr.OpType == OperationType.Assign) { var rightOp = _EmitExpression(expr.RightNode, il); if (expr.LeftNode.LeafType == ExpressionLeafType.VariableAccess) { var leftOp = _EmitExpression(expr.LeftNode, il); il.Add(_constructAssignExpression(leftOp, rightOp)); CurrentFunction.AddLocal(leftOp, expr.ResultType); return leftOp; } else if (expr.LeftNode.OpType == OperationType.ArrayAccess) { // Emit ( E1[E2] = E3) = // Emit (E3) --> R // Emit (E1) --> A // Emit (E2) --> I // A[I] = R // return R; var arrLeftOp = _EmitExpression(expr.LeftNode.LeftNode, il); var arrIndexOp = _EmitExpression(expr.LeftNode.RightNode, il); var arrAccess = _constructBinaryExpressionFromVars(arrLeftOp, arrIndexOp, OperationType.ArrayAccess); var assignExpr = _constructAssignExpression(arrAccess, rightOp); il.Add(assignExpr); // assignExprstring resultVar = GetVariableName(); // var secondAssignExpr = _constructAssignExpression(resultVar, arrAccess); // il.Add(secondAssignExpr); return rightOp; } else { throw new InvalidOperationException("Bad assign construction!"); } } else if (expr.OpType == OperationType.And) { var leftOp = _EmitExpression(expr.LeftNode, il); CurrentFunction.AddLocal(leftOp, expr.ResultType); var branch = new ILBranch(); branch.Line = GetLabel(); branch.Condition = _constructVariableAccess(leftOp); var succ = new ILDummy(); succ.Line = GetLabel(); var fail = new ILDummy(); fail.Line = GetLabel(); var end = new ILDummy(); end.Line = GetLabel(); var gotoEnd = new ILGoto(end.Line); branch.SuccessJump = succ.Line; branch.FailJump = fail.Line; var resultVariable = GetVariableName(); il.Add(branch); il.Add(succ); var rightOp = _EmitExpression(expr.RightNode, il); CurrentFunction.AddLocal(rightOp, expr.ResultType); il.Add(_constructAssignExpression(resultVariable, rightOp)); il.Add(gotoEnd); il.Add(fail); il.Add(_constructAssignExpressionToConst(resultVariable, false)); il.Add(end); CurrentFunction.AddLocal(resultVariable, expr.ResultType); return resultVariable; } else if (expr.OpType == OperationType.Or) { var leftOp = _EmitExpression(expr.LeftNode, il); CurrentFunction.AddLocal(leftOp, expr.ResultType); var branch = new ILBranch(); branch.Line = GetLabel(); branch.Condition = _constructVariableAccess(leftOp); var succ = new ILDummy(); succ.Line = GetLabel(); var fail = new ILDummy(); fail.Line = GetLabel(); var end = new ILDummy(); end.Line = GetLabel(); var gotoEnd = new ILGoto(end.Line); branch.SuccessJump = succ.Line; branch.FailJump = fail.Line; var resultVariable = GetVariableName(); il.Add(branch); il.Add(fail); var rightOp = _EmitExpression(expr.RightNode, il); CurrentFunction.AddLocal(rightOp, expr.ResultType); il.Add(_constructAssignExpression(resultVariable, rightOp)); il.Add(gotoEnd); il.Add(succ); il.Add(_constructAssignExpressionToConst(resultVariable, true)); il.Add(end); CurrentFunction.AddLocal(resultVariable, expr.ResultType); return resultVariable; } else if (expr.OpType == OperationType.UNot || expr.OpType == OperationType.UMinus) { var op1 = _EmitExpression(expr.LeftNode, il); string varName= GetVariableName(); var ilExpr = _constructBinaryExpressionFromVars(op1, "", expr.OpType); il.Add(_constructAssignExpression(varName, ilExpr)); CurrentFunction.AddLocal(varName, expr.ResultType); return varName; } else { var op1 = _EmitExpression(expr.LeftNode, il); var op2 = _EmitExpression(expr.RightNode, il); string varName = GetVariableName(); var ilExpr = _constructBinaryExpressionFromVars(op1, op2, expr.OpType); il.Add(_constructAssignExpression(varName, ilExpr)); CurrentFunction.AddLocal(varName, expr.ResultType); return varName; } } throw new InvalidOperationException("Bad expression! " + expr.ToString()); }
public static void EmitWhileDo(WhileDoStatement wd, List<ILInstuction> il) { ILBranch branch = new ILBranch(); branch.Line = GetLabel(); branch.Condition = ConstructILExpression(wd.Condition); ILDummy succ = new ILDummy(); succ.Line = GetLabel(); ILDummy fail = new ILDummy(); fail.Line = GetLabel(); ILGoto gotoBegin = new ILGoto(branch.Line); branch.SuccessJump = succ.Line; branch.FailJump = fail.Line; il.Add(branch); il.Add(succ); EmitStatementList(wd.Statements, il); il.Add(gotoBegin); il.Add(fail); }