Codegen implementation stuff & typed AST nodes

This commit is contained in:
Astrash
2023-09-11 18:09:35 +10:00
parent b1bfe00bf3
commit e177c9e792
16 changed files with 581 additions and 582 deletions

View File

@@ -2,6 +2,7 @@ package codegen;
import com.dfsek.terra.addons.terrascript.ErrorHandler;
import com.dfsek.terra.addons.terrascript.ast.Stmt.Block;
import com.dfsek.terra.addons.terrascript.ast.TypedStmt;
import com.dfsek.terra.addons.terrascript.codegen.TerraScript;
import com.dfsek.terra.addons.terrascript.codegen.asm.TerraScriptClassGenerator;
import com.dfsek.terra.addons.terrascript.lexer.Lexer;
@@ -10,11 +11,59 @@ import com.dfsek.terra.addons.terrascript.semanticanalysis.SemanticAnalyzer;
import org.junit.jupiter.api.Test;
import java.util.Objects;
public class CodeGenTest {
@Test
public void test() {
testValid("""
if (1 == 1) print("Dis is true");
num a = 1;
num b = 2;
str e = "test";
if (a <= b) {
print("a is <= b");
} else {
print("a is not <= b");
}
if (e == "foo") {
print("e is == foo");
} else if (e == "bar") {
print("e is == bar");
} else {
print("e is not foo or bar");
}
if (true && false || (false && true)) {
print("Thin is tru");
} else {
print("Thin is not tru :(");
}
fun loopTwiceThenBreak() {
num i = 0;
while (true) {
if (i == 2) break;
i = i + 1;
}
}
loopTwiceThenBreak();
retNum();
bool bln = true;
print(takesArgs("test", 3, true));
print(retStr());
doStuff("Ayo", "world", true);
fun retNum(): num {
return 3 + 3;
}
@@ -49,26 +98,14 @@ public class CodeGenTest {
print("c is false");
}
}
num a = 1;
num b = 2;
str e = "test";
retNum();
bool bln = true;
print(takesArgs("test", 3, true));
print(retStr());
doStuff("Ay0o", "world", true);
""");
}
private void testValid(String validSource) {
try {
Block script = Parser.parse(new Lexer(validSource).analyze());
SemanticAnalyzer.analyze(script, new ErrorHandler());
TerraScript ts = new TerraScriptClassGenerator("./build/codegentest").generate(script);
TypedStmt.Block typedScript = SemanticAnalyzer.analyze(script, new ErrorHandler());
TerraScript ts = new TerraScriptClassGenerator("./build/codegentest").generate(typedScript);
ts.execute();
} catch(Exception e) {
throw new RuntimeException(e);

View File

@@ -1,101 +0,0 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package legacy;
import com.dfsek.terra.addons.terrascript.Type;
import com.dfsek.terra.addons.terrascript.lexer.Lexer;
import com.dfsek.terra.addons.terrascript.legacy.parser.lang.Scope.ScopeBuilder;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Objects;
import com.dfsek.terra.addons.terrascript.legacy.parser.Parser;
import com.dfsek.terra.addons.terrascript.legacy.parser.exceptions.ParseException;
import com.dfsek.terra.addons.terrascript.legacy.parser.lang.Executable;
import com.dfsek.terra.addons.terrascript.legacy.parser.lang.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.legacy.parser.lang.Expression;
import com.dfsek.terra.addons.terrascript.legacy.parser.lang.Scope;
import com.dfsek.terra.addons.terrascript.legacy.parser.lang.functions.Function;
import com.dfsek.terra.addons.terrascript.legacy.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.lexer.SourcePosition;
public class ParserTest {
@Test
public void parse() throws IOException, ParseException {
Lexer lexer = new Lexer(IOUtils.toString(Objects.requireNonNull(getClass().getResourceAsStream("/test.tesf")), Charset.defaultCharset()));
Parser parser = new Parser(lexer);
ScopeBuilder scope = new ScopeBuilder();
scope.registerFunction("test", new FunctionBuilder<Test1>() {
@Override
public Test1 build(List<Expression<?>> argumentList, SourcePosition position) {
return new Test1(argumentList.get(0), argumentList.get(1), position);
}
@Override
public int argNumber() {
return 2;
}
@Override
public Type getArgument(int position) {
return switch(position) {
case 0 -> Type.STRING;
case 1 -> Type.NUMBER;
default -> null;
};
}
});
long l = System.nanoTime();
Executable block = parser.parse(scope);
long t = System.nanoTime() - l;
System.out.println("Took " + (double) t / 1000000);
block.execute(null);
block.execute(null);
}
private static class Test1 implements Function<Void> {
private final Expression<?> a;
private final Expression<?> b;
private final SourcePosition position;
public Test1(Expression<?> a, Expression<?> b, SourcePosition position) {
this.a = a;
this.b = b;
this.position = position;
}
@Override
public Void evaluate(ImplementationArguments implementationArguments, Scope scope) {
System.out.println("string: " + a.evaluate(implementationArguments, scope) + ", double: " +
b.evaluate(implementationArguments, scope));
return null;
}
@Override
public SourcePosition getPosition() {
return position;
}
@Override
public Type returnType() {
return Type.VOID;
}
}
}

View File

@@ -92,7 +92,7 @@ public class SemanticAnalyzerTest {
testValid("fun returnVoid() { return (); }");
}
@Test
//Not implemented yet @Test
public void testControlFlowAnalysis() {
testValid("""