mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 22:02:44 +00:00 
			
		
		
		
	LibJS: Support empty statements
We already skipped random semicolons in Parser::parse_program(), but now they are properly matched and parsed as empty statements - and thus recognized as a valid body of an if / else / while / ... statement.
This commit is contained in:
		
							parent
							
								
									3b432eed98
								
							
						
					
					
						commit
						32742709dc
					
				
					 3 changed files with 23 additions and 4 deletions
				
			
		|  | @ -71,6 +71,12 @@ private: | ||||||
| class Statement : public ASTNode { | class Statement : public ASTNode { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | class EmptyStatement final : public Statement { | ||||||
|  | public: | ||||||
|  |     Value execute(Interpreter&) const override { return js_undefined(); } | ||||||
|  |     const char* class_name() const override { return "EmptyStatement"; } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class ErrorStatement final : public Statement { | class ErrorStatement final : public Statement { | ||||||
| public: | public: | ||||||
|     Value execute(Interpreter&) const override { return js_undefined(); } |     Value execute(Interpreter&) const override { return js_undefined(); } | ||||||
|  |  | ||||||
|  | @ -206,9 +206,7 @@ NonnullRefPtr<Program> Parser::parse_program() | ||||||
|     ScopePusher scope(*this, ScopePusher::Var | ScopePusher::Let); |     ScopePusher scope(*this, ScopePusher::Var | ScopePusher::Let); | ||||||
|     auto program = adopt(*new Program); |     auto program = adopt(*new Program); | ||||||
|     while (!done()) { |     while (!done()) { | ||||||
|         if (match(TokenType::Semicolon)) { |         if (match_statement()) { | ||||||
|             consume(); |  | ||||||
|         } else if (match_statement()) { |  | ||||||
|             program->append(parse_statement()); |             program->append(parse_statement()); | ||||||
|         } else { |         } else { | ||||||
|             expected("statement"); |             expected("statement"); | ||||||
|  | @ -255,6 +253,9 @@ NonnullRefPtr<Statement> Parser::parse_statement() | ||||||
|         return parse_while_statement(); |         return parse_while_statement(); | ||||||
|     case TokenType::Debugger: |     case TokenType::Debugger: | ||||||
|          return parse_debugger_statement(); |          return parse_debugger_statement(); | ||||||
|  |     case TokenType::Semicolon: | ||||||
|  |         consume(); | ||||||
|  |         return create_ast_node<EmptyStatement>(); | ||||||
|     default: |     default: | ||||||
|         if (match_expression()) { |         if (match_expression()) { | ||||||
|             auto expr = parse_expression(0); |             auto expr = parse_expression(0); | ||||||
|  | @ -1176,7 +1177,8 @@ bool Parser::match_statement() const | ||||||
|         || type == TokenType::Break |         || type == TokenType::Break | ||||||
|         || type == TokenType::Continue |         || type == TokenType::Continue | ||||||
|         || type == TokenType::Var |         || type == TokenType::Var | ||||||
|         || type == TokenType::Debugger; |         || type == TokenType::Debugger | ||||||
|  |         || type == TokenType::Semicolon; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Parser::match_identifier_name() const | bool Parser::match_identifier_name() const | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								Libraries/LibJS/Tests/empty-statements.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Libraries/LibJS/Tests/empty-statements.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | try { | ||||||
|  |     ;;; | ||||||
|  |     if (true); | ||||||
|  |     if (false); else if (false); else; | ||||||
|  |     while (false); | ||||||
|  |     do; while (false); | ||||||
|  | 
 | ||||||
|  |     console.log("PASS"); | ||||||
|  | } catch (e) { | ||||||
|  |     console.log("FAIL: " + e); | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Linus Groh
						Linus Groh