summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tom Willemse2020-11-25 22:06:42 -0800
committerGravatar Tom Willemse2020-11-25 22:06:42 -0800
commit57e87978ef416ce2898a65a9b67e37be91263e67 (patch)
treeca08d1a2773986f96522bdcb22819755a14e3c9f
parentae33509615c4088ab50d7c76f9b1881d10f8354c (diff)
downloadcrafting-interpreters-57e87978ef416ce2898a65a9b67e37be91263e67.tar.gz
crafting-interpreters-57e87978ef416ce2898a65a9b67e37be91263e67.zip
Chapter 8: Add assignment
-rw-r--r--src/com/craftinginterpreters/lox/AstPrinter.java5
-rw-r--r--src/com/craftinginterpreters/lox/Environment.java9
-rw-r--r--src/com/craftinginterpreters/lox/Interpreter.java7
-rw-r--r--src/com/craftinginterpreters/lox/Parser.java20
-rw-r--r--src/com/craftinginterpreters/tool/GenerateAst.java2
5 files changed, 41 insertions, 2 deletions
diff --git a/src/com/craftinginterpreters/lox/AstPrinter.java b/src/com/craftinginterpreters/lox/AstPrinter.java
index 82294c6..58376cb 100644
--- a/src/com/craftinginterpreters/lox/AstPrinter.java
+++ b/src/com/craftinginterpreters/lox/AstPrinter.java
@@ -36,6 +36,11 @@ class AstPrinter implements Expr.Visitor<String>, Stmt.Visitor<String> {
}
@Override
+ public String visitAssignExpr(Expr.Assign expression) {
+ return parenthesize(expression.name.lexeme + " = ", expression.value);
+ }
+
+ @Override
public String visitVarStmt(Stmt.Var statement) {
return parenthesize("define " + statement.name.lexeme + " = ", statement.initializer);
}
diff --git a/src/com/craftinginterpreters/lox/Environment.java b/src/com/craftinginterpreters/lox/Environment.java
index 634659b..8d8a374 100644
--- a/src/com/craftinginterpreters/lox/Environment.java
+++ b/src/com/craftinginterpreters/lox/Environment.java
@@ -14,6 +14,15 @@ class Environment {
throw new RuntimeError(name, "Undefined variable '" + name.lexeme + "'.");
}
+ void assign(Token name, Object value) {
+ if (values.containsKey(name.lexeme)) {
+ values.put(name.lexeme, value);
+ return;
+ }
+
+ throw new RuntimeError(name, "Undefined variable '" + name.lexeme + "'.");
+ }
+
void define(String name, Object value) {
values.put(name, value);
}
diff --git a/src/com/craftinginterpreters/lox/Interpreter.java b/src/com/craftinginterpreters/lox/Interpreter.java
index f4e7f99..7378164 100644
--- a/src/com/craftinginterpreters/lox/Interpreter.java
+++ b/src/com/craftinginterpreters/lox/Interpreter.java
@@ -114,6 +114,13 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
}
@Override
+ public Object visitAssignExpr(Expr.Assign expr) {
+ Object value = evaluate(expr.value);
+ environment.assign(expr.name, value);
+ return value;
+ }
+
+ @Override
public Object visitBinaryExpr(Expr.Binary expr) {
Object left = evaluate(expr.left);
Object right = evaluate(expr.right);
diff --git a/src/com/craftinginterpreters/lox/Parser.java b/src/com/craftinginterpreters/lox/Parser.java
index 9a9c0e6..9e76a54 100644
--- a/src/com/craftinginterpreters/lox/Parser.java
+++ b/src/com/craftinginterpreters/lox/Parser.java
@@ -27,7 +27,7 @@ class Parser {
}
private Expr expression() {
- return equality();
+ return assignment();
}
private Stmt declaration() {
@@ -73,6 +73,24 @@ class Parser {
return new Stmt.Expression(expr);
}
+ private Expr assignment() {
+ Expr expr = equality();
+
+ if (match(EQUAL)) {
+ Token equals = previous();
+ Expr value = assignment();
+
+ if (expr instanceof Expr.Variable) {
+ Token name = ((Expr.Variable) expr).name;
+ return new Expr.Assign(name, value);
+ }
+
+ error(equals, "Invalid assignment target.");
+ }
+
+ return expr;
+ }
+
private Expr equality() {
Expr expr = comparison();
diff --git a/src/com/craftinginterpreters/tool/GenerateAst.java b/src/com/craftinginterpreters/tool/GenerateAst.java
index d2cb5cf..f96e315 100644
--- a/src/com/craftinginterpreters/tool/GenerateAst.java
+++ b/src/com/craftinginterpreters/tool/GenerateAst.java
@@ -15,7 +15,7 @@ public class GenerateAst {
String outputDir = args[0];
defineAst(outputDir, "Expr",
- Arrays.asList("Binary : Expr left, Token operator, Expr right", "Grouping : Expr expression",
+ Arrays.asList("Assign : Token name, Expr value", "Binary : Expr left, Token operator, Expr right", "Grouping : Expr expression",
"Literal : Object value", "Unary : Token operator, Expr right", "Variable : Token name"));
defineAst(outputDir, "Stmt", Arrays.asList("Expression : Expr expression", "Print : Expr expression",
"Var : Token name, Expr initializer"));