Chapter 8: Add assignment
This commit is contained in:
parent
ae33509615
commit
57e87978ef
5 changed files with 41 additions and 2 deletions
|
@ -35,6 +35,11 @@ class AstPrinter implements Expr.Visitor<String>, Stmt.Visitor<String> {
|
||||||
return expr.name.lexeme;
|
return expr.name.lexeme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visitAssignExpr(Expr.Assign expression) {
|
||||||
|
return parenthesize(expression.name.lexeme + " = ", expression.value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String visitVarStmt(Stmt.Var statement) {
|
public String visitVarStmt(Stmt.Var statement) {
|
||||||
return parenthesize("define " + statement.name.lexeme + " = ", statement.initializer);
|
return parenthesize("define " + statement.name.lexeme + " = ", statement.initializer);
|
||||||
|
|
|
@ -14,6 +14,15 @@ class Environment {
|
||||||
throw new RuntimeError(name, "Undefined variable '" + name.lexeme + "'.");
|
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) {
|
void define(String name, Object value) {
|
||||||
values.put(name, value);
|
values.put(name, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,13 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitAssignExpr(Expr.Assign expr) {
|
||||||
|
Object value = evaluate(expr.value);
|
||||||
|
environment.assign(expr.name, value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitBinaryExpr(Expr.Binary expr) {
|
public Object visitBinaryExpr(Expr.Binary expr) {
|
||||||
Object left = evaluate(expr.left);
|
Object left = evaluate(expr.left);
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expr expression() {
|
private Expr expression() {
|
||||||
return equality();
|
return assignment();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stmt declaration() {
|
private Stmt declaration() {
|
||||||
|
@ -73,6 +73,24 @@ class Parser {
|
||||||
return new Stmt.Expression(expr);
|
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() {
|
private Expr equality() {
|
||||||
Expr expr = comparison();
|
Expr expr = comparison();
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public class GenerateAst {
|
||||||
String outputDir = args[0];
|
String outputDir = args[0];
|
||||||
|
|
||||||
defineAst(outputDir, "Expr",
|
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"));
|
"Literal : Object value", "Unary : Token operator, Expr right", "Variable : Token name"));
|
||||||
defineAst(outputDir, "Stmt", Arrays.asList("Expression : Expr expression", "Print : Expr expression",
|
defineAst(outputDir, "Stmt", Arrays.asList("Expression : Expr expression", "Print : Expr expression",
|
||||||
"Var : Token name, Expr initializer"));
|
"Var : Token name, Expr initializer"));
|
||||||
|
|
Loading…
Reference in a new issue