From 89709fef971e0ff0bcc2e929895e5d6eb30969a8 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sun, 5 Aug 2018 20:32:10 -0700 Subject: [PATCH] Split symbol table into have a separate hash for each entry type. --- src/chalk/codegen.cr | 21 +++++++++------------ src/chalk/compiler.cr | 20 ++++++++++---------- src/chalk/ir.cr | 2 +- src/chalk/table.cr | 32 ++++++++++++++------------------ src/chalk/typecheck.cr | 4 ++-- 5 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/chalk/codegen.cr b/src/chalk/codegen.cr index 9c57b78..298740d 100644 --- a/src/chalk/codegen.cr +++ b/src/chalk/codegen.cr @@ -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 diff --git a/src/chalk/compiler.cr b/src/chalk/compiler.cr index 65244fd..22f03ac 100644 --- a/src/chalk/compiler.cr +++ b/src/chalk/compiler.cr @@ -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) diff --git a/src/chalk/ir.cr b/src/chalk/ir.cr index 7f543fa..6e6a69c 100644 --- a/src/chalk/ir.cr +++ b/src/chalk/ir.cr @@ -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 diff --git a/src/chalk/table.cr b/src/chalk/table.cr index 239cdcf..9f5b533 100644 --- a/src/chalk/table.cr +++ b/src/chalk/table.cr @@ -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) diff --git a/src/chalk/typecheck.cr b/src/chalk/typecheck.cr index eb384ac..57a445d 100644 --- a/src/chalk/typecheck.cr +++ b/src/chalk/typecheck.cr @@ -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|