-
Notifications
You must be signed in to change notification settings - Fork 608
/
compiler.rb
112 lines (89 loc) · 2.18 KB
/
compiler.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
require 'compiler2/system_hints'
class Compiler2
class Error < RuntimeError
end
def self.compile_file(path, flags=nil)
sexp = File.to_sexp(path, true)
comp = new(Compiler2::Generator)
node = comp.into_script(sexp)
return node.to_description(:__script__).to_cmethod
end
def self.compile_string(string, flags=nil, filename="(eval)", line=1)
sexp = string.to_sexp(filename, line, true)
comp = new(Compiler2::Generator)
node = comp.convert_sexp([:snippit, sexp])
return node.to_description(:__eval_script__).to_cmethod
end
def initialize(gen_class)
@variables = {}
@generator_class = gen_class
@call_plugins = []
@file = "(unknown)"
@line = 0
load_plugins
end
attr_reader :call_plugins
attr_accessor :generator_class
def set_position(file, line)
@file, @line = file, line
end
def load_plugins
# The default plugins
activate :block_given
activate :primitive
activate :assembly
activate :method_visibility
activate :fastmath
end
def activate(name)
cls = Compiler2::Plugins.find_plugin(name)
raise Error, "Unknown plugin '#{name}'" unless cls
@call_plugins << cls.new(self)
end
def inspect
"#<#{self.class}>"
end
def convert_sexp(sexp)
return nil if sexp.nil?
klass = Compiler2::Node::Mapping[sexp.first]
raise Error, "Unable to resolve #{sexp.first}" unless klass
return klass.create(self, sexp)
end
def into_script(sexp)
begin
convert_sexp([:script, sexp])
rescue Object => e
puts "Compilation error detected: #{e.message}"
puts " near #{@file}:#{@line}"
puts
puts e.backtrace.show
end
end
def get(tag)
@variables[tag]
end
def set(tag, val=true)
if tag.kind_of? Hash
cur = @variables.dup
@variables.merge! tag
begin
yield
ensure
@variables = cur
end
else
cur = @variables[tag]
@variables[tag] = val
begin
yield
ensure
@variables[tag] = cur
end
end
end
end
require 'compiler2/nodes'
require 'compiler2/local'
require 'compiler2/bytecode'
require 'compiler2/generator'
require 'compiler2/plugins'