]> git.mdlowis.com Git - proto/cerise-c.git/commitdiff
added array literal parsing and code generation
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 11 Jun 2024 01:29:16 +0000 (21:29 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 11 Jun 2024 01:29:16 +0000 (21:29 -0400)
cerise-c.m
cerise-c.rb

index 9af7d030b314ecc89370ee764cfb48f9b1bdf539..d8d91c4dc061e9e4a0d82e2b8d4bbe2352eb5f0c 100644 (file)
@@ -88,7 +88,7 @@ TestStringOps()
 
 Main()
 {
-    def foo = 123
+    def foo = [1,2,3]
     def bar = foo
     TestLiterals()
     TestBoolOps()
index ac0e26004327c3525c6a202870fa36d7fc8a8c52..6f1b1c6b3128156094b5d6ad8ad7539720f3b927 100755 (executable)
@@ -499,22 +499,52 @@ class Parser
   end
 
   def const_or_ident()
-    tok = consume()
-    if tok.type == :bool
-      IR::Const.new(tok.pos, Value::Bool, tok.text == "true")
-    elsif tok.type == :string
-      IR::Const.new(tok.pos, Value::String, tok.text)
-    elsif tok.type == :int
-      IR::Const.new(tok.pos, Value::Int, tok.text.to_i)
-    elsif tok.type == :float
-      IR::Const.new(tok.pos, Value::Float, tok.text.to_f)
-    elsif tok.type == :void
-      IR::Const.new(tok.pos, Value::Void, :void)
-    elsif tok.type == :ident
-      IR::Var.new(tok.pos, nil, tok.text.to_sym)
+    if matches("[")
+      array_literal()
+    elsif matches("{")
+      hash_literal()
     else
-      error("invalid constant #{tok}")
+      tok = consume()
+      if tok.type == :bool
+        IR::Const.new(tok.pos, Value::Bool, tok.text == "true")
+      elsif tok.type == :string
+        IR::Const.new(tok.pos, Value::String, tok.text)
+      elsif tok.type == :int
+        IR::Const.new(tok.pos, Value::Int, tok.text.to_i)
+      elsif tok.type == :float
+        IR::Const.new(tok.pos, Value::Float, tok.text.to_f)
+      elsif tok.type == :void
+        IR::Const.new(tok.pos, Value::Void, :void)
+      elsif tok.type == :ident
+        IR::Var.new(tok.pos, nil, tok.text.to_sym)
+      else
+        error("invalid constant #{tok}")
+      end
+    end
+  end
+
+  def array_literal()
+    exprs = []
+    expect("[")
+    loc = location()
+    while !matches("]")
+      exprs << expression()
+      expect(",") if !matches("]")
     end
+    expect("]")
+    exprs
+    IR::Const.new(loc, nil, exprs)
+  end
+
+  def hash_literal()
+    exprs = {}
+    expect("{")
+#      while !matches("}")
+#        exprs << expression()
+#        expect(",") if !matches("}")
+#      end
+    expect("}")
+    exprs
   end
 end
 
@@ -1076,13 +1106,22 @@ module Codegen
   def self.emit_const(state, v)
     var = mktemp(state)
     if v.value.is_a? Integer
-      putln state,  "Value #{var} = MakeInt(#{v.value});"
+      putln state, "Value #{var} = MakeInt(#{v.value});"
     elsif v.value.is_a? Float
-      putln state,  "Value #{var} = MakeReal(#{v.value});"
+      putln state, "Value #{var} = MakeReal(#{v.value});"
     elsif v.value == true || v.value == false
-      putln state,  "Value #{var} = MakeBool(#{v.value});"
+      putln state, "Value #{var} = MakeBool(#{v.value});"
     elsif v.value.is_a? String
-      putln state,  "Value #{var} = MakeString(#{v.value});"
+      putln state, "Value #{var} = MakeString(#{v.value});"
+    elsif v.value.is_a? Array
+      putln state, "Value #{var} = MakeArrayOfLength(#{v.value.length});"
+      v.value.each_with_index do |e, i|
+        val = emit(state, e)
+        putln state, "Array_SetIndex(#{var}, #{i}, #{val});"
+
+      end
+    elsif v.value.is_a? Hash
+      putln state,  "Value #{var} = MakeHash(#{v.value});"
     else
       raise "code emitting constants of this type not implemented"
     end
@@ -1214,7 +1253,7 @@ end
 
 $parser  = Parser.new("cerise-c.m")
 $checker = TypeChecker.new($parser)
-state = Codegen.init($parser)
+$state = Codegen.init($parser)
 
 puts "#include <runtime.h>\n\n"
 
@@ -1227,13 +1266,13 @@ $parser.syms.each do |name, val|
   args = val.value.args.map{|e| "Value #{e.name}" }.join(", ")
   puts "Value #{name}(#{args}) {"
   $parser.syms.open_scope
-  state.locals = val.value.locals
+  $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)
   end
   val.value.body.each do |stmnt|
-    Codegen.emit(state, stmnt)
+    Codegen.emit($state, stmnt)
   end
   puts "}\n\n"
   $parser.syms.close_scope