Exemplo n.º 1
0
        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());
        }
Exemplo n.º 2
0
 private static string m_getPreparedString(OperationType opType, Expression expr)
 {
     if (m_greaterPriority(opType, expr))
         return "(" + expr.ToString() + ")";
     else
         return expr.ToString();
 }