%{
open Stroodel.Syntax
open Stroodel.Util
%}

// These tokens are used in the parser rules below and
// are known by both the parser and the lexer. First,
// all the keywords:
%token <Info> THE
%token <Info> ATOM
%token <Info> PAIR
%token <Info> LIST
%token <Info> LAMBDA
%token <Info> NAT
%token <Info> NIL
%token <Info> CONS
%token <Info> SAME
%token <Info> SOLE
%token <Info> ZERO
%token <Info> PI

%token <Info> ATOMLITERAL

// identifier:
%token <string> ID
%token <int> INTV
// TODO: identifiers should be of type <string * Info> etc.!

// symbols:
%token <Info> LPAREN
%token <Info> RPAREN
%token <Info> TICK
%token <Info> EOF

// the parser returns a Syntax.Expr:
%start start
%type <Expr> start

%%

start: expr EOF { $1 }

expr:
	| LPAREN THE expr expr RPAREN	{ The ($3, $4) }
	| LPAREN PAIR expr expr RPAREN	{ Pair ($3, $4) }
	| LPAREN CONS expr expr RPAREN	{ Cons ($3, $4) }
	| LPAREN LIST expr RPAREN		{ ListType $3 }
	| LPAREN PI LPAREN argumentDecl RPAREN expr RPAREN	{ Pi ($4, $6) }
	| LPAREN LAMBDA LPAREN arguments RPAREN expr RPAREN	{ Lambda ($4, $6) }
	| TICK ID				{ AtomLiteral ("'" + $2) }
	| ID					{ Var $1 }
	| INTV					{ NatLiteral $1 }
	| ATOM					{ Atom }
	| SOLE					{ Sole }
	| ZERO					{ Zero }
	| NAT							{ Nat }
	| NIL							{ Nil }

argumentDecl:
	// TODO: multiple arguments as part of the declaration!
	| LPAREN ID expr RPAREN			{ ArgumentDecl ($2, $3) }

arguments:
	// TODO: multiple arguments!
	| ID							{ $1 }
