syntax bikeshedding wheeee
M fml/src/parser.rs +25 -19
@@ 512,7 512,7 @@ impl<'input> Parser<'input> {
                 self.expect(T::RParen);
                 lhs
             }
-            // Tuple literal
+            // Tuple or struct literal
             T::LBrace => self.parse_constructor(),
             // Nominal type literal
             // $Foo(3)

          
@@ 624,9 624,25 @@ impl<'input> Parser<'input> {
         ast::ExprNode::new(ast::Expr::Lambda { signature, body })
     }
 
-    /// tuple constructor = "{" [expr {"," expr} [","] "}"
+    /// If we see `.foo = bar` in our thing then it's a struct
     fn parse_constructor(&mut self) -> ast::ExprNode {
         self.expect(T::LBrace);
+        if self.peek_is(T::Period.discr()) {
+            self.parse_struct_literal()
+        } else {
+            self.parse_tuple_literal()
+        }
+    }
+
+    /// struct constructor = "{" "." ident "=" expr {"," ...} "}"
+    fn parse_struct_literal(&mut self) -> ast::ExprNode {
+        let body = self.parse_struct_lit_fields();
+        self.expect(T::RBrace);
+        ast::ExprNode::new(ast::Expr::StructCtor { body })
+    }
+
+    /// tuple constructor = "{" [expr {"," expr} [","] "}"
+    fn parse_tuple_literal(&mut self) -> ast::ExprNode {
         let mut body = vec![];
         while let Some(expr) = self.parse_expr(0) {
             body.push(expr);

          
@@ 640,27 656,17 @@ impl<'input> Parser<'input> {
         ast::ExprNode::new(ast::Expr::TupleCtor { body })
     }
 
-    /// struct literal = "struct" "{" ... "}"
-    fn parse_struct_literal(&mut self) -> ast::ExprNode {
-        self.expect(T::Struct);
-        self.expect(T::LBrace);
-        let body = self.parse_struct_lit_fields();
-        self.expect(T::RBrace);
-        ast::ExprNode::new(ast::Expr::StructCtor { body })
-    }
-
     fn parse_struct_lit_fields(&mut self) -> HashMap<String, ast::ExprNode> {
         let mut fields = HashMap::new();
 
         loop {
-            match self.lex.peek() {
-                Some((T::Ident(_i), _span)) => {
-                    let name = self.expect_ident();
-                    self.expect(T::Equals);
-                    let vl = self.parse_expr(0).unwrap();
-                    fields.insert(name, vl);
-                }
-                _ => break,
+            if self.peek_expect(T::Period.discr()) {
+                let name = self.expect_ident();
+                self.expect(T::Equals);
+                let vl = self.parse_expr(0).unwrap();
+                fields.insert(name, vl);
+            } else {
+                break;
             }
 
             if self.peek_expect(T::Comma.discr()) {

          
M fml/tests/test_struct1.gt +4 -4
@@ 10,10 10,10 @@ end
 
 
 fn main(): I32 =
-    let f1: Foo = id($Foo struct {
-        a = 3,
-        b = false
+    let f1: Foo = id($Foo {
+        .a = 3,
+        .b = false
     })
-    let f2: struct a: I32, b: Bool end = id(struct { a = 3, b = false })
+    let f2: struct a: I32, b: Bool end = id({ .a = 3, .b = false })
     3
 end

          
M fml/tests/test_struct2.gt +6 -6
@@ 5,17 5,17 @@ type Foo = struct
 end
 
 fn thing(i: I32): Foo =
-    $Foo struct {
-        a = i,
-        b = false,
+    $Foo {
+        .a = i,
+        .b = false,
     }
 end
 
 
 fn main(): I32 =
-    let f1: Foo = $Foo struct {
-        a = 3,
-        b = false
+    let f1: Foo = $Foo {
+        .a = 3,
+        .b = false
     }
     let f2: Foo = thing(4)
     3

          
M fml/tests/test_struct3.gt +5 -5
@@ 5,16 5,16 @@ type Foo = struct
 end
 
 fn thing(i: I32): Foo =
-    $Foo struct {
-        a = i,
-        b = false,
+    $Foo {
+        .a = i,
+        .b = false,
     }
 end
 
 
 fn main(): I32 =
-    let f1: Foo = $Foo struct {
-        a = 3,
+    let f1: Foo = $Foo {
+        .a = 3,
     }
     let f2: Foo = thing(4)
     3

          
M fml/tests/test_struct4.gt +3 -3
@@ 10,9 10,9 @@ end
 
 
 fn main(): I32 =
-    let f1: Foo(I32) = id($Foo(I32) struct {
-        a = 3,
-        b = false
+    let f1: Foo(I32) = id($Foo(I32) {
+        .a = 3,
+        .b = false
     })
     --let f2: struct a: I32, b: Bool end = id(struct { a = 3, b = false })
     3