public override void VisitRoutine(RoutineDefinition routine)
{
currentRoutine = routine;
MethodBuilder methodBuilder = routine.MethodBuilder;
ilGenerator = methodBuilder.GetILGenerator();
returnLabel = ilGenerator.DefineLabel();
localVariableStack = new RoutineLocalVariableStack();
foreach (Argument arg in routine.Arguments) {
if (arg.Mode == ArgumentMode.Out) {
ilGenerator.Emit(OpCodes.Ldarg, arg.Index);
Type argType = arg.RawType.GetElementType();
EmitVoid(argType);
EmitStind(argType);
}
}
routine.StatementList.Accept(this);
ilGenerator.MarkLabel(returnLabel);
ilGenerator.Emit(OpCodes.Ret);
if ((program.Target == Target.Exe ||
program.Target == Target.WinExe) &&
currentType.Name == "MAIN" &&
methodBuilder.Name == "main") {
MethodBuilder entryPoint =
currentType.DefineMethod("Main",
MethodAttributes.Public |
MethodAttributes.Static,
null, Type.EmptyTypes);
ILGenerator il = entryPoint.GetILGenerator();
il.Emit(OpCodes.Newobj, currentClass.Constructor);
il.EmitCall(OpCodes.Call, methodBuilder, null);
il.Emit(OpCodes.Ret);
PEFileKinds kind;
if (program.Target == Target.Exe)
kind = PEFileKinds.ConsoleApplication;
else
kind = PEFileKinds.WindowApplication;
program.Assembly.SetEntryPoint(entryPoint, kind);
}
currentRoutine = null;
}