for loop
This commit is contained in:
parent
69042ccf99
commit
e8aeb6d5c5
4 changed files with 107 additions and 6 deletions
|
@ -231,7 +231,6 @@ func (i *Interpreter) visitWhileStmt(w *WhileStmt) {
|
|||
}
|
||||
|
||||
w.body.accept(i)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
59
parser.go
59
parser.go
|
@ -69,6 +69,7 @@ func (p *Parser) varDecl() Stmt {
|
|||
// statement -> exprStmt
|
||||
//
|
||||
// | whileStmt
|
||||
// | forStmt
|
||||
// | printStmt
|
||||
// | blockStmt
|
||||
// | breakStmt
|
||||
|
@ -95,6 +96,10 @@ func (p *Parser) statement() Stmt {
|
|||
return p.whileStmt()
|
||||
}
|
||||
|
||||
if p.match(FOR) {
|
||||
return p.forStmt()
|
||||
}
|
||||
|
||||
if p.match(BREAK) {
|
||||
return p.breakStmt()
|
||||
}
|
||||
|
@ -171,6 +176,60 @@ func (p *Parser) whileStmt() Stmt {
|
|||
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" ";"
|
||||
func (p *Parser) envStmt() Stmt {
|
||||
p.consume(SEMICOLON, "Expect ';' after 'env'.")
|
||||
|
|
36
tests/for.lox
Normal file
36
tests/for.lox
Normal 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;
|
||||
}
|
|
@ -13,16 +13,23 @@ var iterator = 100;
|
|||
{
|
||||
while (iterator < 100) {
|
||||
{
|
||||
print iterator;
|
||||
iterator = iterator + 2;
|
||||
{
|
||||
print iterator;
|
||||
iterator = iterator + 2;
|
||||
|
||||
if (iterator > 50) {
|
||||
break;
|
||||
if (iterator > 50) 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;
|
Loading…
Reference in a new issue