end
#
def infer(env, expr)
- if expr.is_a? IR::Const
+ if expr.is_a? IR::Func
+ infer_func(env, expr)
+ elsif expr.is_a? IR::Return
+ infer_return(env, expr)
+ elsif expr.is_a? IR::Const
infer_const(env, expr)
- elsif (expr.is_a? IR::Op)
- infer_op(env, expr)
elsif expr.is_a? IR::Var
infer_var(env, expr)
-# elsif expr.is_a? IR::Let
-# infer_let(env, expr)
-# elsif expr.is_a? IR::If
-# infer_ifexpr(env, expr)
-# elsif expr.is_a? IR::Set
-# infer_set(env, expr)
-# elsif expr.is_a? IR::Func
-# infer_func(env, expr)
-# elsif expr.is_a? IR::Apply
-# infer_apply(env, expr)
+ elsif expr.is_a? IR::Def
+ infer_def(env, expr)
+ elsif expr.is_a? IR::Set
+ infer_set(env, expr)
+ elsif expr.is_a? IR::Op
+ infer_op(env, expr)
+ elsif expr.is_a? IR::Call
+ infer_call(env, expr)
+ elsif expr.is_a? IR::If
+ infer_if(env, expr)
else
+ pp expr
error(expr.loc, "unable to determine type of expression")
end
end
private
+ def infer_func(env, expr)
+ raise "unimplemented"
+ end
+
+ def infer_return(env, expr)
+ raise "unimplemented"
+ end
+
+ def infer_const(env, expr)
+ expr.type
+ end
+
+ def infer_var(env, expr)
+ if env[expr.name].nil?
+ error(expr.loc, "symbol '#{expr.name}' not defined")
+ end
+ expr.type = env[expr.name][:type]
+ end
+
+ def infer_def(env, expr)
+ raise "unimplemented"
+ end
+
+ def infer_set(env, expr)
+ raise "unimplemented"
+ end
+
+ def infer_op(env, expr)
+ # infer the operand type first
+ vtype = infer(env, expr.left)
+ if (expr.left and expr.right)
+ check_binary(env, expr, vtype)
+ else
+ check_unary(env, expr, vtype)
+ end
+ end
+
+ def infer_call(env, expr)
+ raise "unimplemented"
+ end
+
+ def infer_if(env, expr)
+ raise "unimplemented"
+ end
+
+
+
+
# def make_typevar()
# @typevar ||= 0
# var = "abcdefghijklmnopqrstuvwxyz"[@typevar]
# check(env, let.expr, type)
# end
- def infer_const(env, expr)
- expr.type
- end
-
- def infer_op(env, expr)
- # infer the operand type first
- vtype = infer(env, expr.left)
- if (expr.left and expr.right)
- check_binary(env, expr, vtype)
- else
- check_unary(env, expr, vtype)
- end
- end
-
-
- def infer_var(env, expr)
- if env[expr.name].nil?
- error(expr.loc, "symbol '#{expr.name}' not defined")
- end
- expr.type = env[expr.name][:type]
- end
#
# def infer_let(env, let)
# if let.body.nil?