meta_compile 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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