end
end
-class SymTable < Hash
- attr_accessor :parent
+class SymTable
+ Symbol = Struct.new(:name, :loc, :kind, :type, :value)
- def initialize(parent = nil)
- @global_scope = true if not parent.nil?
- @parent = (parent || {})
+ def initialize()
+ @scopes = [{}, {}]
end
- def clone()
- SymTable.new(self)
+ def builtin?(name)
+ (not local? name) and (not (@scopes[0] || {})[name].nil?)
end
- def [](key)
- (super(key) || @parent[key])
+ def global?(name)
+ (not local? name) and (not (@scopes[1] || {})[name].nil?)
end
- def defined?(key)
- not self[key].nil?
+ def parameter?(name)
+ (not local? name) and (not (@scopes[2] || {})[name].nil?)
end
- def typed?(key)
- not (self[key] || {})[:type].nil?
+ def local?(name)
+ find_sym(@scopes[3..-1], name)
end
- def add_sym(name, loc, kind, scope = :local, type = nil, value = nil)
- self[name] = {
- loc: loc,
- kind: kind,
- scope: scope,
- type: type,
- value: nil
- }
+ def add_builtin(name, kind, type, value)
+ @scopes[0][name] =
+ Symbol.new(name, 0, kind, type, value)
end
- def set_type(name, type)
- (self[name] || {})[:type] = type
+ def find_sym(scopes, name)
+ scopes.reverse_each.detect do |scope|
+ scope[name]
+ end
end
- def global?(name)
- if self[name]
- @global_scope
- elsif @parent.class == SymTable
- @parent.global?(name)
- else
- nil
- end
+ def open_scope()
+ @scopes.push({})
end
+
+ def close_scope()
+ @scopes.pop
+ end
+
+ def reset_scope()
+ @scopes = @scopes[0..1]
+ end
+
+ def [](name)
+ find_sym(@scopes, name)
+ end
+
+
+
+# def add_sym(name, loc, kind, scope = :local, type = nil, value = nil)
+# self[name] = {
+# loc: loc,
+# kind: kind,
+# scope: scope,
+# type: type,
+# value: nil
+# }
+# end
+#
+# def set_type(name, type)
+# (self[name] || {})[:type] = type
+# end
end
+
+
module IR
Func = Struct.new(:loc, :type, :args, :body)
Return = Struct.new(:loc, :type, :value)
end
end
-$parser = Parser.new("cerise.m")
-#pp $parser.syms
-#pp $parser.defs
-$parser.defs.each do |name, val|
- puts "func #{name.to_sym.inspect}, #{val.value.args.length} do"
- val.value.body.each do |stmnt|
- Codegen.emit(stmnt)
- end
- puts "end\n\n"
-# puts val
-end
+#$parser = Parser.new("cerise.m")
+#$parser.defs.each do |name, val|
+# puts "func #{name.to_sym.inspect}, #{val.value.args.length} do"
+# val.value.body.each do |stmnt|
+# Codegen.emit(stmnt)
+# end
+# puts "end\n\n"
+#end
+
+syms = SymTable.new
+syms.add_builtin(:foo, :var, nil, nil)
+syms.add_sym(:foo, :var, nil, nil)
+#syms.add_param(:foo, :var, nil, nil)
+#syms.add_param(:foo, :var, nil, nil)
+# def add_builtin(name, kind, type, value)
+
+pp syms