func
end
-$parser.exprs.each do |e|
+$toplevel = $parser.exprs.map do |e|
if e.is_a? ANF::Let and e.expr.is_a? ANF::Func
patch_vars($parser.syms.clone, e, false)
else
patch_vars($parser.syms.clone, e, true)
end
- pp e
+# pp e
+# puts ""
+ e
+end
+
+#pp $lifted
+#puts ""
+
+$lifted.each do |name, value|
+ let = ANF::Let.new(0, nil,
+ ANF::Var.new(0, nil, name),
+ value,
+ nil)
+ ANF.check(let)
+ ANF.pp(let)
+ puts ""
+end
+
+$toplevel.each do |e|
+ ANF.pp(e)
+ ANF.check(e)
+ puts ""
end
-pp $lifted
-#pp parser.exprs[0]
-#pp parser.syms
-#pp parser.exprs
# | <boolean>
# | <string>
# | <var>
+# | (env-ref <number>)
# | (void)
#
# <cexp> = (<aexp> <aexp> ...)
Const = Struct.new(:loc, :type, :value)
Var = Struct.new(:loc, :type, :name)
EnvRef = Struct.new(:loc, :type, :index)
+ Env = Struct.new(:loc, :type, :index)
Let = Struct.new(:loc, :type, :var, :expr, :body)
If = Struct.new(:loc, :type, :cond, :then, :else)
Set = Struct.new(:loc, :type, :var, :expr)
Apply = Struct.new(:loc, :type, :func, :args)
def self.check_atomic(expr)
- case expr.class
- when Const
- when Var
- when Func
+ if (expr.is_a? Const) or (expr.is_a? Var) or (expr.is_a? Func)
return
else
raise "not ANF compliant"
end
def self.check_complex(expr)
- case expr.class
- when Apply
- when If
- when Set
- return
+ if (expr.is_a? Apply) or (expr.is_a? If) or (expr.is_a? Set)
+ return
else
- raise "not ANF compliant"
+ check_atomic(expr)
end
end
def self.check(expr)
- case expr.class
- when Let
+ if expr.is_a? Let
check_let(expr)
- when If
- check_if(expr)
- when Set
- check_set(expr)
- when Func
- check_func(expr)
- when Apply
- check_apply(expr)
+ else
+ check_complex(expr)
end
end
def self.check_let(expr)
- if not expr.body
- check(expr.value)
+ if expr.body.nil?
+ check(expr.expr)
else
- check_complex(expr.value)
+ check_complex(expr.expr)
check(expr.body)
end
end
end
def self.check_func(expr)
- check(expr.body)
+ check(expr.expr)
end
def self.check_apply(expr)
check_atomic(e)
end
end
+
+ def self.print(str, indent = 0)
+ $stdout.print (" " * indent) + str
+ end
+
+ def self.pp(expr, indent = 0)
+ if expr.is_a? Let
+ print_let(expr, indent)
+ elsif expr.is_a? If
+ print_if(expr, indent)
+ elsif expr.is_a? Set
+ print_set(expr, indent)
+ elsif expr.is_a? Func
+ print_func(expr, indent)
+ elsif expr.is_a? Apply
+ print_apply(expr, indent)
+ elsif expr.is_a? Const
+ print("#{expr.value}\n", indent)
+ elsif expr.is_a? Var
+ print("#{expr.name}\n", indent)
+ elsif expr.is_a? Env
+ print("ENV_CREATE\n", indent)
+ elsif expr.is_a? EnvRef
+ print("ENV_REF\n", indent)
+ else
+ raise "unexpected form: #{expr.class}"
+ end
+ end
+
+ def self.print_let(expr, indent = 0)
+ print("let #{expr.var.name} = ", indent)
+ pp(expr.expr, 0)
+ if not expr.body.nil?
+ print("in\n", indent)
+ pp(expr.body, indent+1)
+ end
+ end
+
+ def self.print_if(expr, indent = 0)
+ print("if", indent)
+ end
+
+ def self.print_set(expr, indent = 0)
+ print("set", indent)
+ end
+
+ def self.print_func(expr, indent = 0)
+ args = expr.args.map{|a| a.name }.join(", ")
+ print("func(#{args})\n", indent)
+ pp(expr.expr, indent+1)
+ end
+
+ def self.print_apply(expr, indent = 0)
+ args = expr.args.map do |a|
+ if a.is_a? Const
+ "#{a.value}"
+ elsif a.is_a? Var
+ "#{a.name}"
+ elsif a.is_a? EnvRef
+ "ENV_REF"
+ else
+ raise "argument to apply is not atomic"
+ end
+ end.join(", ")
+ print("#{expr.func}(#{args})", indent)
+ end
end