meta_compile 0.0.8 → 0.0.10

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 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.
6
+ This uses a [C version of Meta-II](https://github.com/impeachgod/meta) developed by Long Nguyen to bootstrap a Ruby version from a [fully self-contained, 26 (non-empty) line specification file](https://raw.github.com/robertfeldt/meta_compile/master/bootstrap/meta_to_ruby_minimal.meta). The [generated Ruby Meta-II compiler file](https://github.com/robertfeldt/meta_compile/blob/master/bin/meta_compile) is 231 lines of Ruby code.
7
7
 
8
8
  Install
9
9
  -------
@@ -25,16 +25,24 @@ Manually verifying that it is a meta compiler
25
25
 
26
26
  In your local copy of the git repo, use the pre-generated binary to compile the specification file to a ruby file:
27
27
 
28
- bin/meta_compile bootstrap/meta_for_ruby.txt t.rb
28
+ bin/meta_compile bootstrap/meta_to_ruby_minimal.meta t.rb
29
29
 
30
30
  This generates a t.rb which is itself a compiler for meta syntax specs. So lets use it to generate itself:
31
31
 
32
- ruby t.rb bootstrap/meta_for_ruby.txt t2.rb
32
+ ruby t.rb bootstrap/meta_to_ruby_minimal.meta t2.rb
33
33
 
34
34
  And ensure they are really the same:
35
35
 
36
36
  diff t.rb t2.rb
37
37
 
38
+ To be really sure we can try the generated t2.rb as a meta-compiler:
39
+
40
+ ruby t2.rb bootstrap/meta_to_ruby_minimal.meta t3.rb
41
+
42
+ and this should convince us:
43
+
44
+ diff t2.rb t3.rb
45
+
38
46
  Limitations
39
47
  -----------
40
48
  + Very bad/little error handling
data/Rakefile CHANGED
@@ -33,52 +33,75 @@ task :bootstrap do
33
33
  Dir.chdir("bootstrap") do
34
34
  puts "1. Build bootstrap compiler"
35
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"
36
+ puts "2. Use the c meta compiler to compile the meta_to_ruby_minimal.meta description"
37
+ pexec "./bootstrapped_c meta_to_ruby_minimal.meta compile_to_ruby.c"
38
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"
39
+ pexec "gcc -o meta_r compile_to_ruby.c"
40
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"
41
+ pexec "./meta_r meta_to_ruby_minimal.meta meta_ruby_compiler_from_c.rb"
42
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"
43
+ pexec "ruby -I. meta_ruby_compiler_from_c.rb meta_to_ruby_minimal.meta > meta_ruby_compiler.rb"
44
+ puts "6. Ruby version differ since it has single instead of double quotes around strings"
45
45
  #pexec "diff meta_ruby_compiler_from_c.rb meta_ruby_compiler.rb"
46
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"
47
+ pexec "ruby -I. meta_ruby_compiler.rb meta_to_ruby_minimal.meta > meta_ruby_compiler2.rb"
48
48
  pexec "diff meta_ruby_compiler.rb meta_ruby_compiler2.rb"
49
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"
50
+ pexec "ruby -I. meta_ruby_compiler2.rb meta_to_ruby_minimal.meta > meta_ruby_compiler3.rb"
51
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"
52
+ puts "Summary:\nCreated a #{loc('meta_ruby_compiler.rb')} line meta-II meta compiler from a #{loc('meta_to_ruby_minimal.meta')} line meta-II spec\n\n"
53
+ end
54
+ end
55
+
56
+ # Bootstrap a syntax from the meta_compile compiler
57
+ def bootstrap_from_meta_compile(syntaxFile)
58
+ pexec "meta_compile #{syntaxFile} > tgen.rb"
59
+ ensure_is_meta("tgen.rb", syntaxFile)
60
+ end
61
+
62
+ def diff_files(f1, f2)
63
+ File.read(f1) != File.read(f2)
64
+ end
65
+
66
+ def ensure_is_meta(generatedFile, specFile)
67
+ pexec "ruby #{generatedFile} #{specFile} > t.rb"
68
+ pexec "ruby t.rb #{specFile} > t2.rb"
69
+ # Obviously we should now be able to go on and on... :)
70
+ pexec "ruby t2.rb #{specFile} > t3.rb"
71
+ begin
72
+ if diff_files("t.rb", "t2.rb") || diff_files("t2.rb", "t3.rb")
73
+ puts "ERROR: #{generatedFile} is NOT a meta compiler (generated from #{specFile})"
74
+ exit(-1)
75
+ else
76
+ puts "YES #{generatedFile} is meta!!! (generated from #{specFile})"
77
+ end
78
+ ensure
79
+ FileUtils.rm_f Dir.glob("t*.rb")
53
80
  end
54
81
  end
55
82
 
56
83
  desc "Make binary from the bootstrapped ruby meta-II compiler"
57
84
  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
85
  FileUtils.cp "bootstrap/meta_ruby_compiler.rb", "bin/meta_compile"
68
86
  FileUtils.chmod 0755, "bin/meta_compile"
69
87
  puts "Created binary in bin/meta_compile"
70
88
  end
71
89
 
90
+ desc "Ensure it is a meta compiler"
91
+ task :ensure_meta => [:make_bin] do
92
+ ensure_is_meta "bin/meta_compile", "bootstrap/meta_to_ruby_minimal.meta"
93
+ end
94
+
72
95
  desc "Update line counts in README.template.md to make README.md"
73
96
  task :update_readme => [:bootstrap] do
74
97
  rmeta2_compiler_loc = loc('bootstrap/meta_ruby_compiler.rb')
75
- rmeta2_spec_loc = loc('bootstrap/meta_for_ruby.txt')
98
+ rmeta2_spec_loc = loc('bootstrap/meta_to_ruby_minimal.meta')
76
99
  readme = File.read("README.template.md").gsub("%%RMetaII_SPEC_LOC%%", rmeta2_spec_loc.to_s)
77
100
  readme = readme.gsub("%%RMetaII_COMPILER_LOC%%", rmeta2_compiler_loc.to_s)
78
101
  File.open("README.md", "w") {|f| f.puts readme}
79
102
  end
80
103
 
81
- task :default => :make_bin
104
+ task :default => :ensure_meta
82
105
 
83
106
  desc "Build the gem"
84
107
  task :build_gem => [:make_bin] do
@@ -99,7 +122,7 @@ end
99
122
 
100
123
  task :clean do
101
124
  Dir.chdir("bootstrap") do
102
- 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}
125
+ 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_to_ruby.c meta_c meta_r}
103
126
  end
104
127
  FileUtils.rm_f Dir.glob("t*.rb")
105
128
  end
data/bin/meta_compile CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "strscan"
3
- class RMetaII
3
+ class C_program
4
+ $c = self
4
5
  def compile(str, out)
5
6
  @i, @o = StringScanner.new(str), out
6
7
  compile_program
@@ -197,14 +198,17 @@ raise("error at: " + @i.rest.split("\n")[0]) if !@f
197
198
  @o.print "\n"
198
199
  @o.print 'require "strscan"'
199
200
  @o.print "\n"
200
- @o.print 'class '
201
+ @o.print 'class C_'
201
202
  @o.print @t
202
203
  @o.print "\n"
204
+ @o.print '$c = self'
205
+ @o.print "\n"
203
206
  @o.print 'def compile(str, out)'
204
207
  @o.print "\n"
205
208
  @o.print '@i, @o = StringScanner.new(str), out'
206
209
  @o.print "\n"
207
- @o.print 'compile_program'
210
+ @o.print 'compile_'
211
+ @o.print @t
208
212
  @o.print "\n"
209
213
  @o.print 'end'
210
214
  @o.print "\n"
@@ -218,13 +222,10 @@ raise("error at: " + @i.rest.split("\n")[0]) if !@f
218
222
  raise("error at: " + @i.rest.split("\n")[0]) if !@f
219
223
  @o.print 'end'
220
224
  @o.print "\n"
221
- @o.print 'begin; puts("Use: " + $0 + " <in> <out>"); exit; end if ARGV.length != 2'
222
- @o.print "\n"
223
- @o.print 'File.open(ARGV[1], "w") {|f| RMetaII.new.compile(File.read(ARGV[0]), f)}'
225
+ @o.print '$c.new.compile(File.read(ARGV[0]), STDOUT) if __FILE__ == $0'
224
226
  @o.print "\n"
225
227
  end
226
228
  end while false
227
229
  end
228
230
  end
229
- begin; puts("Use: " + $0 + " <in> <out>"); exit; end if ARGV.length != 2
230
- File.open(ARGV[1], "w") {|f| RMetaII.new.compile(File.read(ARGV[0]), f)}
231
+ $c.new.compile(File.read(ARGV[0]), STDOUT) if __FILE__ == $0
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "strscan"
3
- class RMetaII
3
+ class C_program
4
+ $c = self
4
5
  def compile(str, out)
5
6
  @i, @o = StringScanner.new(str), out
6
7
  compile_program
@@ -197,14 +198,17 @@ raise("error at: " + @i.rest.split("\n")[0]) if !@f
197
198
  @o.print "\n"
198
199
  @o.print 'require "strscan"'
199
200
  @o.print "\n"
200
- @o.print 'class '
201
+ @o.print 'class C_'
201
202
  @o.print @t
202
203
  @o.print "\n"
204
+ @o.print '$c = self'
205
+ @o.print "\n"
203
206
  @o.print 'def compile(str, out)'
204
207
  @o.print "\n"
205
208
  @o.print '@i, @o = StringScanner.new(str), out'
206
209
  @o.print "\n"
207
- @o.print 'compile_program'
210
+ @o.print 'compile_'
211
+ @o.print @t
208
212
  @o.print "\n"
209
213
  @o.print 'end'
210
214
  @o.print "\n"
@@ -218,13 +222,10 @@ raise("error at: " + @i.rest.split("\n")[0]) if !@f
218
222
  raise("error at: " + @i.rest.split("\n")[0]) if !@f
219
223
  @o.print 'end'
220
224
  @o.print "\n"
221
- @o.print 'begin; puts("Use: " + $0 + " <in> <out>"); exit; end if ARGV.length != 2'
222
- @o.print "\n"
223
- @o.print 'File.open(ARGV[1], "w") {|f| RMetaII.new.compile(File.read(ARGV[0]), f)}'
225
+ @o.print '$c.new.compile(File.read(ARGV[0]), STDOUT) if __FILE__ == $0'
224
226
  @o.print "\n"
225
227
  end
226
228
  end while false
227
229
  end
228
230
  end
229
- begin; puts("Use: " + $0 + " <in> <out>"); exit; end if ARGV.length != 2
230
- File.open(ARGV[1], "w") {|f| RMetaII.new.compile(File.read(ARGV[0]), f)}
231
+ $c.new.compile(File.read(ARGV[0]), STDOUT) if __FILE__ == $0
File without changes
@@ -1,4 +1,4 @@
1
- .syntax RMetaII
1
+ .syntax program
2
2
 
3
3
  outarg = '$' <'@o.print @t'> | .string <'@o.print ' $>;
4
4
 
@@ -6,7 +6,7 @@ out = '<' *outarg '>' <'@o.print "\n"'>;
6
6
 
7
7
  exp3 = .id <'compile_' $>
8
8
  | .string <'@i.scan /\s*/; s=' $ '; l=s.length;'>
9
- <'@f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil'>
9
+ <'@f = (@i.peek(l) == s) ? (@t=s; @i.pos += l) : nil'>
10
10
  | '.id' <'@i.scan /\s*/; @f = @t = @i.scan /[A-Za-z]+[A-Za-z0-9_]+/'>
11
11
  | '.string' <'@i.scan /\s*/; @f = @t = @i.scan /\047[^\047]*\047/'>
12
12
  | '(' exp1 ')'
@@ -24,12 +24,11 @@ exp1 = <'begin'> exp2
24
24
  rule = .id <'def compile_' $> '=' exp1 ';' <'end'>;
25
25
 
26
26
  program = '.syntax' .id
27
- <'#!/usr/bin/env ruby'> <'require "strscan"'>
28
- <'class ' $> <'def compile(str, out)'>
27
+ <'#!/usr/bin/env ruby'> <'require "strscan"'>
28
+ <'class C_' $> <'$c = self'> <'def compile(str, out)'>
29
29
  <'@i, @o = StringScanner.new(str), out'>
30
- <'compile_program'> <'end'>
30
+ <'compile_' $> <'end'>
31
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)}'>;
32
+ <'$c.new.compile(File.read(ARGV[0]), STDOUT) if __FILE__ == $0'>;
34
33
 
35
34
  .end
data/meta_compile.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'meta_compile'
3
- s.version = '0.0.8'
3
+ s.version = '0.0.10'
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"
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.8
4
+ version: 0.0.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -23,10 +23,10 @@ files:
23
23
  - meta_compile.gemspec
24
24
  - bin/meta_compile
25
25
  - bootstrap/bootstrap.c
26
- - bootstrap/meta_for_c.txt
27
- - bootstrap/meta_for_ruby.txt
28
- - bootstrap/meta_for_ruby_single_flag.txt
29
26
  - bootstrap/meta_ruby_compiler.rb
27
+ - bootstrap/meta_to_c.meta
28
+ - bootstrap/meta_to_ruby_minimal.meta
29
+ - bootstrap/meta_to_ruby_minimal_single_flag.meta
30
30
  - bootstrap/original_support.h
31
31
  - bootstrap/support.h
32
32
  homepage: http://rubygems.org/gems/meta_compile