Split symbol table into have a separate hash for each entry type.
This commit is contained in:
parent
61fb44bbce
commit
89709fef97
|
@ -19,7 +19,7 @@ module Chalk
|
|||
@table = Table.new table
|
||||
|
||||
@function.params.each do |param|
|
||||
@table[param] = VarEntry.new @registers
|
||||
@table.set_var param, VarEntry.new @registers
|
||||
@registers += 1
|
||||
end
|
||||
end
|
||||
|
@ -74,9 +74,8 @@ module Chalk
|
|||
def generate!(tree, table, target, free)
|
||||
case tree
|
||||
when Trees::TreeId
|
||||
entry = table[tree.id]?
|
||||
raise "Unknown variable" unless entry &&
|
||||
entry.is_a?(VarEntry)
|
||||
entry = table.get_var? tree.id
|
||||
raise "Unknown variable" unless entry
|
||||
loadr target, entry.register
|
||||
when Trees::TreeLit
|
||||
load target, tree.lit
|
||||
|
@ -85,7 +84,7 @@ module Chalk
|
|||
generate! tree.right, table, free, free + 1
|
||||
opr tree.op, target, free
|
||||
when Trees::TreeCall
|
||||
entry = table[tree.name]?.not_nil!
|
||||
entry = table.get_function?(tree.name).not_nil!
|
||||
raise "Unknown function" unless entry.is_a?(FunctionEntry)
|
||||
generate! tree, entry.function, table, target, free
|
||||
when Trees::TreeBlock
|
||||
|
@ -94,19 +93,17 @@ module Chalk
|
|||
free += generate! child, table, THROWAWAY_REG, free
|
||||
end
|
||||
when Trees::TreeVar
|
||||
entry = table[tree.name]?
|
||||
entry = table.get_var? tree.name
|
||||
if entry == nil
|
||||
entry = VarEntry.new free
|
||||
free += 1
|
||||
table[tree.name] = entry
|
||||
table.set_var tree.name, entry
|
||||
end
|
||||
raise "Unknown variable" unless entry.is_a?(VarEntry)
|
||||
generate! tree.expr, table, entry.register, free
|
||||
generate! tree.expr, table, entry.as(VarEntry).register, free
|
||||
return 1
|
||||
when Trees::TreeAssign
|
||||
entry = table[tree.name]?
|
||||
raise "Unknown variable" unless entry &&
|
||||
entry.is_a?(VarEntry)
|
||||
entry = table.get_var? tree.name
|
||||
raise "Unknown variable" unless entry
|
||||
generate! tree.expr, table, entry.register, free
|
||||
when Trees::TreeIf
|
||||
generate! tree.condition, table, free, free + 1
|
||||
|
|
|
@ -49,15 +49,15 @@ module Chalk
|
|||
@logger.debug("Creating symbol table")
|
||||
trees.each do |tree|
|
||||
@logger.debug("Storing #{tree.name} in symbol table")
|
||||
table[tree.name] = FunctionEntry.new tree
|
||||
table.set_function tree.name, FunctionEntry.new tree
|
||||
end
|
||||
@logger.debug("Done creating symbol table")
|
||||
|
||||
table["get_key"] = FunctionEntry.new Builtin::InlineAwaitKeyFunction.new
|
||||
table["set_delay"] = FunctionEntry.new Builtin::InlineSetDelayFunction.new
|
||||
table["get_delay"] = FunctionEntry.new Builtin::InlineGetDelayFunction.new
|
||||
table["set_sound"] = FunctionEntry.new Builtin::InlineSetSoundFunction.new
|
||||
table["draw_number"] = FunctionEntry.new Builtin::InlineDrawNumberFunction.new
|
||||
table.set_function "get_key", FunctionEntry.new Builtin::InlineAwaitKeyFunction.new
|
||||
table.set_function "set_delay", FunctionEntry.new Builtin::InlineSetDelayFunction.new
|
||||
table.set_function "get_delay", FunctionEntry.new Builtin::InlineGetDelayFunction.new
|
||||
table.set_function "set_sound", FunctionEntry.new Builtin::InlineSetSoundFunction.new
|
||||
table.set_function "draw_number", FunctionEntry.new Builtin::InlineDrawNumberFunction.new
|
||||
return table
|
||||
end
|
||||
|
||||
|
@ -143,8 +143,8 @@ module Chalk
|
|||
first = open.first
|
||||
open.delete first
|
||||
|
||||
entry = table[first]?
|
||||
raise "Unknown function" unless entry && entry.is_a?(FunctionEntry)
|
||||
entry = table.get_function? first
|
||||
raise "Unknown function" unless entry
|
||||
function = entry.function
|
||||
next if function.is_a?(Builtin::InlineFunction)
|
||||
done << first
|
||||
|
@ -166,13 +166,13 @@ module Chalk
|
|||
names = collect_calls(table)
|
||||
names.delete "main"
|
||||
|
||||
main_entry = table["main"]?.as(FunctionEntry)
|
||||
main_entry = table.get_function?("main").not_nil!
|
||||
all_instructions.concat create_code(main_entry.function.as(Trees::TreeFunction),
|
||||
table, Ir::JumpRelativeInstruction.new 0)
|
||||
main_entry.addr = 0
|
||||
|
||||
names.each do |name|
|
||||
entry = table[name]?.as(FunctionEntry)
|
||||
entry = table.get_function?(name).not_nil!
|
||||
entry.addr = all_instructions.size
|
||||
function = entry.function
|
||||
raise "Trying to compile inlined function" if function.is_a?(Builtin::InlineFunction)
|
||||
|
|
|
@ -282,7 +282,7 @@ module Chalk
|
|||
end
|
||||
|
||||
def to_bin(table, stack, index)
|
||||
return 0x2000 | (table[name]?.as(Compiler::FunctionEntry).addr * 2 + 0x200)
|
||||
return 0x2000 | (table.get_function?(name).as(Compiler::FunctionEntry).addr * 2 + 0x200)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
module Chalk
|
||||
module Compiler
|
||||
# An entry in the symbol table.
|
||||
class Entry
|
||||
end
|
||||
|
||||
# An entry that represents a function in the symbol table.
|
||||
class FunctionEntry < Entry
|
||||
class FunctionEntry
|
||||
# Gets the function stored in this entry.
|
||||
getter function
|
||||
# Gets the address in code of this function.
|
||||
|
@ -23,7 +19,7 @@ module Chalk
|
|||
end
|
||||
|
||||
# An entry that represents a variable in the symbol table.
|
||||
class VarEntry < Entry
|
||||
class VarEntry
|
||||
# Gets the register occupied by the variable
|
||||
# in this entry.
|
||||
getter register
|
||||
|
@ -42,22 +38,22 @@ module Chalk
|
|||
getter parent
|
||||
|
||||
def initialize(@parent : Table? = nil)
|
||||
@data = {} of String => Entry
|
||||
@functions = {} of String => FunctionEntry
|
||||
@vars = {} of String => VarEntry
|
||||
end
|
||||
|
||||
# Looks up the given *key* first in this table,
|
||||
# then in its parent, continuing recursively.
|
||||
def []?(key)
|
||||
if entry = @data[key]?
|
||||
return entry
|
||||
end
|
||||
return @parent.try &.[key]?
|
||||
macro table_functions(name)
|
||||
def get_{{name}}?(key)
|
||||
@{{name}}s[key]? || @parent.try &.get_{{name}}?(key)
|
||||
end
|
||||
|
||||
def set_{{name}}(key, value)
|
||||
@{{name}}s[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
# Stores an *entry* under the given *key* into this table.
|
||||
def []=(key, entry)
|
||||
@data[key] = entry
|
||||
end
|
||||
table_functions function
|
||||
table_functions var
|
||||
|
||||
def to_s(io)
|
||||
@parent.try &.to_s(io)
|
||||
|
|
|
@ -12,8 +12,8 @@ module Chalk
|
|||
end
|
||||
|
||||
def reduce(t : TreeCall, children)
|
||||
entry = @table[t.name]?
|
||||
raise "Unknwon function" unless entry && entry.is_a?(Compiler::FunctionEntry)
|
||||
entry = @table.get_function? t.name
|
||||
raise "Unknwon function" unless entry
|
||||
type = entry.function.type
|
||||
raise "Invalid parameters" if type.param_types.size != children.size
|
||||
children.each_with_index do |child, i|
|
||||
|
|
Loading…
Reference in New Issue
Block a user