Differences From Artifact [a819ba1b27fdc13d]:
- File
polemy/parse.d
- 2010-11-07 12:20:47 - part of checkin [5d4cb856d8] on branch trunk - Added FuncallExpression (user: kinaba) [annotate]
To Artifact [4856c979362ef435]:
- File
polemy/parse.d
- 2010-11-07 12:46:23 - part of checkin [3f5dc76a75] on branch trunk - Added funcall expression parser and function literal parser. (user: kinaba) [annotate]
95 95 auto saved = lex.save;
96 96 scope(failure) lex = saved;
97 97 return parseE(0);
98 98 }
99 99
100 100 // [TODO] multi-char operators are not supported by the lexer...
101 101 static immutable string[][] operator_perferences = [
102 - [","],
103 - ["="], // caution! left associative
102 + ["="],
104 103 ["or"],
105 104 ["and"],
106 105 ["!="],
107 106 ["=="],
108 107 ["<","<=",">",">="],
109 108 ["|"],
110 109 ["^"],
................................................................................
142 141 }
143 142
144 143 Expression parseBaseExpression()
145 144 {
146 145 if( lex.empty )
147 146 throw new ParserException("EOF during parsing an expression");
148 147 auto pos = lex.front.pos;
148 + Expression e = parseBaseBaseExpression();
149 + while( tryEat("(") ) // funcall
150 + {
151 + Expression[] args;
152 + while( !tryEat(")") ) {
153 + if( lex.empty ) {
154 + auto ex = ParserException.create(lex,"Unexpected EOF");
155 + throw ex;
156 + }
157 + args ~= parseE();
158 + if( !tryEat(",") ) {
159 + eat(")", "after function parameters");
160 + break;
161 + }
162 + }
163 + e = new FuncallExpression(pos, e, args);
164 + }
165 + return e;
166 + }
167 +
168 + Expression parseBaseBaseExpression()
169 + {
170 + if( lex.empty )
171 + throw new ParserException("EOF during parsing an expression");
172 + auto pos = lex.front.pos;
149 173
150 174 if( lex.front.kind == Token.Kind.number )
151 175 {
152 176 scope(exit) lex.popFront;
153 177 return new IntLiteralExpression(pos, BigInt(cast(string)lex.front.str));
154 178 }
155 179 if( lex.front.kind == Token.Kind.stringLiteral )
................................................................................
159 183 }
160 184 if( tryEat("(") )
161 185 {
162 186 auto e = parseE();
163 187 eat(")", "after parenthesized expression");
164 188 return e;
165 189 }
190 +
191 + if( tryEat("fun") )
192 + {
193 + eat("(", "after fun");
194 + string[] params;
195 + for(;;)
196 + {
197 + if( lex.empty ) {
198 + auto e = ParserException.create(lex,"Unexpected EOF");
199 + throw e;
200 + }
201 + if( lex.front.kind != Token.Kind.identifier ) {
202 + auto e = ParserException.create(lex,"Identifier Expected for parameters");
203 + throw e;
204 + }
205 + params ~= lex.front.str;
206 + lex.popFront;
207 + if( !tryEat(",") ) {
208 + eat(")", "after function parameters");
209 + break;
210 + }
211 + }
212 + eat("{", "after function parameters");
213 + Statement[] funbody;
214 + while(!tryEat("}")) {
215 + if( lex.empty ) {
216 + auto e = ParserException.create(lex,"Unexpected EOF");
217 + throw e;
218 + }
219 + funbody ~= parseStatement();
220 + }
221 + return new FunLiteralExpression(pos, params, funbody);
222 + }
166 223 scope(exit) lex.popFront;
167 224 return new VarExpression(pos, lex.front.str);
168 225 }
169 226
170 227 private:
171 228 Lexer lex;
172 229
................................................................................
226 283
227 284 Program prog = p.parseProgram();
228 285 assert( prog.length == 3 );
229 286 assert( prog[0] == s0 );
230 287 assert( prog[1] == s1 );
231 288 assert( prog[2] == s2 );
232 289 }
290 +
291 +unittest
292 +{
293 + auto p = parserFromString(`
294 + var f = fun(x,y){x+y;};
295 + f(1,fun(abc){}(4));
296 + `);
297 + Program prog = p.parseProgram();
298 + assert( prog.length == 2 );
299 + assert( prog[0] == new DeclStatement(null, "f", new FunLiteralExpression(null,
300 + ["x","y"], [new ExprStatement(null,
301 + new FuncallExpression(null, new VarExpression(null, "+"),
302 + new VarExpression(null, "x"), new VarExpression(null, "y")))]
303 + )));
304 + assert( prog[1] == new ExprStatement(null, new FuncallExpression(null,
305 + new VarExpression(null, "f"),
306 + new IntLiteralExpression(null, BigInt(1)),
307 + new FuncallExpression(null,
308 + new FunLiteralExpression(null, ["abc"], [
309 + ]),
310 + new IntLiteralExpression(null, BigInt(4))
311 + ))));
312 +}