рдореИрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдмреНрд░реЗрдирдлреИрдХ рд╕рдкреНрддрд╛рд╣ рд╣реИ рдФрд░ рдореИрдВрдиреЗ рдПрдХ рдХрдВрдкрд╛рдЗрд▓рд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЦрд╛рд╕рдХрд░ рдЬрдм рд╕реЗ рдЙрдиреНрд╣реЛрдВрдиреЗ рдореБрдЭреЗ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рддрд░реАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рдХреЛрдб рд╕рдВрдХрд▓рди рдХреЗ рдЗрд╕ рддрд░реАрдХреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ рдФрд░ рд╕рдмрд╕реЗ
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐
.NET рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдореЗрдВ рдХрд┐рд╕реА рднреА рд╕реЛрд░реНрд╕ рдХреЛрдб рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ 3 рдХрд╛рдо рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ:
- рдПрдХ рдирдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ рдФрд░ System.Reflection рдФрд░ System.Reflection.Emit рдирд╛рдорд╕реНрдерд╛рди рдХреЛ рдЗрд╕рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ
- рд╕реНрд░реЛрдд рдХреЛрдб рдХрд╛ рдЗрдирдкреБрдЯ рдФрд░ рд╕рддреНрдпрд╛рдкрди рдкреНрд░рджрд╛рди рдХрд░реЗрдВ
- рдЗрд╕ рдХреЛрдб рдХреЛ рдПрдХ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ
рдФрд░ рдЕрдЧрд░ рдкрд╣рд▓реЗ рдХреЗ рд╕рд╛рде, рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ, рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА, рддреЛ рдЬрд╛рдБрдЪ рдФрд░ рд╕рдВрдХрд▓рди рдХреЗ рд╕рд╛рде рдХреБрдЫ рд╕рдорд╕реНрдпрд╛рдПрдВ рдкреИрджрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ рдпрджрд┐ рд╕рдорд╕реНрдпрд╛рдПрдВ рдирд╣реАрдВ рд╣реИрдВред
рдЗрд╕рд▓рд┐рдП, рд╕реЛрд░реНрд╕ рдХреЛрдб рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ
рд╢реБрджреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЗрд╕рдореЗрдВ рдХреМрди рд╕реЗ рдСрдкрд░реЗрдВрдб рд╣реИрдВред рдЙрдирдореЗрдВ рд╕реЗ рдХреЗрд╡рд▓ 8 рд╣реИрдВ:
- > - рдЕрдЧрд▓реА рд╕реЗрд▓ рдкрд░ рдЬрд╛рдПрдВ
- <- рдкрд┐рдЫрд▓реА рд╕реЗрд▓ рдкрд░ рдЬрд╛рдПрдВ
- + - рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдореЗрдВ рдорд╛рди 1 рд╕реЗ рдмрдврд╝рд╛рдПрдБ
- - - рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдореЗрдВ рдореВрд▓реНрдп 1 рд╕реЗ рдШрдЯрд╛рдПрдВ
- ред - рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рд╕реЗ рдореВрд▓реНрдп рдкреНрд░рд┐рдВрдЯ рдХрд░реЗрдВ
- , - рдмрд╛рд╣рд░ рд╕реЗ рдореВрд▓реНрдп рджрд░реНрдЬ рдХрд░реЗрдВ рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдореЗрдВ рд╕рд╣реЗрдЬреЗрдВ
- [- рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХрд╛ рдорд╛рди рд╢реВрдиреНрдп рд╣реИ, рддреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЯреЗрдХреНрд╕реНрдЯ рдореЗрдВ рд╕реЗрд▓ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЙрд╕реА рдХреЗ рдмрд╛рдж рдЖрдЧреЗ рдмрдврд╝реЗрдВ] (рд╢реВрдиреНрдп рдореЗрдВ рд▓реЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИ)
- ] - рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХрд╛ рдорд╛рди рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реИ, рддреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЯреЗрдХреНрд╕реНрдЯ рдореЗрдВ рдкреНрд░рддреАрдХ рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдПрдВ [(рдЦрд╛рддреЗ рдореЗрдВ рдШреЛрдВрд╕рд▓реЗ рдХрд╛ рд╢рд┐рдХрд╛рд░ рд╣реЛ рд░рд╣рд╛ рд╣реИ)
рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рд╕реНрд░реЛрдд рдХреЛрдб рд╕рд╣реА рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд╕реНрд░реЛрдд рдХреЛрдб рдЦрд╛рд▓реА рдирд╣реАрдВ рд╣реИ, рдФрд░ рдпрд╣ рдХрд┐ рдЫреЛрд░реЛрдВ рдХрд╛ рдШреЛрдВрд╕рд▓рд╛ рдЯреВрдЯрд╛ рдирд╣реАрдВ рд╣реИред
рдЪрд▓реЛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рдХреЛрдб рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ:
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;
}
рдлрд╝рдВрдХреНрд╢рди рдХреЗрд╡рд▓ рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреЛрдб рд╡рд╣рд╛рдВ рд╣реИ рдФрд░ рдЙрджреНрдШрд╛рдЯрди рдФрд░ рд╕рдорд╛рдкрди рдХреЛрд╖реНрдардХ рд╕рд╣реА рдХреНрд░рдо рдореЗрдВ рд╣реИрдВ, рдФрд░ рдЙрдирдХреА рд╕рдВрдЦреНрдпрд╛ рд╕рдорд╛рди рд╣реИред
рд╕рдВрдХрд▓рди
рддреБрд░рдВрдд рдПрдХ рдЖрд░рдХреНрд╖рдг рдХрд░реЗрдВ рдХрд┐ рд╣рдо 30,000 рдмрд╛рдЗрдЯреНрд╕ рдХреА рдореЗрдореЛрд░реА рд╕реАрдорд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдХрдВрдкрд╛рдЗрд▓рд░ рд▓рд╛рдЧреВ рдХрд░реЗрдВрдЧреЗред рдкреНрд░рддреНрдпреЗрдХ рдХреЛрд╢рд┐рдХрд╛ рдХрд╛ рдЖрдХрд╛рд░ 1 рдмрд╛рдЗрдЯ рд╣реЛрддрд╛ рд╣реИред
рдЙрд╕ рдкрд░ рдкрд░рд┐рдЪрд╛рд▓рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдХ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдпрд╛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдмрди рдЬрд╛рддрд╛ рд╣реИред
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());
рдЕрдм рдЖрдкрдХреЛ рдЙрди рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рдорд┐рд▓реЗ рдереЗред MSDN рдХрд╛ рдХрд╣рдирд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
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); //
рдЗрдЪреНрдЫрд╛ рд░рдЦрдиреЗ рд╡рд╛рд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдБ VS2010 рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб + .sln рд╣реИ
UPD: рдЕрд╕рд╛рдорд╛рдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреА рдУрд░ рдЕрдЧреНрд░рд╕рд░