Differences From Artifact [789e91a27a62e096]:
- File
polemy/parse.d
- 2010-11-21 14:24:33 - part of checkin [3995a5eb6a] on branch trunk - added iikagen pattern match (user: kinaba) [annotate]
To Artifact [9df8a8a07696ff22]:
- File
polemy/parse.d
- 2010-11-23 07:42:13 - part of checkin [6ac127ddd0] on branch trunk - new evaluator (user: kinaba) [annotate]
98 98 string kwd = "@" ~ layer;
99 99 string var = layer;
100 100
101 101 auto e = tryEat("(")
102 102 ? parseLambdaAfterOpenParen(pos) // let var ( ...
103 103 : (eat("=", "after "~kwd), E(0)); // let var = ...
104 104 if( moreDeclarationExists() )
105 - return new LetExpression(pos, var, SystemLayer, e, Body());
105 + return new Let(pos, var, SystemLayer, e, Body());
106 106 else
107 - return new LetExpression(pos, var, SystemLayer, e,
108 - new LayExpression(pos, SystemLayer, new VarExpression(pos, var))
107 + return new Let(pos, var, SystemLayer, e,
108 + new Lay(pos, SystemLayer, new Var(pos, var))
109 109 );
110 110 }
111 111 else
112 112 {
113 113 string kwd = layer;
114 114 if( layer.empty && !tryEat(kwd="let") && !tryEat(kwd="var") && !tryEat(kwd="def") )
115 115 return null; // none of {@lay, let, var, def} occurred, it's not a declaration
................................................................................
117 117 auto varpos = currentPosition();
118 118 string var = eatId("after "~kwd, AllowQuoted); // name of the declared variable
119 119
120 120 auto e = tryEat("(")
121 121 ? parseLambdaAfterOpenParen(varpos) // let var ( ...
122 122 : (eat("=", "after "~kwd), E(0)); // let var = ...
123 123 if( moreDeclarationExists() )
124 - return new LetExpression(pos, var, layer, e, Body());
124 + return new Let(pos, var, layer, e, Body());
125 125 else
126 - return new LetExpression(pos, var, layer, e, new VarExpression(varpos, var));
126 + return new Let(pos, var, layer, e, new Var(varpos, var));
127 127 }
128 128 }
129 129
130 130 AST TopLevelExpression()
131 131 {
132 132 /// TopLevelExpression ::= Expression ([";"|"in"] Body?)?
133 133
134 134 auto pos = currentPosition();
135 135 auto e = E(0);
136 136 if( moreDeclarationExists() )
137 - return new LetExpression(pos, "_", "", e, Body());
137 + return new Let(pos, "_", "", e, Body());
138 138 else
139 139 return e;
140 140 }
141 141
142 142 private bool moreDeclarationExists()
143 143 {
144 144 return (tryEat(";") || tryEat("in")) && !closingBracket();
................................................................................
177 177 return lhs;
178 178
179 179 auto pos = currentPosition();
180 180 foreach(op; operator_perferences[level])
181 181 if( tryEat(op) )
182 182 if( op[0]=='.' )
183 183 return rec(
184 - new FuncallExpression(lhs.pos, new VarExpression(pos, op), lhs, parseId()));
184 + new App(lhs.pos, new Var(pos, op), lhs, parseId()));
185 185 else
186 - return rec(
187 - new FuncallExpression(lhs.pos, new VarExpression(pos, op), lhs, E(level+1)));
186 + return rec(
187 + new App(lhs.pos, new Var(pos, op), lhs, E(level+1)));
188 188 return lhs;
189 189 }
190 190
191 191 if( operator_perferences.length <= level )
192 192 return Funcall();
193 193 else
194 194 return rec(E(level+1));
................................................................................
209 209 throw genex!UnexpectedEOF(pos, "closing ')' for arguments not found");
210 210 args ~= E(0);
211 211 if( !tryEat(",") ) {
212 212 eat(")", "after function parameters");
213 213 break;
214 214 }
215 215 }
216 - e = new FuncallExpression(e.pos, e, args);
216 + e = new App(e.pos, e, args);
217 217 }
218 218 else if( tryEat("{") )
219 219 {
220 220 e = parseTableSetAfterBrace(e);
221 221 }
222 222 else
223 223 break;
................................................................................
230 230 return e;
231 231 auto pos = currentPosition();
232 232 for(;;)
233 233 {
234 234 string key = eatId("for table key", AllowQuoted);
235 235 eat(":", "after table key");
236 236 AST val = E(0);
237 - e = new FuncallExpression(pos, new VarExpression(pos,".="),
238 - e, new StrLiteral(pos,key), val);
237 + e = new App(pos, new Var(pos,".="),
238 + e, new Str(pos,key), val);
239 239 if( !tryEat(",") )
240 240 {
241 241 eat("}", "for the end of table literal");
242 242 break;
243 243 }
244 244 }
245 245 return e;
................................................................................
250 250 if( lex.empty )
251 251 throw genex!UnexpectedEOF(currentPosition(), "Reached EOF when tried to parse an expression");
252 252
253 253 auto pos = lex.front.pos;
254 254 if( lex.front.quoted )
255 255 {
256 256 scope(exit) lex.popFront;
257 - return new StrLiteral(pos, lex.front.str);
257 + return new Str(pos, lex.front.str);
258 258 }
259 259 if( isNumber(lex.front.str) )
260 260 {
261 261 scope(exit) lex.popFront;
262 - return new IntLiteral(pos, BigInt(cast(string)lex.front.str));
262 + return new Int(pos, BigInt(cast(string)lex.front.str));
263 263 }
264 264 if( tryEat("@") )
265 265 {
266 266 auto lay = "@"~eatId("for layer ID");
267 267 eat("(", "for layered execution");
268 268 auto e = Body();
269 269 eat(")", "after "~lay~"(...");
270 - return new LayExpression(pos, lay, e);
270 + return new Lay(pos, lay, e);
271 271 }
272 272 if( tryEat("(") )
273 273 {
274 274 auto e = Body();
275 275 eat(")", "after parenthesized expression");
276 276 return e;
277 277 }
278 278 if( tryEat("{") )
279 279 {
280 - AST e = new FuncallExpression(pos, new VarExpression(pos,"{}"));
280 + AST e = new App(pos, new Var(pos,"{}"));
281 281 return parseTableSetAfterBrace(e);
282 282 }
283 283 if( tryEat("if") )
284 284 {
285 285 eat("(", "after if");
286 286 auto cond = E(0);
287 287 eat(")", "after if condition");
................................................................................
292 292 auto el = doNothingExpression();
293 293 auto elsePos = (lex.empty ? LexPosition.dummy : lex.front.pos);
294 294 if( tryEat("else") ) {
295 295 eat("{", "after else");
296 296 el = Body();
297 297 eat("}", "after else body");
298 298 }
299 - return new FuncallExpression(pos,
300 - new VarExpression(pos, "if"),
299 + return new App(pos,
300 + new Var(pos, "if"),
301 301 cond,
302 - new FunLiteral(thenPos, [], th),
303 - new FunLiteral(elsePos, [], el)
302 + new Fun(thenPos, [], th),
303 + new Fun(elsePos, [], el)
304 304 );
305 305 }
306 306 if( tryEat("case") )
307 307 {
308 308 return parsePatternMatch(pos);
309 309 }
310 310 if( tryEat("fun") || tryEat("\u03BB") ) // lambda!!
311 311 {
312 312 eat("(", "after fun");
313 313 return parseLambdaAfterOpenParen(pos);
314 314 }
315 315 scope(exit) lex.popFront;
316 - return new VarExpression(pos, lex.front.str);
316 + return new Var(pos, lex.front.str);
317 317 }
318 318
319 319 AST parsePatternMatch(LexPosition pos)
320 320 {
321 321 // case( pmExpr )cases
322 322 //==>
323 323 // let pmVar = pmExpr in (... let pmTryFirst = ... in pmTryFirst())
324 324 eat("(", "after case");
325 325 AST pmExpr = E(0);
326 326 eat(")", "after case");
327 327 string pmVar = freshVarName();
328 328 string pmTryFirst = freshVarName();
329 329 AST pmBody = parsePatternMatchCases(pmVar, pmTryFirst,
330 - new FuncallExpression(pos, new VarExpression(pos, pmTryFirst)));
331 - return new LetExpression(pos, pmVar, [], pmExpr, pmBody);
330 + new App(pos, new Var(pos, pmTryFirst)));
331 + return new Let(pos, pmVar, [], pmExpr, pmBody);
332 332 }
333 333
334 334 AST parsePatternMatchCases(string pmVar, string tryThisBranchVar, AST thenDoThis)
335 335 {
336 336 // when( pat ) { cBody }
337 337 //==>
338 338 // ... let failBranchVar = ... in
................................................................................
343 343 string failBranchVar = freshVarName();
344 344
345 345 eat("(", "after when");
346 346 auto pr = parsePattern();
347 347 eat(")", "after when");
348 348 eat("{", "after pattern");
349 349 AST cBody = Body();
350 - AST judgement = new FuncallExpression(pos, new VarExpression(pos, "if"),
351 - ppTest(pmVar, pr), new FunLiteral(pos,[],ppBind(pmVar, pr, cBody)),
352 - new VarExpression(pos, failBranchVar));
350 + AST judgement = new App(pos, new Var(pos, "if"),
351 + ppTest(pmVar, pr), new Fun(pos,[],ppBind(pmVar, pr, cBody)),
352 + new Var(pos, failBranchVar));
353 353 eat("}", "after pattern clause");
354 354 return parsePatternMatchCases(pmVar, failBranchVar,
355 - new LetExpression(pos, tryThisBranchVar, [],
356 - new FunLiteral(pos,[],judgement), thenDoThis)
355 + new Let(pos, tryThisBranchVar, [],
356 + new Fun(pos,[],judgement), thenDoThis)
357 357 );
358 358 }
359 359 else
360 360 {
361 361 auto pos = currentPosition();
362 - AST doNothing = new FunLiteral(pos,[],
363 - new StrLiteral(pos, sprintf!"(pattern match failure:%s)"(pos)));
364 - return new LetExpression(currentPosition(), tryThisBranchVar, [], doNothing, thenDoThis);
362 + AST doNothing = new Fun(pos,[],
363 + new Str(pos, sprintf!"(pattern match failure:%s)"(pos)));
364 + return new Let(currentPosition(), tryThisBranchVar, [], doNothing, thenDoThis);
365 365 }
366 366 }
367 367
368 368 // hageshiku tenuki
369 369 abstract class SinglePattern
370 370 {
371 371 string[] path;
372 372 mixin SimpleClass;
373 373 private AST access(string pmVar, string[] path) {
374 374 auto pos = currentPosition();
375 - AST e = new VarExpression(pos, pmVar);
375 + AST e = new Var(pos, pmVar);
376 376 foreach(p; path)
377 - e = new FuncallExpression(pos, new VarExpression(pos, "."), e, new StrLiteral(pos, p));
377 + e = new App(pos, new Var(pos, "."), e, new Str(pos, p));
378 378 return e;
379 379 }
380 380 private AST has(AST e, string k) {
381 381 auto pos = currentPosition();
382 382 return opAndAnd(
383 - new FuncallExpression(pos, new VarExpression(pos, "_istable"), e),
384 - new FuncallExpression(pos, new VarExpression(pos, ".?"), e, new StrLiteral(pos, k))
383 + new App(pos, new Var(pos, "_istable"), e),
384 + new App(pos, new Var(pos, ".?"), e, new Str(pos, k))
385 385 );
386 386 }
387 387 private AST opAndAnd(AST a, AST b) {
388 388 if( a is null ) return b;
389 389 if( b is null ) return a;
390 390 auto pos = currentPosition();
391 - return new FuncallExpression(pos,
392 - new VarExpression(pos, "if"),
391 + return new App(pos,
392 + new Var(pos, "if"),
393 393 a,
394 - new FunLiteral(pos, [], b),
395 - new FunLiteral(pos, [], new IntLiteral(pos, 0))
394 + new Fun(pos, [], b),
395 + new Fun(pos, [], new Int(pos, 0))
396 396 );
397 397 }
398 398 AST ppTest(string pmVar) {
399 399 AST c = null;
400 400 for(int i=0; i<path.length; ++i)
401 401 c = opAndAnd(c, has(access(pmVar,path[0..i]), path[i]));
402 402 return c;
................................................................................
409 409 }
410 410 class VarPattern : SinglePattern
411 411 {
412 412 string name;
413 413 mixin SimpleClass;
414 414 AST ppBind(string pmVar, AST thenDoThis) {
415 415 auto pos = currentPosition();
416 - return new LetExpression(pos, name, [], access(pmVar,path), thenDoThis);
416 + return new Let(pos, name, [], access(pmVar,path), thenDoThis);
417 417 }
418 418 }
419 419 class ConstantPattern : SinglePattern
420 420 {
421 421 AST e;
422 422 mixin SimpleClass;
423 423 AST ppTest(string pmVar) {
424 424 auto pos = currentPosition();
425 425 return opAndAnd( super.ppTest(pmVar),
426 - new FuncallExpression(pos, new VarExpression(pos,"=="), access(pmVar,path), e)
426 + new App(pos, new Var(pos,"=="), access(pmVar,path), e)
427 427 );
428 428 }
429 429 }
430 430
431 431 SinglePattern[] parsePattern(string[] path = null)
432 432 {
433 433 SinglePattern[] result;
................................................................................
441 441 } while( tryEat(",") );
442 442 eat("}", "at the end of table pattern");
443 443 }
444 444 }
445 445 else
446 446 {
447 447 AST e = E(0);
448 - if(auto ev = cast(VarExpression)e)
448 + if(auto ev = cast(Var)e)
449 449 if(ev.name == "_")
450 450 result ~= new WildPattern(path);
451 451 else
452 452 result ~= new VarPattern(path, ev.name);
453 453 else
454 454 result ~= new ConstantPattern(path, e);
455 455 }
................................................................................
460 460 {
461 461 auto pos = currentPosition();
462 462 AST cond = null;
463 463 foreach(p; pats) {
464 464 AST c2 = p.ppTest(pmVar);
465 465 if( c2 !is null )
466 466 cond = cond is null ? c2
467 - : new FuncallExpression(pos, new VarExpression(pos,"&&"), cond, c2);
467 + : new App(pos, new Var(pos,"&&"), cond, c2);
468 468 }
469 - return cond is null ? new IntLiteral(currentPosition(), 1) : cond;
469 + return cond is null ? new Int(currentPosition(), 1) : cond;
470 470 }
471 471
472 472 AST ppBind(string pmVar, SinglePattern[] pats, AST thenDoThis)
473 473 {
474 474 foreach(p; pats)
475 475 thenDoThis = p.ppBind(pmVar, thenDoThis);
476 476 return thenDoThis;
477 477 }
478 478
479 479 AST parseId()
480 480 {
481 481 scope(exit) lex.popFront;
482 - return new StrLiteral(currentPosition(), lex.front.str);
482 + return new Str(currentPosition(), lex.front.str);
483 483 }
484 484
485 485 AST parseLambdaAfterOpenParen(immutable LexPosition pos)
486 486 {
487 487 Parameter[] params;
488 488 while( !tryEat(")") )
489 489 {
................................................................................
492 492 eat(")", "after function parameters");
493 493 break;
494 494 }
495 495 }
496 496 eat("{", "after function parameters");
497 497 auto funbody = Body();
498 498 eat("}", "after function body");
499 - return new FunLiteral(pos, params, funbody);
499 + return new Fun(pos, params, funbody);
500 500 }
501 501
502 502 Parameter parseParam()
503 503 {
504 504 string var;
505 505 string[] lay;
506 506 while( !closingBracket() && !lex.empty && lex.front.str!="," )
................................................................................
554 554 throw genex!ParseException(currentPosition(), "identifier is expected but not found "~msg);
555 555 scope(exit) lex.popFront;
556 556 return lex.front.str;
557 557 }
558 558
559 559 AST doNothingExpression()
560 560 {
561 - return new StrLiteral(currentPosition(), "(empty function body)");
561 + return new Str(currentPosition(), "(empty function body)");
562 562 }
563 563
564 564 immutable(LexPosition) currentPosition()
565 565 {
566 566 return lex.empty ? null : lex.front.pos;
567 567 }
568 568 }