Beispiel #1
0
 private void CodeCall(FuncCallExpression call, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il, List<Function> allFuncs, LocalBuilder tmpVar)
 {
     var func = FindFunc(call, allFuncs);
     foreach (var expression in call.Params)
         CodeExpression(expression, locals, globals, parameters, il, allFuncs, tmpVar);
     il.Emit(OpCodes.Call, func.Info);
 }
Beispiel #2
0
 public Function(string name, Type returnType, FuncParam[] parameters, Block body, MethodBuilder info)
 {
     Name = name;
     ReturnType = returnType;
     Params = parameters;
     Body = body;
     Info = info;
     ILGenerator = info.GetILGenerator();
 }
Beispiel #3
0
        private void CodeBinary(BinaryExpression binary, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il, List<Function> allFuncs, LocalBuilder tmpVar)
        {
            CodeExpression(binary.LeftOperand, locals, globals, parameters, il, allFuncs, tmpVar);
            CodeExpression(binary.RightOperand, locals, globals, parameters, il, allFuncs, tmpVar);
            var op = binary.Operator;

            if (!CodeLogicOp(op, il))
                if (!CodeGreatOp(op, il))
                    if (!CodeLessOp(op, il))
                        CodeMathOp(op, il);
        }
Beispiel #4
0
 private void CodeBlock(Block block, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il,
     Stack<Label> breaks, List<Function> allFuncs, LocalBuilder tmpVar)
 {
     foreach (var statement in block.Statements)
         CodeStatement(statement, locals, globals, parameters, il, breaks, allFuncs, tmpVar);
 }
Beispiel #5
0
        private FuncParam[] ProcessFuncParams(ParamDeclaration[] paramDeclarations)
        {
            var pars = new FuncParam[paramDeclarations.Length];

            for (int i = 0; i < paramDeclarations.Length; i++)
            {
                var type = GetType(paramDeclarations[i].Type, paramDeclarations[i].IsArray);
                pars[i] = new FuncParam(paramDeclarations[i].NewValue, type, i);
            }

            return pars;
        }
Beispiel #6
0
 private void CodeWrite(WriteStatement write, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il, List<Function> allFuncs, LocalBuilder tmpVar)
 {
     CodeExpression(write.Expression, locals, globals, parameters, il, allFuncs, tmpVar);
     il.Emit(OpCodes.Call, typeof (Console).GetMethod("Write", new Type[] {typeof (int)}));
 }
Beispiel #7
0
        private void CodeWhile(WhileStatement whileStatement, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il,
            Stack<Label> breaks, List<Function> allFuncs, LocalBuilder tmpVar)
        {
            var endLabel = il.DefineLabel();
            var startLabel = il.DefineLabel();
            breaks.Push(endLabel);

            il.MarkLabel(startLabel);
            CodeExpression(whileStatement.Condition, locals, globals, parameters, il, allFuncs, tmpVar);
            il.Emit(OpCodes.Brfalse_S, endLabel);
            CodeStatement(whileStatement.Statement, locals, globals, parameters, il, breaks, allFuncs, tmpVar);
            il.Emit(OpCodes.Br_S, startLabel);

            il.MarkLabel(breaks.Pop());
        }
Beispiel #8
0
 private void CodeUnary(UnaryExpression unary, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il, List<Function> allFuncs, LocalBuilder tmpVar)
 {
     CodeExpression(unary.Expression, locals, globals, parameters, il, allFuncs, tmpVar);
     if (unary.Operator == Terminals.Minus)
         il.Emit(OpCodes.Neg);
     else
     {
         il.Emit(OpCodes.Ldc_I4_0);
         il.Emit(OpCodes.Ceq);
     }
 }
Beispiel #9
0
 private void CodeGet(GetValueExpression get, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il)
 {
     var vname = GetVariableName(get);
     if (locals.Any(x => x.Name == vname))
     {
         var loc = locals.First(x => x.Name == vname);
         il.Emit(OpCodes.Ldloc, loc.Info);
     }
     else if (globals.Any(x => x.Name == vname))
     {
         var glo = globals.First(x => x.Name == vname);
         il.Emit(OpCodes.Ldsfld, glo.FieldInfo);
     }
     else
     {
         var par = parameters.First(x => x.Name == vname);
         il.Emit(OpCodes.Ldarg_S, (byte)par.Index);
     }
 }
Beispiel #10
0
        private void CodeSetArray(SetArrayValueExpression set, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il, List<Function> allFuncs, LocalBuilder tmpVar)
        {
            var vname = GetVariableName(set);
            Type t;
            if (locals.Any(x => x.Name == vname))
            {
                var loc = locals.First(x => x.Name == vname);
                t = loc.Type;
                il.Emit(OpCodes.Ldloc, loc.Info);
            }
            else if (globals.Any(x => x.Name == vname))
            {
                var glo = globals.First(x => x.Name == vname);
                t = glo.Type;
                il.Emit(OpCodes.Ldsfld, glo.FieldInfo);
            }
            else
            {
                var par = parameters.First(x => x.Name == vname);
                t = par.Type;
                il.Emit(OpCodes.Ldarg_S, (byte)par.Index);
            }

            CodeExpression(set.Index, locals, globals, parameters, il, allFuncs, tmpVar);
            CodeExpression(set.Value, locals, globals, parameters, il, allFuncs, tmpVar);
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Stloc, tmpVar);

            if (t == typeof (byte[]))
                il.Emit(OpCodes.Stelem_I1);
            else
                il.Emit(OpCodes.Stelem_I4);
            il.Emit(OpCodes.Ldloc, tmpVar);
        }
Beispiel #11
0
 private void CodeSet(SetValueExpression set, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il, List<Function> allFuncs, LocalBuilder tmpVar)
 {
     CodeExpression(set.Value, locals, globals, parameters, il, allFuncs, tmpVar);
     il.Emit(OpCodes.Dup);
     var vname = GetVariableName(set);
     if (locals.Any(x => x.Name == vname))
     {
         var loc = locals.First(x => x.Name == vname);
         il.Emit(OpCodes.Stloc, loc.Info);
     }
     else if (globals.Any(x => x.Name == vname))
     {
         var glo = globals.First(x => x.Name == vname);
         il.Emit(OpCodes.Stsfld, glo.FieldInfo);
     }
     else
     {
         var par = parameters.First(x => x.Name == vname);
         il.Emit(OpCodes.Starg_S, (byte)par.Index);
     }
 }
Beispiel #12
0
 private void CodeReturn(ReturnStatement returnStatement, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il, List<Function> allFuncs, LocalBuilder tmpVar)
 {
     CodeExpression(returnStatement.Expression, locals, globals, parameters, il, allFuncs, tmpVar);
     il.Emit(OpCodes.Ret);
 }
Beispiel #13
0
        private void CodeRead(ReadStatement readStatement, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il)
        {
            il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine", new Type[0]));
            il.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[]{typeof(string)}));

            var vname = GetVariableName(readStatement);
            if (locals.Any(x => x.Name == vname))
            {
                var loc = locals.First(x => x.Name == vname);
                il.Emit(OpCodes.Stloc, loc.Info);
            }
            else if (globals.Any(x => x.Name == vname))
            {
                var glo = globals.First(x => x.Name == vname);
                il.Emit(OpCodes.Stsfld, glo.FieldInfo);
            }
            else
            {
                var par = parameters.First(x => x.Name == vname);
                il.Emit(OpCodes.Starg_S, (byte)par.Index);
            }
        }
Beispiel #14
0
 private void CodeNumber(NumberExpression number, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il)
 {
     switch (number.Num.Value)
     {
         case 0:
             il.Emit(OpCodes.Ldc_I4_0);
             break;
         case 1:
             il.Emit(OpCodes.Ldc_I4_1);
             break;
         case 2:
             il.Emit(OpCodes.Ldc_I4_2);
             break;
         case 3:
             il.Emit(OpCodes.Ldc_I4_3);
             break;
         case 4:
             il.Emit(OpCodes.Ldc_I4_4);
             break;
         case 5:
             il.Emit(OpCodes.Ldc_I4_5);
             break;
         case 6:
             il.Emit(OpCodes.Ldc_I4_6);
             break;
         case 7:
             il.Emit(OpCodes.Ldc_I4_7);
             break;
         case 8:
             il.Emit(OpCodes.Ldc_I4_8);
             break;
         default:
             il.Emit(OpCodes.Ldc_I4, number.Num.Value);
             break;
     }
 }
Beispiel #15
0
 private void CodeIf(IfStatement ifStatement, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il,
     Stack<Label> breaks, List<Function> allFuncs, LocalBuilder tmpVar)
 {
     var trueJmp = il.DefineLabel();
     CodeExpression(ifStatement.Condition, locals, globals, parameters, il, allFuncs, tmpVar);
     il.Emit(OpCodes.Brtrue_S, trueJmp);
     CodeStatement(ifStatement.FalseStatement, locals, globals, parameters, il, breaks, allFuncs, tmpVar);
     il.MarkLabel(trueJmp);
     CodeStatement(ifStatement.TrueStatement, locals, globals, parameters, il, breaks, allFuncs, tmpVar);
 }
Beispiel #16
0
 private void CodeExpression(Expression expression, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il, List<Function> allFuncs, LocalBuilder tmpVar)
 {
     if (expression is BinaryExpression)
         CodeBinary(expression as BinaryExpression, locals, globals, parameters, il, allFuncs, tmpVar);
     else if (expression is FuncCallExpression)
         CodeCall(expression as FuncCallExpression, locals, globals, parameters, il, allFuncs, tmpVar);
     else if (expression is GetArrayValueExpression)
         CodeGetArray(expression as GetArrayValueExpression, locals, globals, parameters, il, allFuncs, tmpVar);
     else if (expression is GetValueExpression)
         CodeGet(expression as GetValueExpression, locals, globals, parameters, il);
     else if (expression is NumberExpression)
         CodeNumber(expression as NumberExpression, locals, globals, parameters, il);
     else if (expression is SetArrayValueExpression)
         CodeSetArray(expression as SetArrayValueExpression, locals, globals, parameters, il, allFuncs, tmpVar);
     else if (expression is SetValueExpression)
         CodeSet(expression as SetValueExpression, locals, globals, parameters, il, allFuncs, tmpVar);
     else if (expression is UnaryExpression)
         CodeUnary(expression as UnaryExpression, locals, globals, parameters, il, allFuncs, tmpVar);
     else
         throw new InvalidDataException();
 }
Beispiel #17
0
 private void CodeStatement(Statement statement, List<LocalVariable> locals, List<GlobalVariable> globals, FuncParam[] parameters, ILGenerator il, 
     Stack<Label> breaks, List<Function> allFuncs, LocalBuilder tmpVar)
 {
     if (statement is Block)
         CodeBlock(statement as Block, locals, globals, parameters, il, breaks, allFuncs, tmpVar);
     else if (statement is BreakStatement)
         CodeBreak(il, breaks);
     else if (statement is Expression)
     {
         CodeExpression(statement as Expression, locals, globals, parameters, il, allFuncs, tmpVar);
         il.Emit(OpCodes.Pop);
     }
     else if (statement is IfStatement)
         CodeIf(statement as IfStatement, locals, globals, parameters, il, breaks, allFuncs, tmpVar);
     else if (statement is ReadStatement)
         CodeRead(statement as ReadStatement, locals, globals, parameters, il);
     else if (statement is ReturnStatement)
         CodeReturn(statement as ReturnStatement, locals, globals, parameters, il, allFuncs, tmpVar);
     else if (statement is WhileStatement)
         CodeWhile(statement as WhileStatement, locals, globals, parameters, il, breaks, allFuncs, tmpVar);
     else if (statement is WriteStatement)
         CodeWrite(statement as WriteStatement, locals, globals, parameters, il, allFuncs, tmpVar);
     else if (statement is WritelnStatement)
         CodeWriteln(il);
     else
         throw new InvalidDataException();
 }