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 auto saved = lex.save; 95 auto saved = lex.save;
96 scope(failure) lex = saved; 96 scope(failure) lex = saved;
97 return parseE(0); 97 return parseE(0);
98 } 98 }
99 99
100 // [TODO] multi-char operators are not supported by the lexer... 100 // [TODO] multi-char operators are not supported by the lexer...
101 static immutable string[][] operator_perferences = [ 101 static immutable string[][] operator_perferences = [
102 [","], | 102 ["="],
103 ["="], // caution! left associative <
104 ["or"], 103 ["or"],
105 ["and"], 104 ["and"],
106 ["!="], 105 ["!="],
107 ["=="], 106 ["=="],
108 ["<","<=",">",">="], 107 ["<","<=",">",">="],
109 ["|"], 108 ["|"],
110 ["^"], 109 ["^"],
................................................................................................................................................................................
142 } 141 }
143 142
144 Expression parseBaseExpression() 143 Expression parseBaseExpression()
145 { 144 {
146 if( lex.empty ) 145 if( lex.empty )
147 throw new ParserException("EOF during parsing an express 146 throw new ParserException("EOF during parsing an express
148 auto pos = lex.front.pos; 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,"Un
> 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 express
> 172 auto pos = lex.front.pos;
149 173
150 if( lex.front.kind == Token.Kind.number ) 174 if( lex.front.kind == Token.Kind.number )
151 { 175 {
152 scope(exit) lex.popFront; 176 scope(exit) lex.popFront;
153 return new IntLiteralExpression(pos, BigInt(cast(string) 177 return new IntLiteralExpression(pos, BigInt(cast(string)
154 } 178 }
155 if( lex.front.kind == Token.Kind.stringLiteral ) 179 if( lex.front.kind == Token.Kind.stringLiteral )
................................................................................................................................................................................
159 } 183 }
160 if( tryEat("(") ) 184 if( tryEat("(") )
161 { 185 {
162 auto e = parseE(); 186 auto e = parseE();
163 eat(")", "after parenthesized expression"); 187 eat(")", "after parenthesized expression");
164 return e; 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,"Une
> 199 throw e;
> 200 }
> 201 if( lex.front.kind != Token.Kind.identifier ) {
> 202 auto e = ParserException.create(lex,"Ide
> 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,"Une
> 217 throw e;
> 218 }
> 219 funbody ~= parseStatement();
> 220 }
> 221 return new FunLiteralExpression(pos, params, funbody);
> 222 }
166 scope(exit) lex.popFront; 223 scope(exit) lex.popFront;
167 return new VarExpression(pos, lex.front.str); 224 return new VarExpression(pos, lex.front.str);
168 } 225 }
169 226
170 private: 227 private:
171 Lexer lex; 228 Lexer lex;
172 229
................................................................................................................................................................................
226 283
227 Program prog = p.parseProgram(); 284 Program prog = p.parseProgram();
228 assert( prog.length == 3 ); 285 assert( prog.length == 3 );
229 assert( prog[0] == s0 ); 286 assert( prog[0] == s0 );
230 assert( prog[1] == s1 ); 287 assert( prog[1] == s1 );
231 assert( prog[2] == s2 ); 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
> 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 }