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); }
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(); }
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); }
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); }
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; }
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)})); }
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()); }
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); } }
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); } }
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); }
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); } }
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); }
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); } }
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; } }
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); }
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(); }
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(); }