This commit is contained in:
Greg 2024-10-08 20:32:13 +03:00
parent 69042ccf99
commit e8aeb6d5c5
4 changed files with 107 additions and 6 deletions

View file

@ -231,7 +231,6 @@ func (i *Interpreter) visitWhileStmt(w *WhileStmt) {
} }
w.body.accept(i) w.body.accept(i)
} }
} }

View file

@ -69,6 +69,7 @@ func (p *Parser) varDecl() Stmt {
// statement -> exprStmt // statement -> exprStmt
// //
// | whileStmt // | whileStmt
// | forStmt
// | printStmt // | printStmt
// | blockStmt // | blockStmt
// | breakStmt // | breakStmt
@ -95,6 +96,10 @@ func (p *Parser) statement() Stmt {
return p.whileStmt() return p.whileStmt()
} }
if p.match(FOR) {
return p.forStmt()
}
if p.match(BREAK) { if p.match(BREAK) {
return p.breakStmt() return p.breakStmt()
} }
@ -171,6 +176,60 @@ func (p *Parser) whileStmt() Stmt {
return &WhileStmt{cond, body} return &WhileStmt{cond, body}
} }
// for -> "for" ( "(" ( varDecl | exprStmt | ";" ) expression? ";" expression ")" )? statement
func (p *Parser) forStmt() Stmt {
if p.check(LEFT_BRACE) {
return &WhileStmt{&Literal{true}, p.statement()}
}
p.consume(LEFT_PAREN, "Expect '(' after 'for'.")
var init Stmt
if p.match(SEMICOLON) {
init = nil
} else if p.match(VAR) {
init = p.varDecl()
} else {
init = p.exprStmt()
}
var cond Expr
if !p.check(SEMICOLON) {
cond = p.expression()
}
p.consume(SEMICOLON, "Expect ';' after for loop condition;")
var incr Expr
if !p.check(RIGHT_PAREN) {
incr = p.expression()
}
p.consume(RIGHT_PAREN, "Expect ')' after for clauses;")
var body = p.statement()
if incr != nil {
body = &BlockStmt{[]Stmt{body, &ExprStmt{incr}}}
}
if cond == nil {
cond = &Literal{true}
}
body = &WhileStmt{cond, body}
if init != nil {
body = &BlockStmt{[]Stmt{init, body}}
}
return body
}
// env -> "env" ";" // env -> "env" ";"
func (p *Parser) envStmt() Stmt { func (p *Parser) envStmt() Stmt {
p.consume(SEMICOLON, "Expect ';' after 'env'.") p.consume(SEMICOLON, "Expect ';' after 'env'.")

36
tests/for.lox Normal file
View file

@ -0,0 +1,36 @@
print "full form -------------------------";
for (var i = 0; i < 100; i = i + 20) print i;
print "without init ----------------------";
var n = 100;
for (;n > 0; n = n - 20) print n;
print "only cond -----------------------";
var i = 1;
for (;i < 100;) {
print i;
i = i + 10;
}
print "inf ---------------------------";
var b = 0;
for {
print b;
b = b + 5;
if (b > 10) break;
print "after break";
}
print "fibonachi ------------------------";
var temp;
var first = 0;
for (var second = 1; first < 10000; second = temp + second) {
print first;
temp = first;
first = second;
}

View file

@ -13,16 +13,23 @@ var iterator = 100;
{ {
while (iterator < 100) { while (iterator < 100) {
{ {
print iterator; {
iterator = iterator + 2; print iterator;
iterator = iterator + 2;
if (iterator > 50) { if (iterator > 50) break;
break;
print "shoud not be printed after 50";
} }
print "shoud not be printed after 50"; print "OUTER also shoud not be printed after 50";
} }
} }
} }
while (iterator < 100) iterator = iterator + 2;
print iterator; print iterator;