added test and fixed stuff

This commit is contained in:
Sander Hautvast 2020-11-19 22:58:49 +01:00
parent adc54f0042
commit 33400c7268
3 changed files with 101 additions and 52 deletions

View file

@ -15,7 +15,7 @@ import java.util.regex.Pattern;
*/ */
public class SourceCompiler { public class SourceCompiler {
private final static Pattern firstBlanksplitter = Pattern.compile("(.+?) (.+)"); private final static Pattern firstBlanksplitter = Pattern.compile("(.+?) (.+)");
private final static Pattern parensplitter = Pattern.compile("(.+?)(\\(.*?\\))"); private final static Pattern parensplitter = Pattern.compile("(.+?)\\((.*?)\\)");
private final static Pattern returntypesplitter = Pattern.compile("(.+?)->(.*?)"); private final static Pattern returntypesplitter = Pattern.compile("(.+?)->(.*?)");
private final String sourcecode; private final String sourcecode;
private final List<Instruction> instructions = new ArrayList<>(); private final List<Instruction> instructions = new ArrayList<>();
@ -62,60 +62,82 @@ public class SourceCompiler {
private BeeMethod parseMethod(String text) { private BeeMethod parseMethod(String text) {
String[] tokens = split(text, returntypesplitter); String[] tokens = split(text, returntypesplitter);
Class<?> returnType; final String first;
final Class<?> returnType;
if (tokens.length > 0) {
try { try {
returnType = Class.forName(tokens[1].trim()); returnType = Class.forName(tokens[1].trim());
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Not a valid type: "+tokens[1].trim()); throw new IllegalArgumentException("Not a valid type: " + tokens[1].trim());
}
first = tokens[0].trim();
} else {
first = text;
returnType = Void.TYPE;
} }
String first = tokens[0].trim(); String[] flagsNameParameters = split(first, firstBlanksplitter);
String[] flagsNameParameters = first.split(" ");
Set<MethodAccessFlag> flags = new HashSet<>(); Set<MethodAccessFlag> flags = new HashSet<>();
int i=0; int i = 0;
Optional<MethodAccessFlag> maybeFlag = MethodAccessFlag.get(flagsNameParameters[i]); Optional<MethodAccessFlag> maybeFlag = MethodAccessFlag.get(flagsNameParameters[i].toUpperCase());
while (maybeFlag.isPresent()){ while (maybeFlag.isPresent()) {
flags.add(maybeFlag.get()); flags.add(maybeFlag.get());
i+=1; i += 1;
maybeFlag = MethodAccessFlag.get(flagsNameParameters[i]); maybeFlag = MethodAccessFlag.get(flagsNameParameters[i]);
} }
String[] nameParams = split(flagsNameParameters[i], parensplitter); String[] nameParams = split(flagsNameParameters[i], parensplitter);
String methodName = nameParams[0]; Set<BeeParameter> parameters = new HashSet<>();
String methodName = "";
if (nameParams.length > 0) {
methodName = nameParams[0];
String params = nameParams[1]; String params = nameParams[1];
String[] paramTokens = params.split(","); String[] paramTokens = params.split(",");
Set<BeeParameter> parameters = new HashSet<>();
for (String paramToken : paramTokens) { for (String paramToken : paramTokens) {
String[] declaration = paramToken.trim().split(" "); String[] declaration = paramToken.trim().split(" ");
String type = declaration[0]; String type = declaration[0];
String name = declaration[1]; String name = declaration[1];
try { try {
parameters.add(new BeeParameter(Class.forName(type), name)); parameters.add(new BeeParameter(getType(type), name));
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new IllegalArgumentException("field type " + type + " not found"); throw new IllegalArgumentException("field type " + type + " not found");
} }
} }
}
currentLine += 1; currentLine += 1;
List<CodeLine> lines = new ArrayList<>(); List<CodeLine> lines = new ArrayList<>();
Instruction nextInstruction = instructions.get(currentLine); Instruction nextInstruction = instructions.get(currentLine);
while (nextInstruction instanceof CodeLine) { while (nextInstruction instanceof CodeLine) {
lines.add((CodeLine) nextInstruction); lines.add((CodeLine) nextInstruction);
currentLine += 1; currentLine += 1;
if (currentLine >= instructions.size()){
break; // too tired to think
}
nextInstruction = instructions.get(currentLine); nextInstruction = instructions.get(currentLine);
} }
return new BeeMethod(methodName,flags, parameters, returnType, lines);
return new BeeMethod(methodName, flags, parameters, returnType, lines);
}
private Class<?> getType(String type) throws ClassNotFoundException {
return switch (type) {
case "int" -> int.class;
case "double" -> double.class;
default -> Class.forName(type);
};
} }
private BeeConstructor parseConstructor(String text) { private BeeConstructor parseConstructor(String text) {
String[] tokens = split(text, parensplitter); String[] tokens = split(text, parensplitter);
String flag = tokens[0]; String flag = tokens[0];
MethodAccessFlag methodAccessFlag = MethodAccessFlag.get(flag).orElseThrow(illegalArgument("Not a valid flag " + flag)); MethodAccessFlag methodAccessFlag = MethodAccessFlag.get(flag.toUpperCase()).orElseThrow(illegalArgument("Not a valid flag " + flag));
String params = tokens[1]; String params = tokens[1];
String[] paramTokens = params.split(",");
Set<BeeParameter> parameters = new HashSet<>(); Set<BeeParameter> parameters = new HashSet<>();
if (params.length() > 0) {
String[] paramTokens = params.split(",");
for (String paramToken : paramTokens) { for (String paramToken : paramTokens) {
String[] declaration = paramToken.trim().split(" "); String[] declaration = paramToken.trim().split(" ");
String type = declaration[0]; String type = declaration[0];
@ -126,6 +148,7 @@ public class SourceCompiler {
throw new IllegalArgumentException("field type " + type + " not found"); throw new IllegalArgumentException("field type " + type + " not found");
} }
} }
}
currentLine += 1; currentLine += 1;
List<CodeLine> lines = new ArrayList<>(); List<CodeLine> lines = new ArrayList<>();
Instruction nextInstruction = instructions.get(currentLine); Instruction nextInstruction = instructions.get(currentLine);
@ -133,8 +156,8 @@ public class SourceCompiler {
lines.add((CodeLine) nextInstruction); lines.add((CodeLine) nextInstruction);
currentLine += 1; currentLine += 1;
nextInstruction = instructions.get(currentLine); nextInstruction = instructions.get(currentLine);
}
}
return new BeeConstructor(Set.of(methodAccessFlag), parameters, lines); return new BeeConstructor(Set.of(methodAccessFlag), parameters, lines);
} }
@ -185,20 +208,32 @@ public class SourceCompiler {
} }
private Instruction compileLine(String line) { private Instruction compileLine(String line) {
if (!line.startsWith(" ")) {
String[] tokens = split(line, firstBlanksplitter); String[] tokens = split(line, firstBlanksplitter);
String operation = tokens[0]; String operation = tokens[0];
String operand = tokens[1]; String operand = tokens[1];
if (!line.startsWith(" ")) {
ClassOperation classOperation = ClassOperation.get(operation).orElseThrow(illegalArgument(operation)); ClassOperation classOperation = ClassOperation.get(operation).orElseThrow(illegalArgument(operation));
return new ClassInstruction(classOperation, operand); return new ClassInstruction(classOperation, operand);
} else { } else {
Opcode opcode = Opcode.get(operation).orElseThrow(illegalArgument(operation)); line = line.substring(2);
String operation;
String operand;
if (line.indexOf(' ') > -1) {
String[] tokens = split(line, firstBlanksplitter);
operation = tokens[0];
operand = tokens[1];
} else {
operation = line;
operand = null;
}
Opcode opcode = Opcode.get(operation).orElseThrow(illegalArgument("Illegal opcode: " + operation));
return new CodeLine(opcode, operand); return new CodeLine(opcode, operand);
} }
} }
private Supplier<IllegalArgumentException> illegalArgument(String text) { private Supplier<IllegalArgumentException> illegalArgument(String text) {
return () -> new IllegalArgumentException("Illegal: " + text); return () -> new IllegalArgumentException(text);
} }
private String[] split(String text, Pattern splitter) { private String[] split(String text, Pattern splitter) {

View file

@ -0,0 +1,14 @@
package nl.sander.beejava;
import nl.sander.beejava.apiv2.BeeSource;
import nl.sander.beejava.apiv2.SourceCompiler;
import org.junit.jupiter.api.Test;
public class SourceCompilerTest {
@Test
public void test(){
BeeSource beeSource = new SourceCompiler(TestData2.simpleBean).doCompile();
System.out.println(beeSource);
}
}

View file

@ -2,15 +2,15 @@ package nl.sander.beejava;
public class TestData2 { public class TestData2 {
public final String simpleBean= """ public final static String simpleBean= """
public class simpleBean class com.acme.SimpleBean(V15)
field value:int field public final int value
constructor() constructor public()
INVOKE super() INVOKE super()
RETURN RETURN
method getValue() method public getValue() -> int
RETURN this.value RETURN this.value
method setValue(int newVale) method public setValue(int newValue)
LOAD newValue LOAD newValue
PUT this.value PUT this.value
RETURN RETURN