public bool CheckSource()
{
if (Src.Length == 0) throw new ArgumentException(" ");
int State = 0;
for (int i = 0; i < Src.Length; i++)
{
if (Src[i] == '[') State++;
if (Src[i] == ']') State--;
// , .
if (State < 0) throw new ArgumentException(String.Format(" . : {0}", i++));
}
if (State != 0) Console.WriteLine(" .");
return State == 0;
}
AssemblyBuilder ASM = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("BrainFuck Compiled Program"), AssemblyBuilderAccess.RunAndSave); //
ASM.Save(Filename);
ModuleBuilder MDB = ASM.DefineDynamicModule(Filename); //
TypeBuilder TPB = MDB.DefineType("Program", TypeAttributes.Class); //
TPB.CreateType(); //
FieldBuilder FDB_1 = TPB.DefineField("Memory", typeof(byte[]), FieldAttributes.Private); // private byte[] Memory; // .
FieldBuilder FDB_2 = TPB.DefineField("Point", typeof(int), FieldAttributes.Private); //private int Point; // .
MethodBuilder MTB = TPB.DefineMethod("Main", MethodAttributes.Static, CallingConventions.Any); //static void Main() //Main Procedure
ASM.SetEntryPoint(MTB.GetBaseDefinition());
ILGenerator MTB_IL=MTB.GetILGenerator();
MTB_IL.Emit(OpCodes.Ldc_I4,30000); // 30000 -
MTB_IL.Emit(OpCodes.Newarr,typeof(byte)); // 30000
MTB_IL.Emit(OpCodes.Stsfld, FDB_1); // Memory
foreach (var t in Src) // , .
{
switch (t)
{
case '>':
{
MTB_IL.Emit(OpCodes.Ldsfld,FDB_2); // POINT
MTB_IL.Emit(OpCodes.Ldc_I4_1); // 1
MTB_IL.Emit(OpCodes.Add); //
MTB_IL.Emit(OpCodes.Stsfld,FDB_2); // Point
break;
}
case '<':
{
MTB_IL.Emit(OpCodes.Ldsfld, FDB_2);// POINT
MTB_IL.Emit(OpCodes.Ldc_I4_1); // 1
MTB_IL.Emit(OpCodes.Sub); //
MTB_IL.Emit(OpCodes.Stsfld, FDB_2); // Point
break;
}
case '+':
{
MTB_IL.Emit(OpCodes.Ldsfld, FDB_1);// MEMORY
MTB_IL.Emit(OpCodes.Ldsfld, FDB_2);// POINT
MTB_IL.Emit(OpCodes.Ldelema, typeof(byte)); // MEMORY[POINT]
MTB_IL.Emit(OpCodes.Dup);
MTB_IL.Emit(OpCodes.Ldobj, typeof(byte));
MTB_IL.Emit(OpCodes.Ldc_I4_1);
MTB_IL.Emit(OpCodes.Add); //
MTB_IL.Emit(OpCodes.Conv_U1);
MTB_IL.Emit(OpCodes.Stobj, typeof(byte));//
break;
}
case '-':
{
MTB_IL.Emit(OpCodes.Ldsfld, FDB_1);// MEMORY
MTB_IL.Emit(OpCodes.Ldsfld, FDB_2);// POINT
MTB_IL.Emit(OpCodes.Ldelema, typeof(byte));// MEMORY[POINT]
MTB_IL.Emit(OpCodes.Dup);
MTB_IL.Emit(OpCodes.Ldobj, typeof(byte));
MTB_IL.Emit(OpCodes.Ldc_I4_1);
MTB_IL.Emit(OpCodes.Sub); //
MTB_IL.Emit(OpCodes.Conv_U1);
MTB_IL.Emit(OpCodes.Stobj, typeof(byte));//
break;
}
case '[':
{
var Lbl = MTB_IL.DefineLabel(); //
MTB_IL.MarkLabel(Lbl); // ,
Scopes.Push(Lbl); // . :)
break;
}
case ']':
{
MTB_IL.Emit(OpCodes.Ldsfld, FDB_1); // 3
MTB_IL.Emit(OpCodes.Ldsfld, FDB_2); //
MTB_IL.Emit(OpCodes.Ldelem_U1); //FDB_1 FDB_2
MTB_IL.Emit(OpCodes.Ldc_I4_0); // 0
MTB_IL.Emit(OpCodes.Ceq); // =0
MTB_IL.Emit(OpCodes.Brtrue,5); //
MTB_IL.Emit(OpCodes.Br,Scopes.Pop()); // . 5 .
break;
}
case '.':
{
MTB_IL.Emit(OpCodes.Ldsfld, FDB_1);// MEMORY
MTB_IL.Emit(OpCodes.Ldsfld, FDB_2);// POINT
MTB_IL.Emit(OpCodes.Ldelem_U1);// MEMORY[POINT]
MTB_IL.EmitCall(OpCodes.Call,typeof(Console).GetMethod("WriteLine",new[] {typeof(char)}),new[] {typeof(char)}); //Console.WriteLine(MEMORY[POINT]);
MTB_IL.Emit(OpCodes.Nop);
break;
}
case ',':
{
MTB_IL.Emit(OpCodes.Ldsfld, FDB_1);// MEMORY
MTB_IL.Emit(OpCodes.Ldsfld, FDB_2);// POINT
MTB_IL.EmitCall(OpCodes.Call, typeof(Console).GetMethod("ReadLine"), new[] { typeof(string) }); //Console.ReadLine();
MTB_IL.Emit(OpCodes.Call,typeof(Convert).GetMethod("ToByte",new[] {typeof(string)})); // .
MTB_IL.Emit(OpCodes.Stelem_I1); //
break;
}
}
}
MTB_IL.Emit(OpCodes.Ret); //
TPB.CreateType(); //
ASM.Save(Filename); //
Source: https://habr.com/ru/post/113215/
All Articles