Differences From Artifact [fe0b0bcfc1d8a230]:
- File
polemy/parse.d
- 2010-11-07 15:03:38 - part of checkin [820e7198cc] on branch trunk - Made helloworld work. (user: kinaba) [annotate]
To Artifact [31eeea68e341add3]:
- File
polemy/parse.d
- 2010-11-07 16:31:52 - part of checkin [633e700889] on branch trunk - If-expression implemented. Factorial now works. (user: kinaba) [annotate]
51 this(Lexer lex) 51 this(Lexer lex)
52 { 52 {
53 this.lex = lex; 53 this.lex = lex;
54 } 54 }
55 55
56 Program parseProgram() 56 Program parseProgram()
57 { 57 {
> 58 Program p = parseStatements();
> 59 if( !lex.empty ) {
> 60 auto e = ParserException.create(lex, "cannot reach eof")
> 61 throw e;
> 62 }
> 63 return p;
> 64 }
> 65
> 66 Program parseStatements()
> 67 {
58 Program p; 68 Program p;
59 while( !lex.empty ) | 69 while( !lex.empty && (lex.front.kind!=Token.Kind.identifier || l
60 p ~= parseStatement(); 70 p ~= parseStatement();
61 return p; 71 return p;
62 } 72 }
63 73
64 Statement parseStatement() 74 Statement parseStatement()
65 { 75 {
66 auto saved = lex.save; 76 auto saved = lex.save;
................................................................................................................................................................................
183 } 193 }
184 if( tryEat("(") ) 194 if( tryEat("(") )
185 { 195 {
186 auto e = parseE(); 196 auto e = parseE();
187 eat(")", "after parenthesized expression"); 197 eat(")", "after parenthesized expression");
188 return e; 198 return e;
189 } 199 }
> 200 if( tryEat("if") )
> 201 {
> 202 eat("(", "after if");
> 203 auto cond = parseE();
> 204 eat(")", "after if condition");
> 205 auto thenPos = lex.front.pos;
> 206 eat("{", "after if condition");
> 207 Statement[] th = parseStatements();
> 208 eat("}", "after if-then body");
> 209 Statement[] el;
> 210 auto elsePos = lex.front.pos;
> 211 if( tryEat("else") ) {
> 212 eat("{", "after else");
> 213 el = parseStatements();
> 214 eat("}", "after else body");
> 215 }
> 216 return new FuncallExpression(pos,
> 217 new VarExpression(pos, "if"),
> 218 cond,
> 219 new FunLiteralExpression(thenPos, [], th),
> 220 new FunLiteralExpression(elsePos, [], el)
> 221 );
> 222 }
190 223
191 if( tryEat("fun") ) 224 if( tryEat("fun") )
192 { 225 {
193 eat("(", "after fun"); 226 eat("(", "after fun");
194 string[] params; 227 string[] params;
195 while(!tryEat(")")) 228 while(!tryEat(")"))
196 { 229 {
................................................................................................................................................................................
311 )))); 344 ))));
312 } 345 }
313 unittest 346 unittest
314 { 347 {
315 auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x 348 auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x
316 Program prog = p.parseProgram(); 349 Program prog = p.parseProgram();
317 } 350 }
> 351
> 352 unittest
> 353 {
> 354 auto p = parserFromString(`if(x<2){1;}else{x;};`);
> 355 Program prog = p.parseProgram();
> 356 assert( prog[0] == new ExprStatement(null, new FuncallExpression(null,
> 357 new VarExpression(null, "if"),
> 358 new FuncallExpression(null, new VarExpression(null,"<"), new Var
> 359 new IntLiteralExpression(null, BigInt(2))),
> 360 new FunLiteralExpression(null, [], [new ExprStatement(null, new
> 361 new FunLiteralExpression(null, [], [new ExprStatement(null, new
> 362 )));
> 363 }