A Tiny BASIC parser, interpreter and transpiler (to Java bytecode) written in Java.
Note: This project is more-or-less very experimental and does not have no-where near complete support for the Tiny BASIC language. I.e., it's tokenisation process is very basic and not suitable for this language.
- Core Tiny BASIC language support
- Parser and interpreter
- Transpiler to Java bytecode (BETA)
- very rudimentary and not fully functional
- if statements are prone to breaking due to the contrast in handling of control flow in Java vs Tiny BASIC
- TODO Unit tests for parser and interpreter
- TODO JavaDoc documentation for all public classes and methods
importme.darragh.javatinybasic.ast.Token;
importme.darragh.javatinybasic.parser.Parser;
importme.darragh.javatinybasic.parser.ParserInvalidLineException;
importjava.util.List;
publicclassParserDemo {
publicstaticvoidmain(String[] args) throwsParserInvalidLineException {
List<Token> tokens = Parser.parse(""" 10 REM This is a comment 20 LET A = 5 + 5 30 LET B = 10 40 PRINT "A + B =", A + B 50 INPUT C 60 PRINT C 70 END """);
for (Tokentoken : tokens) {
System.out.printf("%s\t%s\t%s%n", token.lineNumber(), token.statement(), token.expression());
}
}
}importme.darragh.javatinybasic.ast.Token;
importme.darragh.javatinybasic.interpreter.Interpreter;
importme.darragh.javatinybasic.parser.Parser;
importme.darragh.javatinybasic.parser.ParserInvalidLineException;
importjava.util.List;
importjava.util.Scanner;
publicclassInterpreterDemo {
publicstaticvoidmain(String[] args) throwsParserInvalidLineException {
Scannerscanner = newScanner(System.in);
List<Token> tokens = Parser.parse(""" 10 LET A = 5 20 LET B = 10 30 PRINT "Initial A and B:", A, B 40 INPUT C 50 IF C > B THEN 80 60 PRINT "C is less or equal to B" 70 GOTO 90 80 PRINT "C is greater than B" 90 FOR I = 1 TO 3 STEP 1 100 PRINT "Loop iteration:", I 110 NEXT I 120 GOSUB 150 130 PRINT "Back from subroutine" 140 END 150 PRINT "In subroutine" 160 RETURN """);
Interpreterinterpreter = newInterpreter(tokens,
/* input */scanner::nextInt,
/* output */System.out::println,
/* finished */ () -> System.out.println("Finished!")
);
interpreter.run();
scanner.close();
}
}
⚠️ Unstable.
importme.darragh.javatinybasic.ast.Token;
importme.darragh.javatinybasic.parser.Parser;
importme.darragh.javatinybasic.parser.ParserInvalidLineException;
importme.darragh.javatinybasic.transpiler.Transpiler;
importjava.nio.file.Paths;
importjava.util.List;
publicclassTranspilerDemo {
publicstaticvoidmain(String[] args) throwsParserInvalidLineException {
List<Token> tokens = Parser.parse(""" 10 LET A = 5 20 IF A = 5 THEN 50 30 GOTO 60 50 PRINT "= PASS" 51 GOTO 70 60 PRINT "= FAIL" 61 GOTO 70 70 LET A = 5 80 IF A <> 3 THEN 110 90 GOTO 120 110 PRINT "<> PASS" 111 GOTO 130 120 PRINT "<> FAIL" 121 GOTO 130 130 LET A = 2 140 IF A < 3 THEN 170 150 GOTO 180 170 PRINT "< PASS" 171 GOTO 190 180 PRINT "< FAIL" 181 GOTO 190 190 LET A = 7 200 IF A > 3 THEN 230 210 GOTO 240 230 PRINT "> PASS" 231 GOTO 250 240 PRINT "> FAIL" 241 GOTO 250 250 LET A = 4 260 IF A <= 4 THEN 290 270 GOTO 300 290 PRINT "<= PASS" 291 GOTO 310 300 PRINT "<= FAIL" 301 GOTO 310 310 LET A = 6 320 IF A >= 6 THEN 350 330 GOTO 360 350 PRINT ">= PASS" 351 GOTO 370 360 PRINT ">= FAIL" 361 GOTO 370 370 FOR I = 1 TO 5 STEP 1 380 PRINT I 390 NEXT I 400 END """);
Transpilertranspiler = newTranspiler(tokens);
transpiler.toFile(Paths.get("example.jar"));
}
}{line number} REM {comment (ignored line)}
{line number} LET {variable} = {expression (current value of variable|literal number|arithmetic expression)}
{line number} PRINT {expression (current value of variable|literal number|arithmetic expression|"string")}, {...}
{line number} INPUT {variable}
{line number} IF {expression (current value of variable|literal number|arithmetic expression)} {comparison operator} {expression (current value of variable|literal number|arithmetic expression)} THEN {line number}
{line number} FOR {variable} = {expression (current value of variable|literal number|arithmetic expression)} TO {expression (current value of variable|literal number)} STEP {expression (current value of variable|literal number)}
{line number} NEXT {variable}
{line number} GOTO {line number}
{line number} GOSUB {line number}
{line number} RETURN (exits out of the GOSUB)
{line number} END
This attempts to be faithful to the original Tiny BASIC syntax, but may not support all features or edge cases. The parser is designed to be simple and easy to understand, so it may not handle all possible syntax errors gracefully.
= EQUAL
<> NOT_EQUAL
< LESS_THAN
> GREATER_THAN
<= LESS_THAN_OR_EQUAL
>= GREATER_THAN_OR_EQUAL