]> git.mdlowis.com Git - proto/cerise-c.git/commitdiff
implemented record definition, initialization, and access syntax
authorMike Lowis <mike.lowis@gentex.com>
Wed, 8 Jan 2025 20:04:10 +0000 (15:04 -0500)
committerMike Lowis <mike.lowis@gentex.com>
Wed, 8 Jan 2025 20:04:10 +0000 (15:04 -0500)
Records.m
cerise-c.m
lib/parser.rb
lib/type_checker.rb

index 07db8d88d24e630be51ba0806e31afbac1ee0111..614fe0222034cdae8962e08489d9634e27a2dc57 100644 (file)
--- a/Records.m
+++ b/Records.m
@@ -7,5 +7,4 @@ Rec1 is record {
 Rec2 is record (Rec1) {
     bar = int
     baz = Rec2
-    foo = Rec2
 }
\ No newline at end of file
index 05d842f10219b7d38b7151ec1e2e2956b87f09d5..5a46ca3cd789c428686c3160165eb2cf87fb3e7a 100644 (file)
@@ -190,7 +190,7 @@ TestIfBlocks(){
 
 TestRecords(){
     def foo = new Records:Rec1 { foo = 42 }
-#    assert foo.foo == 42
+    assert foo.foo == 42
 #    set foo.foo = 43
 #    assert foo.foo == 43
 }
index f3cea9aad58113249baf503f30d4e92e00b67c74..7f3a4d0386e060ed3679ddbd1d6d904bfc31e5f0 100644 (file)
@@ -485,6 +485,8 @@ class Parser
       expr = func_call(expr)
     elsif matches("[")
       expr = array_or_hash_access(expr)
+    elsif matches(".")
+      expr = record_access(expr)
     end
     expr
   end
@@ -508,6 +510,13 @@ class Parser
     make_binop(loc, "[", expr, key)
   end
 
+  def record_access(expr)
+    expect(".")
+    loc = location
+    field = identifier()
+    make_binop(loc, ".", expr, field)
+  end
+
   def const_or_ident()
     if matches(:new)
       record_literal()
index 69f3085251e8ec94e05de0b39b3c0af551e3b667..f682d2b817ee846c48355f24f7c3bcf77ce40a2f 100644 (file)
@@ -492,6 +492,18 @@ class TypeChecker
       else
         error(expr.loc, "don't know how to index into type: #{left_type}")
       end
+    elsif expr.op == "."
+      rec_type = lookup_type(env, infer(env, expr.left))
+      if rec_type.form != :record
+        error(expr.loc, "left hand side of the '.' operator is not a record type")
+      end
+      if not expr.right.is_a? IR::Var
+        error(expr.loc, "right hand side of '.' operator is not an identifier")
+      end
+      if expr.right.module != nil
+        error(expr.loc, "qualified identifier is not valid right hand operand for the '.' operator")
+      end
+      expr.type = rec_type.fields[expr.right.name]
     else
       tname = typename(vtype)
       optype = BinaryOps[expr.op][tname]