functions
This commit is contained in:
		@@ -28,6 +28,19 @@ class ASTPrinter implements Expr.Visitor<String> {
 | 
				
			|||||||
    return parenthesize(expr.operator.lexeme, expr.right);
 | 
					    return parenthesize(expr.operator.lexeme, expr.right);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public String visitCallExpr(Expr.Call expr) {
 | 
				
			||||||
 | 
					    StringBuilder builder = new StringBuilder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    builder.append(expr.callee.toString()).append("(");
 | 
				
			||||||
 | 
					    for (Expr arg : expr.arguments) {
 | 
				
			||||||
 | 
					      builder.append(arg.accept(this)).append(", ");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    builder.append(")");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return builder.toString();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Override
 | 
					  @Override
 | 
				
			||||||
  public String visitVariableExpr(Expr.Variable expr) {
 | 
					  public String visitVariableExpr(Expr.Variable expr) {
 | 
				
			||||||
    return expr.name.toString();
 | 
					    return expr.name.toString();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ abstract class Expr {
 | 
				
			|||||||
  interface Visitor<R> {
 | 
					  interface Visitor<R> {
 | 
				
			||||||
    R visitAssignExpr(Assign expr);
 | 
					    R visitAssignExpr(Assign expr);
 | 
				
			||||||
    R visitBinaryExpr(Binary expr);
 | 
					    R visitBinaryExpr(Binary expr);
 | 
				
			||||||
 | 
					    R visitCallExpr(Call expr);
 | 
				
			||||||
    R visitGroupingExpr(Grouping expr);
 | 
					    R visitGroupingExpr(Grouping expr);
 | 
				
			||||||
    R visitLiteralExpr(Literal expr);
 | 
					    R visitLiteralExpr(Literal expr);
 | 
				
			||||||
    R visitLogicalExpr(Logical expr);
 | 
					    R visitLogicalExpr(Logical expr);
 | 
				
			||||||
@@ -45,6 +46,23 @@ abstract class Expr {
 | 
				
			|||||||
    final Expr right;
 | 
					    final Expr right;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static class Call extends Expr {
 | 
				
			||||||
 | 
					    Call(Expr callee, Token paren, List<Expr> arguments) {
 | 
				
			||||||
 | 
					      this.callee = callee;
 | 
				
			||||||
 | 
					      this.paren = paren;
 | 
				
			||||||
 | 
					      this.arguments = arguments;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    <R> R accept(Visitor<R> visitor) {
 | 
				
			||||||
 | 
					      return visitor.visitCallExpr(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    final Expr callee;
 | 
				
			||||||
 | 
					    final Token paren;
 | 
				
			||||||
 | 
					    final List<Expr> arguments;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static class Grouping extends Expr {
 | 
					  static class Grouping extends Expr {
 | 
				
			||||||
    Grouping(Expr expression) {
 | 
					    Grouping(Expr expression) {
 | 
				
			||||||
      this.expression = expression;
 | 
					      this.expression = expression;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,32 @@
 | 
				
			|||||||
package lox;
 | 
					package lox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
 | 
					class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
 | 
				
			||||||
  private Environment environment = new Environment();
 | 
					  final Environment globals = new Environment();
 | 
				
			||||||
 | 
					  private Environment environment = globals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Interpreter() {
 | 
				
			||||||
 | 
					    globals.define(
 | 
				
			||||||
 | 
					        "clock",
 | 
				
			||||||
 | 
					        new LoxCallable() {
 | 
				
			||||||
 | 
					          @Override
 | 
				
			||||||
 | 
					          public int arity() {
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          @Override
 | 
				
			||||||
 | 
					          public Object call(Interpreter interpreter, List<Object> arguments) {
 | 
				
			||||||
 | 
					            return (double) System.currentTimeMillis() / 1000.0;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          @Override
 | 
				
			||||||
 | 
					          public String toString() {
 | 
				
			||||||
 | 
					            return "<native fn>";
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void interpret(List<Stmt> statements) {
 | 
					  void interpret(List<Stmt> statements) {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -57,6 +80,27 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
 | 
				
			|||||||
    return null;
 | 
					    return null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public Object visitCallExpr(Expr.Call expr) {
 | 
				
			||||||
 | 
					    Object callee = evaluate(expr.callee);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<Object> arguments = new ArrayList<>();
 | 
				
			||||||
 | 
					    for (Expr argument : expr.arguments) {
 | 
				
			||||||
 | 
					      arguments.add(evaluate(argument));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(callee instanceof LoxCallable)) {
 | 
				
			||||||
 | 
					      throw new RuntimeError(expr.paren, "Can only call functions and classes");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    LoxCallable function = (LoxCallable) callee;
 | 
				
			||||||
 | 
					    if (arguments.size() != function.arity()) {
 | 
				
			||||||
 | 
					      throw new RuntimeError(
 | 
				
			||||||
 | 
					          expr.paren,
 | 
				
			||||||
 | 
					          "Expected " + function.arity() + " arguments but called with " + arguments.size() + ".");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return function.call(this, arguments);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Override
 | 
					  @Override
 | 
				
			||||||
  public Object visitBinaryExpr(Expr.Binary expr) {
 | 
					  public Object visitBinaryExpr(Expr.Binary expr) {
 | 
				
			||||||
    Object left = evaluate(expr.left);
 | 
					    Object left = evaluate(expr.left);
 | 
				
			||||||
@@ -119,6 +163,13 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
 | 
				
			|||||||
    return null;
 | 
					    return null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public Void visitFunctionStmt(Stmt.Function stmt) {
 | 
				
			||||||
 | 
					    LoxFunction function = new LoxFunction(stmt, environment);
 | 
				
			||||||
 | 
					    environment.define(stmt.name.lexeme, function);
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Override
 | 
					  @Override
 | 
				
			||||||
  public Void visitIfStmt(Stmt.If stmt) {
 | 
					  public Void visitIfStmt(Stmt.If stmt) {
 | 
				
			||||||
    if (isTruthy(evaluate(stmt.condition))) {
 | 
					    if (isTruthy(evaluate(stmt.condition))) {
 | 
				
			||||||
@@ -136,6 +187,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;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								src/lox/LoxCallable.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/lox/LoxCallable.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					package lox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface LoxCallable {
 | 
				
			||||||
 | 
					  int arity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Object call(Interpreter interpreter, List<Object> arguments);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								src/lox/LoxFunction.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/lox/LoxFunction.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					package lox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LoxFunction implements LoxCallable {
 | 
				
			||||||
 | 
					  private final Stmt.Function declaration;
 | 
				
			||||||
 | 
					  private final Environment closure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LoxFunction(Stmt.Function declaration, Environment closure) {
 | 
				
			||||||
 | 
					    this.closure = closure;
 | 
				
			||||||
 | 
					    this.declaration = declaration;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public Object call(Interpreter interpreter, List<Object> arguments) {
 | 
				
			||||||
 | 
					    Environment environment = new Environment(closure);
 | 
				
			||||||
 | 
					    for (int i = 0; i < declaration.params.size(); i++) {
 | 
				
			||||||
 | 
					      environment.define(declaration.params.get(i).lexeme, arguments.get(i));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      interpreter.executeBlock(declaration.body, environment);
 | 
				
			||||||
 | 
					    } catch (Return returnValue) {
 | 
				
			||||||
 | 
					      return returnValue.value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public int arity() {
 | 
				
			||||||
 | 
					    return declaration.params.size();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public String toString() {
 | 
				
			||||||
 | 
					    return "<fn " + declaration.name.lexeme + ">";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -26,6 +26,9 @@ class Parser {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  private Stmt declaration() {
 | 
					  private Stmt declaration() {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
 | 
					      if (match(FUN)) {
 | 
				
			||||||
 | 
					        return function("function");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (match(VAR)) {
 | 
					      if (match(VAR)) {
 | 
				
			||||||
        return varDeclaration();
 | 
					        return varDeclaration();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -57,6 +60,9 @@ class Parser {
 | 
				
			|||||||
    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();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -72,6 +78,16 @@ 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 whileStatement() {
 | 
					  private Stmt whileStatement() {
 | 
				
			||||||
    consume(LEFT_PAREN, "Expect '(' after 'while");
 | 
					    consume(LEFT_PAREN, "Expect '(' after 'while");
 | 
				
			||||||
    Expr condition = expression();
 | 
					    Expr condition = expression();
 | 
				
			||||||
@@ -87,6 +103,24 @@ class Parser {
 | 
				
			|||||||
    return new Stmt.Expression(value);
 | 
					    return new Stmt.Expression(value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private Stmt function(String kind) {
 | 
				
			||||||
 | 
					    Token name = consume(IDENTIFIER, "Expect " + kind + " name.");
 | 
				
			||||||
 | 
					    consume(LEFT_PAREN, "Expect '(' after " + kind + "name");
 | 
				
			||||||
 | 
					    List<Token> parameters = new ArrayList<>();
 | 
				
			||||||
 | 
					    if (!check(RIGHT_PAREN)) {
 | 
				
			||||||
 | 
					      do {
 | 
				
			||||||
 | 
					        if (parameters.size() >= 255) {
 | 
				
			||||||
 | 
					          error(peek(), "Can't have more than 255 parameters.");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        parameters.add(consume(IDENTIFIER, "Expect parameter name."));
 | 
				
			||||||
 | 
					      } while (match(COMMA));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    consume(RIGHT_PAREN, "Expect ')' after parameters.");
 | 
				
			||||||
 | 
					    consume(LEFT_BRACE, "Expect '{' before " + kind + " body.");
 | 
				
			||||||
 | 
					    List<Stmt> body = block();
 | 
				
			||||||
 | 
					    return new Stmt.Function(name, parameters, body);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private Stmt ifStatement() {
 | 
					  private Stmt ifStatement() {
 | 
				
			||||||
    consume(LEFT_PAREN, "Expect '(' after 'if'.");
 | 
					    consume(LEFT_PAREN, "Expect '(' after 'if'.");
 | 
				
			||||||
    Expr condition = expression();
 | 
					    Expr condition = expression();
 | 
				
			||||||
@@ -245,7 +279,38 @@ class Parser {
 | 
				
			|||||||
      Expr right = unary();
 | 
					      Expr right = unary();
 | 
				
			||||||
      return new Expr.Unary(operator, right);
 | 
					      return new Expr.Unary(operator, right);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return primary();
 | 
					    return call();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private Expr call() {
 | 
				
			||||||
 | 
					    Expr expr = primary();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (true) {
 | 
				
			||||||
 | 
					      if (match(LEFT_PAREN)) {
 | 
				
			||||||
 | 
					        expr = finishCall(expr);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return expr;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private Expr finishCall(Expr callee) {
 | 
				
			||||||
 | 
					    List<Expr> arguments  = new ArrayList<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!check(RIGHT_PAREN)) {
 | 
				
			||||||
 | 
					      do {
 | 
				
			||||||
 | 
					        arguments.add(expression());
 | 
				
			||||||
 | 
					      } while (match(COMMA));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Token paren = consume(RIGHT_PAREN, "Expected ')' after argument list");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (arguments.size() >= 255) {
 | 
				
			||||||
 | 
					      error(peek(), "Can't have more than 255 arguments");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return new Expr.Call(callee, paren, arguments);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private Expr primary() {
 | 
					  private Expr primary() {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								src/lox/Return.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/lox/Return.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					package lox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Return extends RuntimeException{
 | 
				
			||||||
 | 
					  final Object value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Return(Object value) {
 | 
				
			||||||
 | 
					    super(null, null, false, false);
 | 
				
			||||||
 | 
					    this.value = value;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -6,9 +6,11 @@ abstract class Stmt {
 | 
				
			|||||||
  interface Visitor<R> {
 | 
					  interface Visitor<R> {
 | 
				
			||||||
    R visitBlockStmt(Block stmt);
 | 
					    R visitBlockStmt(Block stmt);
 | 
				
			||||||
    R visitExpressionStmt(Expression stmt);
 | 
					    R visitExpressionStmt(Expression stmt);
 | 
				
			||||||
 | 
					    R visitFunctionStmt(Function stmt);
 | 
				
			||||||
    R visitIfStmt(If stmt);
 | 
					    R visitIfStmt(If stmt);
 | 
				
			||||||
    R visitVarStmt(Var stmt);
 | 
					    R visitVarStmt(Var stmt);
 | 
				
			||||||
    R visitPrintStmt(Print stmt);
 | 
					    R visitPrintStmt(Print stmt);
 | 
				
			||||||
 | 
					    R visitReturnStmt(Return stmt);
 | 
				
			||||||
    R visitWhileStmt(While stmt);
 | 
					    R visitWhileStmt(While stmt);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,6 +40,23 @@ abstract class Stmt {
 | 
				
			|||||||
    final Expr expression;
 | 
					    final Expr expression;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static class Function extends Stmt {
 | 
				
			||||||
 | 
					    Function(Token name, List<Token> params, List<Stmt> body) {
 | 
				
			||||||
 | 
					      this.name = name;
 | 
				
			||||||
 | 
					      this.params = params;
 | 
				
			||||||
 | 
					      this.body = body;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    <R> R accept(Visitor<R> visitor) {
 | 
				
			||||||
 | 
					      return visitor.visitFunctionStmt(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    final Token name;
 | 
				
			||||||
 | 
					    final List<Token> params;
 | 
				
			||||||
 | 
					    final List<Stmt> body;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static class If extends Stmt {
 | 
					  static class If extends Stmt {
 | 
				
			||||||
    If(Expr condition, Stmt thenBranch, Stmt elseBranch) {
 | 
					    If(Expr condition, Stmt thenBranch, Stmt elseBranch) {
 | 
				
			||||||
      this.condition = condition;
 | 
					      this.condition = condition;
 | 
				
			||||||
@@ -83,6 +102,21 @@ abstract class Stmt {
 | 
				
			|||||||
    final Expr expression;
 | 
					    final Expr expression;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static class Return extends Stmt {
 | 
				
			||||||
 | 
					    Return(Token keyword, Expr value) {
 | 
				
			||||||
 | 
					      this.keyword = keyword;
 | 
				
			||||||
 | 
					      this.value = value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    <R> R accept(Visitor<R> visitor) {
 | 
				
			||||||
 | 
					      return visitor.visitReturnStmt(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    final Token keyword;
 | 
				
			||||||
 | 
					    final Expr value;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static class While extends Stmt {
 | 
					  static class While extends Stmt {
 | 
				
			||||||
    While(Expr condition, Stmt body) {
 | 
					    While(Expr condition, Stmt body) {
 | 
				
			||||||
      this.condition = condition;
 | 
					      this.condition = condition;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ public class GenerateAST {
 | 
				
			|||||||
        Arrays.asList(
 | 
					        Arrays.asList(
 | 
				
			||||||
            "Assign   : Token name, Expr value",
 | 
					            "Assign   : Token name, Expr value",
 | 
				
			||||||
            "Binary   : Expr left, Token operator, Expr right",
 | 
					            "Binary   : Expr left, Token operator, Expr right",
 | 
				
			||||||
 | 
					            "Call     : Expr callee, Token paren, List<Expr> arguments",
 | 
				
			||||||
            "Grouping : Expr expression",
 | 
					            "Grouping : Expr expression",
 | 
				
			||||||
            "Literal  : Object value",
 | 
					            "Literal  : Object value",
 | 
				
			||||||
            "Logical  : Expr left, Token operator, Expr right",
 | 
					            "Logical  : Expr left, Token operator, Expr right",
 | 
				
			||||||
@@ -32,9 +33,11 @@ public class GenerateAST {
 | 
				
			|||||||
        Arrays.asList(
 | 
					        Arrays.asList(
 | 
				
			||||||
            "Block      : List<Stmt> statements",
 | 
					            "Block      : List<Stmt> statements",
 | 
				
			||||||
            "Expression : Expr expression",
 | 
					            "Expression : Expr expression",
 | 
				
			||||||
 | 
					            "Function   : Token name, List<Token> params, List<Stmt> body",
 | 
				
			||||||
            "If         : Expr condition, Stmt thenBranch, Stmt elseBranch",
 | 
					            "If         : Expr condition, Stmt thenBranch, Stmt elseBranch",
 | 
				
			||||||
            "Var        : Token name, Expr initializer",
 | 
					            "Var        : Token name, Expr initializer",
 | 
				
			||||||
            "Print      : Expr expression",
 | 
					            "Print      : Expr expression",
 | 
				
			||||||
 | 
					            "Return     : Token keyword, Expr value",
 | 
				
			||||||
            "While      : Expr condition, Stmt body"));
 | 
					            "While      : Expr condition, Stmt body"));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user