]> git.mdlowis.com Git - proto/cerise-c.git/commitdiff
implemented fully qualified identifiers. type checker needs updates to properly handl...
authorMike Lowis <mike.lowis@gentex.com>
Wed, 6 Nov 2024 18:23:15 +0000 (13:23 -0500)
committerMike Lowis <mike.lowis@gentex.com>
Wed, 6 Nov 2024 18:23:15 +0000 (13:23 -0500)
lib/parser.rb
lib/type_checker.rb

index 49f053205ddd5317d03153e005f7d9777739eb0e..af775721d600cc7a669524685cf6a71d819a64eb 100644 (file)
@@ -180,6 +180,7 @@ class Parser
 
   def toplevel_defintion
     ident = identifier()
+    ident.module = @module
     if matches("(") then
       val = function_definition(ident)
     elsif accept(:is)
@@ -261,7 +262,7 @@ class Parser
   def qualified_identifier()
     tok = expect(:ident)
     varname = IR::Var.new(tok.pos, nil, tok.text.to_sym, nil)
-    if matches(".")
+    if accept(".")
       mod = syms[varname.name]
       if mod.nil?
         error("no such module: '#{varname.name}'")
@@ -492,23 +493,27 @@ class Parser
     elsif matches("{")
       hash_literal()
     else
-      tok = consume()
-      if tok.type == :bool
-        IR::Const.new(tok.pos, :bool, tok.text == "true")
-      elsif tok.type == :string
-        IR::Const.new(tok.pos, :string, tok.text)
-      elsif tok.type == :int
-        IR::Const.new(tok.pos, :int, tok.text.to_i)
-      elsif tok.type == :char
-        IR::Const.new(tok.pos, :int, tok.text[1].ord)
-      elsif tok.type == :float
-        IR::Const.new(tok.pos, :float, tok.text.to_f)
-      elsif tok.type == :void
-        IR::Const.new(tok.pos, :void, :void)
-      elsif tok.type == :ident
+      if peek().type == :ident
         qualified_identifier()
       else
-        error("invalid constant #{tok}")
+        tok = consume()
+        if tok.type == :bool
+          IR::Const.new(tok.pos, :bool, tok.text == "true")
+        elsif tok.type == :string
+          IR::Const.new(tok.pos, :string, tok.text)
+        elsif tok.type == :int
+          IR::Const.new(tok.pos, :int, tok.text.to_i)
+        elsif tok.type == :char
+          IR::Const.new(tok.pos, :int, tok.text[1].ord)
+        elsif tok.type == :float
+          IR::Const.new(tok.pos, :float, tok.text.to_f)
+        elsif tok.type == :void
+          IR::Const.new(tok.pos, :void, :void)
+#        elsif tok.type == :ident
+#          qualified_identifier()
+        else
+          error("invalid constant #{tok}")
+        end
       end
     end
   end
index a4eba9dd07410d1583628213bac5b21f84fe3795..439bf50af8e4c45310145e5ba3be00820b9e7ba1 100644 (file)
@@ -385,6 +385,14 @@ class TypeChecker
     expr.type = optype[-1]
   end
 
+  def typename(var)
+    if var.module.nil?
+      var.name.to_sym
+    else
+      "#{var.module}_#{var.name}".to_sym
+    end
+  end
+
   def check_binary(env, expr, vtype)
     if expr.op == "["
       left_type = infer(env, expr.left)
@@ -403,7 +411,8 @@ class TypeChecker
         error(expr.loc, "don't know how to index into type: #{left_type}")
       end
     else
-      optype = BinaryOps[expr.op][vtype]
+      tname = typename(vtype)
+      optype = BinaryOps[expr.op][tname]
       error(expr.loc, "unknown binary operation '#{expr.op}' for operand type #{vtype}") if optype.nil?
       check(env, expr.left,  optype[0])
       check(env, expr.right, optype[1])