PageRenderTime 64ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/hugs98-Nov2003/src/parser.y

https://github.com/gitpan/Language-Haskell
Happy | 1265 lines | 1197 code | 68 blank | 0 comment | 0 complexity | c7b2bb2aed0965c0f8d4bcd733fbb7d0 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. /* --------------------------------------------------------------------------
  2. * Hugs parser (included as part of input.c)
  3. *
  4. * Expect 16 shift/reduce conflicts when passing this grammar through yacc,
  5. * but don't worry; they should all be resolved in an appropriate manner.
  6. *
  7. * The Hugs 98 system is Copyright (c) Mark P Jones, Alastair Reid, the
  8. * Yale Haskell Group, and the OGI School of Science & Engineering at OHSU,
  9. * 1994-2003, All rights reserved. It is distributed as free software under
  10. * the license in the file "License", which is included in the distribution.
  11. *
  12. * $RCSfile: parser.y,v $
  13. * $Revision: 1.44 $
  14. * $Date: 2003/10/14 13:56:23 $
  15. * ------------------------------------------------------------------------*/
  16. %{
  17. #ifndef lint
  18. #define lint
  19. #endif
  20. #define defTycon(n,l,lhs,rhs,w) tyconDefn(intOf(l),lhs,rhs,w); sp-=n
  21. #define sigdecl(l,vs,t) ap(SIGDECL,triple(l,vs,t))
  22. #define fixdecl(l,ops,a,p) ap(FIXDECL,\
  23. triple(l,ops,mkInt(mkSyntax(a,intOf(p)))))
  24. #define grded(gs) ap(GUARDED,gs)
  25. #define bang(t) ap(BANG,t)
  26. #define only(t) ap(ONLY,t)
  27. #define letrec(bs,e) (nonNull(bs) ? ap(LETREC,pair(bs,e)) : e)
  28. #define qualify(ps,t) (nonNull(ps) ? ap(QUAL,pair(ps,t)) : t)
  29. #define exportSelf() singleton(ap(MODULEENT,mkCon(module(currentModule).text)))
  30. #define yyerror(s) /* errors handled elsewhere */
  31. #define YYSTYPE Cell
  32. #ifdef YYBISON
  33. # if !defined(__GNUC__) || __GNUC__ <= 1
  34. static void __yy_memcpy Args((char*,char*, unsigned int));
  35. # endif
  36. #endif
  37. #ifdef _MANAGED
  38. static void yymemcpy (char *yyto, const char *yyfrom, size_t yycount);
  39. #endif
  40. static Cell local gcShadow Args((Int,Cell));
  41. static Void local syntaxError Args((String));
  42. static String local unexpected Args((Void));
  43. static Cell local checkPrec Args((Cell));
  44. static Cell local buildTuple Args((List));
  45. static List local checkCtxt Args((List));
  46. static Cell local checkPred Args((Cell));
  47. static Pair local checkDo Args((List));
  48. static Cell local checkTyLhs Args((Cell));
  49. #if MUDO
  50. static Pair local checkMDo Args((List));
  51. #endif
  52. #if !TREX
  53. static Void local noTREX Args((String));
  54. #endif
  55. #if !IPARAM
  56. static Void local noIP Args((String));
  57. #endif
  58. #if !MUDO
  59. static Void local noMDo Args((String));
  60. #endif
  61. /* For the purposes of reasonably portable garbage collection, it is
  62. * necessary to simulate the YACC stack on the Hugs stack to keep
  63. * track of all intermediate constructs. The lexical analyser
  64. * pushes a token onto the stack for each token that is found, with
  65. * these elements being removed as reduce actions are performed,
  66. * taking account of look-ahead tokens as described by gcShadow()
  67. * below.
  68. *
  69. * Of the non-terminals used below, only start, topDecl & begin
  70. * do not leave any values on the Hugs stack. The same is true for the
  71. * terminals EXPR and SCRIPT. At the end of a successful parse, there
  72. * should only be one element left on the stack, containing the result
  73. * of the parse.
  74. */
  75. #define gc0(e) gcShadow(0,e)
  76. #define gc1(e) gcShadow(1,e)
  77. #define gc2(e) gcShadow(2,e)
  78. #define gc3(e) gcShadow(3,e)
  79. #define gc4(e) gcShadow(4,e)
  80. #define gc5(e) gcShadow(5,e)
  81. #define gc6(e) gcShadow(6,e)
  82. #define gc7(e) gcShadow(7,e)
  83. %}
  84. %token EXPR CTXT SCRIPT
  85. %token CASEXP OF DATA TYPE IF
  86. %token THEN ELSE WHERE LET IN
  87. %token INFIXN INFIXL INFIXR PRIMITIVE TNEWTYPE
  88. %token DEFAULT DERIVING DO TCLASS TINSTANCE
  89. /*#if MUDO*/
  90. %token MDO
  91. /*#endif*/
  92. %token REPEAT ALL NUMLIT CHARLIT STRINGLIT
  93. %token VAROP VARID CONOP CONID
  94. %token QVAROP QVARID QCONOP QCONID
  95. /*#if TREX*/
  96. %token RECSELID IPVARID
  97. /*#endif*/
  98. %token COCO '=' UPTO '@' '\\'
  99. %token '|' '-' FROM ARROW '~'
  100. %token '!' IMPLIES '(' ',' ')'
  101. %token '[' ';' ']' '`' '.'
  102. %token TMODULE IMPORT HIDING QUALIFIED ASMOD
  103. %token NEEDPRIMS
  104. %token FOREIGN
  105. %%
  106. /*- Top level script/module structure -------------------------------------*/
  107. start : EXPR exp lwherePart {inputExpr = letrec($3,$2); sp-=2;}
  108. | CTXT context {inputContext = $2; sp-=1;}
  109. | SCRIPT topModule {valDefns = $2; sp-=1;}
  110. | error {syntaxError("input");}
  111. ;
  112. /*- Haskell module header/import parsing: -----------------------------------
  113. * Syntax for Haskell modules (module headers and imports) is parsed but
  114. * most of it is ignored. However, module names in import declarations
  115. * are used, of course, if import chasing is turned on.
  116. *-------------------------------------------------------------------------*/
  117. /* In Haskell 1.2, the default module header was "module Main where"
  118. * In 1.3, this changed to "module Main(main) where".
  119. * We use the 1.2 header because it breaks much less pre-module code.
  120. */
  121. topModule : startMain begin modBody end {
  122. setExportList(singleton(ap(MODULEENT,mkCon(module(currentModule).text))));
  123. $$ = gc3($3);
  124. }
  125. | startMain '{' modBody '}' {
  126. setExportList(singleton(ap(MODULEENT,mkCon(module(currentModule).text))));
  127. $$ = gc4($3);
  128. }
  129. | TMODULE modname expspec WHERE '{' modBody end
  130. {setExportList($3); $$ = gc7($6);}
  131. | TMODULE error {syntaxError("module definition");}
  132. ;
  133. /* To implement the Haskell module system, we have to keep track of the
  134. * current module. We rely on the use of LALR parsing to ensure that this
  135. * side effect happens before any declarations within the module.
  136. */
  137. startMain : /* empty */ {startModule(conMain);
  138. $$ = gc0(NIL);}
  139. ;
  140. modname : qconid {startModule(mkCon(mkNestedQual($1))); $$ = gc1(NIL);}
  141. ;
  142. modid : qconid {$$ = mkCon(mkNestedQual($1));}
  143. | STRINGLIT { String modName = findPathname(textToStr(textOf($1)));
  144. if (modName) { /* fillin pathname if known */
  145. $$ = mkStr(findText(modName));
  146. } else {
  147. $$ = $1;
  148. }
  149. }
  150. ;
  151. modBody : /* empty */ {$$ = gc0(NIL); }
  152. | ';' modBody {$$ = gc2($2);}
  153. | topDecls {$$ = gc1($1);}
  154. | impDecls chase {$$ = gc2(NIL);}
  155. | impDecls ';' chase topDecls {$$ = gc4($4);}
  156. ;
  157. /*- Exports: --------------------------------------------------------------*/
  158. expspec : /* empty */ {$$ = gc0(exportSelf());}
  159. | '(' ')' {$$ = gc2(NIL);}
  160. | '(' ',' ')' {$$ = gc3(NIL);}
  161. | '(' exports ')' {$$ = gc3($2);}
  162. | '(' exports ',' ')' {$$ = gc4($2);}
  163. ;
  164. exports : exports ',' export {$$ = gc3(cons($3,$1));}
  165. | export {$$ = gc1(singleton($1));}
  166. ;
  167. /* The qcon should be qconid.
  168. * Relaxing the rule lets us explicitly export (:) from the Prelude.
  169. */
  170. export : qvar {$$ = $1;}
  171. | qcon {$$ = $1;}
  172. | qconid '(' UPTO ')' {$$ = gc4(pair($1,DOTDOT));}
  173. | qconid '(' qnames ')' {$$ = gc4(pair($1,$3));}
  174. | TMODULE modid {$$ = gc2(ap(MODULEENT,$2));}
  175. ;
  176. qnames : /* empty */ {$$ = gc0(NIL);}
  177. | ',' {$$ = gc1(NIL);}
  178. | qnames1 {$$ = $1;}
  179. | qnames1 ',' {$$ = gc2($1);}
  180. ;
  181. qnames1 : qnames1 ',' qname {$$ = gc3(cons($3,$1));}
  182. | qname {$$ = gc1(singleton($1));}
  183. ;
  184. qname : qvar {$$ = $1;}
  185. | qcon {$$ = $1;}
  186. ;
  187. /*- Import declarations: --------------------------------------------------*/
  188. impDecls : impDecls ';' impDecl {imps = cons($3,imps); $$=gc3(NIL);}
  189. | impDecls ';' {$$ = gc2(NIL); }
  190. | impDecl {imps = singleton($1); $$=gc1(NIL);}
  191. ;
  192. chase : /* empty */ {if (chase(imps)) {
  193. clearStack();
  194. onto(imps);
  195. done();
  196. closeAnyInput();
  197. return 0;
  198. }
  199. $$ = gc0(NIL);
  200. }
  201. ;
  202. /* Note that qualified import ignores the import list. */
  203. impDecl : IMPORT modid impspec {addUnqualImport($2,NIL,$3);
  204. $$ = gc3($2);}
  205. | IMPORT modid ASMOD modid impspec
  206. {addUnqualImport($2,$4,$5);
  207. $$ = gc5($2);}
  208. | IMPORT QUALIFIED modid ASMOD modid impspec
  209. {addQualImport($3,$5,$6);
  210. $$ = gc6($3);}
  211. | IMPORT QUALIFIED modid impspec
  212. {addQualImport($3,$3,$4);
  213. $$ = gc4($3);}
  214. | IMPORT error {syntaxError("import declaration");}
  215. ;
  216. impspec : /* empty */ {$$ = gc0(DOTDOT);}
  217. | HIDING '(' imports ')' {$$ = gc4(ap(HIDDEN,$3));}
  218. | '(' imports ')' {$$ = gc3($2);}
  219. ;
  220. imports : /* empty */ {$$ = gc0(NIL);}
  221. | ',' {$$ = gc1(NIL);}
  222. | imports1 {$$ = $1;}
  223. | imports1 ',' {$$ = gc2($1);}
  224. ;
  225. imports1 : imports1 ',' import {$$ = gc3(cons($3,$1));}
  226. | import {$$ = gc1(singleton($1));}
  227. ;
  228. import : var {$$ = $1;}
  229. | CONID {$$ = gc1(pair($1,NONE));}
  230. | CONID '(' UPTO ')' {$$ = gc4(pair($1,DOTDOT));}
  231. | CONID '(' names ')' {$$ = gc4(pair($1,$3));}
  232. ;
  233. names : /* empty */ {$$ = gc0(NIL);}
  234. | ',' {$$ = gc1(NIL);}
  235. | names1 {$$ = $1;}
  236. | names1 ',' {$$ = gc2($1);}
  237. ;
  238. names1 : names1 ',' name {$$ = gc3(cons($3,$1));}
  239. | name {$$ = gc1(singleton($1));}
  240. ;
  241. name : var {$$ = $1;}
  242. | con {$$ = $1;}
  243. ;
  244. /*- Top-level declarations: -----------------------------------------------*/
  245. topDecls : topDecls ';' {$$ = gc2($1);}
  246. | topDecls ';' topDecl {$$ = gc2($1);}
  247. | topDecls ';' decl {$$ = gc3(cons($3,$1));}
  248. | topDecl {$$ = gc0(NIL);}
  249. | decl {$$ = gc1(cons($1,NIL));}
  250. ;
  251. /*- Type declarations: ----------------------------------------------------*/
  252. topDecl : TYPE tyLhs '=' type {defTycon(4,$3,$2,$4,SYNONYM);}
  253. | TYPE tyLhs '=' type IN invars
  254. {defTycon(6,$3,$2,
  255. ap($4,$6),RESTRICTSYN);}
  256. | TYPE error {syntaxError("type definition");}
  257. | DATA btype2 '=' constrs deriving
  258. {defTycon(5,$3,checkTyLhs($2),
  259. ap(rev($4),$5),DATATYPE);}
  260. | DATA context IMPLIES tyLhs '=' constrs deriving
  261. {defTycon(7,$5,$4,
  262. ap(qualify($2,rev($6)),
  263. $7),DATATYPE);}
  264. | DATA btype2 {defTycon(2,$1,checkTyLhs($2),
  265. ap(NIL,NIL),DATATYPE);}
  266. | DATA context IMPLIES tyLhs {defTycon(4,$1,$4,
  267. ap(qualify($2,NIL),
  268. NIL),DATATYPE);}
  269. | DATA error {syntaxError("data definition");}
  270. | TNEWTYPE btype2 '=' nconstr deriving
  271. {defTycon(5,$3,checkTyLhs($2),
  272. ap($4,$5),NEWTYPE);}
  273. | TNEWTYPE context IMPLIES tyLhs '=' nconstr deriving
  274. {defTycon(7,$5,$4,
  275. ap(qualify($2,$6),
  276. $7),NEWTYPE);}
  277. | TNEWTYPE error {syntaxError("newtype definition");}
  278. | NEEDPRIMS NUMLIT {if (isInt($2)) {
  279. needPrims(intOf($2));
  280. } else {
  281. syntaxError("needprims decl");
  282. }
  283. sp-=2;}
  284. | NEEDPRIMS error {syntaxError("needprims decl");}
  285. ;
  286. tyLhs : tyLhs varid {$$ = gc2(ap($1,$2));}
  287. | CONID {$$ = $1;}
  288. | error {syntaxError("type defn lhs");}
  289. ;
  290. invars : invars ',' invar {$$ = gc3(cons($3,$1));}
  291. | invar {$$ = gc1(cons($1,NIL));}
  292. ;
  293. invar : var COCO topType {$$ = gc3(sigdecl($2,singleton($1),
  294. $3));}
  295. | var {$$ = $1;}
  296. ;
  297. constrs : constrs '|' pconstr {$$ = gc3(cons($3,$1));}
  298. | pconstr {$$ = gc1(cons($1,NIL));}
  299. ;
  300. pconstr : ALL varids '.' qconstr {$$ = gc4(ap(POLYTYPE,
  301. pair(rev($2),$4)));}
  302. | constr {$$ = $1;}
  303. ;
  304. qconstr : context IMPLIES constr {$$ = gc3(qualify($1,$3));}
  305. | constr {$$ = $1;}
  306. ;
  307. constr : '!' btype conop bbtype {$$ = gc4(ap(ap($3,bang($2)),$4));}
  308. | btype1 conop bbtype {$$ = gc3(ap(ap($2,$1),$3));}
  309. | btype2 conop bbtype {$$ = gc3(ap(ap($2,$1),$3));}
  310. | bpolyType conop bbtype {$$ = gc3(ap(ap($2,$1),$3));}
  311. | btype2 {$$ = $1;}
  312. | btype3 {$$ = $1;}
  313. | btype4 {$$ = $1;}
  314. | con '{' fieldspecs '}' {$$ = gc4(ap(LABC,pair($1,rev($3))));}
  315. | con '{' '}' {$$ = gc3(ap(LABC,pair($1,NIL)));}
  316. | error {syntaxError("data type definition");}
  317. ;
  318. btype3 : btype2 '!' atype {$$ = gc3(ap($1,bang($3)));}
  319. | btype3 '!' atype {$$ = gc3(ap($1,bang($3)));}
  320. | btype3 atype {$$ = gc2(ap($1,$2));}
  321. ;
  322. btype4 : btype2 bpolyType {$$ = gc2(ap($1,$2));}
  323. | btype3 bpolyType {$$ = gc2(ap($1,$2));}
  324. | btype4 bpolyType {$$ = gc2(ap($1,$2));}
  325. | btype4 atype {$$ = gc2(ap($1,$2));}
  326. | btype4 '!' atype {$$ = gc3(ap($1,bang($3)));}
  327. ;
  328. bbtype : '!' btype {$$ = gc2(bang($2));}
  329. | btype {$$ = $1;}
  330. | bpolyType {$$ = $1;}
  331. ;
  332. nconstr : pconstr {$$ = gc1(singleton($1));}
  333. ;
  334. fieldspecs: fieldspecs ',' fieldspec {$$ = gc3(cons($3,$1));}
  335. | fieldspec {$$ = gc1(cons($1,NIL));}
  336. ;
  337. fieldspec : vars COCO polyType {$$ = gc3(pair(rev($1),$3));}
  338. | vars COCO type {$$ = gc3(pair(rev($1),$3));}
  339. | vars COCO '!' type {$$ = gc4(pair(rev($1),bang($4)));}
  340. ;
  341. deriving : /* empty */ {$$ = gc0(NIL);}
  342. | DERIVING qconid {$$ = gc2(singleton($2));}
  343. | DERIVING '(' derivs0 ')' {$$ = gc4($3);}
  344. ;
  345. derivs0 : /* empty */ {$$ = gc0(NIL);}
  346. | derivs {$$ = gc1(rev($1));}
  347. ;
  348. derivs : derivs ',' qconid {$$ = gc3(cons($3,$1));}
  349. | qconid {$$ = gc1(singleton($1));}
  350. ;
  351. /*- Processing definitions of primitives ----------------------------------*/
  352. topDecl : PRIMITIVE prims COCO topType{primDefn($1,$2,$4); sp-=4;}
  353. ;
  354. prims : prims ',' prim {$$ = gc3(cons($3,$1));}
  355. | prim {$$ = gc1(cons($1,NIL));}
  356. | error {syntaxError("primitive defn");}
  357. ;
  358. prim : var STRINGLIT {$$ = gc2(pair($1,$2));}
  359. | var {$$ = $1;}
  360. ;
  361. /*- Foreign Function Interface --------------------------------------------*/
  362. topDecl : FOREIGN IMPORT var STRINGLIT var COCO topType
  363. {foreignImport($1,$3,NIL,$4,$5,$7); sp-=7;}
  364. | FOREIGN IMPORT var var COCO topType
  365. {foreignImport($1,$3,NIL,$4,$4,$6); sp-=6;}
  366. | FOREIGN IMPORT var var STRINGLIT var COCO topType
  367. {foreignImport($1,$3,$4,$5,$6,$8); sp-=8;}
  368. | FOREIGN IMPORT var var var COCO topType
  369. {foreignImport($1,$3,$4,$5,$5,$7); sp-=7;}
  370. | FOREIGN var var STRINGLIT var COCO topType
  371. {foreignExport($1,$2,$3,$4,$5,$7); sp-=7;}
  372. ;
  373. /*- Class declarations: ---------------------------------------------------*/
  374. topDecl : TCLASS crule fds wherePart {classDefn(intOf($1),$2,$4,$3); sp-=4;}
  375. | TINSTANCE irule wherePart {instDefn(intOf($1),$2,$3); sp-=3;}
  376. | DEFAULT '(' dtypes ')' {defaultDefn(intOf($1),$3); sp-=4;}
  377. | TCLASS error {syntaxError("class declaration");}
  378. | TINSTANCE error {syntaxError("instance declaration");}
  379. | DEFAULT error {syntaxError("default declaration");}
  380. ;
  381. crule : context IMPLIES btype2 {$$ = gc3(pair($1,checkPred($3)));}
  382. | btype2 {$$ = gc1(pair(NIL,checkPred($1)));}
  383. ;
  384. irule : context IMPLIES btype2 {$$ = gc3(pair($1,checkPred($3)));}
  385. | btype2 {$$ = gc1(pair(NIL,checkPred($1)));}
  386. ;
  387. dtypes : /* empty */ {$$ = gc0(NIL);}
  388. | dtypes1 {$$ = gc1(rev($1));}
  389. ;
  390. dtypes1 : dtypes1 ',' type {$$ = gc3(cons($3,$1));}
  391. | type {$$ = gc1(cons($1,NIL));}
  392. ;
  393. fds : /* empty */ {$$ = gc0(NIL);}
  394. | '|' fds1 {h98DoesntSupport(row,"dependent parameters");
  395. $$ = gc2(rev($2));}
  396. ;
  397. fds1 : fds1 ',' fd {$$ = gc3(cons($3,$1));}
  398. | fd {$$ = gc1(cons($1,NIL));}
  399. ;
  400. fd : varids0 ARROW varids0 {$$ = gc3(pair(rev($1),rev($3)));}
  401. | error {syntaxError("functional dependency");}
  402. ;
  403. varids0 : /* empty */ {$$ = gc0(NIL);}
  404. | varids0 varid {$$ = gc2(cons($2,$1));}
  405. ;
  406. /*- Type expressions: -----------------------------------------------------*/
  407. topType : ALL varids '.' topType0 {$$ = gc4(ap(POLYTYPE,
  408. pair(rev($2),$4)));}
  409. | topType0 {$$ = $1;}
  410. ;
  411. topType0 : context IMPLIES topType1 {$$ = gc3(qualify($1,$3));}
  412. | topType1 {$$ = $1;}
  413. ;
  414. topType1 : bpolyType ARROW topType1 {$$ = gc3(fn($1,$3));}
  415. | btype1 ARROW topType1 {$$ = gc3(fn($1,$3));}
  416. | btype2 ARROW topType1 {$$ = gc3(fn($1,$3));}
  417. | btype {$$ = $1;}
  418. ;
  419. polyType : ALL varids '.' sigType {$$ = gc4(ap(POLYTYPE,
  420. pair(rev($2),$4)));}
  421. | bpolyType {$$ = $1;}
  422. ;
  423. bpolyType : '(' polyType ')' {$$ = gc3($2);}
  424. | '(' lcontext IMPLIES type ')' {$$ = gc5(qualify($2,$4));}
  425. ;
  426. varids : varids varid {$$ = gc2(cons($2,$1));}
  427. | varid {$$ = gc1(singleton($1));}
  428. ;
  429. sigType : context IMPLIES type {$$ = gc3(qualify($1,$3));}
  430. | type {$$ = $1;}
  431. ;
  432. context : '(' ')' {$$ = gc2(NIL);}
  433. | btype2 {$$ = gc1(singleton(checkPred($1)));}
  434. | '(' btype2 ')' {$$ = gc3(singleton(checkPred($2)));}
  435. | '(' btypes2 ')' {$$ = gc3(checkCtxt(rev($2)));}
  436. | lacks {$$ = gc1(singleton($1));}
  437. | '(' lacks1 ')' {$$ = gc3(checkCtxt(rev($2)));}
  438. ;
  439. lcontext : lacks {$$ = gc1(singleton($1));}
  440. | '(' lacks1 ')' {$$ = gc3(checkCtxt(rev($2)));}
  441. ;
  442. lacks : varid '\\' varid {
  443. #if TREX
  444. $$ = gc3(ap(mkExt(textOf($3)),$1));
  445. #else
  446. noTREX("a type context");
  447. #endif
  448. }
  449. | IPVARID COCO type {
  450. #if IPARAM
  451. $$ = gc3(pair(mkIParam($1),$3));
  452. #else
  453. noIP("a type context");
  454. #endif
  455. }
  456. ;
  457. lacks1 : btypes2 ',' lacks {$$ = gc3(cons($3,$1));}
  458. | lacks1 ',' btype2 {$$ = gc3(cons($3,$1));}
  459. | lacks1 ',' lacks {$$ = gc3(cons($3,$1));}
  460. | btype2 ',' lacks {$$ = gc3(cons($3,cons($1,NIL)));}
  461. | lacks {$$ = gc1(singleton($1));}
  462. ;
  463. type : type1 {$$ = $1;}
  464. | btype2 {$$ = $1;}
  465. ;
  466. type1 : btype1 {$$ = $1;}
  467. | bpolyType ARROW type {$$ = gc3(fn($1,$3));}
  468. | btype1 ARROW type {$$ = gc3(fn($1,$3));}
  469. | btype2 ARROW type {$$ = gc3(fn($1,$3));}
  470. | error {syntaxError("type expression");}
  471. ;
  472. btype : btype1 {$$ = $1;}
  473. | btype2 {$$ = $1;}
  474. ;
  475. btype1 : btype1 atype {$$ = gc2(ap($1,$2));}
  476. | atype1 {$$ = $1;}
  477. ;
  478. btype2 : btype2 atype {$$ = gc2(ap($1,$2));}
  479. | qconid {$$ = $1;}
  480. ;
  481. atype : atype1 {$$ = $1;}
  482. | qconid {$$ = $1;}
  483. ;
  484. atype1 : varid {$$ = $1;}
  485. | '(' ')' {$$ = gc2(typeUnit);}
  486. | '(' ARROW ')' {$$ = gc3(typeArrow);}
  487. | '(' type1 ')' {$$ = gc3($2);}
  488. | '(' btype2 ')' {$$ = gc3($2);}
  489. | '(' tupCommas ')' {$$ = gc3($2);}
  490. | '(' btypes2 ')' {$$ = gc3(buildTuple($2));}
  491. | '(' typeTuple ')' {$$ = gc3(buildTuple($2));}
  492. | '(' tfields ')' {
  493. #if TREX
  494. $$ = gc3(revOnto($2,typeNoRow));
  495. #else
  496. noTREX("a type");
  497. #endif
  498. }
  499. | '(' tfields '|' type ')' {
  500. #if TREX
  501. $$ = gc5(revOnto($2,$4));
  502. #else
  503. noTREX("a type");
  504. #endif
  505. }
  506. | '[' type ']' {$$ = gc3(ap(typeList,$2));}
  507. | '[' ']' {$$ = gc2(typeList);}
  508. | '_' {h98DoesntSupport(row,"anonymous type variables");
  509. $$ = gc1(inventVar());}
  510. ;
  511. btypes2 : btypes2 ',' btype2 {$$ = gc3(cons($3,$1));}
  512. | btype2 ',' btype2 {$$ = gc3(cons($3,cons($1,NIL)));}
  513. ;
  514. typeTuple : type1 ',' type {$$ = gc3(cons($3,cons($1,NIL)));}
  515. | btype2 ',' type1 {$$ = gc3(cons($3,cons($1,NIL)));}
  516. | btypes2 ',' type1 {$$ = gc3(cons($3,$1));}
  517. | typeTuple ',' type {$$ = gc3(cons($3,$1));}
  518. ;
  519. /*#if TREX*/
  520. tfields : tfields ',' tfield {$$ = gc3(cons($3,$1));}
  521. | tfield {$$ = gc1(singleton($1));}
  522. ;
  523. tfield : varid COCO type {h98DoesntSupport(row,"extensible records");
  524. $$ = gc3(ap(mkExt(textOf($1)),$3));}
  525. ;
  526. /*#endif*/
  527. /*- Value declarations: ---------------------------------------------------*/
  528. gendecl : INFIXN optDigit ops {$$ = gc3(fixdecl($1,$3,NON_ASS,$2));}
  529. | INFIXN error {syntaxError("fixity decl");}
  530. | INFIXL optDigit ops {$$ = gc3(fixdecl($1,$3,LEFT_ASS,$2));}
  531. | INFIXL error {syntaxError("fixity decl");}
  532. | INFIXR optDigit ops {$$ = gc3(fixdecl($1,$3,RIGHT_ASS,$2));}
  533. | INFIXR error {syntaxError("fixity decl");}
  534. | vars COCO topType {$$ = gc3(sigdecl($2,$1,$3));}
  535. | vars COCO error {syntaxError("type signature");}
  536. ;
  537. optDigit : NUMLIT {$$ = gc1(checkPrec($1));}
  538. | /* empty */ {$$ = gc0(mkInt(DEF_PREC));}
  539. ;
  540. ops : ops ',' op {$$ = gc3(cons($3,$1));}
  541. | op {$$ = gc1(singleton($1));}
  542. ;
  543. vars : vars ',' var {$$ = gc3(cons($3,$1));}
  544. | var {$$ = gc1(singleton($1));}
  545. ;
  546. decls : '{' decls0 end {$$ = gc3($2);}
  547. | '{' decls1 end {$$ = gc3($2);}
  548. ;
  549. decls0 : /* empty */ {$$ = gc0(NIL);}
  550. | decls0 ';' {$$ = gc2($1);}
  551. | decls1 ';' {$$ = gc2($1);}
  552. ;
  553. decls1 : decls0 decl {$$ = gc2(cons($2,$1));}
  554. ;
  555. decl : gendecl {$$ = $1;}
  556. | funlhs rhs {$$ = gc2(ap(FUNBIND,pair($1,$2)));}
  557. | funlhs COCO type rhs {$$ = gc4(ap(FUNBIND,
  558. pair($1,ap(RSIGN,
  559. ap($4,$3)))));}
  560. | pat0 rhs {$$ = gc2(ap(PATBIND,pair($1,$2)));}
  561. ;
  562. funlhs : funlhs0 {$$ = $1;}
  563. | funlhs1 {$$ = $1;}
  564. | npk {$$ = $1;}
  565. ;
  566. funlhs0 : pat10_vI varop pat0 {$$ = gc3(ap2($2,$1,$3));}
  567. | infixPat varop pat0 {$$ = gc3(ap2($2,$1,$3));}
  568. | NUMLIT varop pat0 {$$ = gc3(ap2($2,$1,$3));}
  569. | var varop_pl pat0 {$$ = gc3(ap2($2,$1,$3));}
  570. | var '+' pat0_INT {$$ = gc3(ap2(varPlus,$1,$3));}
  571. ;
  572. funlhs1 : '(' funlhs0 ')' apat {$$ = gc4(ap($2,$4));}
  573. | '(' funlhs1 ')' apat {$$ = gc4(ap($2,$4));}
  574. | '(' npk ')' apat {$$ = gc4(ap($2,$4));}
  575. | var apat {$$ = gc2(ap($1,$2));}
  576. | funlhs1 apat {$$ = gc2(ap($1,$2));}
  577. ;
  578. rhs : rhs1 wherePart {$$ = gc2(letrec($2,$1));}
  579. | error {syntaxError("declaration");}
  580. ;
  581. rhs1 : '=' exp {$$ = gc2(pair($1,$2));}
  582. | gdrhs {$$ = gc1(grded(rev($1)));}
  583. ;
  584. gdrhs : gdrhs gddef {$$ = gc2(cons($2,$1));}
  585. | gddef {$$ = gc1(singleton($1));}
  586. ;
  587. gddef : '|' exp0 '=' exp {$$ = gc4(pair($3,pair($2,$4)));}
  588. ;
  589. wherePart : /* empty */ {$$ = gc0(NIL);}
  590. | WHERE decls {$$ = gc2($2);}
  591. ;
  592. /* lwherePart and ldecls permit the binding of both 'normal'
  593. * and implicit parameter bindings.
  594. */
  595. lwherePart : /* empty */ {$$ = gc0(NIL);}
  596. | WHERE ldecls {$$ = gc2($2);}
  597. ;
  598. ldecls : '{' ldecls0 end {$$ = gc3($2);}
  599. | '{' ldecls1 end {$$ = gc3($2);}
  600. ;
  601. ldecls0 : /* empty */ {$$ = gc0(NIL);}
  602. | ldecls0 ';' {$$ = gc2($1);}
  603. | ldecls1 ';' {$$ = gc2($1);}
  604. ;
  605. ldecls1 : ldecls0 ldecl {$$ = gc2(cons($2,$1));}
  606. ;
  607. ldecl : IPVARID '=' exp {
  608. #if IPARAM
  609. $$ = gc3(pair($1,$3));
  610. #else
  611. noIP("a binding");
  612. #endif
  613. }
  614. | IPVARID error {syntaxError("a binding");}
  615. | decl {$$ = $1;}
  616. ;
  617. /*- Patterns: -------------------------------------------------------------*/
  618. pat : npk {$$ = $1;}
  619. | pat_npk {$$ = $1;}
  620. ;
  621. pat_npk : pat0 COCO type {$$ = gc3(ap(ESIGN,pair($1,$3)));}
  622. | pat0 {$$ = $1;}
  623. ;
  624. npk : var '+' NUMLIT {$$ = gc3(ap2(varPlus,$1,$3));}
  625. ;
  626. pat0 : var {$$ = $1;}
  627. | NUMLIT {$$ = $1;}
  628. | pat0_vI {$$ = $1;}
  629. ;
  630. pat0_INT : var {$$ = $1;}
  631. | pat0_vI {$$ = $1;}
  632. ;
  633. pat0_vI : pat10_vI {$$ = $1;}
  634. | infixPat {$$ = gc1(ap(INFIX,$1));}
  635. ;
  636. infixPat : '-' pat10 {$$ = gc2(ap(NEG,only($2)));}
  637. | '-' error {syntaxError("pattern");}
  638. | var qconop pat10 {$$ = gc3(ap(ap($2,only($1)),$3));}
  639. | var qconop '-' pat10 {$$ = gc4(ap(NEG,ap2($2,only($1),$4)));}
  640. | NUMLIT qconop pat10 {$$ = gc3(ap(ap($2,only($1)),$3));}
  641. | NUMLIT qconop '-' pat10 {$$ = gc4(ap(NEG,ap2($2,only($1),$4)));}
  642. | pat10_vI qconop pat10 {$$ = gc3(ap(ap($2,only($1)),$3));}
  643. | pat10_vI qconop '-' pat10 {$$ = gc4(ap(NEG,ap2($2,only($1),$4)));}
  644. | infixPat qconop pat10 {$$ = gc3(ap(ap($2,$1),$3));}
  645. | infixPat qconop '-' pat10 {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
  646. ;
  647. pat10 : fpat {$$ = $1;}
  648. | apat {$$ = $1;}
  649. ;
  650. pat10_vI : fpat {$$ = $1;}
  651. | apat_vI {$$ = $1;}
  652. ;
  653. fpat : fpat apat {$$ = gc2(ap($1,$2));}
  654. | gcon apat {$$ = gc2(ap($1,$2));}
  655. ;
  656. apat : NUMLIT {$$ = $1;}
  657. | var {$$ = $1;}
  658. | apat_vI {$$ = $1;}
  659. ;
  660. apat_vI : var '@' apat {$$ = gc3(ap(ASPAT,pair($1,$3)));}
  661. | gcon {$$ = $1;}
  662. | qcon '{' patbinds '}' {$$ = gc4(ap(CONFLDS,pair($1,$3)));}
  663. | CHARLIT {$$ = $1;}
  664. | STRINGLIT {$$ = $1;}
  665. | '_' {$$ = gc1(WILDCARD);}
  666. | '(' pat_npk ')' {$$ = gc3($2);}
  667. | '(' npk ')' {$$ = gc3($2);}
  668. | '(' pats2 ')' {$$ = gc3(buildTuple($2));}
  669. | '[' pats1 ']' {$$ = gc3(ap(FINLIST,rev($2)));}
  670. | '~' apat {$$ = gc2(ap(LAZYPAT,$2));}
  671. /*#if TREX*/
  672. | '(' patfields ')' {
  673. #if TREX
  674. $$ = gc3(revOnto($2,nameNoRec));
  675. #else
  676. $$ = gc3(NIL);
  677. #endif
  678. }
  679. | '(' patfields '|' pat ')' {$$ = gc5(revOnto($2,$4));}
  680. /*#endif TREX*/
  681. ;
  682. pats2 : pats2 ',' pat {$$ = gc3(cons($3,$1));}
  683. | pat ',' pat {$$ = gc3(cons($3,singleton($1)));}
  684. ;
  685. pats1 : pats1 ',' pat {$$ = gc3(cons($3,$1));}
  686. | pat {$$ = gc1(singleton($1));}
  687. ;
  688. patbinds : /* empty */ {$$ = gc0(NIL);}
  689. | patbinds1 {$$ = gc1(rev($1));}
  690. ;
  691. patbinds1 : patbinds1 ',' patbind {$$ = gc3(cons($3,$1));}
  692. | patbind {$$ = gc1(singleton($1));}
  693. ;
  694. patbind : qvar '=' pat {$$ = gc3(pair($1,$3));}
  695. | var {$$ = $1;}
  696. ;
  697. /*#if TREX*/
  698. patfields : patfields ',' patfield {$$ = gc3(cons($3,$1));}
  699. | patfield {$$ = gc1(singleton($1));}
  700. ;
  701. patfield : varid '=' pat {
  702. #if TREX
  703. $$ = gc3(ap(mkExt(textOf($1)),$3));
  704. #else
  705. noTREX("a pattern");
  706. #endif
  707. }
  708. ;
  709. /*#endif TREX*/
  710. /*- Expressions: ----------------------------------------------------------*/
  711. exp : exp_err {$$ = $1;}
  712. | error {syntaxError("expression");}
  713. ;
  714. exp_err : exp0a COCO sigType {$$ = gc3(ap(ESIGN,pair($1,$3)));}
  715. | exp0 {$$ = $1;}
  716. ;
  717. exp0 : exp0a {$$ = $1;}
  718. | exp0b {$$ = $1;}
  719. ;
  720. exp0a : infixExpa {$$ = gc1(ap(INFIX,$1));}
  721. | exp10a {$$ = $1;}
  722. ;
  723. exp0b : infixExpb {$$ = gc1(ap(INFIX,$1));}
  724. | exp10b {$$ = $1;}
  725. ;
  726. infixExpa : infixExpa qop '-' exp10a {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
  727. | infixExpa qop exp10a {$$ = gc3(ap(ap($2,$1),$3));}
  728. | '-' exp10a {$$ = gc2(ap(NEG,only($2)));}
  729. | exp10a qop '-' exp10a {$$ = gc4(ap(NEG,
  730. ap(ap($2,only($1)),$4)));}
  731. | exp10a qop exp10a {$$ = gc3(ap(ap($2,only($1)),$3));}
  732. ;
  733. infixExpb : infixExpa qop '-' exp10b {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
  734. | infixExpa qop exp10b {$$ = gc3(ap(ap($2,$1),$3));}
  735. | '-' exp10b {$$ = gc2(ap(NEG,only($2)));}
  736. | exp10a qop '-' exp10b {$$ = gc4(ap(NEG,
  737. ap(ap($2,only($1)),$4)));}
  738. | exp10a qop exp10b {$$ = gc3(ap(ap($2,only($1)),$3));}
  739. ;
  740. exp10a : CASEXP exp OF '{' alts end {$$ = gc6(ap(CASE,pair($2,rev($5))));}
  741. | DO '{' stmts end {$$ = gc4(ap(DOCOMP,checkDo($3)));}
  742. | MDO '{' stmts end {
  743. #if MUDO
  744. $$ = gc4(ap(MDOCOMP, checkMDo($3)));
  745. #else
  746. noMDo("an expression");
  747. #endif
  748. }
  749. | appExp {$$ = $1;}
  750. ;
  751. exp10b : '\\' pats ARROW exp {$$ = gc4(ap(LAMBDA,
  752. pair(rev($2),
  753. pair($3,$4))));}
  754. | LET ldecls IN exp {$$ = gc4(letrec($2,$4));}
  755. | IF exp THEN exp ELSE exp {$$ = gc6(ap(COND,triple($2,$4,$6)));}
  756. ;
  757. pats : pats apat {$$ = gc2(cons($2,$1));}
  758. | apat {$$ = gc1(cons($1,NIL));}
  759. ;
  760. appExp : appExp aexp {$$ = gc2(ap($1,$2));}
  761. | aexp {$$ = $1;}
  762. ;
  763. aexp : qvar {$$ = $1;}
  764. | qvar '@' aexp {$$ = gc3(ap(ASPAT,pair($1,$3)));}
  765. | '~' aexp {$$ = gc2(ap(LAZYPAT,$2));}
  766. | IPVARID {$$ = $1;}
  767. | '_' {$$ = gc1(WILDCARD);}
  768. | gcon {$$ = $1;}
  769. | qcon '{' fbinds '}' {$$ = gc4(ap(CONFLDS,pair($1,$3)));}
  770. | aexp '{' fbinds '}' {$$ = gc4(ap(UPDFLDS,
  771. triple($1,NIL,$3)));}
  772. | NUMLIT {$$ = $1;}
  773. | CHARLIT {$$ = $1;}
  774. | STRINGLIT {$$ = $1;}
  775. | REPEAT {$$ = $1;}
  776. | '(' exp ')' {$$ = gc3($2);}
  777. | '(' exps2 ')' {$$ = gc3(buildTuple($2));}
  778. /*#if TREX*/
  779. | '(' vfields ')' {
  780. #if TREX
  781. $$ = gc3(revOnto($2,nameNoRec));
  782. #else
  783. $$ = gc3(NIL);
  784. #endif
  785. }
  786. | '(' vfields '|' exp ')' {$$ = gc5(revOnto($2,$4));}
  787. | RECSELID {$$ = $1;}
  788. /*#endif*/
  789. | '[' list ']' {$$ = gc3($2);}
  790. | '(' exp10a qop ')' {$$ = gc4(ap($3,$2));}
  791. | '(' qvarop_mi exp0 ')' {$$ = gc4(ap(ap(nameFlip,$2),$3));}
  792. | '(' qconop exp0 ')' {$$ = gc4(ap(ap(nameFlip,$2),$3));}
  793. ;
  794. exps2 : exps2 ',' exp {$$ = gc3(cons($3,$1));}
  795. | exp ',' exp {$$ = gc3(cons($3,cons($1,NIL)));}
  796. ;
  797. /*#if TREX*/
  798. vfields : vfields ',' vfield {$$ = gc3(cons($3,$1));}
  799. | vfield {$$ = gc1(singleton($1));}
  800. ;
  801. vfield : varid '=' exp {
  802. #if TREX
  803. $$ = gc3(ap(mkExt(textOf($1)),$3));
  804. #else
  805. noTREX("an expression");
  806. #endif
  807. }
  808. ;
  809. /*#endif*/
  810. alts : alts1 {$$ = $1;}
  811. | ';' alts {$$ = gc2($2);}
  812. ;
  813. alts1 : alts1 ';' alt {$$ = gc3(cons($3,$1));}
  814. | alts1 ';' {$$ = gc2($1);}
  815. | alt {$$ = gc1(cons($1,NIL));}
  816. ;
  817. alt : pat altRhs wherePart {$$ = gc3(pair($1,letrec($3,$2)));}
  818. ;
  819. altRhs : guardAlts {$$ = gc1(grded(rev($1)));}
  820. | ARROW exp {$$ = gc2(pair($1,$2));}
  821. | error {syntaxError("case expression");}
  822. ;
  823. guardAlts : guardAlts guardAlt {$$ = gc2(cons($2,$1));}
  824. | guardAlt {$$ = gc1(cons($1,NIL));}
  825. ;
  826. guardAlt : '|' exp0 ARROW exp {$$ = gc4(pair($3,pair($2,$4)));}
  827. ;
  828. stmts : stmts1 {$$ = $1;}
  829. | ';' stmts {$$ = gc2($2);}
  830. ;
  831. stmts1 : stmts1 ';' stmt {$$ = gc3(cons($3,$1));}
  832. | stmts1 ';' {$$ = gc2($1);}
  833. | stmt {$$ = gc1(cons($1,NIL));}
  834. ;
  835. stmt : exp_err FROM exp {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
  836. | LET ldecls {$$ = gc2(ap(QWHERE,$2));}
  837. /* | IF exp {$$ = gc2(ap(BOOLQUAL,$2));}*/
  838. | exp_err {$$ = gc1(ap(DOQUAL,$1));}
  839. ;
  840. fbinds : /* empty */ {$$ = gc0(NIL);}
  841. | fbinds1 {$$ = gc1(rev($1));}
  842. ;
  843. fbinds1 : fbinds1 ',' fbind {$$ = gc3(cons($3,$1));}
  844. | fbind {$$ = gc1(singleton($1));}
  845. ;
  846. fbind : var {$$ = $1;}
  847. | qvar '=' exp {$$ = gc3(pair($1,$3));}
  848. ;
  849. /*- List Expressions: -------------------------------------------------------*/
  850. list : exp {$$ = gc1(ap(FINLIST,cons($1,NIL)));}
  851. | exps2 {$$ = gc1(ap(FINLIST,rev($1)));}
  852. | exp zipquals {
  853. #if ZIP_COMP
  854. if (length($2)==1) {
  855. $$ = gc2(ap(COMP,pair($1,hd($2))));
  856. } else {
  857. if (haskell98)
  858. syntaxError("list comprehension");
  859. $$ = gc2(ap(ZCOMP,pair($1,rev($2))));
  860. }
  861. #else
  862. if (length($2)!=1) {
  863. syntaxError("list comprehension");
  864. }
  865. $$ = gc2(ap(COMP,pair($1,hd($2))));
  866. #endif
  867. }
  868. | exp UPTO exp {$$ = gc3(ap(ap(nameFromTo,$1),$3));}
  869. | exp ',' exp UPTO {$$ = gc4(ap(ap(nameFromThen,$1),$3));}
  870. | exp UPTO {$$ = gc2(ap(nameFrom,$1));}
  871. | exp ',' exp UPTO exp {$$ = gc5(ap(ap(ap(nameFromThenTo,
  872. $1),$3),$5));}
  873. ;
  874. zipquals : zipquals '|' quals {$$ = gc3(cons(rev($3),$1));}
  875. | '|' quals {$$ = gc2(cons(rev($2),NIL));}
  876. ;
  877. quals : quals ',' qual {$$ = gc3(cons($3,$1));}
  878. | qual {$$ = gc1(cons($1,NIL));}
  879. ;
  880. qual : exp FROM exp {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
  881. | exp {$$ = gc1(ap(BOOLQUAL,$1));}
  882. | LET ldecls {$$ = gc2(ap(QWHERE,$2));}
  883. ;
  884. /*- Identifiers and symbols: ----------------------------------------------*/
  885. gcon : qcon {$$ = $1;}
  886. | '(' ')' {$$ = gc2(nameUnit);}
  887. | '[' ']' {$$ = gc2(nameNil);}
  888. | '(' tupCommas ')' {$$ = gc3($2);}
  889. ;
  890. tupCommas : tupCommas ',' {$$ = gc2(mkTuple(tupleOf($1)+1));}
  891. | ',' {$$ = gc1(mkTuple(2));}
  892. ;
  893. varid : VARID {$$ = $1;}
  894. | HIDING {$$ = gc1(varHiding);}
  895. | QUALIFIED {$$ = gc1(varQualified);}
  896. | ASMOD {$$ = gc1(varAsMod);}
  897. ;
  898. qconid : QCONID {$$ = $1;}
  899. | CONID {$$ = $1;}
  900. ;
  901. var : varid {$$ = $1;}
  902. | '(' VAROP ')' {$$ = gc3($2);}
  903. | '(' '+' ')' {$$ = gc3(varPlus);}
  904. | '(' '-' ')' {$$ = gc3(varMinus);}
  905. | '(' '!' ')' {$$ = gc3(varBang);}
  906. | '(' '.' ')' {$$ = gc3(varDot);}
  907. ;
  908. qvar : QVARID {$$ = $1;}
  909. | '(' QVAROP ')' {$$ = gc3($2);}
  910. | var {$$ = $1;}
  911. ;
  912. con : CONID {$$ = $1;}
  913. | '(' CONOP ')' {$$ = gc3($2);}
  914. ;
  915. qcon : QCONID {$$ = $1;}
  916. | '(' QCONOP ')' {$$ = gc3($2);}
  917. | con {$$ = $1;}
  918. ;
  919. varop : '+' {$$ = gc1(varPlus);}
  920. | '-' {$$ = gc1(varMinus);}
  921. | varop_mipl {$$ = $1;}
  922. ;
  923. varop_mi : '+' {$$ = gc1(varPlus);}
  924. | varop_mipl {$$ = $1;}
  925. ;
  926. varop_pl : '-' {$$ = gc1(varMinus);}
  927. | varop_mipl {$$ = $1;}
  928. ;
  929. varop_mipl: VAROP {$$ = $1;}
  930. | '`' varid '`' {$$ = gc3($2);}
  931. | '!' {$$ = gc1(varBang);}
  932. | '.' {$$ = gc1(varDot);}
  933. ;
  934. qvarop : '-' {$$ = gc1(varMinus);}
  935. | qvarop_mi {$$ = $1;}
  936. ;
  937. qvarop_mi : QVAROP {$$ = $1;}
  938. | '`' QVARID '`' {$$ = gc3($2);}
  939. | varop_mi {$$ = $1;}
  940. ;
  941. conop : CONOP {$$ = $1;}
  942. | '`' CONID '`' {$$ = gc3($2);}
  943. ;
  944. qconop : QCONOP {$$ = $1;}
  945. | '`' QCONID '`' {$$ = gc3($2);}
  946. | conop {$$ = $1;}
  947. ;
  948. op : varop {$$ = $1;}
  949. | conop {$$ = $1;}
  950. ;
  951. qop : qvarop {$$ = $1;}
  952. | qconop {$$ = $1;}
  953. ;
  954. /*- Tricks to force insertion of leading and closing braces ---------------*/
  955. begin : /* empty */ {goOffside(startColumn);}
  956. ;
  957. /* deal with trailing semicolon */
  958. end : '}' {$$ = $1;}
  959. | error {yyerrok;
  960. if (canUnOffside()) {
  961. unOffside();
  962. /* insert extra token on stack*/
  963. push(NIL);
  964. pushed(0) = pushed(1);
  965. pushed(1) = mkInt(column);
  966. }
  967. else
  968. syntaxError("definition");
  969. }
  970. ;
  971. /*-------------------------------------------------------------------------*/
  972. %%
  973. static Cell local gcShadow(n,e) /* keep parsed fragments on stack */
  974. Int n;
  975. Cell e; {
  976. /* If a look ahead token is held then the required stack transformation
  977. * is:
  978. * pushed: n 1 0 1 0
  979. * x1 | ... | xn | la ===> e | la
  980. * top() top()
  981. *
  982. * Othwerwise, the transformation is:
  983. * pushed: n-1 0 0
  984. * x1 | ... | xn ===> e
  985. * top() top()
  986. */
  987. if (yychar>=0) {
  988. pushed(n-1) = top();
  989. pushed(n) = e;
  990. }
  991. else
  992. pushed(n-1) = e;
  993. sp -= (n-1);
  994. return e;
  995. }
  996. static Void local syntaxError(s) /* report on syntax error */
  997. String s; {
  998. ERRMSG(row) "Syntax error in %s (unexpected %s)", s, unexpected()
  999. EEND;
  1000. }
  1001. static String local unexpected() { /* find name for unexpected token */
  1002. static char buffer[100];
  1003. static char *fmt = "%s \"%s\"";
  1004. static char *kwd = "keyword";
  1005. switch (yychar) {
  1006. case 0 : return "end of input";
  1007. #define keyword(kw) sprintf(buffer,fmt,kwd,kw); return buffer;
  1008. case INFIXL : keyword("infixl");
  1009. case INFIXR : keyword("infixr");
  1010. case INFIXN : keyword("infix");
  1011. case TINSTANCE : keyword("instance");
  1012. case TCLASS : keyword("class");
  1013. case PRIMITIVE : keyword("primitive");
  1014. case CASEXP : keyword("case");
  1015. case OF : keyword("of");
  1016. case IF : keyword("if");
  1017. case THEN : keyword("then");
  1018. case ELSE : keyword("else");
  1019. case WHERE : keyword("where");
  1020. case TYPE : keyword("type");
  1021. case DATA : keyword("data");
  1022. case TNEWTYPE : keyword("newtype");
  1023. case LET : keyword("let");
  1024. case IN : keyword("in");
  1025. case DERIVING : keyword("deriving");
  1026. case DEFAULT : keyword("default");
  1027. case IMPORT : keyword("import");
  1028. case TMODULE : keyword("module");
  1029. case ALL : keyword("forall");
  1030. #undef keyword
  1031. case ARROW : return "`->'";
  1032. case '=' : return "`='";
  1033. case COCO : return "`::'";
  1034. case '-' : return "`-'";
  1035. case '!' : return "`!'";
  1036. case ',' : return "comma";
  1037. case '@' : return "`@'";
  1038. case '(' : return "`('";
  1039. case ')' : return "`)'";
  1040. case '{' : return "`{', possibly due to bad layout";
  1041. case '}' : return "`}', possibly due to bad layout";
  1042. case '_' : return "`_'";
  1043. case '|' : return "`|'";
  1044. case '.' : return "`.'";
  1045. case ';' : return "`;', possibly due to bad layout";
  1046. case UPTO : return "`..'";
  1047. case '[' : return "`['";
  1048. case ']' : return "`]'";
  1049. case FROM : return "`<-'";
  1050. case '\\' : return "backslash (lambda)";
  1051. case '~' : return "tilde";
  1052. case '`' : return "backquote";
  1053. #if TREX
  1054. case RECSELID : sprintf(buffer,"selector \"#%s\"",
  1055. textToStr(extText(snd(yylval))));
  1056. return buffer;
  1057. #endif
  1058. #if IPARAM
  1059. case IPVARID : sprintf(buffer,"implicit parameter \"?%s\"",
  1060. textToStr(textOf(yylval)));
  1061. return buffer;
  1062. #endif
  1063. case VAROP :
  1064. case VARID :
  1065. case CONOP :
  1066. case CONID : sprintf(buffer,"symbol \"%s\"",
  1067. textToStr(textOf(yylval)));
  1068. return buffer;
  1069. case QVAROP :
  1070. case QVARID :
  1071. case QCONOP :
  1072. case QCONID : sprintf(buffer,"symbol \"%s\"",
  1073. identToStr(yylval));
  1074. return buffer;
  1075. case HIDING : return "symbol \"hiding\"";
  1076. case QUALIFIED : return "symbol \"qualified\"";
  1077. case ASMOD : return "symbol \"as\"";
  1078. case NUMLIT : return "numeric literal";
  1079. case CHARLIT : return "character literal";
  1080. case STRINGLIT : return "string literal";
  1081. case IMPLIES : return "`=>'";
  1082. default : return "token";
  1083. }
  1084. }
  1085. static Cell local checkPrec(p) /* Check for valid precedence value*/
  1086. Cell p; {
  1087. if (!isInt(p) || intOf(p)<MIN_PREC || intOf(p)>MAX_PREC) {
  1088. ERRMSG(row) "Precedence value must be an integer in the range [%d..%d]",
  1089. MIN_PREC, MAX_PREC
  1090. EEND;
  1091. }
  1092. return p;
  1093. }
  1094. static Cell local buildTuple(tup) /* build tuple (x1,...,xn) from */
  1095. List tup; { /* list [xn,...,x1] */
  1096. Int n = 0;
  1097. Cell t = tup;
  1098. Cell x;
  1099. do { /* . . */
  1100. x = fst(t); /* / \ / \ */
  1101. fst(t) = snd(t); /* xn . . xn */
  1102. snd(t) = x; /* . ===> . */
  1103. x = t; /* . . */
  1104. t = fun(x); /* . . */
  1105. n++; /* / \ / \ */
  1106. } while (nonNull(t)); /* x1 NIL (n) x1 */
  1107. fst(x) = mkTuple(n);
  1108. return tup;
  1109. }
  1110. static List local checkCtxt(con) /* validate context */
  1111. Type con; {
  1112. mapOver(checkPred, con);
  1113. return con;
  1114. }
  1115. static Cell local checkPred(c) /* check that type expr is a valid */
  1116. Cell c; { /* constraint */
  1117. Cell cn = getHead(c);
  1118. #if TREX
  1119. if (isExt(cn) && argCount==1)
  1120. return c;
  1121. #endif
  1122. #if IPARAM
  1123. if (isIP(cn))
  1124. return c;
  1125. #endif
  1126. if (!isQCon(cn) /*|| argCount==0*/)
  1127. syntaxError("class expression");
  1128. return c;
  1129. }
  1130. static Pair local checkDo(dqs) /* convert reversed list of dquals */
  1131. List dqs; { /* to an (expr,quals) pair */
  1132. if (isNull(dqs) || whatIs(hd(dqs))!=DOQUAL) {
  1133. ERRMSG(row) "Last generator in do {...} must be an expression"
  1134. EEND;
  1135. }
  1136. fst(dqs) = snd(fst(dqs)); /* put expression in fst of pair */
  1137. snd(dqs) = rev(snd(dqs)); /* & reversed list of quals in snd */
  1138. return dqs;
  1139. }
  1140. #if MUDO
  1141. static Pair local checkMDo(dqs) /* convert reversed list of dquals */
  1142. List dqs; { /* to an (expr,quals) pair */
  1143. if (isNull(dqs) || whatIs(hd(dqs))!=DOQUAL) {
  1144. ERRMSG(row) "Last generator in mdo {...} must be an expression"
  1145. EEND;
  1146. }
  1147. fst(dqs) = snd(fst(dqs)); /* put expression in fst of pair */
  1148. snd(dqs) = rev(snd(dqs)); /* & reversed list of quals in snd */
  1149. return dqs;
  1150. }
  1151. #endif
  1152. static Cell local checkTyLhs(c) /* check that lhs is of the form */
  1153. Cell c; { /* T a1 ... a */
  1154. Cell tlhs = c;
  1155. while (isAp(tlhs) && whatIs(arg(tlhs))==VARIDCELL) {
  1156. tlhs = fun(tlhs);
  1157. }
  1158. if (whatIs(tlhs)!=CONIDCELL) {
  1159. ERRMSG(row) "Illegal left hand side in datatype definition"
  1160. EEND;
  1161. }
  1162. return c;
  1163. }
  1164. #if !TREX
  1165. static Void local noTREX(where)
  1166. String where; {
  1167. ERRMSG(row) "Attempt to use TREX records while parsing %s.\n", where ETHEN
  1168. ERRTEXT "(TREX is disabled in this build of Hugs)"
  1169. EEND;
  1170. }
  1171. #endif
  1172. #if !IPARAM
  1173. static Void local noIP(where)
  1174. String where; {
  1175. ERRMSG(row) "Attempt to use Implicit Parameters while parsing %s.\n", where ETHEN
  1176. ERRTEXT "(Implicit Parameters are disabled in this build of Hugs)"
  1177. EEND;
  1178. }
  1179. #endif
  1180. #if !MUDO
  1181. /***
  1182. Due to the way we implement this stuff, this function will actually
  1183. never be called. When MUDO is not defined, the lexer thinks that mdo
  1184. is just another identifier, and hence the MDO token is never returned
  1185. to the parser: consequently the mdo production is never reduced, making
  1186. this code unreachable. The alternative is to let the lexer to
  1187. recognize "mdo" all the time, but that's not Haskell compliant. In any
  1188. case we keep this function here, even if just for documentation purposes.
  1189. ***/
  1190. static Void local noMDo(where)
  1191. String where; {
  1192. ERRMSG(row) "Attempt to use MDO while parsing %s.\n", where ETHEN
  1193. ERRTEXT "(Recursive monadic bindings are disabled in this build of Hugs)"
  1194. EEND;
  1195. }
  1196. #endif
  1197. /*-------------------------------------------------------------------------*/