great commit history

This commit is contained in:
nora 2021-05-28 14:40:37 +02:00 committed by GitHub
parent af55c80677
commit 0b96e0dd0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 1279 additions and 0 deletions

View file

@ -0,0 +1,45 @@
package com.github.nilstrieb.grsbpl;
import com.github.nilstrieb.grsbpl.language.IntStack;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class IntStackTest {
@Test
void pushPop() {
IntStack s = new IntStack();
s.push(100);
s.push(50);
assertEquals(50, s.pop());
assertEquals(100, s.pop());
assertThrows(IndexOutOfBoundsException.class, s::pop);
}
@Test
void applyFunction() {
IntStack s = new IntStack();
s.push(10);
s.push(2);
s.apply2((i1, i2) -> i1 / i2);
assertEquals(5, s.pop());
assertThrows(IndexOutOfBoundsException.class, s::pop);
}
@Test
void resize() {
IntStack s = new IntStack();
for (int i = 0; i < 1000; i++) {
s.push(i);
}
for (int i = 999; i >= 0; i--) {
assertEquals(i, s.pop());
}
}
}

View file

@ -0,0 +1,195 @@
package com.github.nilstrieb.grsbpl;
import com.github.nilstrieb.grsbpl.language.Interpreter;
import com.github.nilstrieb.grsbpl.language.Lexer;
import com.github.nilstrieb.grsbpl.language.Token;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
class InterpreterTest {
static Interpreter interpreter;
static OutStream out;
@BeforeEach
void setup() {
interpreter = new Interpreter();
out = new OutStream();
System.setOut(out);
}
@Test
void arithmeticOperations() {
String program = "1 1 * 2 +";
assertEquals(3, run(program));
String program2 = "10 5 /";
assertEquals(2, run(program2));
}
@Test
void bigNumbers() {
String program = "1000 1234 +";
assertEquals(2234, run(program));
}
@Test
void comment() {
String program = "1 # sdkfjsaf se9 83 252h43ui\n 2 # test 5 # +";
assertEquals(3, run(program));
}
@Test
void variables() {
String program = "1 &one 2 &two 3 &three 8 @two +";
assertEquals(10, run(program));
}
@Test
void labels() {
String program = "1 :first 2 0";
assertEquals(0, run(program));
}
@Test
void gotoBack() {
String program = "100000000 &i \n" +
":start \n" +
"@i nout '\n' out \n" +
"@i 1 - &i \n" +
"@i goto start \n" +
" 0";
int result = 0;
assertEquals(result, run(program));
}
@Test
void gotoSkip() {
String program = "1 :first 0 goto first 1 goto skip 3754 78349758 :skip";
int result = 1;
assertEquals(result, run(program));
}
@Test
void fizzBuzz() throws IOException, URISyntaxException {
String program = Files.readString(Path.of(getClass().getClassLoader().getResource("fizzbuzz.grsbpl").toURI()));
int result = 0;
StringBuilder resultString = new StringBuilder();
for (int i = 1; i < 100; i++) {
if (i % 15 == 0) resultString.append("FizzBuzz\n");
else if (i % 5 == 0) resultString.append("Buzz\n");
else if (i % 3 == 0) resultString.append("Fizz\n");
else resultString.append(i).append("\n");
}
assertEquals(result, run(program));
assertEquals(resultString.toString(), out.getOut());
}
@Test
void stackManipulationTest() {
String program = "1 2 swap";
assertEquals(1, run(program));
String program2 = "0 not";
assertEquals(1, run(program2));
String program3 = "1 not";
assertEquals(0, run(program3));
String program4 = "5 dup pop";
assertEquals(5, run(program4));
String program5 = "1 2 pop";
assertEquals(1, run(program5));
}
@Test
void bitwise() {
String p1 = "10 10 xor";
assertEquals(0, run(p1));
String p2 = "1 bnot";
assertEquals(~1, run(p2));
String p3 = 0xFF + " 1 and";
assertEquals(1, run(p3));
String p4 = 0b001 + " " + 0b101 + " or";
assertEquals(0b101, run(p4));
}
@Test
void functionTest() {
String program = "" +
"1 printNumber " +
"2 printNumber " +
"3 printNumber " +
"1 goto end" +
" " +
"function printNumber 1 nout 0 return" +
":end 0";
int result = 0;
assertEquals(result, run(program));
assertEquals("123", out.getOut());
}
@Test
void factorial() throws URISyntaxException, IOException {
String program0 = 0 + Files.readString(Path.of(getClass().getClassLoader().getResource("factorial.grsbpl").toURI()));
String program1 = 1 + Files.readString(Path.of(getClass().getClassLoader().getResource("factorial.grsbpl").toURI()));
String program10 = 10 + Files.readString(Path.of(getClass().getClassLoader().getResource("factorial.grsbpl").toURI()));
assertEquals(1, run(program0));
assertEquals(1, run(program1));
assertEquals(3628800, run(program10));
}
@Test
void outTest() {
String program = "'\n' '!' 'd' 'l' 'r' 'o' 'w' ' ' 'o' 'l' 'l' 'e' 'h' out out out out out out out out out out out out out 0";
assertEquals(0, run(program));
assertEquals("hello world!\n", out.getOut());
}
static class OutStream extends PrintStream {
private final StringBuilder builder = new StringBuilder();
public OutStream() {
super(new OutputStream() {
@Override
public void write(int b) {
}
});
}
@Override
public void print(char c) {
builder.append(c);
}
@Override
public void print(int i) {
builder.append(i);
}
public String getOut() {
return builder.toString();
}
}
int run(String program) {
List<Token> tokens = new Lexer().lex(program.toCharArray());
return interpreter.run(tokens);
}
}

View file

@ -0,0 +1,122 @@
package com.github.nilstrieb.grsbpl;
import com.github.nilstrieb.grsbpl.language.Lexer;
import com.github.nilstrieb.grsbpl.language.Token;
import com.github.nilstrieb.grsbpl.language.TokenType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.github.nilstrieb.grsbpl.language.TokenType.*;
import static org.junit.jupiter.api.Assertions.*;
class LexerTest {
Lexer lexer;
@BeforeEach
void setup() {
lexer = new Lexer();
}
@Test
void keywords() {
String program = "out in nout xor or and not bnot pop dup swap goto function return not";
List<TokenType> expected = List.of(OUT, IN, NOUT, XOR, OR, AND, NOT, BNOT, POP, DUP, SWAP, GOTO, FUNCTION, RETURN, NOT, EOF);
List<TokenType> actual = getTypes(lex(program));
assertEquals(expected, actual);
}
@Test
void symbols() {
String program = "+ & @ - % / * : +";
List<TokenType> expected = List.of(PLUS, AMPERSAND, AT, MINUS, PERCENT, SLASH, STAR, COLUMN, PLUS, EOF);
List<TokenType> actual = getTypes(lex(program));
assertEquals(expected, actual);
}
@Test
void identifiers() {
String program = "out test xor hallo + stack";
List<TokenType> expected = List.of(OUT, IDENTIFIER, XOR, IDENTIFIER, PLUS, IDENTIFIER, EOF);
List<Token> actual = lex(program);
assertEquals(expected, getTypes(actual));
Token test = new Token(IDENTIFIER, "test", 1, 4);
assertEquals(test, actual.get(1));
}
@Test
void numbers() {
String program = "out 347 test 64006 in";
List<TokenType> expected = List.of(OUT, CHARACTER, IDENTIFIER, CHARACTER, IN, EOF);
List<Token> actual = lex(program);
assertEquals(expected, getTypes(actual));
Token test = new Token(CHARACTER, 347, 1, 4);
assertEquals(test, actual.get(1));
}
@Test
void chars() {
String program = "'h' '\\n' '\\r' '\\f' '\\\\' '\\b' '\\'' '\\0'";
List<Character> expected = List.of('h', '\n', '\r', '\f', '\\', '\b', '\'', '\0');
List<Token> actual = lex(program);
assertEquals(expected, actual.stream()
.map(Token::getValue)
.filter(Objects::nonNull)
.limit(8)
.collect(Collectors.toUnmodifiableList()));
}
@Test
void comments() {
String program = "goto # hallo # goto #test\n goto";
List<TokenType> expected = List.of(GOTO, GOTO, GOTO, EOF);
List<TokenType> actual = getTypes(lex(program));
assertEquals(expected, actual);
}
@Test
void lineNumber() {
String program = "goto \n \n goto \ngoto";
List<TokenType> expected = List.of(GOTO, GOTO, GOTO, EOF);
List<Token> actual = lex(program);
assertEquals(expected, getTypes(actual));
Token test = new Token(GOTO, null, 4, 0);
assertEquals(test, actual.get(2));
}
@Test
void identifierName() {
String program = "test ABC g9tgq fe_53f";
List<String> expected = List.of("test", "ABC", "g9tgq", "fe_53f");
assertEquals(expected, getValues(lex(program)));
}
List<Token> lex(String program) {
return lexer.lex(program.toCharArray());
}
List<Object> getValues(List<Token> tokens) {
return tokens.stream()
.map(Token::getValue)
.filter(Objects::nonNull)
.collect(Collectors.toUnmodifiableList());
}
List<TokenType> getTypes(List<Token> tokens) {
return tokens.stream()
.map(Token::getType)
.collect(Collectors.toUnmodifiableList());
}
}