Add return statement
This commit is contained in:
parent
4a71c219b5
commit
0dbf155da5
6 changed files with 53 additions and 11 deletions
|
@ -21,4 +21,5 @@ add_jar(Lox
|
|||
Environment.java
|
||||
LoxCallable.java
|
||||
LoxFunction.java
|
||||
Return.java
|
||||
ENTRY_POINT com/craftinginterpreters/lox/Lox)
|
||||
|
|
|
@ -10,7 +10,9 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
|||
Interpreter() {
|
||||
globals.define("clock", new LoxCallable() {
|
||||
@Override
|
||||
public int arity() { return 0; }
|
||||
public int arity() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call(Interpreter interpreter, List<Object> arguments) {
|
||||
|
@ -18,7 +20,9 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return "<native fn>"; }
|
||||
public String toString() {
|
||||
return "<native fn>";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -172,6 +176,15 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@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;
|
||||
|
|
|
@ -22,7 +22,11 @@ class LoxFunction implements LoxCallable {
|
|||
environment.define(declaration.params.get(i).lexeme, arguments.get(i));
|
||||
}
|
||||
|
||||
try {
|
||||
interpreter.executeBlock(declaration.body, environment);
|
||||
} catch (Return returnValue) {
|
||||
return returnValue.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.");
|
||||
|
||||
|
|
10
src/com/craftinginterpreters/lox/Return.java
Normal file
10
src/com/craftinginterpreters/lox/Return.java
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue