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;
|
||||
}
|
||||
|
||||
@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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -113,6 +113,13 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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"));
|
||||
|
|
Loading…
Reference in a new issue