@@ -2,10 +2,7 @@ use scoped_arena::Scope;
22use std::cell::RefCell;
33
44use crate::source::{ByteRange, BytePos, StringId, StringInterner};
5- use crate::surface::{
6- Arg, BinOp, ExprField, FormatField, Item, ItemDef, Module, ParseMessage,
7- Pattern, Param, Plicity, Term, TypeField,
8- };
5+ use crate::surface::*;
96use crate::surface::lexer::{Error as LexerError, Token};
107
118grammar<'arena, 'source>(
@@ -29,6 +26,7 @@ extern {
2926 "fun" => Token::KeywordFun,
3027 "if" => Token::KeywordIf,
3128 "let" => Token::KeywordLet,
29+ "letrec" => Token::KeywordLetrec,
3230 "match" => Token::KeywordMatch,
3331 "overlap" => Token::KeywordOverlap,
3432 "Type" => Token::KeywordType,
@@ -113,20 +111,21 @@ pub Term: Term<'arena, ByteRange> = {
113111
114112LetTerm: Term<'arena, ByteRange> = {
115113 FunTerm,
116- <start: @L> "let" <def_pattern: Pattern> <def_type: (":" <LetTerm>)?> "=" <def_expr: Term> ";" <body_expr: LetTerm> <end: @R> => {
117- Term::Let(
118- ByteRange::new(start, end),
119- def_pattern,
120- def_type.map(|def_type| scope.to_scope(def_type) as &_),
121- scope.to_scope(def_expr),
122- scope.to_scope(body_expr),
123- )
114+ <start: @L> "let" <def: LetDef> ";" <body_expr: LetTerm> <end: @R> => {
115+ Term::Let(ByteRange::new(start, end), scope.to_scope(def), scope.to_scope(body_expr))
116+ },
117+ <start: @L> "letrec" <defs: Seq1<LetDef, ",">> ";" <body_expr: LetTerm> <end: @R> => {
118+ Term::Letrec(ByteRange::new(start, end), defs, scope.to_scope(body_expr))
124119 },
125120 <start: @L> "if" <cond_expr: FunTerm> "then" <then_expr: LetTerm> "else" <else_expr: LetTerm> <end: @R> => {
126121 Term::If(ByteRange::new(start, end), scope.to_scope(cond_expr), scope.to_scope(then_expr), scope.to_scope(else_expr))
127122 },
128123};
129124
125+ LetDef: LetDef<'arena, ByteRange> = {
126+ <pattern: Pattern> <r#type: (":" <LetTerm>)?> "=" <expr: Term> => LetDef {pattern, r#type, expr},
127+ };
128+
130129FunTerm: Term<'arena, ByteRange> = {
131130 EqExpr,
132131 <start: @L> <plicity: Plicity> <param_type: AppTerm> "->" <body_type: FunTerm> <end: @R> => {
0 commit comments