Control Flow 9

This commit is contained in:
nazrin 2025-06-01 21:08:11 +00:00
parent e749367886
commit f0ff14e5b5
6 changed files with 133 additions and 14 deletions

View file

@ -57,7 +57,7 @@ class Parser{
Lox.error(token, message);
return new ParseError("hello");
}
private void synchronize(){
private void synchronise(){
advance();
with(TokenType) while(!isAtEnd){
if(previous().type == SEMICOLON)
@ -89,11 +89,61 @@ class Parser{
consume(TokenType.SEMICOLON, "Expect ';' after expression.");
return new Stmt.Expression(expr);
}
private Stmt ifStatement(){
consume(TokenType.LEFT_PAREN, "Expect '(' after 'if'.");
Expr condition = expression();
consume(TokenType.RIGHT_PAREN, "Expect ')' after if condition.");
Stmt thenBranch = statement();
Stmt elseBranch = null;
if(match(TokenType.ELSE))
elseBranch = statement();
return new Stmt.If(condition, thenBranch, elseBranch);
}
private Stmt forStatement(){
consume(TokenType.LEFT_PAREN, "Expect '(' after 'for'.");
Stmt initialiser;
if(match(TokenType.SEMICOLON))
initialiser = null;
else if(match(TokenType.VAR))
initialiser = varDeclaration();
else
initialiser = expressionStatement();
Expr condition = check(TokenType.SEMICOLON) ? new Expr.Literal(TValue.bln(true)) : expression();
consume(TokenType.SEMICOLON, "Expect ';' after loop condition.");
Expr increment;
if(!check(TokenType.RIGHT_PAREN))
increment = expression();
consume(TokenType.RIGHT_PAREN, "Expect ')' after for clauses.");
Stmt body = statement();
if(increment !is null)
body = new Stmt.Block([ body, new Stmt.Expression(increment) ]);
body = new Stmt.While(condition, body);
if(initialiser !is null)
body = new Stmt.Block([ initialiser, body ]);
return body;
}
private Stmt whileStatement(){
consume(TokenType.LEFT_PAREN, "Expect '(' after 'while'.");
Expr condition = expression();
consume(TokenType.RIGHT_PAREN, "Expect ')' after condition.");
Stmt body = statement();
return new Stmt.While(condition, body);
}
private Stmt statement(){
if(match(TokenType.LEFT_BRACE))
return new Stmt.Block(block());
if(match(TokenType.IF))
return ifStatement();
if(match(TokenType.FOR))
return forStatement();
if(match(TokenType.WHILE))
return whileStatement();
if(match(TokenType.PRINT))
return printStatement();
if(match(TokenType.LEFT_BRACE))
return new Stmt.Block(block());
return expressionStatement();
}
private Stmt[] block(){
@ -107,7 +157,7 @@ class Parser{
return assignment();
}
private Expr assignment(){
Expr expr = equality();
Expr expr = or();
if(match(TokenType.EQUAL)){
Token equals = previous();
Expr value = assignment();
@ -117,6 +167,24 @@ class Parser{
}
return expr;
}
private Expr or(){
Expr expr = and();
while(match(TokenType.OR)){
Token operator = previous();
Expr right = and();
expr = new Expr.Logical(expr, operator, right);
}
return expr;
}
private Expr and(){
Expr expr = equality();
while(match(TokenType.AND)){
Token operator = previous();
Expr right = equality();
expr = new Expr.Logical(expr, operator, right);
}
return expr;
}
private Expr equality(){
Expr expr = comparison();
while(match(TokenType.BANG_EQUAL, TokenType.EQUAL_EQUAL)){
@ -181,11 +249,11 @@ class Parser{
}
private Stmt varDeclaration(){
Token name = consume(TokenType.IDENTIFIER, "Expect variable name.");
Expr initializer = null;
Expr initialiser = null;
if(match(TokenType.EQUAL))
initializer = expression();
initialiser = expression();
consume(TokenType.SEMICOLON, "Expect ';' after variable declaration.");
return new Stmt.Var(name, initializer);
return new Stmt.Var(name, initialiser);
}
private Stmt declaration(){
try {
@ -193,7 +261,7 @@ class Parser{
return varDeclaration();
return statement();
} catch(ParseError error){
synchronize();
synchronise();
return null;
}
}