Diff
Not logged in

Differences From Artifact [8212de2433d6e818]:

To Artifact [7ed0053850ffa032]:


72 72 } 73 73 74 74 AST Declaration() // returns null if it is not a declaration 75 75 { 76 76 /// Declaration ::= 77 77 /// ["@" Layer|"let"|"var"|"def"] Var "=" Expression ([";"|"in"] Body?)? 78 78 /// | ["@" Layer|"let"|"var"|"def"] Var "(" Param%"," ")" "{" Body "}" ([";"|"in"] Body?)? 79 + /// | ["@" "@" Layer "=" Expression ([";"|"in"] Body?)? 80 + /// | ["@" "@" Layer "(" Param%"," ")" "{" Body "}" ([";"|"in"] Body?)? 79 81 80 82 auto pos = currentPosition(); 81 83 string layer = ""; 84 + bool layerRiseDecl = false; 82 85 83 86 if( tryEat("@") ) 84 87 { 85 88 layer = "@" ~ eatId("after @", AllowQuoted); 86 - if( tryEat("(") ) 87 - return null; // @lay(...) expression, not a declaration 88 - } 89 - 90 - string kwd = layer; 91 - if( layer.empty && !tryEat(kwd="let") && !tryEat(kwd="var") && !tryEat(kwd="def") ) 92 - return null; // none of {@lay, let, var, def} occurred, it's not a declaration 93 - 94 - auto varpos = currentPosition(); 95 - string var = eatId("after "~kwd, AllowQuoted); // name of the declared variable 96 - 97 - auto e = tryEat("(") 98 - ? parseLambdaAfterOpenParen(varpos) // let var ( ... 99 - : (eat("=", "after "~kwd), E(0)); // let var = ... 100 - 101 - if( moreDeclarationExists() ) 102 - return new LetExpression(pos, var, layer, e, Body()); 89 + if( layer == "@@" ) 90 + { 91 + layer = "@" ~ eatId("after @@", AllowQuoted); 92 + layerRiseDecl = true; 93 + } 94 + else 95 + { 96 + if( tryEat("(") ) 97 + return null; // @lay(...) expression, not a declaration 98 + } 99 + } 100 + 101 + // [TODO] Refactor 102 + if( layerRiseDecl ) 103 + { 104 + string kwd = "@" ~ layer; 105 + string var = layer; 106 + 107 + auto e = tryEat("(") 108 + ? parseLambdaAfterOpenParen(pos) // let var ( ... 109 + : (eat("=", "after "~kwd), E(0)); // let var = ... 110 + if( moreDeclarationExists() ) 111 + return new LetExpression(pos, var, "(system)", e, Body()); 112 + else 113 + return new LetExpression(pos, var, "(system)", e, new VarExpression(pos, var)); 114 + } 103 115 else 104 - return new LetExpression(pos, var, layer, e, new VarExpression(varpos, var)); 116 + { 117 + string kwd = layer; 118 + if( layer.empty && !tryEat(kwd="let") && !tryEat(kwd="var") && !tryEat(kwd="def") ) 119 + return null; // none of {@lay, let, var, def} occurred, it's not a declaration 120 + 121 + auto varpos = currentPosition(); 122 + string var = eatId("after "~kwd, AllowQuoted); // name of the declared variable 123 + 124 + auto e = tryEat("(") 125 + ? parseLambdaAfterOpenParen(varpos) // let var ( ... 126 + : (eat("=", "after "~kwd), E(0)); // let var = ... 127 + if( moreDeclarationExists() ) 128 + return new LetExpression(pos, var, layer, e, Body()); 129 + else 130 + return new LetExpression(pos, var, layer, e, new VarExpression(varpos, var)); 131 + } 105 132 } 106 133 107 134 AST TopLevelExpression() 108 135 { 109 136 /// TopLevelExpression ::= Expression ([";"|"in"] Body?)? 110 137 111 138 auto pos = currentPosition(); ................................................................................ 404 431 { 405 432 mixin EasyAST; 406 433 assert_eq(parseString(`def foo(x) { x+1 }; foo`), 407 434 let("foo", "", 408 435 fun(["x"], call(var("+"), var("x"), intl(1))), 409 436 var("foo")) 410 437 ); 438 + 439 + assert_eq(parseString(`@@type ( x ) { x }`), 440 + let("@type", "(system)", fun(["x"], var("x")), var("@type")) ); 411 441 }