aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Tuomi <jan-sebastian.tuomi@aalto.fi>2016-07-31 22:50:34 +0300
committerJan Tuomi <jan-sebastian.tuomi@aalto.fi>2016-07-31 22:50:34 +0300
commit20a3fb57ae9ee1e70a2d57169742d481eac82fe9 (patch)
tree7c464d9ecc6274a3b43762b17e2dacec2d267c30
parentae7275e7ab7ea2b4599b613454d4c1149855bced (diff)
Implement enhanced REPL, relates to #13
Add command history and welcome message
-rw-r--r--pom.xml7
-rw-r--r--src/main/com/jantuomi/tunkki/Main.java68
-rw-r--r--src/main/com/jantuomi/tunkki/Tunkki.java83
-rw-r--r--src/main/com/jantuomi/tunkki/core/runtime/builtins/IncludeBuiltinFunction.java3
-rw-r--r--src/main/com/jantuomi/tunkki/repl/Repl.java52
-rw-r--r--src/test/com/jantuomi/tunkki/MainTest.java6
6 files changed, 155 insertions, 64 deletions
diff --git a/pom.xml b/pom.xml
index ed3d68d..6b02081 100644
--- a/pom.xml
+++ b/pom.xml
@@ -80,5 +80,12 @@
<version>4.12</version>
</dependency>
+ <!-- https://mvnrepository.com/artifact/jline/jline -->
+ <dependency>
+ <groupId>jline</groupId>
+ <artifactId>jline</artifactId>
+ <version>2.14.2</version>
+ </dependency>
+
</dependencies>
</project> \ No newline at end of file
diff --git a/src/main/com/jantuomi/tunkki/Main.java b/src/main/com/jantuomi/tunkki/Main.java
index 5148b68..37979ab 100644
--- a/src/main/com/jantuomi/tunkki/Main.java
+++ b/src/main/com/jantuomi/tunkki/Main.java
@@ -8,6 +8,7 @@ import com.jantuomi.tunkki.core.runtime.Interpreter;
import com.jantuomi.tunkki.core.tokenizer.Tokenizer;
import com.jantuomi.tunkki.core.tokenizer.token.Token;
import com.jantuomi.tunkki.exception.TunkkiError;
+import com.jantuomi.tunkki.repl.Repl;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
@@ -17,75 +18,22 @@ import java.util.Scanner;
public class Main {
+ private static Tunkki tunkki;
+
public static void main(String[] args) throws Exception {
- boolean parseSuccess = parseArguments(args);
+ tunkki = new Tunkki();
+
+ boolean parseSuccess = tunkki.parseArguments(args);
if (!parseSuccess) {
return;
}
if (CommandLineArgumentContainer.getInstance().isInteractive()) {
- repl();
+ tunkki.repl();
} else {
String sourceFileContents = CommandLineArgumentContainer.getInstance().getSourceFileContents();
- run(sourceFileContents);
- }
- }
-
- public static void repl() throws InterruptedException {
- Scanner scanner = new Scanner(System.in);
- String input;
- while (true) {
- System.out.print(">> ");
- input = scanner.nextLine();
-
- try {
- run(input);
- } catch (TunkkiError e) {
- e.printStackTrace();
- Thread.sleep(50);
- }
+ tunkki.run(sourceFileContents);
}
}
- public static void run(String input) throws TunkkiError {
- Tokenizer tokenizer = Tokenizer.getInstance();
- List<Token> sequence = tokenizer.tokenize(input);
-
- Collections.reverse(sequence);
-
- List<Token> trees = Parser.getInstance().parse(sequence);
- if (CommandLineArgumentContainer.getInstance().isDebugModeActive()) {
- Parser.getInstance().printAllTrees(trees);
- }
-
- List<ASTNode> nodes = ASTGenerator.getInstance().generate(trees);
- if (CommandLineArgumentContainer.getInstance().isDebugModeActive()) {
- ASTGenerator.getInstance().printAllTrees(nodes);
- }
-
- String output = Interpreter.execute(nodes);
-
- if (output.trim().length() > 0) {
- System.out.println(output);
- }
- }
-
- public static boolean parseArguments(String[] args) {
- CommandLineArgumentContainer container = CommandLineArgumentContainer.getInstance();
- CmdLineParser parser = new CmdLineParser(container);
-
-
- try {
- if (args.length == 0) {
- throw new CmdLineException("Please provide an argument.");
- }
- parser.parseArgument(args);
- } catch (CmdLineException e) {
- System.err.println(e.getMessage());
- parser.printUsage(System.err);
- return false;
- }
-
- return true;
- }
}
diff --git a/src/main/com/jantuomi/tunkki/Tunkki.java b/src/main/com/jantuomi/tunkki/Tunkki.java
new file mode 100644
index 0000000..a4120a8
--- /dev/null
+++ b/src/main/com/jantuomi/tunkki/Tunkki.java
@@ -0,0 +1,83 @@
+package com.jantuomi.tunkki;
+
+import com.jantuomi.tunkki.core.CommandLineArgumentContainer;
+import com.jantuomi.tunkki.core.parser.ASTGenerator;
+import com.jantuomi.tunkki.core.parser.Parser;
+import com.jantuomi.tunkki.core.parser.ast.ASTNode;
+import com.jantuomi.tunkki.core.runtime.Interpreter;
+import com.jantuomi.tunkki.core.tokenizer.Tokenizer;
+import com.jantuomi.tunkki.core.tokenizer.token.Token;
+import com.jantuomi.tunkki.exception.TunkkiError;
+import com.jantuomi.tunkki.repl.Repl;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import sun.awt.X11.XToolkit;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Scanner;
+
+public class Tunkki {
+
+ private static Tunkki instance;
+
+ public Tunkki() {
+ instance = this;
+ }
+
+ public static Tunkki getInstance() {
+ return instance;
+ }
+
+ public void repl() throws InterruptedException, IOException {
+ Repl repl = new Repl(this);
+ repl.run();
+ }
+
+ public void run(String input) throws TunkkiError {
+ Tokenizer tokenizer = Tokenizer.getInstance();
+ List<Token> sequence = tokenizer.tokenize(input);
+
+ Collections.reverse(sequence);
+
+ List<Token> trees = Parser.getInstance().parse(sequence);
+ if (CommandLineArgumentContainer.getInstance().isDebugModeActive()) {
+ Parser.getInstance().printAllTrees(trees);
+ }
+
+ List<ASTNode> nodes = ASTGenerator.getInstance().generate(trees);
+ if (CommandLineArgumentContainer.getInstance().isDebugModeActive()) {
+ ASTGenerator.getInstance().printAllTrees(nodes);
+ }
+
+ String output = Interpreter.execute(nodes);
+
+ if (output.trim().length() > 0) {
+ System.out.println(output);
+ }
+ }
+
+ public boolean parseArguments(String[] args) {
+ CommandLineArgumentContainer container = CommandLineArgumentContainer.getInstance();
+ CmdLineParser parser = new CmdLineParser(container);
+
+
+ try {
+ if (args.length == 0) {
+ throw new CmdLineException("Please provide an argument.");
+ }
+ parser.parseArgument(args);
+ } catch (CmdLineException e) {
+ System.err.println(e.getMessage());
+ parser.printUsage(System.err);
+ return false;
+ }
+
+ return true;
+ }
+
+ public String versionString() {
+ return "ALPHA";
+ }
+}
diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/IncludeBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/IncludeBuiltinFunction.java
index e6288ed..8db1d62 100644
--- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/IncludeBuiltinFunction.java
+++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/IncludeBuiltinFunction.java
@@ -2,6 +2,7 @@ package com.jantuomi.tunkki.core.runtime.builtins;
import com.jantuomi.tunkki.Main;
+import com.jantuomi.tunkki.Tunkki;
import com.jantuomi.tunkki.core.CommandLineArgumentContainer;
import com.jantuomi.tunkki.core.parser.datatype.Datatype;
import com.jantuomi.tunkki.core.parser.datatype.StringDatatype;
@@ -47,7 +48,7 @@ public class IncludeBuiltinFunction extends BuiltinFunction {
return null;
}
- Main.run(contents);
+ Tunkki.getInstance().run(contents);
return new VoidDatatype();
}
diff --git a/src/main/com/jantuomi/tunkki/repl/Repl.java b/src/main/com/jantuomi/tunkki/repl/Repl.java
new file mode 100644
index 0000000..817d746
--- /dev/null
+++ b/src/main/com/jantuomi/tunkki/repl/Repl.java
@@ -0,0 +1,52 @@
+package com.jantuomi.tunkki.repl;
+
+import com.jantuomi.tunkki.Tunkki;
+import com.jantuomi.tunkki.exception.TunkkiError;
+import jline.console.*;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * Created by jan on 31.7.2016.
+ */
+public class Repl {
+
+ private Tunkki tunkki;
+
+ public Repl(Tunkki tunkki) {
+ this.tunkki = tunkki;
+ }
+
+ public void run() throws IOException, InterruptedException {
+ showWelcomeText();
+
+ ConsoleReader reader = new ConsoleReader();
+ reader.setBellEnabled(false);
+
+ String line;
+ PrintWriter out = new PrintWriter(System.out);
+
+ while ((line = readLine(reader, "")) != null) {
+ try {
+ tunkki.run(line);
+ }
+ catch (TunkkiError ex) {
+ ex.printStackTrace();
+ Thread.sleep(50);
+ }
+
+ out.flush();
+ }
+ }
+
+ private String readLine(ConsoleReader reader, String promptMessage)
+ throws IOException {
+ String line = reader.readLine(promptMessage + "\ntunkki> ");
+ return line.trim();
+ }
+
+ private void showWelcomeText() {
+ System.out.println(String.format("tunkki REPL version %s", tunkki.versionString()));
+ }
+}
diff --git a/src/test/com/jantuomi/tunkki/MainTest.java b/src/test/com/jantuomi/tunkki/MainTest.java
index fab529b..5d04000 100644
--- a/src/test/com/jantuomi/tunkki/MainTest.java
+++ b/src/test/com/jantuomi/tunkki/MainTest.java
@@ -33,20 +33,20 @@ public class MainTest {
@Test
public void testParseArguments1() {
String[] notAnArgument = {"--not-an-argument"};
- assertFalse(Main.parseArguments(notAnArgument));
+ assertFalse(Tunkki.getInstance().parseArguments(notAnArgument));
}
@Test
public void testParseArguments2() {
String[] fileTestArgument = {"-f", "test.file"};
- assertTrue(Main.parseArguments(fileTestArgument));
+ assertTrue(Tunkki.getInstance().parseArguments(fileTestArgument));
}
@Test
public void testWholeProcedure() throws TunkkiError {
String input = "- + 2 5 1";
- Main.run(input);
+ Tunkki.getInstance().run(input);
assertTrue(out.toString().contains("6"));
}
} \ No newline at end of file