Imports
import PlTheories.FunZero.Syntax.Parsing
import PlTheories.FunZero.Syntax.HelpersLiteral defines the literals we support in our language:
inductive Literal where
| number_lit (s: Nat)
| bool_lit (b: Bool)
| string_lit (s: String)Expr defines the basic expressions of our language:
variable
literal
tuple
lambda abstraction
function application
let binding
inductive Expr where
| var (s: String)
| literal (l: Literal)
| tuple (fst: Expr) (snd: Expr)
| abs (x: String) (body: Expr)
| app (f: Expr) (arg: Expr)
| let_ (v: String) (binding: Expr) (inExpr: Expr)Basically Expr is a tree and for each constructor above we have a parser specification. The ones for var and literal are the following:
The following are a little more complicated, but basically they all follow the pattern of declaring the intermediate rest values in the existential quantifier, and use each one as input to the next.
Now expression includes them all:
mutualdef tuple_parser : Parser Expr
| input, .tuple e1 e2, rest =>
∃ left_rest e1_rest comma_rest e2_rest,
lparen input lparen_token left_rest
∧ expression left_rest e1 e1_rest
∧ comma e1_rest comma_token comma_rest
∧ expression comma_rest e2 e2_rest
∧ rparen e2_rest rparen_token rest
| _, _, _ => False
def lambda_parser : Parser Expr
| input, .abs x body, rest =>
∃ lambda_rest ident_rest arrow_rest,
lambda_tok input lambda_token lambda_rest
∧ identifier lambda_rest x ident_rest
∧ arrow ident_rest arrow_token arrow_rest
∧ expression arrow_rest body rest
| _, _, _ => False
def app_parser : Parser Expr
| input, .app f arg, rest =>
∃ f_rest,
expression input f f_rest
∧ expression f_rest arg rest
| _, _, _ => False
def let_parser : Parser Expr
| input, .let_ v binding inExpr, rest =>
∃ let_rest id_rest eq_rest ex_rest in_rest,
let_tok input let_token let_rest
∧ identifier let_rest v id_rest
∧ equals id_rest equals_token eq_rest
∧ expression eq_rest binding ex_rest
∧ in_tok ex_rest in_token in_rest
∧ expression in_rest inExpr rest
| _, _, _ => Falsedef expression : Parser Expr
| input, .var s, rest => var_parser input (.var s) rest
| input, .literal l, rest => literal_parser input (.literal l) rest
| input, .tuple e1 e2, rest => tuple_parser input (.tuple e1 e2) rest
| input, .abs x body, rest => lambda_parser input (.abs x body) rest
| input, .app f arg, rest => app_parser input (.app f arg) rest
| input, .let_ v binding inExpr, rest =>
let_parser input (.let_ v binding inExpr) rest
end