meta_compile 0.0.15 → 0.1.0

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
@@ -46,3 +46,44 @@ and this should convince us:
46
46
  Limitations
47
47
  -----------
48
48
  + Very bad/little error handling
49
+
50
+ Ok, now what?
51
+ -------------
52
+
53
+ Once the first meta compiler is up and running we can evolve the language. For example I made a change so [Ruby regexps can be used](https://github.com/robertfeldt/meta_compile/blob/master/syntaxes/meta_to_ruby_minimal_with_regexps.meta) instead of only string literals. Note that we need to use a [stepping stone syntax file](https://github.com/robertfeldt/meta_compile/blob/master/syntaxes/stepping_stone_meta_to_ruby_minimal_with_regexps.meta) before we can create a new meta compiler that accepts the new syntax.
54
+
55
+ Let's use this to compile programs which can only contain assignments of numbers to variables:
56
+
57
+ .syntax assignments
58
+ assignments = as *as;
59
+ as = /\w+/ <'address ' $> ':=' ex1 <'store'> ';';
60
+ ex1 = /\d+/ <'literal ' $>;
61
+ .end
62
+
63
+ The new thing here compared to the original Meta-II syntax is the two Regexp's (in as and ex1). First we need to bootstrap the meta compiler that accepts regexps:
64
+
65
+ rake bootstrap_re
66
+
67
+ Then we create a compiler for the assignments syntax:
68
+
69
+ ruby bin/metacomp_re syntaxes/assignments.meta > tas.rb
70
+
71
+ We now have a compiler for assignments and if we apply it [to the file](https://raw.github.com/robertfeldt/meta_compile/master/inputs/assignments.input1):
72
+
73
+ a := 137;
74
+ b := 4;
75
+
76
+ by running the command:
77
+
78
+ ruby tas.rb inputs/assignments.input1
79
+
80
+ it prints:
81
+
82
+ address a
83
+ literal 137
84
+ store
85
+ address d
86
+ literal 4
87
+ store
88
+
89
+ Not bad. :)
data/Rakefile CHANGED
@@ -92,6 +92,38 @@ task :ensure_meta => [:make_bin] do
92
92
  ensure_is_meta "bin/meta_compile", "syntaxes/meta_to_ruby_minimal.meta"
93
93
  end
94
94
 
95
+ def bootstrap_with_stepping_stone(syntaxFile, target)
96
+ syntaxf = File.join("syntaxes", syntaxFile)
97
+ stepstonef = File.join("syntaxes", "stepping_stone_" + syntaxFile)
98
+ pexec "meta_compile #{stepstonef} > tgen_stepstone.rb"
99
+ pexec "ruby tgen_stepstone.rb #{syntaxf} > #{target}"
100
+ ensure_is_meta(target, syntaxf)
101
+ end
102
+
103
+ desc "Bootstrap the meta compiler that accepts regexps"
104
+ task :bootstrap_re do
105
+ bootstrap_with_stepping_stone("meta_to_ruby_minimal_with_regexps.meta", "bin/metacomp_re")
106
+ end
107
+
108
+ def run_example(compiler, example)
109
+ puts "Compiling this input with #{compiler}:\n\n"
110
+ puts File.read(example)
111
+ puts "\ngives output:\n\n"
112
+ pexec "ruby #{compiler} #{example}"
113
+ end
114
+
115
+ def metacomp_re_run_examples(syntaxFile, *inputs)
116
+ pexec "ruby bin/metacomp_re #{syntaxFile} > tas.rb"
117
+ inputs.each do |i|
118
+ run_example("tas.rb", "inputs/#{i}")
119
+ end
120
+ end
121
+
122
+ desc "Compile all inputs for the assignments syntax"
123
+ task :ex_ass do
124
+ metacomp_re_run_examples "syntaxes/assignments.meta", "assignments.input1"
125
+ end
126
+
95
127
  desc "Update line counts in README.template.md to make README.md"
96
128
  task :update => [:bootstrap] do
97
129
  rmeta2_compiler_loc = loc('bootstrap/meta_ruby_compiler.rb')
data/bin/metacomp_re ADDED
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env ruby
2
+ require "strscan"
3
+ class C_program
4
+ $c = self
5
+ def compile(str, out)
6
+ @i, @o = StringScanner.new(str), out
7
+ compile_program
8
+ end
9
+ def compile_outarg
10
+ begin
11
+ @i.scan /\s*/; s='$'; l=s.length;
12
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
13
+ if @f
14
+ @o.print '@o.print @t'
15
+ @o.print "\n"
16
+ end
17
+ break if @f
18
+ @i.scan /\s*/; @f = @t = @i.scan /\047[^\047]*\047/
19
+ if @f
20
+ @o.print '@o.print '
21
+ @o.print @t
22
+ @o.print "\n"
23
+ end
24
+ end while false
25
+ end
26
+ def compile_out
27
+ begin
28
+ @i.scan /\s*/; s='<'; l=s.length;
29
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
30
+ if @f
31
+ begin
32
+ compile_outarg
33
+ end while @f
34
+ @f = true
35
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
36
+ @i.scan /\s*/; s='>'; l=s.length;
37
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
38
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
39
+ @o.print '@o.print "\n"'
40
+ @o.print "\n"
41
+ end
42
+ end while false
43
+ end
44
+ def compile_exp3
45
+ begin
46
+ @i.scan /\s*/; @f = @t = @i.scan /[A-Za-z]+[A-Za-z0-9_]+/
47
+ if @f
48
+ @o.print 'compile_'
49
+ @o.print @t
50
+ @o.print "\n"
51
+ end
52
+ break if @f
53
+ @i.scan /\s*/; @f = @t = @i.scan /\047[^\047]*\047/
54
+ if @f
55
+ @o.print '@i.scan /\s*/; s='
56
+ @o.print @t
57
+ @o.print '; l=s.length;'
58
+ @o.print "\n"
59
+ @o.print '@f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil'
60
+ @o.print "\n"
61
+ end
62
+ break if @f
63
+ @i.scan /\s*/; @f = @t = @i.scan /\/[^\/]*\//
64
+ if @f
65
+ @o.print '@i.scan /\s*/; @f = @t = @i.scan '
66
+ @o.print @t
67
+ @o.print "\n"
68
+ end
69
+ break if @f
70
+ @i.scan /\s*/; s='.id'; l=s.length;
71
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
72
+ if @f
73
+ @o.print '@i.scan /\s*/; @f = @t = @i.scan /[A-Za-z]+[A-Za-z0-9_]+/'
74
+ @o.print "\n"
75
+ end
76
+ break if @f
77
+ @i.scan /\s*/; s='.string'; l=s.length;
78
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
79
+ if @f
80
+ @o.print '@i.scan /\s*/; @f = @t = @i.scan /\047[^\047]*\047/'
81
+ @o.print "\n"
82
+ end
83
+ break if @f
84
+ @i.scan /\s*/; s='.re'; l=s.length;
85
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
86
+ if @f
87
+ @o.print '@i.scan /\s*/; @f = @t = @i.scan /\/[^\/]*\//'
88
+ @o.print "\n"
89
+ end
90
+ break if @f
91
+ @i.scan /\s*/; s='('; l=s.length;
92
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
93
+ if @f
94
+ compile_exp1
95
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
96
+ @i.scan /\s*/; s=')'; l=s.length;
97
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
98
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
99
+ end
100
+ break if @f
101
+ @i.scan /\s*/; s='.e'; l=s.length;
102
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
103
+ if @f
104
+ @o.print '@f = true'
105
+ @o.print "\n"
106
+ end
107
+ break if @f
108
+ @i.scan /\s*/; s='*'; l=s.length;
109
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
110
+ if @f
111
+ @o.print 'begin'
112
+ @o.print "\n"
113
+ compile_exp3
114
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
115
+ @o.print 'end while @f'
116
+ @o.print "\n"
117
+ @o.print '@f = true'
118
+ @o.print "\n"
119
+ end
120
+ end while false
121
+ end
122
+ def compile_exp2
123
+ begin
124
+ begin
125
+ compile_exp3
126
+ if @f
127
+ @o.print 'if @f'
128
+ @o.print "\n"
129
+ end
130
+ break if @f
131
+ compile_out
132
+ if @f
133
+ @o.print 'if true'
134
+ @o.print "\n"
135
+ end
136
+ end while false
137
+ if @f
138
+ begin
139
+ begin
140
+ compile_exp3
141
+ if @f
142
+ @o.print 'raise("error at: " + @i.rest.split("\n")[0]) if !@f'
143
+ @o.print "\n"
144
+ end
145
+ break if @f
146
+ compile_out
147
+ if @f
148
+ end
149
+ end while false
150
+ end while @f
151
+ @f = true
152
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
153
+ @o.print 'end'
154
+ @o.print "\n"
155
+ end
156
+ end while false
157
+ end
158
+ def compile_exp1
159
+ begin
160
+ @o.print 'begin'
161
+ @o.print "\n"
162
+ if true
163
+ compile_exp2
164
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
165
+ begin
166
+ begin
167
+ @i.scan /\s*/; s='|'; l=s.length;
168
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
169
+ if @f
170
+ @o.print 'break if @f'
171
+ @o.print "\n"
172
+ compile_exp2
173
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
174
+ end
175
+ end while false
176
+ end while @f
177
+ @f = true
178
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
179
+ @o.print 'end while false'
180
+ @o.print "\n"
181
+ end
182
+ end while false
183
+ end
184
+ def compile_rule
185
+ begin
186
+ @i.scan /\s*/; @f = @t = @i.scan /[A-Za-z]+[A-Za-z0-9_]+/
187
+ if @f
188
+ @o.print 'def compile_'
189
+ @o.print @t
190
+ @o.print "\n"
191
+ @i.scan /\s*/; s='='; l=s.length;
192
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
193
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
194
+ compile_exp1
195
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
196
+ @i.scan /\s*/; s=';'; l=s.length;
197
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
198
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
199
+ @o.print 'end'
200
+ @o.print "\n"
201
+ end
202
+ end while false
203
+ end
204
+ def compile_program
205
+ begin
206
+ @i.scan /\s*/; s='.syntax'; l=s.length;
207
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
208
+ if @f
209
+ @i.scan /\s*/; @f = @t = @i.scan /[A-Za-z]+[A-Za-z0-9_]+/
210
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
211
+ @o.print '#!/usr/bin/env ruby'
212
+ @o.print "\n"
213
+ @o.print 'require "strscan"'
214
+ @o.print "\n"
215
+ @o.print 'class C_'
216
+ @o.print @t
217
+ @o.print "\n"
218
+ @o.print '$c = self'
219
+ @o.print "\n"
220
+ @o.print 'def compile(str, out)'
221
+ @o.print "\n"
222
+ @o.print '@i, @o = StringScanner.new(str), out'
223
+ @o.print "\n"
224
+ @o.print 'compile_'
225
+ @o.print @t
226
+ @o.print "\n"
227
+ @o.print 'end'
228
+ @o.print "\n"
229
+ begin
230
+ compile_rule
231
+ end while @f
232
+ @f = true
233
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
234
+ @i.scan /\s*/; s='.end'; l=s.length;
235
+ @f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil
236
+ raise("error at: " + @i.rest.split("\n")[0]) if !@f
237
+ @o.print 'end'
238
+ @o.print "\n"
239
+ @o.print '$c.new.compile(File.read(ARGV[0]), STDOUT)'
240
+ @o.print "\n"
241
+ end
242
+ end while false
243
+ end
244
+ end
245
+ $c.new.compile(File.read(ARGV[0]), STDOUT)
@@ -0,0 +1,2 @@
1
+ a := 137;
2
+ d := 4;
data/meta_compile.gemspec CHANGED
@@ -1,12 +1,12 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'meta_compile'
3
- s.version = '0.0.15'
3
+ s.version = '0.1.0'
4
4
  s.date = '2012-11-25'
5
5
  s.summary = "meta compiler framework"
6
6
  s.description = "A meta compilation framework à la Meta-II by Val Schorre"
7
7
  s.authors = ["Robert Feldt"]
8
8
  s.email = 'robert.feldt@gmail.com'
9
- s.files = ["Rakefile", "README.md", "meta_compile.gemspec"] + Dir.glob("bin/*") + Dir.glob("bootstrap/*") + Dir.glob("syntaxes/*")
9
+ s.files = ["Rakefile", "README.md", "meta_compile.gemspec"] + Dir.glob("bin/*") + Dir.glob("bootstrap/*") + Dir.glob("syntaxes/*") + Dir.glob("inputs/*")
10
10
  s.executables << 'meta_compile'
11
11
  s.homepage =
12
12
  'http://rubygems.org/gems/meta_compile'
data/syntaxes/aexp.meta CHANGED
@@ -1,7 +1,7 @@
1
1
  .syntax aexp
2
2
 
3
3
  aexp = as *as;
4
- as = .id <'address' $> ':=' ex1 <'store'> ';';
4
+ as = /\w+/ <'address ' $> ':=' ex1 <'store'> ';';
5
5
  ex1 = ex2 *( '+' ex2 <'add'>
6
6
  | '-' ex2 <'sub'>);
7
7
  ex2 = ex3 *( '*' ex3 <'mpy'>
@@ -11,6 +11,7 @@ ex4 = '+' ex5
11
11
  | '-' ex5 <'minus'>
12
12
  | ex5;
13
13
  ex5 = .id <'load' $>
14
+ | /\d+/ <'literal ' $>
14
15
  | '(' ex1 ')';
15
16
 
16
17
  .end
@@ -0,0 +1,9 @@
1
+ .syntax assignments
2
+
3
+ assignments = as *as;
4
+
5
+ as = /\w+/ <'address ' $> ':=' ex1 <'store'> ';';
6
+
7
+ ex1 = /\d+/ <'literal ' $>;
8
+
9
+ .end
@@ -0,0 +1,36 @@
1
+ .syntax program
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
+ <'@f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil'>
10
+ | .re <'@i.scan /\s*/; @f = @t = @i.scan ' $>
11
+ | '.id' <'@i.scan /\s*/; @f = @t = @i.scan /[A-Za-z]+[A-Za-z0-9_]+/'>
12
+ | '.string' <'@i.scan /\s*/; @f = @t = @i.scan /\047[^\047]*\047/'>
13
+ | '.re' <'@i.scan /\s*/; @f = @t = @i.scan /\/[^\/]*\//'>
14
+ | '(' exp1 ')'
15
+ | '.e' <'@f = true'>
16
+ | '*' <'begin'> exp3 <'end while @f'> <'@f = true'>;
17
+
18
+ exp2 = ( exp3 <'if @f'> | out <'if true'> )
19
+ *( exp3 <'raise("error at: " + @i.rest.split("\n")[0]) if !@f'>
20
+ | out ) <'end'>;
21
+
22
+ exp1 = <'begin'> exp2
23
+ *( '|' <'break if @f'> exp2 )
24
+ <'end while false'>;
25
+
26
+ rule = .id <'def compile_' $> '=' exp1 ';' <'end'>;
27
+
28
+ program = '.syntax' .id
29
+ <'#!/usr/bin/env ruby'> <'require "strscan"'>
30
+ <'class C_' $> <'$c = self'> <'def compile(str, out)'>
31
+ <'@i, @o = StringScanner.new(str), out'>
32
+ <'compile_' $> <'end'>
33
+ *rule '.end' <'end'>
34
+ <'$c.new.compile(File.read(ARGV[0]), STDOUT)'>;
35
+
36
+ .end
@@ -0,0 +1,35 @@
1
+ .syntax program
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
+ <'@f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil'>
10
+ | '.id' <'@i.scan /\s*/; @f = @t = @i.scan /[A-Za-z]+[A-Za-z0-9_]+/'>
11
+ | '.string' <'@i.scan /\s*/; @f = @t = @i.scan /\047[^\047]*\047/'>
12
+ | '.re' <'@i.scan /\s*/; @f = @t = @i.scan /\/[^\/]*\//'>
13
+ | '(' exp1 ')'
14
+ | '.e' <'@f = true'>
15
+ | '*' <'begin'> exp3 <'end while @f'> <'@f = true'>;
16
+
17
+ exp2 = ( exp3 <'if @f'> | out <'if true'> )
18
+ *( exp3 <'raise("error at: " + @i.rest.split("\n")[0]) if !@f'>
19
+ | out ) <'end'>;
20
+
21
+ exp1 = <'begin'> exp2
22
+ *( '|' <'break if @f'> exp2 )
23
+ <'end while false'>;
24
+
25
+ rule = .id <'def compile_' $> '=' exp1 ';' <'end'>;
26
+
27
+ program = '.syntax' .id
28
+ <'#!/usr/bin/env ruby'> <'require "strscan"'>
29
+ <'class C_' $> <'$c = self'> <'def compile(str, out)'>
30
+ <'@i, @o = StringScanner.new(str), out'>
31
+ <'compile_' $> <'end'>
32
+ *rule '.end' <'end'>
33
+ <'$c.new.compile(File.read(ARGV[0]), STDOUT)'>;
34
+
35
+ .end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meta_compile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -22,16 +22,20 @@ files:
22
22
  - README.md
23
23
  - meta_compile.gemspec
24
24
  - bin/meta_compile
25
+ - bin/metacomp_re
25
26
  - bootstrap/bootstrap.c
26
27
  - bootstrap/meta_ruby_compiler.rb
27
28
  - bootstrap/meta_to_c.meta
28
29
  - bootstrap/original_support.h
29
30
  - bootstrap/support.h
30
- - syntaxes/aexp.input1
31
31
  - syntaxes/aexp.meta
32
+ - syntaxes/assignments.meta
32
33
  - syntaxes/meta_to_ruby.meta
33
34
  - syntaxes/meta_to_ruby_minimal.meta
34
35
  - syntaxes/meta_to_ruby_minimal_single_flag.meta
36
+ - syntaxes/meta_to_ruby_minimal_with_regexps.meta
37
+ - syntaxes/stepping_stone_meta_to_ruby_minimal_with_regexps.meta
38
+ - inputs/assignments.input1
35
39
  homepage: http://rubygems.org/gems/meta_compile
36
40
  licenses: []
37
41
  post_install_message:
data/syntaxes/aexp.input1 DELETED
@@ -1 +0,0 @@
1
- a := b