aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tom Willemse2021-02-08 17:42:18 -0800
committerGravatar Tom Willemse2021-02-08 17:42:18 -0800
commit0dbf155da52c5db1cab2688b04c87386a55c5d5b (patch)
treec76c0bc5b4364b7740ae071ee4c1ee7ad9c196e8
parent4a71c219b5fa8e9e28af43925284f429092ba68e (diff)
downloadcrafting-interpreters-0dbf155da52c5db1cab2688b04c87386a55c5d5b.tar.gz
crafting-interpreters-0dbf155da52c5db1cab2688b04c87386a55c5d5b.zip
Add return statement
-rw-r--r--src/com/craftinginterpreters/lox/CMakeLists.txt1
-rw-r--r--src/com/craftinginterpreters/lox/Interpreter.java31
-rw-r--r--src/com/craftinginterpreters/lox/LoxFunction.java6
-rw-r--r--src/com/craftinginterpreters/lox/Parser.java13
-rw-r--r--src/com/craftinginterpreters/lox/Return.java10
-rw-r--r--src/com/craftinginterpreters/tool/GenerateAst.java3
6 files changed, 53 insertions, 11 deletions
diff --git a/src/com/craftinginterpreters/lox/CMakeLists.txt b/src/com/craftinginterpreters/lox/CMakeLists.txt
index a068037..fa93588 100644
--- a/src/com/craftinginterpreters/lox/CMakeLists.txt
+++ b/src/com/craftinginterpreters/lox/CMakeLists.txt
@@ -21,4 +21,5 @@ add_jar(Lox
Environment.java
LoxCallable.java
LoxFunction.java
+ Return.java
ENTRY_POINT com/craftinginterpreters/lox/Lox)
diff --git a/src/com/craftinginterpreters/lox/Interpreter.java b/src/com/craftinginterpreters/lox/Interpreter.java
index 407c537..4549e11 100644
--- a/src/com/craftinginterpreters/lox/Interpreter.java
+++ b/src/com/craftinginterpreters/lox/Interpreter.java
@@ -9,17 +9,21 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
Interpreter() {
globals.define("clock", new LoxCallable() {
- @Override
- public int arity() { return 0; }
+ @Override
+ public int arity() {
+ return 0;
+ }
- @Override
- public Object call(Interpreter interpreter, List<Object> arguments) {
- return (double)System.currentTimeMillis() / 1000.0;
- }
+ @Override
+ public Object call(Interpreter interpreter, List<Object> arguments) {
+ return (double) System.currentTimeMillis() / 1000.0;
+ }
- @Override
- public String toString() { return "<native fn>"; }
- });
+ @Override
+ public String toString() {
+ return "<native fn>";
+ }
+ });
}
@Override
@@ -173,6 +177,15 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
}
@Override
+ public Void visitReturnStmt(Stmt.Return stmt) {
+ Object value = null;
+ if (stmt.value != null)
+ value = evaluate(stmt.value);
+
+ throw new Return(value);
+ }
+
+ @Override
public Void visitVarStmt(Stmt.Var stmt) {
Object value = null;
if (stmt.initializer != null) {
diff --git a/src/com/craftinginterpreters/lox/LoxFunction.java b/src/com/craftinginterpreters/lox/LoxFunction.java
index d2e367b..0f7ebd4 100644
--- a/src/com/craftinginterpreters/lox/LoxFunction.java
+++ b/src/com/craftinginterpreters/lox/LoxFunction.java
@@ -22,7 +22,11 @@ class LoxFunction implements LoxCallable {
environment.define(declaration.params.get(i).lexeme, arguments.get(i));
}
- interpreter.executeBlock(declaration.body, environment);
+ try {
+ interpreter.executeBlock(declaration.body, environment);
+ } catch (Return returnValue) {
+ return returnValue.value;
+ }
return null;
}
diff --git a/src/com/craftinginterpreters/lox/Parser.java b/src/com/craftinginterpreters/lox/Parser.java
index c427bc4..528326c 100644
--- a/src/com/craftinginterpreters/lox/Parser.java
+++ b/src/com/craftinginterpreters/lox/Parser.java
@@ -52,6 +52,8 @@ class Parser {
return ifStatement();
if (match(PRINT))
return printStatement();
+ if (match(RETURN))
+ return returnStatement();
if (match(WHILE))
return whileStatement();
if (match(LEFT_BRACE))
@@ -120,6 +122,17 @@ class Parser {
return new Stmt.Print(value);
}
+ private Stmt returnStatement() {
+ Token keyword = previous();
+ Expr value = null;
+ if (!check(SEMICOLON)) {
+ value = expression();
+ }
+
+ consume(SEMICOLON, "Expect ';' after return value.");
+ return new Stmt.Return(keyword, value);
+ }
+
private Stmt varDeclaration() {
Token name = consume(IDENTIFIER, "Expect variable name.");
diff --git a/src/com/craftinginterpreters/lox/Return.java b/src/com/craftinginterpreters/lox/Return.java
new file mode 100644
index 0000000..5bd62d0
--- /dev/null
+++ b/src/com/craftinginterpreters/lox/Return.java
@@ -0,0 +1,10 @@
+package com.craftinginterpreters.lox;
+
+class Return extends RuntimeException {
+ final Object value;
+
+ Return(Object value) {
+ super(null, null, false, false);
+ this.value = value;
+ }
+}
diff --git a/src/com/craftinginterpreters/tool/GenerateAst.java b/src/com/craftinginterpreters/tool/GenerateAst.java
index 92c7967..2bf442b 100644
--- a/src/com/craftinginterpreters/tool/GenerateAst.java
+++ b/src/com/craftinginterpreters/tool/GenerateAst.java
@@ -23,7 +23,8 @@ public class GenerateAst {
Arrays.asList("Block : List<Stmt> statements", "Expression : Expr expression",
"Function : Token name, List<Token> params, List<Stmt> body",
"If : Expr condition, Stmt thenBranch, Stmt elseBranch", "Print : Expr expression",
- "Var : Token name, Expr initializer", "While : Expr condition, Stmt body"));
+ "Return : Token keyword, Expr value", "Var : Token name, Expr initializer",
+ "While : Expr condition, Stmt body"));
}
private static void defineAst(String outputDir, String baseName, List<String> types) throws IOException {