Skip to content

Commit 90c99b9

Browse files
committed
feat: integrate environment management in interpreter and parser for block statements
1 parent 595a4b4 commit 90c99b9

3 files changed

Lines changed: 41 additions & 7 deletions

File tree

Interpreter/interpreter.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import (
1010
"github.com/shubhdevelop/Lox/environment"
1111
)
1212

13-
type Interpreter struct{}
13+
type Interpreter struct {
14+
Environment *environment.Environment
15+
}
1416

15-
var env = environment.NewEnvironment()
1617
var _ ast.ExprVisitor = (*Interpreter)(nil)
1718
var _ ast.StmtVisitor = (*Interpreter)(nil)
1819

@@ -214,17 +215,35 @@ func (i *Interpreter) VisitVarStmtStmt(stmt ast.VarStmt) interface{} {
214215
value = i.evaluate(stmt.Initializer)
215216
}
216217

217-
env.Define(stmt.Name.Lexeme, value)
218+
i.Environment.Define(stmt.Name.Lexeme, value)
218219
return nil
219220
}
220221

221222
func (i *Interpreter) VisitVariableExpr(expr ast.Variable) interface{} {
222-
value, _ := env.Get(expr.Name)
223+
value, _ := i.Environment.Get(expr.Name)
223224
return value
224225
}
225226

226227
func (i *Interpreter) VisitAssignExpr(expr ast.Assign) interface{} {
227228
value := i.evaluate(expr.Value)
228-
env.Assign(expr.Name, value)
229+
i.Environment.Assign(expr.Name, value)
229230
return value
230231
}
232+
233+
func (i *Interpreter) VisitBlockStmtStmt(stmt ast.BlockStmt) interface{} {
234+
i.executeBlock(stmt.Statement, environment.NewEnclosedEnvironment(i.Environment))
235+
return nil
236+
}
237+
238+
func (i *Interpreter) executeBlock(statements []ast.Stmt, environment *environment.Environment) {
239+
previous := i.Environment
240+
defer func() {
241+
// ensures environment is restored, like Java's finally
242+
i.Environment = previous
243+
}()
244+
245+
i.Environment = environment
246+
for _, stmt := range statements {
247+
i.execute(stmt)
248+
}
249+
}

Lox.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@ import (
77
"os"
88

99
interpreter "github.com/shubhdevelop/Lox/Interpreter"
10-
"github.com/shubhdevelop/Lox/parser"
1110
"github.com/shubhdevelop/Lox/Scanner"
11+
"github.com/shubhdevelop/Lox/environment"
12+
"github.com/shubhdevelop/Lox/parser"
1213
"github.com/shubhdevelop/Lox/state"
1314
)
1415

1516
func run(source string) {
1617
state.HadError = false // Reset error state
1718
scanner := scanner.Scanner{Source: source}
1819
tokens, err := scanner.ScanTokens()
19-
interpreter := interpreter.Interpreter{}
20+
interpreter := interpreter.Interpreter{
21+
environment.NewEnvironment(),
22+
}
2023
parserInstance := parser.Parser{
2124
Tokens: tokens,
2225
}

parser/parser.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,21 @@ func (p *Parser) statement() ast.Stmt {
237237
if p.match(token.PRINT) {
238238
return p.printStatement()
239239
}
240+
if p.match(token.LEFT_BRACE) {
241+
return ast.BlockStmt{p.block()}
242+
}
240243
return p.expressionStatement()
241244
}
242245

246+
func (p *Parser) block() []ast.Stmt {
247+
statements := []ast.Stmt{}
248+
for !p.check(token.RIGHT_BRACE) && !p.isAtEnd() {
249+
statements = append(statements, p.declaration())
250+
}
251+
p.consume(token.RIGHT_BRACE, "Expect '}' after block.")
252+
return statements
253+
}
254+
243255
func (p *Parser) printStatement() ast.Stmt {
244256
value := p.expression()
245257
p.consume(token.SEMICOLON, "Expect ';' after value.")

0 commit comments

Comments
 (0)