primary method

Expr primary()

Implementation

Expr primary() {
  if (match([TokenType.FALSE])) return Literal(false);
  if (match([TokenType.TRUE])) return Literal(true);
  if (match([TokenType.NIL])) return Literal(null);
  if (match([TokenType.NUMBER, TokenType.STRING])) {
    return Literal(previous().literal);
  }
  if (match([TokenType.IF])) {
    consume(TokenType.LEFT_PAREN, "Expect '(' after 'if'.");
    Expr condition = expression();
    consume(TokenType.RIGHT_PAREN, "Expect ')' after if condition.");
    Expr thenBranch = expression();
    Expr? elseBranch;
    if (match([TokenType.ELSE])) {
      elseBranch = expression();
    }
    return Arrayif(condition, thenBranch, elseBranch);
  }

  if (match([TokenType.SUPER])) {
    Token keyword = previous();
    consume(TokenType.DOT, "Expect '.' after 'SUPER'.");
    Token method =
        consume(TokenType.IDENTIFIER, "Expect superclass method name.");
    return Super(keyword, method);
  }
  if (match([TokenType.THIS])) return This(previous());

  if (match([TokenType.IDENTIFIER])) {
    return Variable(previous());
  }
  var currentSnap = current;
  bool isAnonymous = false;
  if (match([TokenType.LEFT_PAREN])) {
    if (!check(TokenType.RIGHT_PAREN)) {
      do {
        if (check(TokenType.RIGHT_PAREN)) break;
        expression();
      } while (match([TokenType.COMMA]));
    }
    consume(TokenType.RIGHT_PAREN, "Expect ')' after parameters.");
    if (check(TokenType.LEFT_BRACE)) {
      isAnonymous = true;
    }
    current = currentSnap;
  }

  if (isAnonymous) {
    consume(TokenType.LEFT_PAREN, "Expect '(' after map.");
    List<Token> parameters = [];
    if (!check(TokenType.RIGHT_PAREN)) {
      do {
        if (check(TokenType.RIGHT_PAREN)) break;
        parameters.add(
          consume(TokenType.IDENTIFIER, "Expect parameter name."),
        );
      } while (match([TokenType.COMMA]));
    }
    Token paren =
        consume(TokenType.RIGHT_PAREN, "Expect ')' after parameters.");
    consume(TokenType.LEFT_BRACE, "Expect '{' before map body.");
    List<Stmt> body = block();
    Expr anony = Anonymous(paren, parameters, body);
    return anony;
  }
  if (match([TokenType.LEFT_PAREN])) {
    Expr expr = expression();
    consume(TokenType.RIGHT_PAREN, "Expect ')' after expression.");
    return Grouping(expr);
  }
  throw error(peek(), "Expect expression.");
}