def function_definition(name)
args = function_arglist()
func = IR::Func.new(name.loc, nil, args, [], [])
+ defs = []
expect("{")
while matches(:def)
local = variable_definition()
func.locals << local.name.name
+ defs << local;
end
stmts = statement_list(["}", :return])
stmts << return_statement
- func.body = stmts
+ func.body = defs + stmts
expect("}");
func
end
if sym.kind == :param
puts " get_param #{sym.value}"
elsif sym.kind == :local
- puts " get_local :#{sym.name}"
+ puts " get_local #{state.locals.index(sym.name)}"
end
else
puts "# invalid var #{v.name}"
end
def self.emit_def(state, v)
- state.add_sym(
+ state.syms.add_sym(
v.name.name, v.loc, :local, v.type, v.value)
emit(state, v.value)
- puts " set_local :#{v.name.name}"
+ raise "invalid local definition: #{v.name.name}" if not state.locals.index(v.name.name)
+ puts " set_local #{state.locals.index(v.name.name)}"
end
def self.emit_set(state, v)
- puts " set_local :#{v.name.name}"
+ emit(state, v.value)
+ raise "invalid local definition: #{v.name.name}" if not state.locals.index(v.name.name)
+ puts " set_local #{state.locals.index(v.name.name)}"
end
def self.emit_if(state, v)
$parser.syms.open_scope
puts "func #{name.to_sym.inspect}, #{val.value.args.length} do"
puts " locals #{val.value.locals.length}" if val.value.locals.length > 0
+ state.locals = val.value.locals
val.value.args.each_with_index do |name, idx|
$parser.syms.add_sym(
name.name, name.loc, :param, name.type, idx)