A. Appendix

Camelot Syntax

exp:
  IF exp THEN exp ELSE exp
| MATCH exp WITH barOpt match
| infixExp
| letExp  
| infixExp ATSIGN identl
;


infixExp:
  atomExp
| ident atomExpRow
| ExtId atomExpRow
| infixExp HASH ident atomExpRow
| infixExp HASH ident
| NEW ExtId atomExpRow
| NEW ident atomExpRow
| ISNULL atomExp      
| SUPER atomExpRow    
| ConId expSeq        
| infixExp CONS infixExp
| infixExp PLUS infixExp
| infixExp MINUS infixExp
| infixExp STAR infixExp 
| infixExp SLASH infixExp
| infixExp MOD infixExp  
| infixExp PLUSDOT infixExp
| infixExp MINUSDOT infixExp
| infixExp STARDOT infixExp 
| infixExp SLASHDOT infixExp
| MINUS atomExp %prec UMINUS
| MINUSDOT atomExp %prec UMINUS
| infixExp EQUALS infixExp
| infixExp DIAMOND infixExp
| infixExp LESS infixExp
| infixExp GREATER infixExp
| infixExp LTEQ infixExp    
| infixExp GTEQ infixExp    
| infixExp EQUALSDOT infixExp
| infixExp DIAMONDDOT infixExp
| infixExp LESSDOT infixExp
| infixExp GREATERDOT infixExp
| infixExp LTEQDOT infixExp   
| infixExp GTEQDOT infixExp   
| infixExp AMP     infixExp   
| infixExp AMPAMP  infixExp   
| infixExp OR      infixExp   
| infixExp BARBAR  infixExp   
| infixExp CARET infixExp     
| NOT atomExp                 
| infixExp COLON type         
| infixExp COERCE type        
| ident UPDATE infixExp       
;

atomExp:
  intval
| floatval
| ConId   
| LSQ RSQ 
| LSQ listExpSeq RSQ
| ident             
| ExtId             
| quoteval          
| charval           
| TRUE
| FALSE
| BEGIN  exp END 
| LPAREN exp RPAREN 
| UNIT              
| NULL COERCE ExtId 
;

listExpSeq:
  exp
| exp SEMI listExpSeq
;

letExp:
  LET ident EQUALS exp IN exp
| LET USCORE EQUALS exp IN exp
;

expSeq:
  LPAREN expSeq1 RPAREN 
| UNIT                  
;

expSeq1:
  exp			
| exp COMMA expSeq1     
;

atomExpRow:
  atomExp  
| atomExp atomExpRow 
;

match:
  matchcase BAR match
| matchcase   %prec ARROW
;

matchcase:
  ConId patSeq ARROW exp
| ConId patSeq ATSIGN USCORE ARROW exp
| ConId patSeq ATSIGN identl ARROW exp
| LSQ RSQ ARROW exp
| LSQ RSQ ATSIGN USCORE ARROW exp
| pat CONS pat ARROW exp
| LPAREN pat CONS pat RPAREN ARROW exp
| LPAREN pat CONS pat RPAREN ATSIGN USCORE ARROW exp
| LPAREN pat CONS pat RPAREN ATSIGN identl ARROW exp
| pat COERCE anyId ARROW exp
| USCORE ARROW exp
;

patSeq:
  LPAREN patSeq1 RPAREN
| /* empty */          
;

patSeq1:
  pat                  
| pat COMMA patSeq1     


pat:
  USCORE
| ident 
;

typeDecSeq:
  typeDec typeDecSeq
| /* empty */       
;

typeDec:
  TYPE tVarSeq typeName EQUALS constrList
;

tVarSeq:
  TYVAR 
| LPAREN tVarSeq1 RPAREN
| /* empty */  
;

tVarSeq1:
  TYVAR                
| TYVAR COMMA tVarSeq1 
;

constrList:
  constr constrListOpt 
| /* empty */          
;

constrListOpt:
  BAR constr constrListOpt
| /* empty */             
;

constr:
  ConId                   
| BANG ConId              
| ConId OF prodtype       
;

prodtype:
  type
| type STAR prodtype
;

identl:
   ident
;

anyId:
   ident 
|  ExtId 
;

identSeq:
   /* empty */
| ident identSeq
;

valDec:
  VAL anyId COLON type
| CLASSTYPE anyId superOpt1 COLON implementSeq classValDecSeq END
;

classValDec:
  valDec
| instanceValDec
;

valDecSeq:
  valDec valDecSeq 
| /* empty */      
;
classValDecSeq:
  classValDec classValDecSeq
| /* empty */      
;

funBlockSeq:
  funBlock funBlockSeq
| /* empty */         
;

funBlock:
  LET recOpt funDef funBlockOpt
;

funBlockOpt:
  AND funDef funBlockOpt
| /* empty */           
;

funDef:
  ident farglist EQUALS exp
;

recOpt:
  REC        
| /* empty */
;

barOpt:
  BAR        
| /* empty */
;

farglist:
  farglist1  
;

farglist1:
  fargitem 
| fargitem farglist1
;

fargitem:
  ident	            
| LPAREN RPAREN   
| UNIT            
| LPAREN fargitem RPAREN
| LPAREN ident COLON type RPAREN
;

classImp:
  CLASS classId identSeq EQUALS superArgsOpt implementSeq ciValDecSeq methodImpSeq END 
;
classId:
   ident 
|  ConId 
|  ExtId 
;

classImpSeq:
  /* empty */ 
| classImp classImpSeq
;

ciValDec:
  valDec 
| fieldValDec 
;
ciValDecSeq:
  ciValDec ciValDecSeq 
| /* empty */      
;

superArgsOpt:
  /* empty */
| anyId identSeq WITH
;

superOpt1:
  /* empty */ 
| IS anyId    
;
implementSeq:
  /* empty */ 
| implement implementSeq
;
implement:
  IMPLEMENT anyId
;
methodImpSeq:
  /* empty */
| methodImp methodImpSeq
;

methodImp:
  METHOD ident farglist tyOpt EQUALS exp
| MAKER farglist superMakerOpt EQUALS exp
| LET recOpt ident farglist tyOpt EQUALS exp /* funImpOpt */
;

superMakerOpt:
  /* empty */            
| COLON SUPER atomExpRow 
;

tyOpt:
  /* empty */ 
| COLON type  
;

type:
  type1 ARROW type
| type1
;

type1:
  INT
| CHAR
| BOOL
| FLOAT
| STRING
| UNITT 
| TYVAR 
| DIAMOND
| ExtId  
| type1 ARRAY
| fancyTypeName
| LPAREN type RPAREN
;

fancyTypeName:
  typeName
| type1 typeName
| LPAREN typeSeq RPAREN typeName
;

instanceValDec:
  methodValDec
| fieldValDec 
;

methodValDec:
  METHOD ident COLON type
;

fieldValDec:
FIELD ident COLON type
;

typeSeq :
  type1 COMMA type1
| type1 COMMA typeSeq
;

typeName:
  ident
;