Lox.java 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* Copyright (C) 2019-2023 Hangzhou HSH Co. Ltd.
  2. * All right reserved.*/
  3. package com.craftinginterpreters.lox;
  4. import java.io.BufferedReader;
  5. import java.io.IOException;
  6. import java.io.InputStreamReader;
  7. import java.nio.charset.Charset;
  8. import java.nio.file.Files;
  9. import java.nio.file.Path;
  10. import java.util.List;
  11. /**
  12. * @author simon
  13. * @date 2023-06-04 15:21
  14. * @desc
  15. */
  16. public class Lox {
  17. private static final Interpreter interpreter = new Interpreter();
  18. private static boolean hadError = false;
  19. private static boolean hadRuntimeError = false;
  20. public static void main(String[] args) throws IOException {
  21. if (args.length > 1) {
  22. System.out.println("Usage: jlox [script]");
  23. System.exit(64);
  24. } else if (args.length == 1) {
  25. runFile(args[0]);
  26. } else {
  27. runPrompt();
  28. }
  29. }
  30. /**
  31. * start jlox from the command line and give it a path to a file, it reads the file and executes
  32. * it
  33. *
  34. * @param path 文件路径
  35. */
  36. private static void runFile(String path) throws IOException {
  37. byte[] bytes = Files.readAllBytes(Path.of(path));
  38. run(new String(bytes, Charset.defaultCharset()));
  39. // Indicate an error in the exit code.
  40. if (hadError) System.exit(65);
  41. if (hadRuntimeError) System.exit(70);
  42. }
  43. /** 提示符里面输入 */
  44. private static void runPrompt() throws IOException {
  45. InputStreamReader input = new InputStreamReader(System.in);
  46. BufferedReader reader = new BufferedReader(input);
  47. for (; ; ) {
  48. System.out.print("> ");
  49. String line = reader.readLine();
  50. if (line == null) break;
  51. run(line);
  52. // reset this flag in the interactive loop. If the user makes a mistake,
  53. // it shouldn’t kill their entire session.
  54. // hadError = true;
  55. }
  56. }
  57. private static void run(String source) {
  58. Scanner scanner = new Scanner(source);
  59. List<Token> tokens = scanner.scanTokens();
  60. // for (Token token : tokens) {
  61. // System.out.println(token);
  62. // }
  63. Parser parser = new Parser(tokens);
  64. List<Stmt> statements = parser.parse();
  65. // Stop if there was a syntax error.
  66. if (hadError) return;
  67. // System.out.println(" ...AST: " + new AstPrinter().print(statements));
  68. interpreter.interpret(statements);
  69. }
  70. /**
  71. * 错误处理
  72. *
  73. * @param line 行号
  74. * @param message 消息
  75. */
  76. static void error(int line, String message) {
  77. report(line, "", message);
  78. }
  79. private static void report(int line, String where, String message) {
  80. System.err.println("[line " + line + " ] Error " + where + ": " + message);
  81. hadError = true;
  82. }
  83. static void error(Token token, String message) {
  84. if (token.type == TokenType.EOF) {
  85. report(token.line, " at end", message);
  86. } else {
  87. report(token.line, " at '" + token.lexeme + "'", message);
  88. }
  89. }
  90. public static void runtimeError(RuntimeError error) {
  91. System.err.println(error.getMessage() + "\n[line " + error.token.line + "]");
  92. hadRuntimeError = true;
  93. }
  94. }