# HG changeset patch # User Simon Heath # Date 1670276483 18000 # Mon Dec 05 16:41:23 2022 -0500 # Node ID efd98a53c3fe474ad24a5d424c80af3e3bc7020a # Parent 964fb997a0f31b0b753074050c92faf701f74db2 BEHOLD MY POWER MUAHAHAAHAHHAHAHAHAAAAAA diff --git a/fml/src/ast.rs b/fml/src/ast.rs --- a/fml/src/ast.rs +++ b/fml/src/ast.rs @@ -78,7 +78,7 @@ }, Let { varname: String, - typename: Type, + typename: Option, init: ExprNode, }, Lambda { diff --git a/fml/src/parser.rs b/fml/src/parser.rs --- a/fml/src/parser.rs +++ b/fml/src/parser.rs @@ -626,8 +626,11 @@ 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) diff --git a/fml/src/typeck.rs b/fml/src/typeck.rs --- a/fml/src/typeck.rs +++ b/fml/src/typeck.rs @@ -214,6 +214,8 @@ // 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 @@ } => { 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 @@ 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); diff --git a/fml/tests/main.rs b/fml/tests/main.rs --- a/fml/tests/main.rs +++ b/fml/tests/main.rs @@ -138,3 +138,9 @@ 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); +} diff --git a/fml/tests/test_let1.gt b/fml/tests/test_let1.gt new file mode 100644 --- /dev/null +++ b/fml/tests/test_let1.gt @@ -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