From 65803fba3a361b6784ebc25eaa2750d2b0eb66f2 Mon Sep 17 00:00:00 2001 From: nigel barink Date: Sat, 23 Mar 2024 13:31:37 +0100 Subject: [PATCH] Basic Repl setup --- app/src/main/java/org/barink/Lox.java | 66 +++++++++++++++++++++ app/src/main/java/org/barink/Scanner.java | 30 ++++++++++ app/src/main/java/org/barink/Token.java | 19 ++++++ app/src/main/java/org/barink/TokenType.java | 24 ++++++++ 4 files changed, 139 insertions(+) create mode 100644 app/src/main/java/org/barink/Lox.java create mode 100644 app/src/main/java/org/barink/Scanner.java create mode 100644 app/src/main/java/org/barink/Token.java create mode 100644 app/src/main/java/org/barink/TokenType.java diff --git a/app/src/main/java/org/barink/Lox.java b/app/src/main/java/org/barink/Lox.java new file mode 100644 index 0000000..bb82800 --- /dev/null +++ b/app/src/main/java/org/barink/Lox.java @@ -0,0 +1,66 @@ +/* + * This Java source file was generated by the Gradle 'init' task. + */ +package org.barink; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; + + +public class Lox { + static boolean hadError = false; + + public static void main(String[] args) { + if (args.length > 1){ + System.out.println("Usage: jlox [script]"); + System.exit(64); + } else if (args.length == 1) { + runFile(args[0]); + }else{ + runPrompt(); + } + } + + private static void runFile(String path) throws IOException{ + byte[] bytes = Files.readAllBytes(Paths.get(path)); + run(new String(bytes, Charset.defaultCharset())); + if (hadError) System.exit(65); + } + + private static void runPrompt() throws IOException{ + InputStreamReader input = new InputStreamReader(System.in); + BufferedReader reader = new BufferedReader(input); + + for(;;){ + System.out.println("> "); + String line = reader.readLine(); + if(line == null ) break; + run(line); + hadError = false; + } + } + + private static void run(String source){ + Scanner scanner = new Scanner(source); + List tokens = scanner.scanTokens(); + + // For now, just print the tokens + for (Token token : tokens){ + System.out.println(token); + } + } + + static void error(int line, String message){ + report(line, "", message); + } + + private static void report(int line, String where, String message){ + hadError = true; + } + + +} diff --git a/app/src/main/java/org/barink/Scanner.java b/app/src/main/java/org/barink/Scanner.java new file mode 100644 index 0000000..3e59d58 --- /dev/null +++ b/app/src/main/java/org/barink/Scanner.java @@ -0,0 +1,30 @@ +package org.barink; + +import java.util.ArrayList; +import java.util.List; + +class Scanner { + private final String source; + private final List tokens = new ArrayList<>(); + private int start = 0; + private int current = 0; + private int line = 1; + + Scanner(String source){ + this.source = source; + } + + List scanTokens(){ + while (!isAtEnd()){ + // We are at the beginning of the next lexeme + start = current; + scanToken(); + } + tokens.add(new Token(TokenType.EOF, "", null, line)); + return tokens + } + + private boolean isAtEnd(){ + return current >= source.length(); + } +} diff --git a/app/src/main/java/org/barink/Token.java b/app/src/main/java/org/barink/Token.java new file mode 100644 index 0000000..f1cfb94 --- /dev/null +++ b/app/src/main/java/org/barink/Token.java @@ -0,0 +1,19 @@ +package org.barink; + +class Token { + final TokenType type; + final String lexeme; + final Object literal; + final int line; + + Token(TokenType type, String lexeme, Object literal, int line){ + this.type = type; + this.lexeme = lexeme; + this.literal = literal; + this.line = line; + } + + public String toString(){ + return type + " " + lexeme + " " + literal; + } +} diff --git a/app/src/main/java/org/barink/TokenType.java b/app/src/main/java/org/barink/TokenType.java new file mode 100644 index 0000000..1e8cbb7 --- /dev/null +++ b/app/src/main/java/org/barink/TokenType.java @@ -0,0 +1,24 @@ +package org.barink; + +enum TokenType { + // Single-character tokens. + LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE, + COMMA, DOT, MINUS, PLUS, SEMICOLON, SLASH, STAR, + + // One or two character tokens. + BANG, BANG_EQUAL, + EQUAL, EQUAL_EQUAL, + GREATER, GREATER_EQUAL, + LESS, LESS_EQUAL, + + // Literals + IDENTIFIER, STRING, NUMBER, + + // Keywords + AND, CLASS, ELSE, FALSE, FUN, FOR, IF, NIL, OR, + PRINT, RETURN, SUPER, THIS, TRUE, VAR, WHILE, + + EOF +} + +