meta_compile 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -3,7 +3,7 @@ meta_compile
3
3
 
4
4
  A meta compilation framework for Ruby à la [Meta-II by Val Schorre](http://ibm-1401.info/Meta-II-schorre.pdf).
5
5
 
6
- Uses a C version of Meta-II developed by Long Nguyen's ([meta](https://github.com/impeachgod/meta)) to bootstrap a Ruby version from a [fully self-contained 28 (non-empty) line specification file](https://raw.github.com/robertfeldt/meta_compile/master/bootstrap/meta_for_ruby.txt). The [generated Ruby Meta-II compiler file](https://github.com/robertfeldt/meta_compile/blob/master/bin/meta_compile) is 229 lines of non-empty Ruby code.
6
+ Uses a C version of Meta-II developed by Long Nguyen's ([meta](https://github.com/impeachgod/meta)) to bootstrap a Ruby version from a [fully self-contained 27 (non-empty) line specification file](https://raw.github.com/robertfeldt/meta_compile/master/bootstrap/meta_for_ruby.txt). The [generated Ruby Meta-II compiler file](https://github.com/robertfeldt/meta_compile/blob/master/bin/meta_compile) is 230 lines of non-empty Ruby code.
7
7
 
8
8
  Install
9
9
  -------
data/Rakefile ADDED
@@ -0,0 +1,111 @@
1
+ require 'fileutils'
2
+
3
+ # A system command that prints commands to stdout before running them
4
+ def pexec(str)
5
+ puts str
6
+ STDOUT.flush
7
+ system str
8
+ puts ""
9
+ end
10
+
11
+ desc "Bootstrap our version of Long Nguyen's C version of Meta-II"
12
+ task :bootstrap_c do
13
+ Dir.chdir "bootstrap"
14
+ puts "1. Build bootstrap compiler"
15
+ pexec "gcc -o bootstrapped_c bootstrap.c"
16
+ puts "2. Use the bootstrapped meta compiler to compile the meta_for_c.txt description of itself"
17
+ pexec "./bootstrapped_c meta_for_c.txt meta_compiler_from_boostrapped_c.c"
18
+ puts "3. Build the compiler we created from the meta description"
19
+ pexec "gcc -o meta_c meta_compiler_from_boostrapped_c.c"
20
+ puts "4. Now use the generated compiler to generate itself"
21
+ pexec "./meta_c meta_for_c.txt meta_compiler.c"
22
+ puts "5. Now ensure the compilers are exactly the same"
23
+ pexec "diff meta_compiler_from_boostrapped_c.c meta_compiler.c"
24
+ end
25
+
26
+ # Non-empty Lines of Code calc
27
+ def loc(filename)
28
+ File.readlines(filename).map {|l| l.strip.length==0?nil:l}.compact.length
29
+ end
30
+
31
+ desc "Bootstrap the Ruby Meta-II compiler"
32
+ task :bootstrap do
33
+ Dir.chdir("bootstrap") do
34
+ puts "1. Build bootstrap compiler"
35
+ pexec "gcc -o bootstrapped_c bootstrap.c"
36
+ puts "2. Use the c meta compiler to compile the meta_for_ruby.txt description"
37
+ pexec "./bootstrapped_c meta_for_ruby.txt compile_syntax_c_to_ruby.c"
38
+ puts "3. Build the stepping stone ruby compiler we created from the meta description"
39
+ pexec "gcc -o meta_r compile_syntax_c_to_ruby.c"
40
+ puts "4. Now use the generated stepping stone compiler to generate a ruby compiler for the ruby meta syntax"
41
+ pexec "./meta_r meta_for_ruby.txt meta_ruby_compiler_from_c.rb"
42
+ puts "5. Run the generated ruby meta compiler to a ruby version"
43
+ pexec "ruby -I. meta_ruby_compiler_from_c.rb meta_for_ruby.txt meta_ruby_compiler.rb"
44
+ puts "6. The Ruby version differ in that it has single quotes instead of double quotes around emitted strings"
45
+ #pexec "diff meta_ruby_compiler_from_c.rb meta_ruby_compiler.rb"
46
+ puts "7. But we can generate again and ensure it is a meta compiler"
47
+ pexec "ruby -I. meta_ruby_compiler.rb meta_for_ruby.txt meta_ruby_compiler2.rb"
48
+ pexec "diff meta_ruby_compiler.rb meta_ruby_compiler2.rb"
49
+ puts "8. One more round just to show off... :)"
50
+ pexec "ruby -I. meta_ruby_compiler2.rb meta_for_ruby.txt meta_ruby_compiler3.rb"
51
+ pexec "diff meta_ruby_compiler.rb meta_ruby_compiler3.rb"
52
+ puts "Summary:\nCreated a #{loc('meta_ruby_compiler.rb')} line meta-II meta compiler from a #{loc('meta_for_ruby.txt')} line meta-II spec\n\n"
53
+ end
54
+ end
55
+
56
+ desc "Make binary from the bootstrapped ruby meta-II compiler"
57
+ task :make_bin => [:bootstrap] do
58
+ # First ensure it is a meta compiler
59
+ puts "Ensure it is a meta-compiler"
60
+ pexec "ruby bootstrap/meta_ruby_compiler.rb bootstrap/meta_for_ruby.txt t.rb"
61
+ if File.read("t.rb") != File.read("bootstrap/meta_ruby_compiler.rb")
62
+ puts "ERROR: bootstrap/meta_ruby_compiler.rb is NOT a meta compiler"
63
+ exit(-1)
64
+ else
65
+ puts "YES it is meta!!!"
66
+ end
67
+ FileUtils.cp "bootstrap/meta_ruby_compiler.rb", "bin/meta_compile"
68
+ FileUtils.chmod 0755, "bin/meta_compile"
69
+ puts "Created binary in bin/meta_compile"
70
+ end
71
+
72
+ desc "Update line counts in README.template.md to make README.md"
73
+ task :update_readme => [:bootstrap] do
74
+ rmeta2_compiler_loc = loc('bootstrap/meta_ruby_compiler.rb')
75
+ rmeta2_spec_loc = loc('bootstrap/meta_for_ruby.txt')
76
+ readme = File.read("README.template.md").gsub("%%RMetaII_SPEC_LOC%%", rmeta2_spec_loc.to_s)
77
+ readme = readme.gsub("%%RMetaII_COMPILER_LOC%%", rmeta2_compiler_loc.to_s)
78
+ File.open("README.md", "w") {|f| f.puts readme}
79
+ end
80
+
81
+ task :default => :make_bin
82
+
83
+ desc "Build the gem"
84
+ task :build_gem => [:make_bin] do
85
+ pexec "rm *.gem"
86
+ pexec "gem build meta_compile.gemspec"
87
+ end
88
+
89
+ desc "Build and install gem"
90
+ task :install_gem => [:build_gem] do
91
+ pexec "sudo gem install meta_compile*.gem"
92
+ end
93
+
94
+ desc "Deploy gem"
95
+ task :deploy => [:install_gem] do
96
+ pexec "gem push meta_compile*.gem"
97
+ end
98
+
99
+ task :clean do
100
+ Dir.chdir("bootstrap") do
101
+ FileUtils.rm_f %w{bootstrapped_c meta_compiler_from_boostrapped_c.c meta_compiler.c meta_ruby_compiler2.rb meta_ruby_compiler3.rb meta_ruby_compiler_from_c.rb compile_syntax_c_to_ruby.c meta_c meta_r}
102
+ end
103
+ FileUtils.rm_f Dir.glob("t*.rb")
104
+ end
105
+
106
+ task :clobber => [:clean] do
107
+ Dir.chdir("bootstrap") do
108
+ FileUtils.rm_f %w{meta_ruby_compiler.rb meta_compile*.gem}
109
+ end
110
+ FileUtils.rm_f Dir.glob("meta_compile-*.gem")
111
+ end
data/bin/meta_compile CHANGED
@@ -218,7 +218,7 @@ raise("error at: " + @i.rest.split("\n")[0]) if !@f
218
218
  raise("error at: " + @i.rest.split("\n")[0]) if !@f
219
219
  @o.print 'end'
220
220
  @o.print "\n"
221
- @o.print 'begin; puts "Use: meta_compile <in> <out>"; exit; end if ARGV.length != 2'
221
+ @o.print 'begin; puts("Use: " + $0 + " <in> <out>"); exit; end if ARGV.length != 2'
222
222
  @o.print "\n"
223
223
  @o.print 'File.open(ARGV[1], "w") {|f| RMetaII.new.compile(File.read(ARGV[0]), f)}'
224
224
  @o.print "\n"
@@ -226,5 +226,5 @@ end
226
226
  end while false
227
227
  end
228
228
  end
229
- begin; puts "Use: meta_compile <in> <out>"; exit; end if ARGV.length != 2
229
+ begin; puts("Use: " + $0 + " <in> <out>"); exit; end if ARGV.length != 2
230
230
  File.open(ARGV[1], "w") {|f| RMetaII.new.compile(File.read(ARGV[0]), f)}
@@ -0,0 +1,260 @@
1
+ #include "support.h"
2
+
3
+ void meta_arg(void)
4
+ {
5
+ do {
6
+ read_literal("$");
7
+ if (test_flag) {
8
+ emit("emit_token();");
9
+ emit_nl();
10
+ }
11
+
12
+ if (test_flag) { break; }
13
+
14
+ read_string();
15
+ if (test_flag) {
16
+ emit("emit(");
17
+ emit_token();
18
+ emit(");");
19
+ emit_nl();
20
+ }
21
+ } while (0);
22
+ }
23
+
24
+ void meta_output(void)
25
+ {
26
+ do {
27
+ read_literal("<");
28
+ if (test_flag) {
29
+ do {
30
+ meta_arg();
31
+ } while (test_flag);
32
+ test_flag = 1;
33
+ error_if_false();
34
+
35
+ read_literal(">");
36
+ error_if_false();
37
+
38
+ emit("emit_nl();");
39
+ emit_nl();
40
+ }
41
+ } while (0);
42
+ }
43
+
44
+ void meta_exp3(void)
45
+ {
46
+ do {
47
+ read_id();
48
+ if (test_flag) {
49
+ emit("meta_");
50
+ emit_token();
51
+ emit("();");
52
+ emit_nl();
53
+ }
54
+
55
+ if (test_flag) { break; }
56
+
57
+ read_string();
58
+ if (test_flag) {
59
+ emit("read_literal(");
60
+ emit_token();
61
+ emit(");");
62
+ emit_nl();
63
+ }
64
+
65
+ if (test_flag) { break; }
66
+
67
+ read_literal(".id");
68
+ if (test_flag) {
69
+ emit("read_id();");
70
+ emit_nl();
71
+ }
72
+
73
+ if (test_flag) { break; }
74
+
75
+ read_literal(".number");
76
+ if (test_flag) {
77
+ emit("read_number();");
78
+ emit_nl();
79
+ }
80
+
81
+ if (test_flag) { break; }
82
+
83
+ read_literal(".string");
84
+ if (test_flag) {
85
+ emit("read_string();");
86
+ emit_nl();
87
+ }
88
+
89
+ if (test_flag) { break; }
90
+
91
+ read_literal("(");
92
+ if (test_flag) {
93
+ meta_exp1();
94
+ error_if_false();
95
+
96
+ read_literal(")");
97
+ error_if_false();
98
+ }
99
+
100
+ if (test_flag) { break; }
101
+
102
+ read_literal(".e");
103
+ if (test_flag) {
104
+ emit("test_flag = 1;");
105
+ emit_nl();
106
+ }
107
+
108
+ if (test_flag) { break; }
109
+
110
+ read_literal("*");
111
+ if (test_flag) {
112
+ emit("do {");
113
+ emit_nl();
114
+
115
+ meta_exp3();
116
+ error_if_false();
117
+
118
+ emit("} while (test_flag);");
119
+ emit_nl();
120
+
121
+ emit("test_flag = 1;");
122
+ emit_nl();
123
+ }
124
+ } while (0);
125
+ }
126
+
127
+ void meta_exp2(void)
128
+ {
129
+ do {
130
+ // open
131
+ do {
132
+ meta_exp3();
133
+ if (test_flag) {
134
+ emit("if (test_flag) {");
135
+ emit_nl();
136
+ }
137
+
138
+ if (test_flag) { break; }
139
+
140
+ meta_output();
141
+ if (test_flag) {
142
+ emit("if (1) {");
143
+ emit_nl();
144
+ }
145
+ } while (0);
146
+ // close
147
+
148
+ if (test_flag) {
149
+ do {
150
+ // open
151
+ do {
152
+ meta_exp3();
153
+ if (test_flag) {
154
+ emit("error_if_false();");
155
+ emit_nl();
156
+ }
157
+
158
+ if (test_flag) { break; }
159
+
160
+ meta_output();
161
+ if (test_flag) {
162
+ }
163
+ } while (0);
164
+ // close
165
+
166
+ } while (test_flag);
167
+ test_flag = 1;
168
+ error_if_false();
169
+
170
+ emit("}");
171
+ emit_nl();
172
+ }
173
+ } while (0);
174
+ }
175
+
176
+ void meta_exp1(void)
177
+ {
178
+ do {
179
+ emit("do {");
180
+ emit_nl();
181
+ if (1) {
182
+ meta_exp2();
183
+ error_if_false();
184
+
185
+ do {
186
+ // open
187
+ do {
188
+ read_literal("|");
189
+ if (test_flag) {
190
+ emit("if (test_flag) { break; }");
191
+ emit_nl();
192
+
193
+ meta_exp2();
194
+ error_if_false();
195
+ }
196
+ } while (0);
197
+ // close
198
+
199
+ } while (test_flag);
200
+ test_flag = 1;
201
+ error_if_false();
202
+
203
+ emit("} while (0);");
204
+ emit_nl();
205
+ }
206
+ } while (0);
207
+ }
208
+
209
+ void meta_stat(void)
210
+ {
211
+ do {
212
+ read_id();
213
+ if (test_flag) {
214
+ emit("void meta_");
215
+ emit_token();
216
+ emit("(void)");
217
+ emit_nl();
218
+
219
+ emit("{");
220
+ emit_nl();
221
+
222
+ read_literal("=");
223
+ error_if_false();
224
+
225
+ meta_exp1();
226
+ error_if_false();
227
+
228
+ read_literal(";");
229
+ error_if_false();
230
+
231
+ emit("}");
232
+ emit_nl();
233
+ }
234
+ } while (0);
235
+ }
236
+
237
+ void meta_program(void)
238
+ {
239
+ do {
240
+ read_literal(".syntax");
241
+ if (test_flag) {
242
+ read_id();
243
+ error_if_false();
244
+
245
+ emit("#include \"support.h\"");
246
+ emit_nl();
247
+
248
+ do {
249
+ meta_stat();
250
+ } while (test_flag);
251
+ test_flag = 1;
252
+ error_if_false();
253
+
254
+ read_literal(".end");
255
+ error_if_false();
256
+ }
257
+ } while (0);
258
+ }
259
+
260
+ // end
Binary file
@@ -0,0 +1,214 @@
1
+ #include "support.h"
2
+ void meta_outarg(void)
3
+ {
4
+ do {
5
+ read_literal("$");
6
+ if (test_flag) {
7
+ emit("@o.print @t");
8
+ emit_nl();
9
+ }
10
+ if (test_flag) { break; }
11
+ read_string();
12
+ if (test_flag) {
13
+ emit("@o.print ");
14
+ emit_token();
15
+ emit_nl();
16
+ }
17
+ } while (0);
18
+ }
19
+ void meta_out(void)
20
+ {
21
+ do {
22
+ read_literal("<");
23
+ if (test_flag) {
24
+ do {
25
+ meta_outarg();
26
+ } while (test_flag);
27
+ test_flag = 1;
28
+ error_if_false();
29
+ read_literal(">");
30
+ error_if_false();
31
+ emit("@o.print \"\\n\"");
32
+ emit_nl();
33
+ }
34
+ } while (0);
35
+ }
36
+ void meta_exp3(void)
37
+ {
38
+ do {
39
+ read_id();
40
+ if (test_flag) {
41
+ emit("compile_");
42
+ emit_token();
43
+ emit_nl();
44
+ }
45
+ if (test_flag) { break; }
46
+ read_string();
47
+ if (test_flag) {
48
+ emit("@i.scan /\\s*/; s=");
49
+ emit_token();
50
+ emit("; l=s.length;");
51
+ emit_nl();
52
+ emit("@f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil");
53
+ emit_nl();
54
+ }
55
+ if (test_flag) { break; }
56
+ read_literal(".id");
57
+ if (test_flag) {
58
+ emit("@i.scan /\\s*/; @f = @t = @i.scan /[A-Za-z]+[A-Za-z0-9_]+/");
59
+ emit_nl();
60
+ }
61
+ if (test_flag) { break; }
62
+ read_literal(".string");
63
+ if (test_flag) {
64
+ emit("@i.scan /\\s*/; @f = @t = @i.scan /\\047[^\\047]*\\047/");
65
+ emit_nl();
66
+ }
67
+ if (test_flag) { break; }
68
+ read_literal("(");
69
+ if (test_flag) {
70
+ meta_exp1();
71
+ error_if_false();
72
+ read_literal(")");
73
+ error_if_false();
74
+ }
75
+ if (test_flag) { break; }
76
+ read_literal(".e");
77
+ if (test_flag) {
78
+ emit("@f = true");
79
+ emit_nl();
80
+ }
81
+ if (test_flag) { break; }
82
+ read_literal("*");
83
+ if (test_flag) {
84
+ emit("begin");
85
+ emit_nl();
86
+ meta_exp3();
87
+ error_if_false();
88
+ emit("end while @f");
89
+ emit_nl();
90
+ emit("@f = true");
91
+ emit_nl();
92
+ }
93
+ } while (0);
94
+ }
95
+ void meta_exp2(void)
96
+ {
97
+ do {
98
+ do {
99
+ meta_exp3();
100
+ if (test_flag) {
101
+ emit("if @f");
102
+ emit_nl();
103
+ }
104
+ if (test_flag) { break; }
105
+ meta_out();
106
+ if (test_flag) {
107
+ emit("if true");
108
+ emit_nl();
109
+ }
110
+ } while (0);
111
+ if (test_flag) {
112
+ do {
113
+ do {
114
+ meta_exp3();
115
+ if (test_flag) {
116
+ emit("raise(\"error at: \" + @i.rest.split(\"\\n\")[0]) if !@f");
117
+ emit_nl();
118
+ }
119
+ if (test_flag) { break; }
120
+ meta_out();
121
+ if (test_flag) {
122
+ }
123
+ } while (0);
124
+ } while (test_flag);
125
+ test_flag = 1;
126
+ error_if_false();
127
+ emit("end");
128
+ emit_nl();
129
+ }
130
+ } while (0);
131
+ }
132
+ void meta_exp1(void)
133
+ {
134
+ do {
135
+ emit("begin");
136
+ emit_nl();
137
+ if (1) {
138
+ meta_exp2();
139
+ error_if_false();
140
+ do {
141
+ do {
142
+ read_literal("|");
143
+ if (test_flag) {
144
+ emit("break if @f");
145
+ emit_nl();
146
+ meta_exp2();
147
+ error_if_false();
148
+ }
149
+ } while (0);
150
+ } while (test_flag);
151
+ test_flag = 1;
152
+ error_if_false();
153
+ emit("end while false");
154
+ emit_nl();
155
+ }
156
+ } while (0);
157
+ }
158
+ void meta_rule(void)
159
+ {
160
+ do {
161
+ read_id();
162
+ if (test_flag) {
163
+ emit("def compile_");
164
+ emit_token();
165
+ emit_nl();
166
+ read_literal("=");
167
+ error_if_false();
168
+ meta_exp1();
169
+ error_if_false();
170
+ read_literal(";");
171
+ error_if_false();
172
+ emit("end");
173
+ emit_nl();
174
+ }
175
+ } while (0);
176
+ }
177
+ void meta_program(void)
178
+ {
179
+ do {
180
+ read_literal(".syntax");
181
+ if (test_flag) {
182
+ read_id();
183
+ error_if_false();
184
+ emit("#!/usr/bin/env ruby");
185
+ emit_nl();
186
+ emit("require \"strscan\"");
187
+ emit_nl();
188
+ emit("class ");
189
+ emit_token();
190
+ emit_nl();
191
+ emit("def compile(str, out)");
192
+ emit_nl();
193
+ emit("@i, @o = StringScanner.new(str), out");
194
+ emit_nl();
195
+ emit("compile_program");
196
+ emit_nl();
197
+ emit("end");
198
+ emit_nl();
199
+ do {
200
+ meta_rule();
201
+ } while (test_flag);
202
+ test_flag = 1;
203
+ error_if_false();
204
+ read_literal(".end");
205
+ error_if_false();
206
+ emit("end");
207
+ emit_nl();
208
+ emit("begin; puts(\"Use: \" + $0 + \" <in> <out>\"); exit; end if ARGV.length != 2");
209
+ emit_nl();
210
+ emit("File.open(ARGV[1], \"w\") {|f| RMetaII.new.compile(File.read(ARGV[0]), f)}");
211
+ emit_nl();
212
+ }
213
+ } while (0);
214
+ }
@@ -0,0 +1,38 @@
1
+ .syntax meta
2
+
3
+ arg = '$' <'emit_token();'>
4
+ | .string <'emit(' $ ');'>;
5
+
6
+ output = '<' *arg '>' <'emit_nl();'>;
7
+
8
+ exp3 = .id <'meta_' $ '();'>
9
+ | .string <'read_literal(' $ ');'>
10
+ | '.id' <'read_id();'>
11
+ | '.number' <'read_number();'>
12
+ | '.string' <'read_string();'>
13
+ | '(' exp1 ')'
14
+ | '.e' <'test_flag = 1;'>
15
+ | '*' <'do {'>
16
+ exp3 <'} while (test_flag);'>
17
+ <'test_flag = 1;'>;
18
+
19
+ exp2 = ( exp3 <'if (test_flag) {'>
20
+ | output <'if (1) {'> )
21
+ *( exp3 <'error_if_false();'>
22
+ | output )
23
+ <'}'>;
24
+
25
+ exp1 = <'do {'> exp2
26
+ *( '|' <'if (test_flag) { break; }'> exp2 )
27
+ <'} while (0);'>;
28
+
29
+ stat = .id <'void meta_' $ '(void)'>
30
+ <'{'>
31
+ '=' exp1 ';'
32
+ <'}'>;
33
+
34
+ program = '.syntax' .id <'#include "support.h"'>
35
+ *stat
36
+ '.end';
37
+
38
+ .end
@@ -29,7 +29,7 @@ program = '.syntax' .id
29
29
  <'@i, @o = StringScanner.new(str), out'>
30
30
  <'compile_program'> <'end'>
31
31
  *rule '.end' <'end'>
32
- <'begin; puts "Use: meta_compile <in> <out>"; exit; end if ARGV.length != 2'>
32
+ <'begin; puts("Use: " + $0 + " <in> <out>"); exit; end if ARGV.length != 2'>
33
33
  <'File.open(ARGV[1], "w") {|f| RMetaII.new.compile(File.read(ARGV[0]), f)}'>;
34
34
 
35
35
  .end
@@ -0,0 +1,35 @@
1
+ .syntax RMetaII
2
+
3
+ outarg = '$' <'@o.print @t'> | .string <'@o.print ' $>;
4
+
5
+ out = '<' *outarg '>' <'@o.print "\n"'>;
6
+
7
+ exp3 = .id <'compile_' $>
8
+ | .string <'@i.scan /\s*/; s=' $ '; l=s.length;'>
9
+ <'@t = (@i.peek(l) == s) ? (@i.pos += l; s) : nil'>
10
+ | '.id' <'@i.scan /\s*/; @t = @i.scan /[A-Za-z]+[A-Za-z0-9_]+/'>
11
+ | '.string' <'@i.scan /\s*/; @t = @i.scan /\047[^\047]*\047/'>
12
+ | '(' exp1 ')'
13
+ | '.e' <'@t = true'>
14
+ | '*' <'begin'> exp3 <'end while @t'> <'@t = true'>;
15
+
16
+ exp2 = ( exp3 <'if @t'> | out <'if true'> )
17
+ *( exp3 <'raise("error at:\n" + @i.rest.split("\n")[0]) if !@t'>
18
+ | out ) <'end'>;
19
+
20
+ exp1 = <'begin'> exp2
21
+ *( '|' <'break if @t'> exp2 )
22
+ <'end while false'>;
23
+
24
+ rule = .id <'def compile_' $> '=' exp1 ';' <'end'>;
25
+
26
+ program = '.syntax' .id
27
+ <'#!/usr/bin/env ruby'> <'require "strscan"'>
28
+ <'class ' $> <'def compile(str, out)'>
29
+ <'@i, @o = StringScanner.new(str), out'>
30
+ <'compile_program'> <'end'>
31
+ *rule '.end' <'end'>
32
+ <'begin; puts("Use: " + $0 + " <in> <out>"); exit; end if ARGV.length != 2'>
33
+ <'File.open(ARGV[1], "w") {|f| RMetaII.new.compile(File.read(ARGV[0]), f)}'>;
34
+
35
+ .end
data/bootstrap/meta_r ADDED
Binary file