Differences From Artifact [8212de2433d6e818]:
- File
polemy/parse.d
- 2010-11-12 04:40:33 - part of checkin [a7b5d1d95a] on branch trunk - refactored the parser, and added layerd params fun(x @t){...} (user: kinaba) [annotate]
To Artifact [7ed0053850ffa032]:
- File
polemy/parse.d
- 2010-11-13 03:55:17 - part of checkin [c368edbcb1] on branch trunk - @@lay(x) { ... } declaration and value rising. (user: kinaba) [annotate]
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 }