if-ELSE!!!!
This commit is contained in:
		
							parent
							
								
									19c9409ccd
								
							
						
					
					
						commit
						6e0b8f950d
					
				
					 8 changed files with 50 additions and 11 deletions
				
			
		|  | @ -1,4 +1,4 @@ | |||
| package ch.fritteli.gombaila.domain.common; | ||||
| 
 | ||||
| public sealed interface NodeStmt extends Node permits NodeStmtAssign, NodeStmtExit, NodeStmtIf, NodeStmtLet, NodeStmtPrint, NodeStmtScope { | ||||
| public sealed interface NodeStmt extends Node permits NodeStmtAssign, NodeStmtExit, NodeStmtIf, NodeStmtIfElse, NodeStmtLet, NodeStmtPrint, NodeStmtScope { | ||||
| } | ||||
|  |  | |||
|  | @ -2,6 +2,5 @@ package ch.fritteli.gombaila.domain.common; | |||
| 
 | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| 
 | ||||
| public record NodeStmtIf(@NotNull NodeExpr expr, @NotNull NodeStmtScope scope) implements NodeStmt { | ||||
| 
 | ||||
| public record NodeStmtIf(@NotNull NodeExpr expr, @NotNull NodeStmtScope ifScope) implements NodeStmt { | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| package ch.fritteli.gombaila.domain.common; | ||||
| 
 | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| 
 | ||||
| public record NodeStmtIfElse(@NotNull NodeExpr expr, @NotNull NodeStmtScope ifScope, | ||||
|                              @NotNull NodeStmtScope elseScope) implements NodeStmt { | ||||
| } | ||||
|  | @ -26,7 +26,8 @@ public enum TokenType { | |||
|     IDENTIFIER, | ||||
|     // the rest | ||||
|     WHITESPACE, | ||||
|     IF; | ||||
|     IF, | ||||
|     ELSE; | ||||
| 
 | ||||
|     public boolean isBinaryOperator() { | ||||
|         return switch (this) { | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ import ch.fritteli.gombaila.domain.common.NodeStmt; | |||
| import ch.fritteli.gombaila.domain.common.NodeStmtAssign; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtExit; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtIf; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtIfElse; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtLet; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtPrint; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtScope; | ||||
|  | @ -27,6 +28,7 @@ final class StmtVisitor { | |||
|             case final NodeStmtPrint stmtPrint -> visit(stmtPrint); | ||||
|             case final NodeStmtScope stmtScope -> visit(stmtScope); | ||||
|             case final NodeStmtIf stmtIf -> visit(stmtIf); | ||||
|             case final NodeStmtIfElse stmtIfElse -> visit(stmtIfElse); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -96,9 +98,30 @@ final class StmtVisitor { | |||
|                 "skip to %s if condition is not met".formatted(label), | ||||
|                 "jz", label | ||||
|         ); | ||||
|         this.visit(stmt.scope()); | ||||
|         this.visit(stmt.ifScope()); | ||||
|         this.generator.printer.label(label); | ||||
|     } | ||||
| 
 | ||||
|     private void visit(@NotNull final NodeStmtIfElse stmt) { | ||||
|         final String afterIfLabel = this.createNextLabel(); | ||||
|         final String afterElseLabel = this.createNextLabel(); | ||||
|         this.generator.generateExpr(stmt.expr()); | ||||
|         this.generator.pop("rax"); | ||||
|         this.generator.printer.commentedLine("test the condition", | ||||
|                 "test", "rax, rax"); | ||||
|         this.generator.printer.commentedLine( | ||||
|                 "skip to %s (else) if condition is not met".formatted(afterIfLabel), | ||||
|                 "jz", afterIfLabel | ||||
|         ); | ||||
|         this.visit(stmt.ifScope()); | ||||
|         this.generator.printer.commentedLine( | ||||
|                 "skip to %s to skip the else".formatted(afterElseLabel), | ||||
|                 "jmp", | ||||
|                 afterElseLabel | ||||
|         ); | ||||
|         this.generator.printer.label(afterIfLabel); | ||||
|         this.visit(stmt.elseScope()); | ||||
|         this.generator.printer.label(afterElseLabel); | ||||
|     } | ||||
| 
 | ||||
|     private String createNextLabel() { | ||||
|  |  | |||
|  | @ -80,6 +80,7 @@ public class Lexer { | |||
|             case "let" -> this.appendToken(new Token(TokenType.LET, line, column)); | ||||
|             case "print" -> this.appendToken(new Token(TokenType.PRINT, line, column)); | ||||
|             case "if" -> this.appendToken(new Token(TokenType.IF, line, column)); | ||||
|             case "else" -> this.appendToken(new Token(TokenType.ELSE, line, column)); | ||||
|             case final String value -> | ||||
|                     this.appendToken(new Token(TokenType.IDENTIFIER, Option.of(value), line, column)); | ||||
|         } | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ import ch.fritteli.gombaila.domain.common.NodeStmt; | |||
| import ch.fritteli.gombaila.domain.common.NodeStmtAssign; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtExit; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtIf; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtIfElse; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtLet; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtPrint; | ||||
| import ch.fritteli.gombaila.domain.common.NodeStmtScope; | ||||
|  | @ -65,9 +66,14 @@ public class Parser { | |||
|             this.assertAndConsumeNextTokenType(TokenType.OPEN_PAREN); | ||||
|             final NodeExpr expr = this.parseExpr(1); | ||||
|             this.assertAndConsumeNextTokenType(TokenType.CLOSE_PAREN); | ||||
|             final NodeStmtScope scope = this.parseScope(); | ||||
|             final NodeStmtScope ifScope = this.parseScope(); | ||||
|             // there /could/ be an else, so let's check that | ||||
|             if (this.checkNextTokenTypeConsuming(TokenType.ELSE)) { | ||||
|                 final NodeStmtScope elseScope = this.parseScope(); | ||||
|                 return new NodeStmtIfElse(expr, ifScope, elseScope); | ||||
|             } | ||||
|             // NB: We do NOT expect a SEMI here, so we return directly. | ||||
|             return new NodeStmtIf(expr, scope); | ||||
|             return new NodeStmtIf(expr, ifScope); | ||||
|         } else if (this.checkNextTokenType(TokenType.IDENTIFIER)) { | ||||
|             result = this.parseStmtAssign(); | ||||
|         } else { | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| let x = (10 - 2 * 3) / 2; | ||||
| if (x-2) { | ||||
|     exit (69); | ||||
| let x = 1; | ||||
| if (x) { | ||||
|     x = 99; | ||||
| } else { | ||||
|     x = 12; | ||||
| } | ||||
| exit(1); | ||||
| exit(x); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue