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