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)
|
w.body.accept(i)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
59
parser.go
59
parser.go
|
@ -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
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;
|
||||||
|
}
|
|
@ -12,17 +12,24 @@ var iterator = 100;
|
||||||
|
|
||||||
{
|
{
|
||||||
while (iterator < 100) {
|
while (iterator < 100) {
|
||||||
|
{
|
||||||
{
|
{
|
||||||
print iterator;
|
print iterator;
|
||||||
iterator = iterator + 2;
|
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;
|
Loading…
Reference in a new issue