Permalink
Browse files

Add munging of global function names on re-definition, and avoid re-c…

…reating an already created class object
  • Loading branch information...
vidarh committed Oct 9, 2014
1 parent 02021ad commit b88a31b4d72fcb89a467e73ed61d1bff8e2843ae
Showing with 45 additions and 13 deletions.
  1. +8 −5 compile_class.rb
  2. +4 −2 compiler.rb
  3. +32 −0 globals.rb
  4. +1 −6 output_functions.rb
View
@@ -14,16 +14,13 @@ def compile_defm(scope, name, args, body)
cleaned = clean_method_name(name)
fname = "__method_#{scope.name}_#{cleaned}"
fname = @global_functions.set(fname, f)
scope.set_vtable_entry(name, fname, f)
# Save to the vtable.
v = scope.vtable[name]
compile_eval_arg(scope,[:sexp, [:call, :__set_vtable, [:self,v.offset, fname.to_sym]]])
# add the method to the global list of functions defined so far
# with its "munged" name.
@global_functions[fname] = f
# This is taken from compile_defun - it does not necessarily make sense for defm
return Value.new([:addr, clean_method_name(fname)])
end
@@ -58,7 +55,13 @@ def compile_class(scope, name,superclass, *exps)
ssize = sscope ? sscope.klass_size : nil
ssize = 0 if ssize.nil?
compile_exp(scope, [:assign, name.to_sym, [:sexp,[:call, :__new_class_object, [cscope.klass_size,superclass,ssize]]]])
compile_eval_arg(scope, [:if,
[:sexp,[:eq, name, 0]],
# then
[:assign, name.to_sym,
[:sexp,[:call, :__new_class_object, [cscope.klass_size,superclass,ssize]]]
]
])
@global_constants << name
View
@@ -25,6 +25,8 @@
require 'splat'
require 'value'
require 'output_functions'
require 'globals'
class Compiler
attr_reader :global_functions
@@ -48,7 +50,7 @@ class Compiler
def initialize emitter = Emitter.new
@e = emitter
@global_functions = {}
@global_functions = Globals.new
@string_constants = {}
@global_constants = Set.new
@global_constants << :false
@@ -210,7 +212,7 @@ def compile_defun(scope, name, args, body)
name = clean_method_name(name)
# add function to the global list of functions defined so far
@global_functions[name] = f
name = @global_functions.set(name,f)
# a function is referenced by its name (in assembly this is a label).
# wherever we encounter that name, we really need the adress of the label.
View
@@ -0,0 +1,32 @@
class Globals
def initialize
@global_functions = {}
end
# Returns the actual name
def set(fname, function)
suffix = ""
i = 0
while @global_functions[fname + suffix]
i += 1
suffix = "__#{i}"
end
fname = fname + suffix
# add the method to the global list of functions defined so far
# with its "munged" name.
@global_functions[fname] = function
fname
end
# We on purpose provide this instead of "each"
# as the use-case we need is function/method
# compilation where additional synthesized methods
# may get added during compilation.
def until_empty!
while f = @global_functions.shift
yield f[0],f[1]
end
end
end
View
@@ -4,12 +4,7 @@ class Compiler
# Similar to output_constants, but for functions.
# Compiles all functions, defined so far and outputs the appropriate assembly code.
def output_functions
# This is a bit ugly, but handles the case of lambdas or inner
# functions being added during the compilation... Should probably
# refactor.
while f = @global_functions.shift
name = f[0]
func = f[1]
@global_functions.until_empty! do |name, func|
# create a function scope for each defined function and compile it appropriately.
# also pass it the current global scope for further lookup of variables used
# within the functions body that aren't defined there (global variables and those,

0 comments on commit b88a31b

Please sign in to comment.