Diff
Not logged in

Differences From Artifact [71d187282fb3ce05]:

To Artifact [2e1caca9f119fc4c]:


8 8 import polemy._common; 9 9 import polemy.failure; 10 10 import polemy.lex; 11 11 import polemy.ast; 12 12 import polemy.layer; 13 13 14 14 /// Parse a string and return its AST 15 -/// Throws: ParseException, LexException, UnexpectedEOF 16 15 17 16 AST parseString(S, T...)(S str, T fn_ln_cn) 18 17 { 19 18 return parserFromString(str, fn_ln_cn).parse(); 20 19 } 21 20 22 21 /// Parse the content of a file and return its AST 23 -/// Throws: ParseException, LexException, UnexpectedEOF 24 22 25 23 AST parseFile(S, T...)(S filename, T ln_cn) 26 24 { 27 25 return parserFromFile(filename, ln_cn).parse(); 28 26 } 29 27 30 28 // Named Constructors of Parser ................................................................................ 71 69 /// Declaration ::= 72 70 /// ["@" Layer|"let"|"var"|"def"] Var "=" Expression ([";"|"in"] Body?)? 73 71 /// | ["@" Layer|"let"|"var"|"def"] Var "(" Param%"," ")" "{" Body "}" ([";"|"in"] Body?)? 74 72 /// | ["@" "@" Layer "=" Expression ([";"|"in"] Body?)? 75 73 /// | ["@" "@" Layer "(" Param%"," ")" "{" Body "}" ([";"|"in"] Body?)? 76 74 77 75 auto pos = currentPosition(); 78 - string layer = ""; 79 - bool layerRiseDecl = false; 76 + Layer layer = ""; 77 + bool layerLiftDecl = false; 80 78 81 79 if( tryEat("@") ) 82 80 { 83 81 layer = "@" ~ eatId("after @", AllowQuoted); 84 82 if( layer == "@@" ) 85 83 { 86 84 layer = "@" ~ eatId("after @@", AllowQuoted); 87 - layerRiseDecl = true; 85 + layerLiftDecl = true; 88 86 } 89 87 else 90 88 { 91 89 if( tryEat("(") ) 92 90 return null; // @lay(...) expression, not a declaration 93 91 } 94 92 } 95 93 96 94 // [TODO] Refactor 97 - if( layerRiseDecl ) 95 + if( layerLiftDecl ) 98 96 { 99 97 string kwd = "@" ~ layer; 100 98 string var = layer; 101 99 102 100 auto e = tryEat("(") 103 101 ? parseLambdaAfterOpenParen(pos) // let var ( ... 104 102 : (eat("=", "after "~kwd), E(0)); // let var = ... 105 103 if( moreDeclarationExists() ) 106 104 return new LetExpression(pos, var, SystemLayer, e, Body()); 107 105 else 108 - return new LetExpression(pos, var, SystemLayer, e, new VarExpression(pos, var)); 106 + return new LetExpression(pos, var, SystemLayer, e, 107 + new LayeredExpression(pos, SystemLayer, new VarExpression(pos, var)) 108 + ); 109 109 } 110 110 else 111 111 { 112 112 string kwd = layer; 113 113 if( layer.empty && !tryEat(kwd="let") && !tryEat(kwd="var") && !tryEat(kwd="def") ) 114 114 return null; // none of {@lay, let, var, def} occurred, it's not a declaration 115 115 ................................................................................ 389 389 throw genex!ParseException(currentPosition(), "identifier is expected but not found "~msg); 390 390 scope(exit) lex.popFront; 391 391 return lex.front.str; 392 392 } 393 393 394 394 AST doNothingExpression() 395 395 { 396 - return new IntLiteral(currentPosition(), BigInt(178)); 396 + return new StrLiteral(currentPosition(), "(empty function body)"); 397 397 } 398 398 399 399 immutable(LexPosition) currentPosition() 400 400 { 401 401 return lex.empty ? null : lex.front.pos; 402 402 } 403 403 } ................................................................................ 416 416 assert_eq(parseString(`1;2;`), let("_","",intl(1),intl(2))); 417 417 assert_eq(parseString(`let x=1 in 2`), let("x","",intl(1),intl(2))); 418 418 assert_eq(parseString(`var x=1;2;`), let("x","",intl(1),intl(2))); 419 419 assert_eq(parseString(`def x=1`), let("x","",intl(1),var("x"))); 420 420 assert_eq(parseString(`@val x=1;`), let("x","@val",intl(1),var("x"))); 421 421 assert_eq(parseString(`@typ x="#int";`), let("x","@typ",strl("#int"),var("x"))); 422 422 assert_eq(parseString(`f(1,2)`), call(var("f"),intl(1),intl(2))); 423 - assert_eq(parseString(`if(1){2}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(178)))); 423 + assert_eq(parseString(`if(1){2}`), call(var("if"),intl(1),fun([],intl(2)),fun([],strl("(empty function body)")))); 424 424 assert_eq(parseString(`if(1){2}else{3}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(3)))); 425 425 assert_eq(parseString(`if(1){}else{3}()()`), 426 - call(call(call(var("if"),intl(1),fun([],intl(178)),fun([],intl(3)))))); 426 + call(call(call(var("if"),intl(1),fun([],strl("(empty function body)")),fun([],intl(3)))))); 427 427 assert_eq(parseString(`1+2*3`), call(var("+"),intl(1),call(var("*"),intl(2),intl(3)))); 428 428 assert_eq(parseString(`(1+2)*3`), call(var("*"),call(var("+"),intl(1),intl(2)),intl(3))); 429 429 assert_eq(parseString(`1*(2+3)`), call(var("*"),intl(1),call(var("+"),intl(2),intl(3)))); 430 430 assert_eq(parseString(`1*2+3`), call(var("+"),call(var("*"),intl(1),intl(2)),intl(3))); 431 431 assert_eq(parseString(`@x(1)`), lay("@x", intl(1))); 432 432 assert_eq(parseString(`fun(x @v @t, y, z @t){}`), 433 - funp([param("x",["@v","@t"]), param("y",[]), param("z",["@t"])], intl(178))); 433 + funp([param("x",["@v","@t"]), param("y",[]), param("z",["@t"])], strl("(empty function body)"))); 434 434 435 435 assert_eq(parseString(` 436 436 let x = 100; #comment 437 437 let y = 200; #comment!!!!! 438 438 x+y 439 439 `), 440 440 let("x", "", intl(100), let("y", "", intl(200), call(var("+"), var("x"), var("y")))) ................................................................................ 472 472 assert_eq(parseString(`def foo(x) { x+1 }; foo`), 473 473 let("foo", "", 474 474 fun(["x"], call(var("+"), var("x"), intl(1))), 475 475 var("foo")) 476 476 ); 477 477 478 478 assert_eq(parseString(`@@type ( x ) { x }`), 479 - let("@type", SystemLayer, fun(["x"], var("x")), var("@type")) ); 479 + let("@type", SystemLayer, fun(["x"], var("x")), lay(SystemLayer, var("@type"))) ); 480 480 481 481 assert_eq(parseString(`{}`), call(var("{}"))); 482 482 assert_eq(parseString(`{foo:1,"bar":2}`), 483 483 call(var(".="), call(var(".="), call(var("{}")), strl("foo"), intl(1)), strl("bar"), intl(2))); 484 484 assert_eq(parseString(`{}.foo`), call(var("."),call(var("{}")),strl("foo"))); 485 485 assert_eq(parseString(`{}.?foo`), call(var(".?"),call(var("{}")),strl("foo"))); 486 486 assert_eq(parseString(`x{y:1}`), call(var(".="),var("x"),strl("y"),intl(1))); 487 487 }