]> git.mdlowis.com Git - proto/cerise-c.git/commitdiff
fleshed out more type rules
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 17 Oct 2024 01:51:01 +0000 (21:51 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 17 Oct 2024 01:51:01 +0000 (21:51 -0400)
cerise-c.m
lib/parser.rb
lib/type_checker.rb

index 8c321a3bfa02c2345d43fd91bf67f4abbbe69249..03e5f7fbaeef84898a26cf5f13e4e43fb3241997 100644 (file)
@@ -85,7 +85,7 @@ TestStringOps()
 #    assert ("foo" + 123.0) == "foo123.000000"
 #    assert ("foo" + true) == "footrue"
 #    assert ("foo" + false) == "foofalse"
-    assert Length("foo") == 3
+#    assert Length("foo") == 3
 }
 
 TestArrayOps()
@@ -96,7 +96,7 @@ TestArrayOps()
     assert array[0] == 42
     assert array[1] == 2
     assert array[2] == 3
-    assert Length(array) == 3
+#    assert Length(array) == 3
 }
 
 TestHashOps()
@@ -106,7 +106,7 @@ TestHashOps()
     set hash["foo"] = item
     assert hash["foo"] == 42
     assert hash["baz"] == "boo"
-    assert Length(hash) == 2
+#    assert Length(hash) == 2
 }
 
 TestEqOps() {
index 9a1f48a2523330905e91ad842b6da2320a5eff16..c844812591e3edcdae210a4946e0afdbd4a4f142 100644 (file)
@@ -12,15 +12,14 @@ class Parser
     @syms = SymTable.new
     @checker = TypeChecker.new(self)
 
-    syms.add_builtin(:Length, :func, [:any, :int], nil)
-
+    syms.add_builtin(:bool,   0, :type, :bool)
 
 #    syms.add_builtin(:void,   0, :type, :void)
-    syms.add_builtin(:bool,   0, :type, :bool)
 #    syms.add_builtin(:int,    0, :type, :int)
 #    syms.add_builtin(:string, 0, :type, :string)
 #    syms.add_builtin(:float,  0, :type, :float)
 
+#    syms.add_builtin(:Length, :func, nil, nil)
 #    syms.add_builtin(:Error,  :func, [:any, :void], nil)
 
     parse_file(path)
index 2f628bec33d627f8810feca05fbaf541d7ea664e..17588764c1c269b95346645b09bc31056e520809 100644 (file)
@@ -2,18 +2,18 @@
 # Type Checking/Inference Module
 ##
 class TypeChecker
-  BaseToTypes = {
-    :bool   => Value::Bool,
-    :int    => Value::Int,
-    :float  => Value::Float,
-#    :string => Value::String,
-  }
-
-  TypesToBase = {
-    Value::Bool  => :bool,
-    Value::Int   => :int,
-    Value::Float => :float,
-  }
+#  BaseToTypes = {
+#    :bool   => Value::Bool,
+#    :int    => Value::Int,
+#    :float  => Value::Float,
+##    :string => Value::String,
+#  }
+#
+#  TypesToBase = {
+#    Value::Bool  => :bool,
+#    Value::Int   => :int,
+#    Value::Float => :float,
+#  }
 
   UnaryOps = {
     "+" => {
@@ -194,6 +194,7 @@ class TypeChecker
   end
 
   def infer_const(env, expr)
+    raise "inferring const"
     expr.type
   end
 
@@ -205,8 +206,25 @@ class TypeChecker
   end
 
   def infer_def(env, expr)
+#    raise "unimplemented"
+#    error(expr.loc, "unimplemented")
+
+    pp expr
+    name = expr.name.name
+    type = expr.value.type
+    if type
+      puts "check"
+      check(env, expr.value, type)
+    else
+      puts "infer"
+      type = infer(env, expr.value)
+    end
+    pp type
+#    env[name] = { loc: expr.loc, type: type }
+    expr.type = :void
+    expr.value.type = type
+    pp expr
     raise "unimplemented"
-    error(expr.loc, "unimplemented")
   end
 
   def infer_set(env, expr)
@@ -225,8 +243,8 @@ class TypeChecker
   end
 
   def infer_call(env, expr)
-    raise "unimplemented"
-    error(expr.loc, "unimplemented")
+    type = infer(env, expr.func)
+    check_call(env, expr, type)
   end
 
   def infer_if(env, expr)
@@ -291,8 +309,14 @@ class TypeChecker
   end
 
   def check_call(env, expr, type)
-    raise "unimplemented"
-    error(expr.loc, "unimplemented")
+#    pp expr
+    error(expr.loc, "object being applied is not a function (has type: #{type.to_s})") if not type.is_a? Array
+    error(expr.loc, "wrong number of arguments to function call") if (type.length - 1) != expr.args.length
+    type[0..-2].each_with_index do |t,i|
+      check(env, expr.args[i], t)
+    end
+    pp type
+    expr.type = type.last
   end
 
   def check_if(env, expr, type)