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
|
Environment.java
|
||||||
LoxCallable.java
|
LoxCallable.java
|
||||||
LoxFunction.java
|
LoxFunction.java
|
||||||
|
Return.java
|
||||||
ENTRY_POINT com/craftinginterpreters/lox/Lox)
|
ENTRY_POINT com/craftinginterpreters/lox/Lox)
|
||||||
|
|
|
@ -9,17 +9,21 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
||||||
|
|
||||||
Interpreter() {
|
Interpreter() {
|
||||||
globals.define("clock", new LoxCallable() {
|
globals.define("clock", new LoxCallable() {
|
||||||
@Override
|
@Override
|
||||||
public int arity() { return 0; }
|
public int arity() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Interpreter interpreter, List<Object> arguments) {
|
public Object call(Interpreter interpreter, List<Object> arguments) {
|
||||||
return (double)System.currentTimeMillis() / 1000.0;
|
return (double) System.currentTimeMillis() / 1000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() { return "<native fn>"; }
|
public String toString() {
|
||||||
});
|
return "<native fn>";
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -172,6 +176,15 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
||||||
return null;
|
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
|
@Override
|
||||||
public Void visitVarStmt(Stmt.Var stmt) {
|
public Void visitVarStmt(Stmt.Var stmt) {
|
||||||
Object value = null;
|
Object value = null;
|
||||||
|
|
|
@ -22,7 +22,11 @@ class LoxFunction implements LoxCallable {
|
||||||
environment.define(declaration.params.get(i).lexeme, arguments.get(i));
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ class Parser {
|
||||||
return ifStatement();
|
return ifStatement();
|
||||||
if (match(PRINT))
|
if (match(PRINT))
|
||||||
return printStatement();
|
return printStatement();
|
||||||
|
if (match(RETURN))
|
||||||
|
return returnStatement();
|
||||||
if (match(WHILE))
|
if (match(WHILE))
|
||||||
return whileStatement();
|
return whileStatement();
|
||||||
if (match(LEFT_BRACE))
|
if (match(LEFT_BRACE))
|
||||||
|
@ -120,6 +122,17 @@ class Parser {
|
||||||
return new Stmt.Print(value);
|
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() {
|
private Stmt varDeclaration() {
|
||||||
Token name = consume(IDENTIFIER, "Expect variable name.");
|
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",
|
Arrays.asList("Block : List<Stmt> statements", "Expression : Expr expression",
|
||||||
"Function : Token name, List<Token> params, List<Stmt> body",
|
"Function : Token name, List<Token> params, List<Stmt> body",
|
||||||
"If : Expr condition, Stmt thenBranch, Stmt elseBranch", "Print : Expr expression",
|
"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 {
|
private static void defineAst(String outputDir, String baseName, List<String> types) throws IOException {
|
||||||
|
|
Loading…
Reference in a new issue