Split symbol table into have a separate hash for each entry type.

This commit is contained in:
Danila Fedorin 2018-08-05 20:32:10 -07:00
parent 61fb44bbce
commit 89709fef97
5 changed files with 36 additions and 43 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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
# Stores an *entry* under the given *key* into this table.
def []=(key, entry)
@data[key] = entry
def set_{{name}}(key, value)
@{{name}}s[key] = value
end
end
table_functions function
table_functions var
def to_s(io)
@parent.try &.to_s(io)

View File

@ -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|