# assert ("foo" + 123.0) == "foo123.000000"
# assert ("foo" + true) == "footrue"
# assert ("foo" + false) == "foofalse"
- assert Length("foo") == 3
+# assert Length("foo") == 3
}
TestArrayOps()
assert array[0] == 42
assert array[1] == 2
assert array[2] == 3
- assert Length(array) == 3
+# assert Length(array) == 3
}
TestHashOps()
set hash["foo"] = item
assert hash["foo"] == 42
assert hash["baz"] == "boo"
- assert Length(hash) == 2
+# assert Length(hash) == 2
}
TestEqOps() {
@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)
# 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 = {
"+" => {
end
def infer_const(env, expr)
+ raise "inferring const"
expr.type
end
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)
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)
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)