M fml/src/ast.rs +1 -1
@@ 78,7 78,7 @@ pub enum Expr {
},
Let {
varname: String,
- typename: Type,
+ typename: Option<Type>,
init: ExprNode,
},
Lambda {
M fml/src/parser.rs +5 -2
@@ 626,8 626,11 @@ impl<'input> Parser<'input> {
fn parse_let(&mut self) -> ast::ExprNode {
self.expect(T::Let);
let varname = self.expect_ident();
- self.expect(T::Colon);
- let typename = self.parse_type();
+ let typename = if self.peek_expect(T::Colon.discr()) {
+ Some(self.parse_type())
+ } else {
+ None
+ };
self.expect(T::Equals);
let init = self
.parse_expr(0)
M fml/src/typeck.rs +7 -3
@@ 214,6 214,8 @@ impl Tck {
// rather than "unknown name". Guess it works for now though.
//
// TODO: The scoping here is still bananas, figure it out
+ // I think we need to get the generic names from the function call
+ // and figure 'em out, rather than just casually adding 'em in here
let tid = self.insert(TypeInfo::Unknown);
named_types.insert(s.clone(), tid);
TypeInfo::Ref(tid)
@@ 405,7 407,11 @@ fn typecheck_expr(
} => {
typecheck_expr(tck, symtbl, init)?;
let init_expr_type = tck.get_expr_type(init);
- let var_type = tck.insert_known(typename);
+ let var_type = if let Some(t) = typename {
+ tck.insert_known(t)
+ } else {
+ tck.insert(TypeInfo::Unknown)
+ };
tck.unify(symtbl, init_expr_type, var_type)?;
// TODO: Make this expr return unit instead of the
@@ 521,8 527,6 @@ fn typecheck_expr(
tck.unify(symtbl, tid, body_type)?;
println!("Done unifying type ctor");
// The type the expression returns
- // TODO: Generic params for type constructors
- //let constructed_type = tck.insert_known(&Type::Named(name.clone(), vec![]));
let constructed_type =
tck.insert_known(&Type::Named(name.clone(), type_params.clone()));
tck.set_expr_type(expr, constructed_type);
M fml/tests/main.rs +6 -0
@@ 138,3 138,9 @@ fn test_struct5() {
let src = include_str!("test_struct5.gt");
let _output = fml::compile("test_struct5.gt", src);
}
+
+#[test]
+fn test_let1() {
+ let src = include_str!("test_let1.gt");
+ let _output = fml::compile("test_let1.gt", src);
+}
A => fml/tests/test_let1.gt +25 -0
@@ 0,0 1,25 @@
+
+type Foo(@Thing) = struct
+ a: @Thing,
+ b: Bool
+end
+
+fn id(x: @T): @T =
+ x
+end
+
+
+fn main(): I32 =
+ let f1 = id($Foo(I32) {
+ .a = 3,
+ .b = false
+ })
+
+ let f2 = id($Foo(Bool) {
+ .a = true,
+ .b = false
+ })
+
+ let f3 = f1
+ 3
+end