-- This Happy file was machine-generated by the BNF converter
{
module Transfer.Syntax.Par where
import Transfer.Syntax.Abs
import Transfer.Syntax.Lex
import Transfer.ErrM
}

%name pModule Module
%name pExp Exp

-- no lexer declaration
%monad { Err } { thenM } { returnM }
%tokentype { Token }

%token 
 ';' { PT _ (TS ";") }
 ':' { PT _ (TS ":") }
 '{' { PT _ (TS "{") }
 '}' { PT _ (TS "}") }
 '=' { PT _ (TS "=") }
 '|' { PT _ (TS "|") }
 '||' { PT _ (TS "||") }
 '::' { PT _ (TS "::") }
 '(' { PT _ (TS "(") }
 ')' { PT _ (TS ")") }
 '[' { PT _ (TS "[") }
 ']' { PT _ (TS "]") }
 ',' { PT _ (TS ",") }
 '_' { PT _ (TS "_") }
 '->' { PT _ (TS "->") }
 '\\' { PT _ (TS "\\") }
 '<-' { PT _ (TS "<-") }
 '>>=' { PT _ (TS ">>=") }
 '>>' { PT _ (TS ">>") }
 '&&' { PT _ (TS "&&") }
 '==' { PT _ (TS "==") }
 '/=' { PT _ (TS "/=") }
 '<' { PT _ (TS "<") }
 '<=' { PT _ (TS "<=") }
 '>' { PT _ (TS ">") }
 '>=' { PT _ (TS ">=") }
 '+' { PT _ (TS "+") }
 '-' { PT _ (TS "-") }
 '*' { PT _ (TS "*") }
 '/' { PT _ (TS "/") }
 '%' { PT _ (TS "%") }
 '.' { PT _ (TS ".") }
 '?' { PT _ (TS "?") }
 'Type' { PT _ (TS "Type") }
 'case' { PT _ (TS "case") }
 'data' { PT _ (TS "data") }
 'derive' { PT _ (TS "derive") }
 'do' { PT _ (TS "do") }
 'else' { PT _ (TS "else") }
 'if' { PT _ (TS "if") }
 'import' { PT _ (TS "import") }
 'in' { PT _ (TS "in") }
 'let' { PT _ (TS "let") }
 'of' { PT _ (TS "of") }
 'rec' { PT _ (TS "rec") }
 'sig' { PT _ (TS "sig") }
 'then' { PT _ (TS "then") }
 'where' { PT _ (TS "where") }

L_ident  { PT _ (TV $$) }
L_quoted { PT _ (TL $$) }
L_integ  { PT _ (TI $$) }
L_doubl  { PT _ (TD $$) }
L_err    { _ }


%%

Ident   :: { Ident }   : L_ident  { Ident $1 }
String  :: { String }  : L_quoted { $1 }
Integer :: { Integer } : L_integ  { (read $1) :: Integer }
Double  :: { Double }  : L_doubl  { (read $1) :: Double }

Module :: { Module }
Module : ListImport ListDecl { Module (reverse $1) (reverse $2) } 


Import :: { Import }
Import : 'import' Ident { Import $2 } 


ListImport :: { [Import] }
ListImport : {- empty -} { [] } 
  | ListImport Import ';' { flip (:) $1 $2 }


Decl :: { Decl }
Decl : 'data' Ident ':' Exp 'where' '{' ListConsDecl '}' { DataDecl $2 $4 $7 } 
  | Ident ':' Exp { TypeDecl $1 $3 }
  | Ident ListPattern Guard '=' Exp { ValueDecl $1 (reverse $2) $3 $5 }
  | 'derive' Ident Ident { DeriveDecl $2 $3 }


ListDecl :: { [Decl] }
ListDecl : {- empty -} { [] } 
  | ListDecl Decl ';' { flip (:) $1 $2 }


ConsDecl :: { ConsDecl }
ConsDecl : Ident ':' Exp { ConsDecl $1 $3 } 


ListConsDecl :: { [ConsDecl] }
ListConsDecl : {- empty -} { [] } 
  | ConsDecl { (:[]) $1 }
  | ConsDecl ';' ListConsDecl { (:) $1 $3 }


Guard :: { Guard }
Guard : '|' Exp1 { GuardExp $2 } 
  | {- empty -} { GuardNo }


Pattern :: { Pattern }
Pattern : Pattern1 '||' Pattern { POr $1 $3 } 
  | Pattern1 { $1 }


Pattern1 :: { Pattern }
Pattern1 : Pattern2 '::' Pattern1 { PListCons $1 $3 } 
  | Pattern2 { $1 }


Pattern2 :: { Pattern }
Pattern2 : Ident Pattern3 ListPattern { PConsTop $1 $2 (reverse $3) } 
  | Pattern3 { $1 }


Pattern3 :: { Pattern }
Pattern3 : 'rec' '{' ListFieldPattern '}' { PRec $3 } 
  | '[' ']' { PEmptyList }
  | '[' ListCommaPattern ']' { PList $2 }
  | '(' CommaPattern ',' ListCommaPattern ')' { PTuple $2 $4 }
  | 'Type' { PType }
  | String { PStr $1 }
  | Integer { PInt $1 }
  | Ident { PVar $1 }
  | '_' { PWild }
  | '(' Pattern ')' { $2 }


CommaPattern :: { CommaPattern }
CommaPattern : Pattern { CommaPattern $1 } 


ListCommaPattern :: { [CommaPattern] }
ListCommaPattern : CommaPattern { (:[]) $1 } 
  | CommaPattern ',' ListCommaPattern { (:) $1 $3 }


ListPattern :: { [Pattern] }
ListPattern : {- empty -} { [] } 
  | ListPattern Pattern3 { flip (:) $1 $2 }


FieldPattern :: { FieldPattern }
FieldPattern : Ident '=' Pattern { FieldPattern $1 $3 } 


ListFieldPattern :: { [FieldPattern] }
ListFieldPattern : {- empty -} { [] } 
  | FieldPattern { (:[]) $1 }
  | FieldPattern ';' ListFieldPattern { (:) $1 $3 }


Exp :: { Exp }
Exp : '(' VarOrWild ':' Exp ')' '->' Exp { EPi $2 $4 $7 } 
  | Exp1 '->' Exp { EPiNoVar $1 $3 }
  | Exp1 { $1 }


VarOrWild :: { VarOrWild }
VarOrWild : Ident { VVar $1 } 
  | '_' { VWild }


Exp1 :: { Exp }
Exp1 : '\\' VarOrWild '->' Exp1 { EAbs $2 $4 } 
  | 'let' '{' ListLetDef '}' 'in' Exp1 { ELet $3 $6 }
  | 'case' Exp 'of' '{' ListCase '}' { ECase $2 $5 }
  | 'if' Exp 'then' Exp 'else' Exp1 { EIf $2 $4 $6 }
  | 'do' '{' ListBind Exp '}' { EDo (reverse $3) $4 }
  | Exp2 { $1 }


LetDef :: { LetDef }
LetDef : Ident '=' Exp { LetDef $1 $3 } 


ListLetDef :: { [LetDef] }
ListLetDef : {- empty -} { [] } 
  | LetDef { (:[]) $1 }
  | LetDef ';' ListLetDef { (:) $1 $3 }


Case :: { Case }
Case : Pattern Guard '->' Exp { Case $1 $2 $4 } 


ListCase :: { [Case] }
ListCase : {- empty -} { [] } 
  | Case { (:[]) $1 }
  | Case ';' ListCase { (:) $1 $3 }


Bind :: { Bind }
Bind : VarOrWild '<-' Exp { BindVar $1 $3 } 
  | Exp { BindNoVar $1 }


ListBind :: { [Bind] }
ListBind : {- empty -} { [] } 
  | ListBind Bind ';' { flip (:) $1 $2 }


Exp3 :: { Exp }
Exp3 : Exp3 '>>=' Exp4 { EBind $1 $3 } 
  | Exp3 '>>' Exp4 { EBindC $1 $3 }
  | Exp4 { $1 }


Exp4 :: { Exp }
Exp4 : Exp5 '||' Exp4 { EOr $1 $3 } 
  | Exp5 { $1 }


Exp5 :: { Exp }
Exp5 : Exp6 '&&' Exp5 { EAnd $1 $3 } 
  | Exp6 { $1 }


Exp6 :: { Exp }
Exp6 : Exp7 '==' Exp7 { EEq $1 $3 } 
  | Exp7 '/=' Exp7 { ENe $1 $3 }
  | Exp7 '<' Exp7 { ELt $1 $3 }
  | Exp7 '<=' Exp7 { ELe $1 $3 }
  | Exp7 '>' Exp7 { EGt $1 $3 }
  | Exp7 '>=' Exp7 { EGe $1 $3 }
  | Exp7 { $1 }


Exp7 :: { Exp }
Exp7 : Exp8 '::' Exp7 { EListCons $1 $3 } 
  | Exp8 { $1 }


Exp8 :: { Exp }
Exp8 : Exp8 '+' Exp9 { EAdd $1 $3 } 
  | Exp8 '-' Exp9 { ESub $1 $3 }
  | Exp9 { $1 }


Exp9 :: { Exp }
Exp9 : Exp9 '*' Exp10 { EMul $1 $3 } 
  | Exp9 '/' Exp10 { EDiv $1 $3 }
  | Exp9 '%' Exp10 { EMod $1 $3 }
  | Exp10 { $1 }


Exp10 :: { Exp }
Exp10 : '-' Exp10 { ENeg $2 } 
  | Exp11 { $1 }


Exp11 :: { Exp }
Exp11 : Exp11 Exp12 { EApp $1 $2 } 
  | Exp12 { $1 }


Exp12 :: { Exp }
Exp12 : Exp12 '.' Ident { EProj $1 $3 } 
  | Exp13 { $1 }


Exp13 :: { Exp }
Exp13 : 'sig' '{' ListFieldType '}' { ERecType $3 } 
  | 'rec' '{' ListFieldValue '}' { ERec $3 }
  | '[' ']' { EEmptyList }
  | '[' ListExp ']' { EList $2 }
  | '(' Exp ',' ListExp ')' { ETuple $2 $4 }
  | Ident { EVar $1 }
  | 'Type' { EType }
  | String { EStr $1 }
  | Integer { EInteger $1 }
  | Double { EDouble $1 }
  | '?' { EMeta }
  | '(' Exp ')' { $2 }


FieldType :: { FieldType }
FieldType : Ident ':' Exp { FieldType $1 $3 } 


ListFieldType :: { [FieldType] }
ListFieldType : {- empty -} { [] } 
  | FieldType { (:[]) $1 }
  | FieldType ';' ListFieldType { (:) $1 $3 }


FieldValue :: { FieldValue }
FieldValue : Ident '=' Exp { FieldValue $1 $3 } 


ListFieldValue :: { [FieldValue] }
ListFieldValue : {- empty -} { [] } 
  | FieldValue { (:[]) $1 }
  | FieldValue ';' ListFieldValue { (:) $1 $3 }


Exp2 :: { Exp }
Exp2 : Exp3 { $1 } 


ListExp :: { [Exp] }
ListExp : Exp { (:[]) $1 } 
  | Exp ',' ListExp { (:) $1 $3 }



{

returnM :: a -> Err a
returnM = return

thenM :: Err a -> (a -> Err b) -> Err b
thenM = (>>=)

happyError :: [Token] -> Err a
happyError ts =
  Bad $ "syntax error at " ++ tokenPos ts ++ if null ts then [] else (" before " ++ unwords (map prToken (take 4 ts)))

myLexer = tokens
}

