1 /* -*- mode: hugs-c; -*- */
2 /* --------------------------------------------------------------------------
3 * Hugs parser (included as part of input.c)
5 * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
6 * All rights reserved. See NOTICE for details and conditions of use etc...
7 * Hugs version 1.4, December 1997
9 * Expect 24 shift/reduce conflicts when passing this grammar through yacc,
10 * but don't worry; they will all be resolved in an appropriate manner.
12 * $RCSfile: parser.y,v $
14 * $Date: 1998/12/02 13:22:26 $
15 * ------------------------------------------------------------------------*/
21 #define defTycon(n,l,lhs,rhs,w) tyconDefn(intOf(l),lhs,rhs,w); sp-=n
22 #define sigdecl(l,vs,t) ap(SIGDECL,triple(l,vs,t))
23 #define grded(gs) ap(GUARDED,gs)
24 #define bang(t) ap(BANG,t)
25 #define only(t) ap(ONLY,t)
26 #define letrec(bs,e) (nonNull(bs) ? ap(LETREC,pair(bs,e)) : e)
27 #define exportSelf() singleton(ap(MODULEENT,mkCon(module(currentModule).text)))
28 #define yyerror(s) /* errors handled elsewhere */
31 static Cell local gcShadow Args((Int,Cell));
32 static Void local syntaxError Args((String));
33 static String local unexpected Args((Void));
34 static Cell local checkPrec Args((Cell));
35 static Void local fixDefn Args((Syntax,Cell,Cell,List));
36 static Void local setSyntax Args((Int,Syntax,Cell));
37 static Cell local buildTuple Args((List));
38 static List local checkContext Args((List));
39 static Cell local checkPred Args((Cell));
40 static Pair local checkDo Args((List));
41 static Cell local checkTyLhs Args((Cell));
43 static Void local noTREX Args((String));
45 static Cell local tidyInfix Args((Cell));
47 /* For the purposes of reasonably portable garbage collection, it is
48 * necessary to simulate the YACC stack on the Hugs stack to keep
49 * track of all intermediate constructs. The lexical analyser
50 * pushes a token onto the stack for each token that is found, with
51 * these elements being removed as reduce actions are performed,
52 * taking account of look-ahead tokens as described by gcShadow()
55 * Of the non-terminals used below, only start, topDecl, fixDecl & begin
56 * do not leave any values on the Hugs stack. The same is true for the
57 * terminals EXPR and SCRIPT. At the end of a successful parse, there
58 * should only be one element left on the stack, containing the result
62 #define gc0(e) gcShadow(0,e)
63 #define gc1(e) gcShadow(1,e)
64 #define gc2(e) gcShadow(2,e)
65 #define gc3(e) gcShadow(3,e)
66 #define gc4(e) gcShadow(4,e)
67 #define gc5(e) gcShadow(5,e)
68 #define gc6(e) gcShadow(6,e)
69 #define gc7(e) gcShadow(7,e)
74 %token CASEXP OF DATA TYPE IF
75 %token THEN ELSE WHERE LET IN
76 %token INFIX INFIXL INFIXR FOREIGN TNEWTYPE
77 %token DEFAULT DERIVING DO TCLASS TINSTANCE
79 %token VAROP VARID NUMLIT CHARLIT STRINGLIT
81 %token QVAROP QVARID QCONOP QCONID
85 %token COCO '=' UPTO '@' '\\'
86 %token '|' '-' FROM ARROW '~'
87 %token '!' IMPLIES '(' ',' ')'
88 %token '[' ';' ']' '`' '.'
89 %token MODULETOK IMPORT HIDING QUALIFIED ASMOD
90 %token EXPORT INTERFACE REQUIRES UNSAFE
93 /*- Top level script/module structure: ------------------------------------*/
95 start : EXPR exp wherePart {inputExpr = letrec($3,$2); sp-=2;}
96 | SCRIPT topModule {valDefns = $2; sp-=1;}
97 | INTERFACE iface {sp-=1;}
98 | error {syntaxError("input");}
101 /*- GHC interface file parsing: -------------------------------------------*/
103 /* Reading in an interface file is surprisingly like reading
104 * a normal Haskell module: we read in a bunch of declarations,
105 * construct symbol table entries, etc. The "only" differences
106 * are that there's no syntactic sugar to deal with and we don't
107 * have to read in expressions.
110 iface : INTERFACE ifaceName NUMLIT checkVersion ifaceDecls { $$ = gc5(NIL); }
111 | INTERFACE error {syntaxError("interface file");}
114 ifaceName : CONID {openGHCIface(textOf($1)); $$ = gc1(NIL);}
117 ifaceDecls: {$$=gc0(NIL);}
118 | ifaceDecl ';' ifaceDecls {$$=gc3(cons($1,$2));}
121 /* We use ifaceData in data decls so as to include () */
122 ifaceDecl : IMPORT CONID NUMLIT { extern String scriptFile;
123 String fileName = findPathname(scriptFile,textToStr(textOf($2)));
124 addGHCImport(intOf($1),textOf($2),fileName);
127 | EXPORT CONID ifaceEntities {}
128 | REQUIRES STRINGLIT { extern String scriptFile;
129 String fileName = findPathname(scriptFile,textToStr(textOf($2)));
130 loadSharedLib(fileName);
133 | INFIXL optdigit op { fixDefn(LEFT_ASS,$1,$2,$3); $$ = gc3(NIL); }
134 | INFIXR optdigit op { fixDefn(RIGHT_ASS,$1,$2,$3); $$ = gc3(NIL); }
135 | INFIX optdigit op { fixDefn(NON_ASS,$1,$2,$3); $$ = gc3(NIL); }
136 | TINSTANCE ifaceQuant ifaceClass '=' ifaceVar { addGHCInstance(intOf($1),$2,$3,textOf($5)); $$ = gc5(NIL); }
137 | NUMLIT TYPE ifaceTCName ifaceTVBndrs '=' ifaceType { addGHCSynonym(intOf($2),$3,$4,$6); $$ = gc6(NIL); }
138 | NUMLIT DATA ifaceData ifaceTVBndrs ifaceConstrs ifaceSels { addGHCDataDecl(intOf($2),$3,$4,$5,$6); $$ = gc6(NIL); }
139 | NUMLIT TNEWTYPE ifaceTCName ifaceTVBndrs ifaceNewTypeConstr { addGHCNewType(intOf($2),$3,$4,$5); $$ = gc5(NIL); }
140 | NUMLIT TCLASS ifaceDeclContext ifaceTCName ifaceTVBndrs ifaceCSigs { addGHCClass(intOf($2),$3,$4,$5,$6); $$ = gc6(NIL); }
141 | NUMLIT ifaceVar COCO ifaceType { addGHCVar(intOf($3),textOf($2),$4); $$ = gc4(NIL); }
142 | error { syntaxError("interface declaration"); }
146 : NUMLIT { $$ = gc1(NIL); }
149 ifaceSels /* [(VarId,Type)] */
151 | WHERE '{' ifaceSels1 '}' { $$ = gc4($3); }
154 ifaceSels1 /* [(VarId,Type)] */
155 : ifaceSel { $$ = gc1(singleton($1)); }
156 | ifaceSel ';' ifaceSels1 { $$ = gc3(cons($1,$3)); }
159 ifaceSel /* (VarId,Type) */
160 : ifaceVarName COCO ifaceType { $$ = gc3(pair($1,$3)); }
163 ifaceCSigs /* [(VarId,Type)] */
165 | WHERE '{' ifaceCSigs1 '}' { $$ = gc4($3); }
168 ifaceCSigs1 /* [(VarId,Type)] */
169 : ifaceCSig { $$ = gc1(singleton($1)); }
170 | ifaceCSig ';' ifaceCSigs1 { $$ = gc3(cons($1,$3)); }
173 ifaceCSig /* (VarId,Type) */
174 : ifaceVarName COCO ifaceType { $$ = gc3(pair($1,$3)); }
175 | ifaceVarName '=' COCO ifaceType { $$ = gc4(pair($1,$4)); } /* has default method */
178 ifaceConstrs /* [(ConId,[VarId],Type)] */
180 | '=' ifaceConstrs1 { $$ = gc2($2); }
183 ifaceConstrs1 /* [(ConId,[VarId],Type)] */
184 : ifaceConstr { $$ = gc1(singleton($1)); }
185 | ifaceConstr '|' ifaceConstrs1 { $$ = gc3(cons($1,$3)); }
188 /* We use ifaceData so as to include () */
189 ifaceConstr /* (ConId,[VarId],Type) */
190 : ifaceData COCO ifaceType { $$ = gc3(triple($1,NIL,$3)); }
191 | ifaceData '{' ifaceVarNames1 '}' COCO ifaceType { $$ = gc6(triple($1,$3,$6)); }
194 ifaceNewTypeConstr /* (ConId,Type) */
196 | '=' ifaceDataName COCO ifaceType { $$ = gc4(pair($2,$4)); }
199 ifaceQuant /* Maybe ([(VarId,Kind)],[(ConId, [Type])]) */
201 | ALL ifaceForall ifaceContext IMPLIES { $$ = gc4(pair($2,$3)); }
205 : ALL ifaceForall ifaceContext IMPLIES ifaceType { $$ = gc5(ap(POLYTYPE,triple($2,$3,$5))); }
206 | ifaceBType ARROW ifaceType { $$ = gc3(fn($1,$3)); }
207 | ifaceBType { $$ = gc1($1); }
210 ifaceForall /* [(VarId,Kind)] */
211 : '[' ifaceTVBndrs ']' { $$ = gc3($2); }
214 ifaceDeclContext /* [(ConId, [Type])] */
216 | '{' ifaceContextList1 '}' IMPLIES { $$ = gc4($2); }
219 ifaceContext /* [(ConId, [Type])] */
221 | '{' ifaceContextList1 '}' { $$ = gc3($2); }
224 ifaceContextList1 /* [(ConId, [Type])] */
225 : ifaceClass { $$ = gc1(singleton($1)); }
226 | ifaceClass ',' ifaceContextList1 { $$ = gc3(cons($1,$3)); }
229 ifaceClass /* (ConId, [Type]) */
230 : ifaceQTCName ifaceATypes { $$ = gc2(pair($1,$2)); }
234 : ifaceType ',' ifaceType { $$ = gc3(doubleton($1,$3)); }
235 | ifaceType ',' ifaceTypes2 { $$ = gc3(cons($1,$3)); }
239 : ifaceAType { $$ = gc1($1); }
240 | ifaceBType ifaceAType { $$ = gc2(ap($1,$2)); }
244 : ifaceQTCName { $$ = gc1($1); }
245 | ifaceTVName { $$ = gc1($1); }
246 | '(' ')' { $$ = gc2(conPreludeUnit); }
247 | '(' ifaceTypes2 ')' { $$ = gc3(buildTuple($2)); }
248 | '[' ifaceType ']' { $$ = gc3(ap(conPreludeList,$2));}
249 | '{' ifaceQTCName ifaceATypes '}' { $$ = gc4(ap(DICTAP,pair($2,$3))); }
250 | '(' ifaceType ')' { $$ = gc3($2); }
255 | ifaceAType ifaceATypes { $$ = gc2(cons($1,$2)); }
260 | ifaceEntity ifaceEntities { $$ = gc2(cons($1,$2)); }
265 | ifaceEntityOcc ifaceStuffInside {}
266 | ifaceEntityOcc '|' ifaceStuffInside {} /* exporting datacons but not tycon */
270 : ifaceVar { $$ = gc1($1); }
271 | ifaceData { $$ = gc1($1); }
272 | ARROW { $$ = gc3(typeArrow); }
273 | '(' ARROW ')' { $$ = gc3(typeArrow); } /* why allow both? */
277 : '{' ifaceValOccs '}' { $$ = gc1($1); }
282 : ifaceValOcc { $$ = gc1(singleton($1)); }
283 | ifaceValOcc ifaceValOccs { $$ = gc2(cons($1,$2)); }
287 : ifaceVar {$$ = gc1($1); }
288 | ifaceData {$$ = gc1($1); }
291 ifaceVar : VARID {$$ = gc1($1); }
292 | VAROP {$$ = gc1($1); }
293 | '!' {$$ = gc1(varBang); }
294 | '.' {$$ = gc1(varDot); }
295 | '-' {$$ = gc1(varMinus);}
298 ifaceData /* ConId | QualConId */
299 : CONID {$$ = gc1($1);}
300 | CONOP {$$ = gc1($1);}
301 | '(' ')' {$$ = gc2(conPreludeUnit);}
302 | '[' ']' {$$ = gc2(conPreludeList);}
305 ifaceVarName /* VarId */
306 : ifaceVar { $$ = gc1($1); }
309 ifaceDataName /* ConId|QualConId */
310 : ifaceData { $$ = gc1($1); }
313 ifaceVarNames1 /* [VarId] */
314 : ifaceVarName { $$ = gc1(singleton($1)); }
315 | ifaceVarName ifaceVarNames1 { $$ = gc2(cons($1,$2)); }
318 ifaceTVName /* VarId */
319 : VARID { $$ = gc1($1); }
322 ifaceTVBndrs /* [(VarId,Kind)] */
324 | ifaceTVBndr ifaceTVBndrs { $$ = gc2(cons($1,$2)); }
327 ifaceTVBndr /* (VarId,Kind) */
328 : ifaceTVName { $$ = gc1(pair($1,STAR)); }
329 | ifaceTVName COCO ifaceAKind { $$ = gc3(pair($1,$3)); }
333 : ifaceAKind { $$ = gc1($1); }
334 | ifaceAKind ARROW ifaceKind { $$ = gc3(fn($1,$3)); }
338 : VAROP { $$ = gc1(STAR); } /* should be '*' */
339 | '(' ifaceKind ')' { $$ = gc1($1); }
343 : CONID { $$ = gc1($1); }
344 | CONOP { $$ = gc1($1); }
345 | '(' ARROW ')' { $$ = gc3(typeArrow); }
346 | '[' ']' { $$ = gc1(conPreludeList); }
350 : ifaceTCName { $$ = gc1($1); }
351 | QCONID { $$ = gc1($1); }
352 | QCONOP { $$ = gc1($1); }
355 /*- Haskell module header/import parsing: ---------------------------------*/
357 /* In Haskell 1.2, the default module header was "module Main where"
358 * In 1.3, this changed to "module Main(main) where".
359 * We use the 1.2 header because it breaks much less pre-module code.
361 topModule : startMain begin modBody end {
362 setExportList(singleton(ap(MODULEENT,mkCon(module(currentModule).text))));
365 | MODULETOK modname expspec WHERE '{' modBody end
366 {setExportList($3); $$ = gc7($6);}
367 | MODULETOK error {syntaxError("module definition");}
369 /* To implement the Haskell module system, we have to keep track of the
370 * current module. We rely on the use of LALR parsing to ensure that this
371 * side effect happens before any declarations within the module.
373 startMain : /* empty */ {startModule(conMain);
376 modname : CONID {startModule($1); $$ = gc1(NIL);}
378 modid : CONID {$$ = gc1($1);}
379 | STRINGLIT { extern String scriptFile;
380 String modName = findPathname(scriptFile,textToStr(textOf($1)));
381 if (modName) { /* fillin pathname if known */
382 $$ = mkStr(findText(modName));
388 modBody : topDecls {$$ = gc1($1);}
389 | fixDecls ';' topDecls {$$ = gc3($3);}
390 | impDecls chase {$$ = gc2(NIL);}
391 | impDecls ';' chase topDecls {$$ = gc4($4);}
392 | impDecls ';' chase fixDecls ';' topDecls
396 /*- Exports: --------------------------------------------------------------*/
398 expspec : /* empty */ {$$ = gc0(exportSelf());}
399 | '(' ')' {$$ = gc2(NIL);}
400 | '(' exports ')' {$$ = gc3($2);}
401 | '(' exports ',' ')' {$$ = gc4($2);}
403 exports : exports ',' export {$$ = gc3(cons($3,$1));}
404 | export {$$ = gc1(singleton($1));}
406 /* The qcon should be qconid.
407 * Relaxing the rule lets us explicitly export (:) from the Prelude.
409 export : qvar {$$ = gc1($1);}
410 | qcon {$$ = gc1($1);}
411 | qcon2 '(' UPTO ')' {$$ = gc4(pair($1,DOTDOT));}
412 | qcon2 '(' qnames ')' {$$ = gc4(pair($1,$3));}
413 | MODULETOK modid {$$ = gc2(ap(MODULEENT,$2));}
415 qnames : /* empty */ {$$ = gc0(NIL);}
416 | ',' {$$ = gc1(NIL);}
417 | qnames1 {$$ = gc1($1);}
418 | qnames1 ',' {$$ = gc2($1);}
420 qnames1 : qnames1 ',' qname {$$ = gc3(cons($3,$1));}
421 | qname {$$ = gc1(singleton($1));}
423 qname : qvar {$$ = gc1($1);}
424 | qcon {$$ = gc1($1);}
425 | '(' ')' {$$ = gc2(conPreludeUnit);}
426 | '[' ']' {$$ = gc2(conPreludeList);}
428 qcon2 : '(' ')' {$$ = gc2(conPreludeUnit);}
429 | '[' ']' {$$ = gc2(conPreludeList);}
430 | qconid {$$ = gc1($1);}
433 /*- Import declarations: --------------------------------------------------*/
435 impDecls : impDecls ';' impDecl {imps = cons($3,imps); $$=gc3(NIL);}
436 | impDecl {imps = singleton($1); $$=gc1(NIL);}
438 chase : /* empty */ {if (chase(imps)) {
448 /* Note that qualified import ignores the import list. */
449 impDecl : IMPORT modid impspec {addQualImport($2,$2);
450 addUnqualImport($2,$3);
452 | IMPORT modid ASMOD modid impspec
453 {addQualImport($2,$4);
454 addUnqualImport($2,$5);
456 | IMPORT QUALIFIED modid ASMOD modid impspec
457 {addQualImport($3,$5);
459 | IMPORT QUALIFIED modid impspec
460 {addQualImport($3,$3);
462 | IMPORT error {syntaxError("import declaration");}
464 impspec : /* empty */ {$$ = gc0(DOTDOT);}
465 | HIDING '(' imports ')' {$$ = gc4(ap(HIDDEN,$3));}
466 | '(' imports ')' {$$ = gc3($2);}
468 imports : /* empty */ {$$ = gc0(NIL);}
469 | ',' {$$ = gc1(NIL);}
470 | imports1 {$$ = gc1($1);}
471 | imports1 ',' {$$ = gc2($1);}
473 imports1 : imports1 ',' import {$$ = gc3(cons($3,$1));}
474 | import {$$ = gc1(singleton($1));}
476 import : var {$$ = gc1($1);}
477 | CONID {$$ = gc1($1);}
478 | CONID '(' UPTO ')' {$$ = gc4(pair($1,DOTDOT));}
479 | CONID '(' names ')' {$$ = gc4(pair($1,$3));}
481 names : /* empty */ {$$ = gc0(NIL);}
482 | ',' {$$ = gc1(NIL);}
483 | names1 {$$ = gc1($1);}
484 | names1 ',' {$$ = gc2($1);}
486 names1 : names1 ',' name {$$ = gc3(cons($3,$1));}
487 | name {$$ = gc1(singleton($1));}
489 name : var {$$ = gc1($1);}
490 | con {$$ = gc1($1);}
493 /*- Fixity declarations: --------------------------------------------------*/
495 fixDecls : fixDecls ';' fixDecl {$$ = gc2(NIL);}
496 | fixDecl {$$ = gc0(NIL);}
498 fixDecl : INFIXL optdigit ops {fixDefn(LEFT_ASS,$1,$2,$3); sp-=3;}
499 | INFIXR optdigit ops {fixDefn(RIGHT_ASS,$1,$2,$3);sp-=3;}
500 | INFIX optdigit ops {fixDefn(NON_ASS,$1,$2,$3); sp-=3;}
502 optdigit : NUMLIT {$$ = gc1(checkPrec($1));}
503 | /* empty */ {$$ = gc0(mkInt(DEF_PREC));}
505 ops : ops ',' op {$$ = gc3(cons($3,$1));}
506 | op {$$ = gc1(cons($1,NIL));}
509 /*- Top-level declarations: -----------------------------------------------*/
511 topDecls : /* empty */ {$$ = gc0(NIL);}
512 | ';' {$$ = gc1(NIL);}
513 | topDecls1 {$$ = gc1($1);}
514 | topDecls1 ';' {$$ = gc2($1);}
516 topDecls1 : topDecls1 ';' topDecl {$$ = gc2($1);}
517 | topDecls1 ';' decl {$$ = gc3(cons($3,$1));}
518 | topDecl {$$ = gc0(NIL);}
519 | decl {$$ = gc1(cons($1,NIL));}
522 /*- Type declarations: ----------------------------------------------------*/
524 topDecl : TYPE tyLhs '=' type {defTycon(4,$3,$2,$4,SYNONYM);}
525 | TYPE tyLhs '=' type IN invars
527 ap($4,$6),RESTRICTSYN);}
528 | DATA btype2 '=' constrs deriving
529 {defTycon(5,$3,checkTyLhs($2),
530 ap(rev($4),$5),DATATYPE);}
531 | DATA context IMPLIES tyLhs '=' constrs deriving
533 ap(ap(QUAL,pair($2,rev($6))),
535 | DATA btype2 {defTycon(2,$1,checkTyLhs($2),
536 ap(NIL,NIL),DATATYPE);}
537 | DATA context IMPLIES tyLhs {defTycon(4,$1,$4,
538 ap(ap(QUAL,pair($2,NIL)),
540 | TNEWTYPE btype2 '=' nconstr deriving
541 {defTycon(5,$3,checkTyLhs($2),
543 | TNEWTYPE context IMPLIES tyLhs '=' nconstr deriving
545 ap(ap(QUAL,pair($2,$6)),
548 tyLhs : tyLhs varid1 {$$ = gc2(ap($1,$2));}
549 | CONID {$$ = gc1($1);}
550 | '[' type ']' {$$ = gc3(ap(conList,$2));}
551 | '(' ')' {$$ = gc2(conUnit);}
552 | '(' typeTuple ')' {$$ = gc3(buildTuple($2));}
553 | error {syntaxError("type defn lhs");}
555 invars : invars ',' invar {$$ = gc3(cons($3,$1));}
556 | invar {$$ = gc1(cons($1,NIL));}
558 invar : qvar COCO topType {$$ = gc3(sigdecl($2,singleton($1),
560 | qvar {$$ = gc1($1);}
562 constrs : constrs '|' constr {$$ = gc3(cons($3,$1));}
563 | constr {$$ = gc1(cons($1,NIL));}
565 constr : '!' btype conop bbtype {$$ = gc4(ap2($3,bang($2),$4));}
566 | btype1 conop bbtype {$$ = gc3(ap2($2,$1,$3));}
567 | btype2 conop bbtype {$$ = gc3(ap2($2,$1,$3));}
568 | bpolyType conop bbtype {$$ = gc3(ap2($2,$1,$3));}
569 | btype2 {$$ = gc1($1);}
570 | btype3 {$$ = gc1($1);}
571 | btype4 {$$ = gc1($1);}
572 | con '{' fieldspecs '}' {$$ = gc4(ap(LABC,pair($1,rev($3))));}
573 | '[' ']' {$$ = gc2(conNil);}
574 | '(' ')' {$$ = gc2(conUnit);}
575 | '(' typeTuple ')' {$$ = gc3(buildTuple($2));}
576 | error {syntaxError("data type definition");}
578 btype3 : btype2 '!' atype {$$ = gc3(ap($1,bang($3)));}
579 | btype3 '!' atype {$$ = gc3(ap($1,bang($3)));}
580 | btype3 atype {$$ = gc2(ap($1,$2));}
582 btype4 : btype2 bpolyType {$$ = gc2(ap($1,$2));}
583 | btype3 bpolyType {$$ = gc2(ap($1,$2));}
584 | btype4 bpolyType {$$ = gc2(ap($1,$2));}
585 | btype4 atype {$$ = gc2(ap($1,$2));}
586 | btype4 '!' atype {$$ = gc3(ap($1,bang($3)));}
588 bbtype : '!' btype {$$ = gc2(bang($2));}
589 | btype {$$ = gc1($1);}
590 | bpolyType {$$ = gc1($1);}
592 fieldspecs: fieldspecs ',' fieldspec {$$ = gc3(cons($3,$1));}
593 | fieldspec {$$ = gc1(cons($1,NIL));}
595 fieldspec : vars COCO polyType {$$ = gc3(pair(rev($1),$3));}
596 | vars COCO type {$$ = gc3(pair(rev($1),$3));}
598 nconstr : con atype {$$ = gc2(singleton(ap($1,$2)));}
599 | con bpolyType {$$ = gc2(singleton(ap($1,$2)));}
601 deriving : /* empty */ {$$ = gc0(NIL);}
602 | DERIVING qconid {$$ = gc2(singleton($2));}
603 | DERIVING '(' derivs0 ')' {$$ = gc4($3);}
605 derivs0 : /* empty */ {$$ = gc0(NIL);}
606 | derivs {$$ = gc1(rev($1));}
608 derivs : derivs ',' qconid {$$ = gc3(cons($3,$1));}
609 | qconid {$$ = gc1(singleton($1));}
612 /*- Processing definitions of primitives ----------------------------------*/
614 topDecl : FOREIGN IMPORT callconv ext_loc ext_name unsafe_flag var COCO type
615 {foreignImport($1,pair($4,$5),$7,$9); sp-=9;}
616 | FOREIGN EXPORT callconv ext_name qvarid COCO type
617 {foreignExport($1,$4,$5,$7); sp-=7;}
620 callconv : var {$$ = gc1(NIL); /* ignored */ }
622 ext_loc : STRINGLIT {$$ = $1;}
624 ext_name : STRINGLIT {$$ = $1;}
626 unsafe_flag: /* empty */ {$$ = gc0(NIL);}
627 | UNSAFE {$$ = gc1(NIL); /* ignored */ }
631 /*- Class declarations: ---------------------------------------------------*/
633 topDecl : TCLASS crule wherePart {classDefn(intOf($1),$2,$3); sp-=3;}
634 | TINSTANCE irule wherePart {instDefn(intOf($1),$2,$3); sp-=3;}
635 | DEFAULT '(' dtypes ')' {defaultDefn(intOf($1),$3); sp-=4;}
637 crule : context IMPLIES btype2 {$$ = gc3(pair($1,checkPred($3)));}
638 | btype2 {$$ = gc1(pair(NIL,checkPred($1)));}
640 irule : context IMPLIES btype2 {$$ = gc3(pair($1,checkPred($3)));}
641 | btype2 {$$ = gc1(pair(NIL,checkPred($1)));}
643 dtypes : /* empty */ {$$ = gc0(NIL);}
644 | dtypes1 {$$ = gc1(rev($1));}
646 dtypes1 : dtypes1 ',' type {$$ = gc3(cons($3,$1));}
647 | type {$$ = gc1(cons($1,NIL));}
650 /*- Type expressions: -----------------------------------------------------*/
652 sigType : context IMPLIES type {$$ = gc3(ap(QUAL,pair($1,$3)));}
653 | type {$$ = gc1($1);}
655 topType : context IMPLIES topType1 {$$ = gc3(ap(QUAL,pair($1,$3)));}
656 | topType1 {$$ = gc1($1);}
658 topType1 : bpolyType ARROW topType1 {$$ = gc3(fn($1,$3));}
659 | btype1 ARROW topType1 {$$ = gc3(fn($1,$3));}
660 | btype2 ARROW topType1 {$$ = gc3(fn($1,$3));}
661 | btype {$$ = gc1($1);}
663 polyType : ALL varid1s '.' sigType {$$ = gc4(ap(POLYTYPE,
665 | bpolyType {$$ = gc1($1);}
667 bpolyType : '(' polyType ')' {$$ = gc3($2);}
669 varid1s : varid1s ',' varid1 {$$ = gc3(cons($3,$1));}
670 | varid1 {$$ = gc1(cons($1,NIL));}
672 context : '(' ')' {$$ = gc2(NIL);}
673 | btype2 {$$ = gc1(singleton(checkPred($1)));}
674 | '(' btype2 ')' {$$ = gc3(singleton(checkPred($2)));}
675 | '(' btypes2 ')' {$$ = gc3(checkContext($2));}
677 | lacks {$$ = gc1(singleton($1));}
678 | '(' lacks1 ')' {$$ = gc3(checkContext($2));}
680 lacks : varid1 '\\' varid1 {
682 $$ = gc3(ap(mkExt(textOf($3)),$1));
684 noTREX("a type context");
688 lacks1 : btypes2 ',' lacks {$$ = gc3(cons($3,$1));}
689 | lacks1 ',' btype2 {$$ = gc3(cons($3,$1));}
690 | lacks1 ',' lacks {$$ = gc3(cons($3,$1));}
691 | btype2 ',' lacks {$$ = gc3(cons($3,cons($1,NIL)));}
692 | lacks {$$ = gc1(singleton($1));}
696 type : type1 {$$ = gc1($1);}
697 | btype2 {$$ = gc1($1);}
699 type1 : btype1 {$$ = gc1($1);}
700 | btype1 ARROW type {$$ = gc3(fn($1,$3));}
701 | btype2 ARROW type {$$ = gc3(fn($1,$3));}
702 | error {syntaxError("type expression");}
704 btype : btype1 {$$ = gc1($1);}
705 | btype2 {$$ = gc1($1);}
707 btype1 : btype1 atype {$$ = gc2(ap($1,$2));}
708 | atype1 {$$ = gc1($1);}
710 btype2 : btype2 atype {$$ = gc2(ap($1,$2));}
711 | qconid {$$ = gc1($1);}
713 atype : atype1 {$$ = gc1($1);}
714 | qconid {$$ = gc1($1);}
716 atype1 : varid1 {$$ = gc1($1);}
717 | '(' ')' {$$ = gc2(conPreludeUnit);}
718 | '(' ARROW ')' {$$ = gc3(typeArrow);}
719 | '(' type1 ')' {$$ = gc3($2);}
720 | '(' btype2 ')' {$$ = gc3($2);}
721 | '(' tupCommas ')' {$$ = gc3($2);}
722 | '(' btypes2 ')' {$$ = gc3(buildTuple($2));}
723 | '(' typeTuple ')' {$$ = gc3(buildTuple($2));}
727 $$ = gc3(revOnto($2,typeNoRow));
732 | '(' tfields '|' type ')' {$$ = gc5(revOnto($2,$4));}
734 | '[' type ']' {$$ = gc3(ap(conPreludeList,$2));}
735 | '[' ']' {$$ = gc2(conPreludeList);}
736 | '_' {$$ = gc1(inventVar());}
738 tupCommas : tupCommas ',' {$$ = gc2(mkTuple(tupleOf($1)+1));}
739 | ',' {$$ = gc1(mkTuple(2));}
741 btypes2 : btypes2 ',' btype2 {$$ = gc3(cons($3,$1));}
742 | btype2 ',' btype2 {$$ = gc3(cons($3,cons($1,NIL)));}
744 typeTuple : type1 ',' type {$$ = gc3(cons($3,cons($1,NIL)));}
745 | btype2 ',' type1 {$$ = gc3(cons($3,cons($1,NIL)));}
746 | btypes2 ',' type1 {$$ = gc3(cons($3,$1));}
747 | typeTuple ',' type {$$ = gc3(cons($3,$1));}
750 tfields : tfields ',' tfield {$$ = gc3(cons($3,$1));}
751 | tfield {$$ = gc1(singleton($1));}
753 tfield : varid COCO type {$$ = gc3(ap(mkExt(textOf($1)),$3));}
757 /*- Value declarations: ---------------------------------------------------*/
759 decllist : '{' decls end {$$ = gc3($2);}
761 decls : /* empty */ {$$ = gc0(NIL);}
762 | ';' {$$ = gc1(NIL);}
763 | decls1 {$$ = gc1($1);}
764 | decls1 ';' {$$ = gc2($1);}
766 decls1 : decls1 ';' decl {$$ = gc3(cons($3,$1));}
767 | decl {$$ = gc1(cons($1,NIL));}
769 /* Sneakily using qvars to eliminate a conflict... */
770 decl : qvars COCO topType {$$ = gc3(sigdecl($2,$1,$3));}
771 | opExp rhs {$$ = gc2(pair($1,$2));}
773 rhs : rhs1 wherePart {$$ = gc2(letrec($2,$1));}
774 | error {syntaxError("declaration");}
776 rhs1 : '=' exp {$$ = gc2(pair($1,$2));}
777 | gdefs {$$ = gc1(grded(rev($1)));}
779 wherePart : WHERE decllist {$$ = gc2($2);}
780 | /*empty*/ {$$ = gc0(NIL);}
782 gdefs : gdefs gdef {$$ = gc2(cons($2,$1));}
783 | gdef {$$ = gc1(cons($1,NIL));}
785 gdef : '|' exp '=' exp {$$ = gc4(pair($3,pair($2,$4)));}
787 vars : vars ',' var {$$ = gc3(cons($3,$1));}
788 | var {$$ = gc1(cons($1,NIL));}
790 qvars : qvars ',' qvar {$$ = gc3(cons($3,$1));}
791 | qvar {$$ = gc1(cons($1,NIL));}
796 var : varid {$$ = gc1($1);}
797 | '(' '-' ')' {$$ = gc3(varMinus);}
799 varid : varid1 {$$ = gc1($1);}
800 | '(' VAROP ')' {$$ = gc3($2);}
801 | '(' '!' ')' {$$ = gc3(varBang);}
802 | '(' '.' ')' {$$ = gc3(varDot);}
804 varid1 : VARID {$$ = gc1($1);}
805 | HIDING {$$ = gc1(varHiding);}
806 | QUALIFIED {$$ = gc1(varQualified);}
807 | ASMOD {$$ = gc1(varAsMod);}
809 qvar : qvarid {$$ = gc1($1);}
810 | '(' qvarsym ')' {$$ = gc3($2);}
811 | '(' '.' ')' {$$ = gc3(varDot);}
812 | '(' '!' ')' {$$ = gc3(varBang);}
813 | '(' '-' ')' {$$ = gc3(varMinus);}
815 qvarid : varid1 {$$ = gc1($1);}
816 | QVARID {$$ = gc1($1);}
819 op : varop {$$ = gc1($1);}
820 | conop {$$ = gc1($1);}
821 | '-' {$$ = gc1(varMinus);}
823 qop : qvarop {$$ = gc1($1);}
824 | qconop {$$ = gc1($1);}
825 | '-' {$$ = gc1(varMinus);}
828 varop : VAROP {$$ = gc1($1);}
829 | '!' {$$ = gc1(varBang);}
830 | '.' {$$ = gc1(varDot);}
831 | '`' varid1 '`' {$$ = gc3($2);}
833 qvarop : qvarsym {$$ = gc1($1);}
834 | '!' {$$ = gc1(varBang);}
835 | '.' {$$ = gc1(varDot);}
836 | '`' qvarid '`' {$$ = gc3($2);}
838 qvarsym : VAROP {$$ = gc1($1);}
839 | QVAROP {$$ = gc1($1);}
842 con : CONID {$$ = gc1($1);}
843 | '(' CONOP ')' {$$ = gc3($2);}
845 qcon : qconid {$$ = gc1($1);}
846 | '(' qconsym ')' {$$ = gc3($2);}
848 qconid : CONID {$$ = gc1($1);}
849 | QCONID {$$ = gc1($1);}
851 qconsym : CONOP {$$ = gc1($1);}
852 | QCONOP {$$ = gc1($1);}
855 conop : CONOP {$$ = gc1($1);}
856 | '`' CONID '`' {$$ = gc3($2);}
858 qconop : qconsym {$$ = gc1($1);}
859 | '`' qconid '`' {$$ = gc3($2);}
862 /*- Expressions: ----------------------------------------------------------*/
864 exp : exp1 {$$ = gc1($1);}
865 | error {syntaxError("expression");}
867 exp1 : opExp COCO sigType {$$ = gc3(ap(ESIGN,pair($1,$3)));}
868 | opExp {$$ = gc1($1);}
870 opExp : opExp0 {$$ = gc1(tidyInfix($1));}
871 | pfxExp {$$ = gc1($1);}
873 opExp0 : opExp0 qop '-' pfxExp {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
874 | opExp0 qop pfxExp {$$ = gc3(ap2($2,$1,$3));}
875 | '-' pfxExp {$$ = gc2(ap(NEG,only($2)));}
876 | pfxExp qop pfxExp {$$ = gc3(ap(ap($2,only($1)),$3));}
877 | pfxExp qop '-' pfxExp {$$ = gc4(ap(NEG,
878 ap(ap($2,only($1)),$4)));}
880 pfxExp : '\\' pats ARROW exp {$$ = gc4(ap(LAMBDA,
883 | LET decllist IN exp {$$ = gc4(letrec($2,$4));}
884 | IF exp THEN exp ELSE exp {$$ = gc6(ap(COND,triple($2,$4,$6)));}
885 | CASEXP exp OF '{' alts end {$$ = gc6(ap(CASE,pair($2,rev($5))));}
886 | DO '{' stmts end {$$ = gc4(ap(DOCOMP,checkDo($3)));}
887 | appExp {$$ = gc1($1);}
889 pats : pats atomic {$$ = gc2(cons($2,$1));}
890 | atomic {$$ = gc1(cons($1,NIL));}
892 appExp : appExp atomic {$$ = gc2(ap($1,$2));}
893 | atomic {$$ = gc1($1);}
895 atomic : qvar {$$ = gc1($1);}
896 | qvar '@' atomic {$$ = gc3(ap(ASPAT,pair($1,$3)));}
897 | '~' atomic {$$ = gc2(ap(LAZYPAT,$2));}
898 | '_' {$$ = gc1(WILDCARD);}
899 | qcon {$$ = gc1($1);}
900 | qcon '{' fbinds '}' {$$ = gc4(ap(CONFLDS,pair($1,$3)));}
901 | atomic '{' fbinds '}' {$$ = gc4(ap(UPDFLDS,
902 triple($1,NIL,$3)));}
903 | '(' ')' {$$ = gc2(conPreludeUnit);}
904 | NUMLIT {$$ = gc1($1);}
905 | CHARLIT {$$ = gc1($1);}
906 | STRINGLIT {$$ = gc1($1);}
907 | REPEAT {$$ = gc1($1);}
908 | '(' exp ')' {$$ = gc3($2);}
909 | '(' exps2 ')' {$$ = gc3(buildTuple($2));}
913 $$ = gc3(revOnto($2,nameNoRec));
918 | '(' vfields '|' exp ')' {$$ = gc5(revOnto($2,$4));}
919 | RECSELID {$$ = gc1($1);}
921 | '[' list ']' {$$ = gc3($2);}
922 | '(' pfxExp qop ')' {$$ = gc4(ap($3,$2));}
923 | '(' qvarop atomic ')' {$$ = gc4(ap2(varFlip,$2,$3));}
924 | '(' qconop atomic ')' {$$ = gc4(ap2(varFlip,$2,$3));}
925 | '(' tupCommas ')' {$$ = gc3($2);}
927 exps2 : exps2 ',' exp {$$ = gc3(cons($3,$1));}
928 | exp ',' exp {$$ = gc3(cons($3,cons($1,NIL)));}
931 vfields : vfields ',' vfield {$$ = gc3(cons($3,$1));}
932 | vfield {$$ = gc1(singleton($1));}
934 vfield : qvarid '=' exp {
936 $$ = gc3(ap(mkExt(textOf($1)),$3));
938 noTREX("an expression");
943 alts : alts1 {$$ = gc1($1);}
944 | alts1 ';' {$$ = gc2($1);}
946 alts1 : alts1 ';' alt {$$ = gc3(cons($3,$1));}
947 | alt {$$ = gc1(cons($1,NIL));}
949 alt : opExp altRhs wherePart {$$ = gc3(pair($1,letrec($3,$2)));}
951 altRhs : guardAlts {$$ = gc1(grded(rev($1)));}
952 | ARROW exp {$$ = gc2(pair($1,$2));}
953 | error {syntaxError("case expression");}
955 guardAlts : guardAlts guardAlt {$$ = gc2(cons($2,$1));}
956 | guardAlt {$$ = gc1(cons($1,NIL));}
958 guardAlt : '|' opExp ARROW exp {$$ = gc4(pair($3,pair($2,$4)));}
960 stmts : stmts1 ';' {$$ = gc2($1);}
961 | stmts1 {$$ = gc1($1);}
963 stmts1 : stmts1 ';' stmt {$$ = gc3(cons($3,$1));}
964 | stmt {$$ = gc1(cons($1,NIL));}
966 stmt : exp1 FROM exp {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
967 | LET decllist {$$ = gc2(ap(QWHERE,$2));}
968 | IF exp {$$ = gc2(ap(BOOLQUAL,$2));}
969 | exp1 {$$ = gc1(ap(DOQUAL,$1));}
971 fbinds : /* empty */ {$$ = gc0(NIL);}
972 | fbinds1 {$$ = gc1(rev($1));}
974 fbinds1 : fbinds1 ',' fbind {$$ = gc3(cons($3,$1));}
975 | fbind {$$ = gc1(singleton($1));}
977 fbind : var {$$ = gc1($1);}
978 | qvar '=' exp {$$ = gc3(pair($1,$3));}
981 /*- List Expressions: -------------------------------------------------------*/
983 list : /* empty */ {$$ = gc0(conPreludeNil);}
984 | exp {$$ = gc1(ap(FINLIST,cons($1,NIL)));}
985 | exps2 {$$ = gc1(ap(FINLIST,rev($1)));}
986 | exp '|' quals {$$ = gc3(ap(COMP,pair($1,rev($3))));}
987 | exp UPTO exp {$$ = gc3(ap2(varEnumFromTo,$1,$3));}
988 | exp ',' exp UPTO {$$ = gc4(ap2(varEnumFromThen,$1,$3));}
989 | exp UPTO {$$ = gc2(ap1(varEnumFrom,$1));}
990 | exp ',' exp UPTO exp {$$ = gc5(ap3(varEnumFromThenTo,
993 quals : quals ',' qual {$$ = gc3(cons($3,$1));}
994 | qual {$$ = gc1(cons($1,NIL));}
996 qual : exp FROM exp {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
997 | exp {$$ = gc1(ap(BOOLQUAL,$1));}
998 | LET decllist {$$ = gc2(ap(QWHERE,$2));}
1001 /*- Tricks to force insertion of leading and closing braces ---------------*/
1003 begin : error {yyerrok; goOffside(startColumn);}
1005 /* deal with trailing semicolon */
1006 end : '}' {$$ = gc1($1);}
1008 if (canUnOffside()) {
1010 /* insert extra token on stack*/
1012 pushed(0) = pushed(1);
1013 pushed(1) = mkInt(column);
1016 syntaxError("definition");
1020 /*-------------------------------------------------------------------------*/
1024 static Cell local gcShadow(n,e) /* keep parsed fragments on stack */
1027 /* If a look ahead token is held then the required stack transformation
1030 * x1 | ... | xn | la ===> e | la
1033 * Othwerwise, the transformation is:
1035 * x1 | ... | xn ===> e
1039 pushed(n-1) = top();
1048 static Void local syntaxError(s) /* report on syntax error */
1050 ERRMSG(row) "Syntax error in %s (unexpected %s)", s, unexpected()
1054 static String local unexpected() { /* find name for unexpected token */
1055 static char buffer[100];
1056 static char *fmt = "%s \"%s\"";
1057 static char *kwd = "keyword";
1060 case 0 : return "end of input";
1062 #define keyword(kw) sprintf(buffer,fmt,kwd,kw); return buffer;
1063 case INFIXL : keyword("infixl");
1064 case INFIXR : keyword("infixr");
1065 case INFIX : keyword("infix");
1066 case FOREIGN : keyword("foreign");
1067 case UNSAFE : keyword("unsafe");
1068 case TINSTANCE : keyword("instance");
1069 case TCLASS : keyword("class");
1070 case CASEXP : keyword("case");
1071 case OF : keyword("of");
1072 case IF : keyword("if");
1073 case THEN : keyword("then");
1074 case ELSE : keyword("else");
1075 case WHERE : keyword("where");
1076 case TYPE : keyword("type");
1077 case DATA : keyword("data");
1078 case TNEWTYPE : keyword("newtype");
1079 case LET : keyword("let");
1080 case IN : keyword("in");
1081 case DERIVING : keyword("deriving");
1082 case DEFAULT : keyword("default");
1083 case IMPORT : keyword("import");
1084 case EXPORT : keyword("export");
1085 case MODULETOK : keyword("module");
1086 case INTERFACE : keyword("interface");
1087 case WILDCARD : keyword("_");
1088 case ALL : keyword("forall");
1091 case ARROW : return "`->'";
1092 case '=' : return "`='";
1093 case COCO : return "`::'";
1094 case '-' : return "`-'";
1095 case '!' : return "`!'";
1096 case ',' : return "comma";
1097 case '@' : return "`@'";
1098 case '(' : return "`('";
1099 case ')' : return "`)'";
1100 case '{' : return "`{'";
1101 case '}' : return "`}'";
1102 case '_' : return "`_'";
1103 case '|' : return "`|'";
1104 case '.' : return "`.'";
1105 case ';' : return "`;'";
1106 case UPTO : return "`..'";
1107 case '[' : return "`['";
1108 case ']' : return "`]'";
1109 case FROM : return "`<-'";
1110 case '\\' : return "backslash (lambda)";
1111 case '~' : return "tilde";
1112 case '`' : return "backquote";
1114 case RECSELID : sprintf(buffer,"selector \"#%s\"",
1115 textToStr(extText(snd(yylval))));
1121 case CONID : sprintf(buffer,"symbol \"%s\"",
1122 textToStr(textOf(yylval)));
1127 case QCONID : sprintf(buffer,"symbol \"%s\"",
1128 identToStr(yylval));
1130 case HIDING : return "symbol \"hiding\"";
1131 case QUALIFIED : return "symbol \"qualified\"";
1132 case ASMOD : return "symbol \"as\"";
1133 case NUMLIT : return "numeric literal";
1134 case CHARLIT : return "character literal";
1135 case STRINGLIT : return "string literal";
1136 case IMPLIES : return "`=>'";
1137 default : return "token";
1141 static Cell local checkPrec(p) /* Check for valid precedence value */
1143 if ((!isInt(p) || intOf(p)<MIN_PREC || intOf(p)>MAX_PREC)
1144 && (!isBignum(p) || bignumOf(p)<MIN_PREC || bignumOf(p)>MAX_PREC)
1146 ERRMSG(row) "Precedence value must be an integer in the range [%d..%d]",
1151 return mkInt(bignumOf(p));
1157 static Void local fixDefn(a,line,p,ops)/* Declare syntax of operators */
1162 Int l = intOf(line);
1163 a = mkSyntax(a,intOf(p));
1164 map2Proc(setSyntax,l,a,ops);
1167 static Void local setSyntax(line,sy,op)/* set syntax of individ. operator */
1171 addSyntax(line,textOf(op),sy);
1172 opDefns = cons(op,opDefns);
1175 static Cell local buildTuple(tup) /* build tuple (x1,...,xn) from list*/
1176 List tup; { /* [xn,...,x1] */
1182 x = fst(t); /* / \ / \ */
1183 fst(t) = snd(t); /* xn . . xn */
1184 snd(t) = x; /* . ===> . */
1186 t = fun(x); /* . . */
1188 } while (nonNull(t)); /* x1 NIL (n) x1 */
1189 fst(x) = mkTuple(n);
1193 static List local checkContext(con) /* validate context */
1195 mapOver(checkPred, con);
1199 static Cell local checkPred(c) /* check that type expr is a valid */
1200 Cell c; { /* constraint */
1201 Cell cn = getHead(c);
1203 if (isExt(cn) && argCount==1)
1206 if (!isQCon(cn) || argCount==0)
1207 syntaxError("class expression");
1211 static Pair local checkDo(dqs) /* convert reversed list of dquals */
1212 List dqs; { /* to an (expr,quals) pair */
1213 if (isNull(dqs) || whatIs(hd(dqs))!=DOQUAL) {
1214 ERRMSG(row) "Last generator in do {...} must be an expression"
1217 fst(dqs) = snd(fst(dqs)); /* put expression in fst of pair */
1218 snd(dqs) = rev(snd(dqs)); /* & reversed list of quals in snd */
1222 static Cell local checkTyLhs(c) /* check that lhs is of the form */
1223 Cell c; { /* T a1 ... a */
1225 while (isAp(tlhs) && whatIs(arg(tlhs))==VARIDCELL)
1227 switch (whatIs(tlhs)) {
1228 case CONIDCELL : return c;
1231 ERRMSG(row) "Illegal left hand side in datatype definition"
1237 static Void local noTREX(where)
1239 ERRMSG(row) "Attempt to use Typed Records with Extensions\nwhile parsing %s. This feature is disabled in this build of Hugs.",
1245 /* Expressions involving infix operators or unary minus are parsed as elements
1246 * of the following type:
1248 * data OpExp = Only Exp | Neg OpExp | Infix OpExp Op Exp
1250 * (The algorithms here do not assume that negation can be applied only once,
1251 * i.e., that - - x is a syntax error, as required by the Haskell report.
1252 * Instead, that restriction is captured by the grammar itself, given above.)
1254 * There are rules of precedence and grouping, expressed by two functions:
1256 * prec :: Op -> Int; assoc :: Op -> Assoc (Assoc = {L, N, R})
1258 * OpExp values are rearranged accordingly when a complete expression has
1259 * been read using a simple shift-reduce parser whose result may be taken
1260 * to be a value of the following type:
1262 * data Exp = Atom Int | Negate Exp | Apply Op Exp Exp | Error String
1264 * The machine on which this parser is based can be defined as follows:
1266 * tidy :: OpExp -> [(Op,Exp)] -> Exp
1267 * tidy (Only a) [] = a
1268 * tidy (Only a) ((o,b):ss) = tidy (Only (Apply o a b)) ss
1269 * tidy (Infix a o b) [] = tidy a [(o,b)]
1270 * tidy (Infix a o b) ((p,c):ss)
1271 * | shift o p = tidy a ((o,b):(p,c):ss)
1272 * | red o p = tidy (Infix a o (Apply p b c)) ss
1273 * | ambig o p = Error "ambiguous use of operators"
1274 * tidy (Neg e) [] = tidy (tidyNeg e) []
1275 * tidy (Neg e) ((o,b):ss)
1276 * | nshift o = tidy (Neg (underNeg o b e)) ss
1277 * | nred o = tidy (tidyNeg e) ((o,b):ss)
1278 * | nambig o = Error "illegal use of negation"
1280 * At each stage, the parser can either shift, reduce, accept, or error.
1281 * The transitions when dealing with juxtaposed operators o and p are
1282 * determined by the following rules:
1284 * shift o p = (prec o > prec p)
1285 * || (prec o == prec p && assoc o == L && assoc p == L)
1287 * red o p = (prec o < prec p)
1288 * || (prec o == prec p && assoc o == R && assoc p == R)
1290 * ambig o p = (prec o == prec p)
1291 * && (assoc o == N || assoc p == N || assoc o /= assoc p)
1293 * The transitions when dealing with juxtaposed unary minus and infix operators
1294 * are as follows. The precedence of unary minus (infixl 6) is hardwired in
1295 * to these definitions, as it is to the definitions of the Haskell grammar
1296 * in the official report.
1298 * nshift o = (prec o > 6)
1299 * nred o = (prec o < 6) || (prec o == 6 && assoc o == L)
1300 * nambig o = prec o == 6 && (assoc o == R || assoc o == N)
1302 * An OpExp of the form (Neg e) means negate the last thing in the OpExp e;
1303 * we can force this negation using:
1305 * tidyNeg :: OpExp -> OpExp
1306 * tidyNeg (Only e) = Only (Negate e)
1307 * tidyNeg (Infix a o b) = Infix a o (Negate b)
1308 * tidyNeg (Neg e) = tidyNeg (tidyNeg e)
1310 * On the other hand, if we want to sneak application of an infix operator
1311 * under a negation, then we use:
1313 * underNeg :: Op -> Exp -> OpExp -> OpExp
1314 * underNeg o b (Only e) = Only (Apply o e b)
1315 * underNeg o b (Neg e) = Neg (underNeg o b e)
1316 * underNeg o b (Infix e p f) = Infix e p (Apply o f b)
1318 * As a concession to efficiency, we lower the number of calls to syntaxOf
1319 * by keeping track of the values of sye, sys throughout the process. The
1320 * value APPLIC is used to indicate that the syntax value is unknown.
1323 #define UMINUS_PREC 6 /* Change these settings at your */
1324 #define UMINUS_ASSOC LEFT_ASS /* own risk; they may not work! */
1326 static Cell local tidyInfix(e) /* convert OpExp to Expr */
1327 Cell e; { /* :: OpExp */
1328 Cell s = NIL; /* :: [(Op,Exp)] */
1329 Syntax sye = APPLIC; /* Syntax of op in e (init unknown)*/
1330 Syntax sys = APPLIC; /* Syntax of op in s (init unknown)*/
1333 switch (whatIs(e)) {
1334 case ONLY : e = snd(e);
1335 while (nonNull(s)) {
1336 Cell next = arg(fun(s));
1343 case NEG : if (nonNull(s)) {
1345 if (sys==APPLIC) { /* calculate sys */
1346 sys = identSyntax(fun(fun(s)));
1347 if (sys==APPLIC) sys=DEF_OPSYNTAX;
1350 if (precOf(sys)==UMINUS_PREC && /* nambig */
1351 assocOf(sys)!=UMINUS_ASSOC) {
1353 "Ambiguous use of unary minus with \"%s\"",
1354 textToStr(textOf(fun(fun(s))))
1358 if (precOf(sys)>UMINUS_PREC) { /* nshift */
1362 while (whatIs(e1)==NEG)
1364 arg(fun(t)) = arg(e1);
1372 /* Intentional fall-thru for nreduce and isNull(s) */
1373 { Cell prev = e; /* e := tidyNeg e */
1374 Cell temp = arg(prev);
1376 for (; whatIs(temp)==NEG; nneg++) {
1377 fun(prev) = varNegate;
1381 /* These special cases are required for
1384 if (isInt(arg(temp))) { /* special cases */
1385 if (nneg&1) /* for literals */
1386 arg(temp) = intNegate(arg(temp));
1388 else if (isBignum(arg(temp))) {
1390 arg(temp) = bignumNegate(arg(temp));
1392 else if (isFloat(arg(temp))) {
1394 arg(temp) = floatNegate(arg(temp));
1397 fun(prev) = varNegate;
1398 arg(prev) = arg(temp);
1405 default : if (isNull(s)) {/* Move operation onto empty stack */
1406 Cell next = arg(fun(e));
1413 else { /* deal with pair of operators */
1415 if (sye==APPLIC) { /* calculate sys and sye */
1416 sye = identSyntax(fun(fun(e)));
1417 if (sye==APPLIC) sye=DEF_OPSYNTAX;
1420 sys = identSyntax(fun(fun(s)));
1421 if (sys==APPLIC) sys=DEF_OPSYNTAX;
1424 if (precOf(sye)==precOf(sys) && /* ambig */
1425 (assocOf(sye)!=assocOf(sys) ||
1426 assocOf(sye)==NON_ASS)) {
1428 "Ambiguous use of operator \"%s\" with \"%s\"",
1429 textToStr(textOf(fun(fun(e)))),
1430 textToStr(textOf(fun(fun(s))))
1434 if (precOf(sye)>precOf(sys) || /* shift */
1435 (precOf(sye)==precOf(sys) &&
1436 assocOf(sye)==LEFT_ASS &&
1437 assocOf(sys)==LEFT_ASS)) {
1438 Cell next = arg(fun(e));
1446 Cell next = arg(fun(s));
1447 arg(fun(s)) = arg(e);
1458 /*-------------------------------------------------------------------------*/