1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . IO ;
4
+ using System . Reflection ;
5
+ using System . Reflection . Emit ;
6
+
7
+ namespace BrainSharp
8
+ {
9
+ internal class Program
10
+ {
11
+ private static ILGenerator ilg ;
12
+ private static LocalBuilder v3 ;
13
+
14
+ private static Stack < Label > labels ;
15
+ private static Stack < Label > labels2 ;
16
+
17
+ private static void Main ( string [ ] args )
18
+ {
19
+ labels = new Stack < Label > ( ) ;
20
+ labels2 = new Stack < Label > ( ) ;
21
+
22
+ AssemblyName name = new AssemblyName ( ) ;
23
+ name . Name = "Test" ;
24
+ AssemblyBuilder bld = AppDomain . CurrentDomain . DefineDynamicAssembly ( name , AssemblyBuilderAccess . Save ) ;
25
+
26
+ ModuleBuilder mb = bld . DefineDynamicModule ( name . Name , "Hello.exe" ) ;
27
+
28
+ TypeBuilder tb = mb . DefineType ( "Program" , TypeAttributes . Public | TypeAttributes . Class ) ;
29
+ MethodBuilder fb = tb . DefineMethod ( "Main" , MethodAttributes . Public | MethodAttributes . Static , typeof ( void ) , new Type [ ] { typeof ( string [ ] ) } ) ;
30
+
31
+ ilg = fb . GetILGenerator ( ) ;
32
+
33
+ ilg . DeclareLocal ( typeof ( byte [ ] ) ) ;
34
+ ilg . DeclareLocal ( typeof ( Int32 ) ) ;
35
+ ilg . DeclareLocal ( typeof ( bool ) ) ;
36
+ v3 = ilg . DeclareLocal ( typeof ( ConsoleKeyInfo ) ) ;
37
+
38
+ ilg . Emit ( OpCodes . Ldc_I4 , 30000 ) ;
39
+ ilg . Emit ( OpCodes . Newarr , typeof ( byte ) ) ;
40
+ ilg . Emit ( OpCodes . Stloc_0 ) ;
41
+
42
+ char [ ] code ;
43
+ int cp = 0 ;
44
+
45
+ if ( args . Length == 0 )
46
+ code = Console . ReadLine ( ) . ToCharArray ( ) ;
47
+ else
48
+ code = File . ReadAllText ( args [ 0 ] ) . ToCharArray ( ) ;
49
+
50
+ while ( cp < code . Length )
51
+ {
52
+ char c = code [ cp ] ;
53
+
54
+ switch ( c )
55
+ {
56
+ case '<' : EmitMpMinus ( ) ; break ;
57
+ case '>' : EmitMpPlus ( ) ; break ;
58
+ case '+' : EmitMemPlus ( ) ; break ;
59
+ case '-' : EmitMemMinus ( ) ; break ;
60
+ case '.' : EmitWrite ( ) ; break ;
61
+ case ',' : EmitRead ( ) ; break ;
62
+ case '[' : EmitLoopStart ( ) ; break ;
63
+ case ']' : EmitLoopEnd ( ) ; break ;
64
+ }
65
+
66
+ cp ++ ;
67
+ }
68
+
69
+ ilg . Emit ( OpCodes . Ret ) ;
70
+
71
+ Type t = tb . CreateType ( ) ;
72
+ // Set the entrypoint (thereby declaring it an EXE)
73
+ bld . SetEntryPoint ( fb , PEFileKinds . ConsoleApplication ) ;
74
+
75
+ // Save it
76
+ bld . Save ( "Hello.exe" ) ;
77
+ }
78
+
79
+ private static void EmitLoopStart ( )
80
+ {
81
+ var br = ilg . DefineLabel ( ) ;
82
+ ilg . Emit ( OpCodes . Br , br ) ;
83
+ labels . Push ( br ) ;
84
+
85
+ var br2 = ilg . DefineLabel ( ) ;
86
+ ilg . MarkLabel ( br2 ) ;
87
+ labels2 . Push ( br2 ) ;
88
+ }
89
+
90
+ private static void EmitLoopEnd ( )
91
+ {
92
+ var lcc = labels . Pop ( ) ;
93
+ ilg . MarkLabel ( lcc ) ;
94
+ ilg . Emit ( OpCodes . Ldloc_0 ) ;
95
+ ilg . Emit ( OpCodes . Ldloc_1 ) ;
96
+ ilg . Emit ( OpCodes . Ldelem_U1 ) ;
97
+ ilg . Emit ( OpCodes . Ldc_I4_0 ) ;
98
+ ilg . Emit ( OpCodes . Cgt_Un ) ;
99
+ ilg . Emit ( OpCodes . Stloc_2 ) ;
100
+ ilg . Emit ( OpCodes . Ldloc_2 ) ;
101
+ ilg . Emit ( OpCodes . Brtrue , labels2 . Pop ( ) ) ;
102
+ }
103
+
104
+ private static void EmitRead ( )
105
+ {
106
+ ilg . Emit ( OpCodes . Ldloc_0 ) ;
107
+ ilg . Emit ( OpCodes . Ldloc_1 ) ;
108
+ ilg . Emit ( OpCodes . Call , typeof ( Console ) . GetMethod ( "ReadKey" , new Type [ ] { } ) ) ;
109
+ ilg . Emit ( OpCodes . Stloc_3 ) ;
110
+ ilg . Emit ( OpCodes . Ldloca_S , v3 ) ;
111
+ ilg . Emit ( OpCodes . Call , typeof ( ConsoleKeyInfo ) . GetMethod ( "get_KeyChar" ) ) ;
112
+ ilg . Emit ( OpCodes . Conv_U1 ) ;
113
+ ilg . Emit ( OpCodes . Stelem_I1 ) ;
114
+ }
115
+
116
+ private static void EmitWrite ( )
117
+ {
118
+ ilg . Emit ( OpCodes . Ldloc_0 ) ;
119
+ ilg . Emit ( OpCodes . Ldloc_1 ) ;
120
+ ilg . Emit ( OpCodes . Ldelem_U1 ) ;
121
+ ilg . Emit ( OpCodes . Call , typeof ( Console ) . GetMethod ( "Write" , new Type [ ] { typeof ( char ) } ) ) ;
122
+ }
123
+
124
+ private static void EmitMemMinus ( )
125
+ {
126
+ ilg . Emit ( OpCodes . Ldloc_0 ) ;
127
+ ilg . Emit ( OpCodes . Ldloc_1 ) ;
128
+ ilg . Emit ( OpCodes . Ldelema , typeof ( byte ) ) ;
129
+ ilg . Emit ( OpCodes . Dup ) ;
130
+ ilg . Emit ( OpCodes . Ldind_U1 ) ;
131
+ ilg . Emit ( OpCodes . Ldc_I4_1 ) ;
132
+ ilg . Emit ( OpCodes . Sub ) ;
133
+ ilg . Emit ( OpCodes . Conv_U1 ) ;
134
+ ilg . Emit ( OpCodes . Stind_I1 ) ;
135
+ }
136
+
137
+ private static void EmitMemPlus ( )
138
+ {
139
+ ilg . Emit ( OpCodes . Ldloc_0 ) ;
140
+ ilg . Emit ( OpCodes . Ldloc_1 ) ;
141
+ ilg . Emit ( OpCodes . Ldelema , typeof ( byte ) ) ;
142
+ ilg . Emit ( OpCodes . Dup ) ;
143
+ ilg . Emit ( OpCodes . Ldind_U1 ) ;
144
+ ilg . Emit ( OpCodes . Ldc_I4_1 ) ;
145
+ ilg . Emit ( OpCodes . Add ) ;
146
+ ilg . Emit ( OpCodes . Conv_U1 ) ;
147
+ ilg . Emit ( OpCodes . Stind_I1 ) ;
148
+ }
149
+
150
+ private static void EmitMpPlus ( )
151
+ {
152
+ ilg . Emit ( OpCodes . Ldloc_1 ) ;
153
+ ilg . Emit ( OpCodes . Ldc_I4_1 ) ;
154
+ ilg . Emit ( OpCodes . Add ) ;
155
+ ilg . Emit ( OpCodes . Stloc_1 ) ;
156
+ }
157
+
158
+ private static void EmitMpMinus ( )
159
+ {
160
+ ilg . Emit ( OpCodes . Ldloc_1 ) ;
161
+ ilg . Emit ( OpCodes . Ldc_I4_1 ) ;
162
+ ilg . Emit ( OpCodes . Sub ) ;
163
+ ilg . Emit ( OpCodes . Stloc_1 ) ;
164
+ }
165
+ }
166
+ }
0 commit comments