e = object.new
e.defaults = [:object, :array, :number, :string, :exception, :hash, :regex]
e.init = {
my.variables = [[:]]
my.unsets = [[]]
my.variable_type = [[:]]
my.next_id = 0
v = my.variables.last
defaults.each { d | v[d] = d }
}
e.next_var = {
w = my
next_unset || { w.next_temp }
}
e.next_unset = {
my.unsets.last.pop
}
e.next_temp = {
"_temp#{my.next_id = my.next_id + 1}"
}
e.new_scope = {
my.unsets << []
my.variables << [:]
my.variable_type << [:]
}
e.pop_scope = {
my.variables.pop
my.unsets.pop
my.variable_type.pop
}
e.new_var = { var |
my.variables.last[var] = next_temp
}
e.local_var? = { var |
my.variables.last[var]
}
e.get = { var |
v = null
my.variables.reverse_each_while { vars |
v = vars[var]
v.null?
}
v
}
e.set = { var, val |
my.variables.last[var] = val
}
e.unset = { var |
true? var.string? && { var.include? "_temp" }
{
my.unsets.last << var
my.variable_type.last[var] = null
}
}
e.set_type = { var, type |
my.variable_type.last[var] = type
}
e.get_type = { var |
t = null
my.variable_type.reverse_each_while { types |
t = types[var]
t.null?
}
t
}
e.do_scope = {
my.unsets << []
}
e.endo_scope = {
my.unsets.pop
}
export e, :env