]> git.mdlowis.com Git - proto/sclpl-rb.git/commitdiff
added anf pretty printing
authorMichael D. Lowis <mike.lowis@gentex.com>
Fri, 20 Jan 2023 21:29:05 +0000 (16:29 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Fri, 20 Jan 2023 21:29:05 +0000 (16:29 -0500)
lib/cerise.rb
lib/utils/anf.rb

index 439aa4c30bcf3e45aebc42bb85ce8c4f7f867522..d93ebc7baefb79234491b05d2b7536d13c61a81f 100755 (executable)
@@ -652,15 +652,32 @@ def close_func(env, func, close_funcs = true)
   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
index aa5cede879fa6475f59fd6d9e66d4a37a2988010..0865c58eb4ccbad00348b2e980802332b3fb931a 100644 (file)
@@ -10,6 +10,7 @@
 #        | <boolean>
 #        | <string>
 #        | <var>
+#        | (env-ref <number>)
 #        | (void)
 #
 # <cexp> = (<aexp> <aexp> ...)
@@ -24,6 +25,7 @@ module ANF
   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)
@@ -31,10 +33,7 @@ module ANF
   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"
@@ -42,36 +41,26 @@ module ANF
   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
@@ -87,7 +76,7 @@ module ANF
   end
 
   def self.check_func(expr)
-    check(expr.body)
+    check(expr.expr)
   end
 
   def self.check_apply(expr)
@@ -95,4 +84,70 @@ module ANF
       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