Diff
Not logged in

Differences From Artifact [31eeea68e341add3]:

To Artifact [752d9af2ecdd593b]:


4 * 4 * 5 * Parser for Polemy programming language 5 * Parser for Polemy programming language 6 */ 6 */ 7 module polemy.parse; 7 module polemy.parse; 8 import polemy._common; 8 import polemy._common; 9 import polemy.lex; 9 import polemy.lex; 10 import polemy.ast; 10 import polemy.ast; 11 import std.bigint; < 12 11 13 /// Parsing Failure 12 /// Parsing Failure 14 13 15 class ParserException : Exception 14 class ParserException : Exception 16 { 15 { 17 private: 16 private: 18 this(string msg) { super(msg); } 17 this(string msg) { super(msg); } ................................................................................................................................................................................ 62 } 61 } 63 return p; 62 return p; 64 } 63 } 65 64 66 Program parseStatements() 65 Program parseStatements() 67 { 66 { 68 Program p; 67 Program p; 69 while( !lex.empty && (lex.front.kind!=Token.Kind.identifier || l | 68 while( !lex.empty && (lex.front.quoted || lex.front.str!="}") ) 70 p ~= parseStatement(); 69 p ~= parseStatement(); 71 return p; 70 return p; 72 } 71 } 73 72 74 Statement parseStatement() 73 Statement parseStatement() 75 { 74 { 76 auto saved = lex.save; 75 auto saved = lex.save; 77 scope(failure) lex = saved; 76 scope(failure) lex = saved; 78 77 79 if( lex.empty ) 78 if( lex.empty ) 80 throw new ParserException("EOF during parsing a statemen 79 throw new ParserException("EOF during parsing a statemen 81 auto pos = lex.front.pos; 80 auto pos = lex.front.pos; 82 81 83 if( lex.front.kind==Token.Kind.identifier && lex.front.str=="var | 82 if( !lex.front.quoted && lex.front.str=="var" ) 84 { 83 { 85 // "var" Var "=" Expression ";" 84 // "var" Var "=" Expression ";" 86 lex.popFront; 85 lex.popFront; 87 string var = lex.front.str; 86 string var = lex.front.str; 88 lex.popFront; 87 lex.popFront; 89 eat("=", "for variable declaration"); 88 eat("=", "for variable declaration"); 90 auto parsed = new DeclStatement(pos, var, parseExpressio 89 auto parsed = new DeclStatement(pos, var, parseExpressio ................................................................................................................................................................................ 177 176 178 Expression parseBaseBaseExpression() 177 Expression parseBaseBaseExpression() 179 { 178 { 180 if( lex.empty ) 179 if( lex.empty ) 181 throw new ParserException("EOF during parsing an express 180 throw new ParserException("EOF during parsing an express 182 auto pos = lex.front.pos; 181 auto pos = lex.front.pos; 183 182 184 if( lex.front.kind == Token.Kind.number ) | 183 if( lex.front.quoted ) > 184 { > 185 scope(exit) lex.popFront; > 186 return new StrLiteralExpression(pos, lex.front.str); > 187 } > 188 if( isNumber(lex.front.str) ) // is_number 185 { 189 { 186 scope(exit) lex.popFront; 190 scope(exit) lex.popFront; 187 return new IntLiteralExpression(pos, BigInt(cast(string) 191 return new IntLiteralExpression(pos, BigInt(cast(string) 188 } 192 } 189 if( lex.front.kind == Token.Kind.stringLiteral ) < 190 { < 191 scope(exit) lex.popFront; < 192 return new StrLiteralExpression(pos, lex.front.str); < 193 } < 194 if( tryEat("(") ) 193 if( tryEat("(") ) 195 { 194 { 196 auto e = parseE(); 195 auto e = parseE(); 197 eat(")", "after parenthesized expression"); 196 eat(")", "after parenthesized expression"); 198 return e; 197 return e; 199 } 198 } 200 if( tryEat("if") ) 199 if( tryEat("if") ) ................................................................................................................................................................................ 227 string[] params; 226 string[] params; 228 while(!tryEat(")")) 227 while(!tryEat(")")) 229 { 228 { 230 if( lex.empty ) { 229 if( lex.empty ) { 231 auto e = ParserException.create(lex,"Une 230 auto e = ParserException.create(lex,"Une 232 throw e; 231 throw e; 233 } 232 } 234 if( lex.front.kind != Token.Kind.identifier ) { | 233 if( lex.front.quoted ) { 235 auto e = ParserException.create(lex,"Ide 234 auto e = ParserException.create(lex,"Ide 236 throw e; 235 throw e; 237 } 236 } 238 params ~= lex.front.str; 237 params ~= lex.front.str; 239 lex.popFront; 238 lex.popFront; 240 if( !tryEat(",") ) { 239 if( !tryEat(",") ) { 241 eat(")", "after function parameters"); 240 eat(")", "after function parameters"); ................................................................................................................................................................................ 268 ~(lex.empty ? "EOF" : lex.front.str)~"' occured" 267 ~(lex.empty ? "EOF" : lex.front.str)~"' occured" 269 throw e; 268 throw e; 270 } 269 } 271 } 270 } 272 271 273 bool tryEat(string kwd) 272 bool tryEat(string kwd) 274 { 273 { 275 if( lex.empty || lex.front.kind!=Token.Kind.identifier || lex.fr | 274 if( lex.empty || lex.front.quoted || lex.front.str!=kwd ) 276 return false; 275 return false; 277 lex.popFront; 276 lex.popFront; 278 return true; 277 return true; 279 } 278 } > 279 > 280 bool isNumber(string s) > 281 { > 282 return find!(`a<'0'||'9'<a`)(s).empty; > 283 } 280 } 284 } 281 285 282 unittest 286 unittest 283 { 287 { 284 auto p = parserFromString(` 288 auto p = parserFromString(` 285 var x = 100; 289 var x = 100; 286 var y = 200; 290 var y = 200; ................................................................................................................................................................................ 339 new IntLiteralExpression(null, BigInt(1)), 343 new IntLiteralExpression(null, BigInt(1)), 340 new FuncallExpression(null, 344 new FuncallExpression(null, 341 new FunLiteralExpression(null, ["abc"], [ 345 new FunLiteralExpression(null, ["abc"], [ 342 ]), 346 ]), 343 new IntLiteralExpression(null, BigInt(4)) 347 new IntLiteralExpression(null, BigInt(4)) 344 )))); 348 )))); 345 } 349 } > 350 > 351 /* 346 unittest 352 unittest 347 { 353 { 348 auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x 354 auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x 349 Program prog = p.parseProgram(); 355 Program prog = p.parseProgram(); 350 } 356 } 351 357 352 unittest 358 unittest ................................................................................................................................................................................ 357 new VarExpression(null, "if"), 363 new VarExpression(null, "if"), 358 new FuncallExpression(null, new VarExpression(null,"<"), new Var 364 new FuncallExpression(null, new VarExpression(null,"<"), new Var 359 new IntLiteralExpression(null, BigInt(2))), 365 new IntLiteralExpression(null, BigInt(2))), 360 new FunLiteralExpression(null, [], [new ExprStatement(null, new 366 new FunLiteralExpression(null, [], [new ExprStatement(null, new 361 new FunLiteralExpression(null, [], [new ExprStatement(null, new 367 new FunLiteralExpression(null, [], [new ExprStatement(null, new 362 ))); 368 ))); 363 } 369 } > 370 */