]> git.mdlowis.com Git - proto/cerise-c.git/commitdiff
Implemented hash and array access and assignment
authorMike Lowis <mike.lowis@gentex.com>
Thu, 13 Jun 2024 18:15:12 +0000 (14:15 -0400)
committerMike Lowis <mike.lowis@gentex.com>
Thu, 13 Jun 2024 18:15:12 +0000 (14:15 -0400)
cerise-c.m
cerise-c.rb

index 832155a5b3f58104cc5b568342596cde18b5cd36..aa00b710052791c090d9a734a25633431d171e4a 100644 (file)
@@ -89,15 +89,20 @@ TestStringOps()
 TestArrayOps()
 {
     def array = [1,2,3]
-    set item = array[0]
-#    set array[0] = item
+    def item = 42
+    set array[0] = item
+    assert array[0] == 42
+    assert array[1] == 2
+    assert array[2] == 3
 }
 
 TestHashOps()
 {
     def hash = {foo: "bar", "baz": "boo"}
-    set item = hash["foo"]
-#    set hash["foo"] = item
+    def item = 42
+    set hash["foo"] = item
+    assert hash["foo"] == 42
+    assert hash["baz"] == "boo"
 }
 
 Main()
index c7245b5c9c70511f253c2b66ac95dbb2fc271eb1..633bf84e80aaab5b2ae6bd95940f2b32af4c6148 100755 (executable)
@@ -363,6 +363,9 @@ class Parser
     loc = location
     expect(:set)
     name = identifier()
+    if matches("[")
+      name = array_or_hash_access(name)
+    end
     expect ("=")
     value = expression()
     IR::Set.new(loc, nil, name, value)
@@ -483,6 +486,8 @@ class Parser
     # Check for function call
     if matches("(")
       expr = func_call(expr)
+    elsif matches("[")
+      expr = array_or_hash_access(expr)
     end
     expr
   end
@@ -498,6 +503,26 @@ class Parser
     call
   end
 
+  def array_or_hash_access(expr)
+    expect("[")
+    loc = location
+    key = expression()
+    expect("]")
+    make_binop(loc, "[", expr, key)
+
+#  def make_binop(loc, op, left, right)
+
+#    call = IR::Call.new(location, nil, expr, [])
+#    expect("(")
+#    while !matches(")")
+#      call.args << expression()
+#      expect(",") if !matches(")")
+#    end
+#    expect(")")
+#    call
+  end
+
+
   def const_or_ident()
     if matches("[")
       array_literal()
@@ -1179,6 +1204,11 @@ module Codegen
       putln state, "#{result} = #{rvar};"
       state.indent -= 1
       putln state, "}"
+    elsif v.op == "["
+      lvar = emit(state, v.left)
+      rvar = emit(state, v.right)
+      result = mktemp(state);
+      putln state, "Value #{result} = ArrayOrHashGet(#{lvar}, #{rvar});"
     else
       lvar = emit(state, v.left)
       rvar = emit(state, v.right)
@@ -1239,9 +1269,17 @@ module Codegen
   end
 
   def self.emit_set(state, v)
-    temp = emit(state, v.value)
-    raise "invalid local definition: #{v.name.name}" if not state.locals.index(v.name.name)
-    putln state, "#{v.name.name} = #{temp};"
+    if v.name.is_a? IR::Op
+      raise "not a valid array or hash access expression" if v.name.op != "["
+      object = emit(state, v.name.left)
+      key = emit(state, v.name.right)
+      value = emit(state, v.value)
+      putln state, "ArrayOrHashSet(#{object}, #{key}, #{value});"
+    else
+      temp = emit(state, v.value)
+      raise "invalid local definition: #{v.name.name}" if not state.locals.index(v.name.name)
+      putln state, "#{v.name.name} = #{temp};"
+    end
   end
 
   def self.emit_assert(state, v)