Skip to content

Commit

Permalink
chore: switch compiler to use file logging
Browse files Browse the repository at this point in the history
  • Loading branch information
Eddie authored and Eddie committed Jun 3, 2024
1 parent 0fa8fbc commit bb75943
Show file tree
Hide file tree
Showing 22 changed files with 147 additions and 52 deletions.
Binary file modified out/artifacts/jungle_jar/jungle.jar
Binary file not shown.
40 changes: 20 additions & 20 deletions src/main/java/com/jungle/ast/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,44 +166,44 @@ public String toString() {

// region Save AST
@NotNull
private static final FileLogger saveLog = new FileLogger("SaveAst");
private static final FileLogger saveLogger = new FileLogger("SaveAst");

public static void save(@NotNull BufferedWriter writer, @Nullable INode node) {
// Non-recursive traversal
Stack<INode> nodeStack = new Stack<>();
nodeStack.push(node);
while (nodeStack.size() > 0) {
INode nextNode = nodeStack.pop();
saveLog.debug("---");
saveLogger.debug("---");
if (nextNode == null) {
saveLog.debug("node is terminal");
saveLogger.debug("node is terminal");
try {
writer.write(TERMINAL);
} catch (IOException e) {
throw new SaveError("failed to write terminal", e);
}
} else {
saveLog.debug("type: " + nextNode.getType());
saveLog.debug("value: " + nextNode.getRawValue());
saveLogger.debug("type: " + nextNode.getType());
saveLogger.debug("value: " + nextNode.getRawValue());
try {
writer.write(nextNode.getType().name());
} catch (IOException e) {
String message = "failed to write node type";
saveLog.error(message, e);
saveLogger.error(message, e);
throw new SaveError(message);
}
if (nextNode.isLeaf()) {
saveLog.debug("node is leaf");
saveLogger.debug("node is leaf");
try {
writer.write(DELIMITER_FIELD);
writer.write(nextNode.getRawValue());
} catch (IOException e) {
String message = "failed to write node value";
saveLog.error(message, e);
saveLogger.error(message, e);
throw new SaveError(message);
}
} else {
saveLog.debug("node is parent");
saveLogger.debug("node is parent");
nodeStack.push(nextNode.getRight());
nodeStack.push(nextNode.getLeft());
}
Expand All @@ -212,7 +212,7 @@ public static void save(@NotNull BufferedWriter writer, @Nullable INode node) {
writer.write(DELIMITER_LINE);
} catch (IOException e) {
String message = "failed to write line delimiter";
saveLog.error(message, e);
saveLogger.error(message, e);
throw new SaveError(message);
}
}
Expand All @@ -222,7 +222,7 @@ public static void save(@NotNull BufferedWriter writer, @Nullable INode node) {

// region Load AST

private static final FileLogger loadLog = new FileLogger("LoadAst");
private static final FileLogger loadLogger = new FileLogger("LoadAst");

@Nullable
public static INode load(@NotNull BufferedReader reader) {
Expand All @@ -235,21 +235,21 @@ public static INode load(@NotNull BufferedReader reader) {
line = reader.readLine();
} catch (IOException e) {
String message = "failed to read file";
loadLog.error(message, e);
loadLogger.error(message, e);
throw new LoadError(message);
}
boolean hasStreamEnded = line == null;
if (hasStreamEnded) {
loadLog.warn("end of stream reached");
loadLogger.warn("end of stream reached");
return null;
}
boolean hasEmptyLine = line.length() == 0;
if (hasEmptyLine) {
loadLog.debug("line is empty");
loadLogger.debug("line is empty");
return null;
}
if (line.trim().startsWith(Character.toString(TERMINAL))) {
loadLog.debug("line is terminal");
loadLogger.debug("line is terminal");
return null;
}
int splitIndex = line.indexOf(DELIMITER_FIELD);
Expand All @@ -260,22 +260,22 @@ public static INode load(@NotNull BufferedReader reader) {
value = null;
} else if (splitIndex == 0) {
String message = "line missing type";
loadLog.error(message);
loadLogger.error(message);
throw new LoadError(message);
} else {
type = line.substring(0, splitIndex);
value = line.substring(splitIndex + 1);
}
type = type.trim();
loadLog.debug("---");
loadLog.debug("type: " + type);
loadLog.debug("value: " + value);
loadLogger.debug("---");
loadLogger.debug("type: " + type);
loadLogger.debug("value: " + value);
Node node;
try {
node = new Node(NodeType.valueOf(type));
} catch (IllegalArgumentException e) {
String message = "line type invalid";
loadLog.error(message, e);
loadLogger.error(message, e);
throw new LoadError(message);
}
boolean isLeafNode = value != null;
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/com/jungle/common/ClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@

import org.jetbrains.annotations.NotNull;

import com.jungle.logger.FileLogger;

public class ClassLoader {

@NotNull
private static final FileLogger logger = new FileLogger(ClassLoader.class.getName());

public static Class<?> load(@NotNull String classPaths, @NotNull String className)
throws MalformedURLException, ClassNotFoundException
{
Expand Down Expand Up @@ -42,7 +47,7 @@ public static Class<?> load(@NotNull String className)
if (classPath == null) {
classPath = ".";
}
System.out.println(String.format("loading class from %s", classPath));
logger.debug(String.format("loading class from %s", classPath));
return load(classPath, className);
}
}
20 changes: 10 additions & 10 deletions src/main/java/com/jungle/compiler/Compiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
import static org.objectweb.asm.Opcodes.*;

public class Compiler {

public static final FileLogger log = new FileLogger(Compiler.class.getSimpleName());
@NotNull
private static final FileLogger logger = new FileLogger(Compiler.class.getSimpleName());

// region Helpers

Expand All @@ -30,7 +30,7 @@ public static void writeClassFile(@NotNull String className, byte[] classData) {
Files.write(classPath, classData);
} catch (IOException e) {
String message = "failed to write to class file";
log.error(message, e);
logger.error(message, e);
throw new CompilerError(message);
}
}
Expand All @@ -41,17 +41,17 @@ public void compile(@NotNull String mainClassName, @NotNull IVisitor mainVisitor
// TODO: handle multi-class
if (ast == null) {
String message = "AST is null";
log.error(message);
logger.error(message);
throw new CompilerError(message);
}
log.debug("generating entrypoint class from template");
logger.debug("generating entrypoint class from template");
ClassWriter initialClassWriter = visitMainClass(mainClassName); // template
ClassReader classReader = new ClassReader(initialClassWriter.toByteArray());
ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
ClassVisitor entrypoint = new MainClassVisitor(classWriter, mainVisitor, ast);
log.debug("traversing AST");
logger.debug("traversing AST");
classReader.accept(entrypoint, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
log.debug("writing class file");
logger.debug("writing class file");
writeClassFile(mainClassName, classWriter.toByteArray());
}

Expand All @@ -60,7 +60,7 @@ public void compile(@NotNull String mainClassName, @NotNull IVisitor mainVisitor
@NotNull
protected ClassWriter visitMainClass(@NotNull String className) {
// class Entrypoint extends Object {}
log.debug("visit main class");
logger.debug("visit main class");
int flags = ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES;
ClassWriter cw = new ClassWriter(flags);
cw.visit(
Expand All @@ -82,7 +82,7 @@ protected ClassWriter visitMainClass(@NotNull String className) {
@NotNull
public static MethodVisitor visitDefaultConstructor(@NotNull ClassWriter cw) {
// public ClassConstructor() { Object::super(); return; }
log.debug("visit default constructor");
logger.debug("visit default constructor");
MethodVisitor mv = cw.visitMethod(
ACC_PUBLIC,
"<init>",
Expand All @@ -106,7 +106,7 @@ public static MethodVisitor visitDefaultConstructor(@NotNull ClassWriter cw) {
@NotNull
public static MethodVisitor visitMainMethod(@NotNull ClassWriter cw) {
// public static void main(String[]) { return; }
log.debug("visit main method");
logger.debug("visit main method");
MethodVisitor mv = cw.visitMethod(
ACC_PUBLIC + ACC_STATIC,
MainMethodVisitor.MAIN_METHOD_NAME,
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/com/jungle/compiler/MainClassVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@

import com.jungle.ast.INode;
import com.jungle.compiler.visitor.IVisitor;
import com.jungle.logger.FileLogger;

import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class MainClassVisitor extends ClassVisitor {
@NotNull
private static final FileLogger logger = new FileLogger(MainClassVisitor.class.getSimpleName());

@NotNull
private final IVisitor mainVisitor;

Expand All @@ -25,7 +30,7 @@ public MethodVisitor visitMethod(int flags, String name, String desc, String sig
MethodVisitor mv = super.visitMethod(flags, name, desc, signature, exceptions);
boolean isMainMethod = MainMethodVisitor.MAIN_METHOD_NAME.equals(name);
if (isMainMethod) {
Compiler.log.debug("emit custom instructions in main class");
logger.debug("emit custom instructions in main class");
return new MainMethodVisitor(mv, mainVisitor, ast);
}
return mv;
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/com/jungle/compiler/MainMethodVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

import com.jungle.ast.INode;
import com.jungle.compiler.visitor.IVisitor;
import com.jungle.logger.FileLogger;

import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class MainMethodVisitor extends MethodVisitor {
@NotNull
private static final FileLogger logger = new FileLogger(MainMethodVisitor.class.getSimpleName());

public static final String MAIN_METHOD_NAME = "main";

@NotNull
Expand All @@ -24,7 +29,7 @@ public MainMethodVisitor(MethodVisitor mv, @NotNull IVisitor mainVisitor, @NotNu
@Override
public void visitInsn(final int opcode) {
if (opcode == Opcodes.RETURN) {
Compiler.log.debug("emit instructions just before existing RETURN operation");
logger.debug("emit instructions just before existing RETURN operation");
mainVisitor.visit(this, ast);
}
super.visitInsn(opcode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
import com.jungle.compiler.symbol.SymbolEntry;
import com.jungle.compiler.symbol.SymbolTable;
import com.jungle.compiler.symbol.SymbolType;
import com.jungle.logger.FileLogger;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.MethodVisitor;

import java.util.Stack;

public class OperandStackContext {
@NotNull
private static final FileLogger logger = new FileLogger(OperandStackContext.class.getName());

// region Singleton Factory
@Nullable
private static OperandStackContext operandStackContext = null;
Expand Down Expand Up @@ -60,7 +65,7 @@ public void visitLoad(
@NotNull String variableName
) {
// Get local variable index value and push variable value onto the operand stack
System.out.println("visit load " + variableName);
logger.debug("visit load " + variableName);

SymbolEntry entry = getSymbolTable().get(variableName);
if (entry == null) {
Expand All @@ -84,7 +89,7 @@ public void visitStore(
@NotNull String variableName
) {
// Pop value off the operand stack and set local variable index value
System.out.println("visit store " + variableName);
logger.debug("visit store " + variableName);

OperandStackType variableType = pop();
SymbolType variableSymbolType = variableType.getSymbolType();
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/jungle/compiler/visitor/AssertVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,22 @@
import com.jungle.ast.NodeType;
import com.jungle.compiler.operand.OperandStackContext;
import com.jungle.compiler.operand.OperandStackType;
import com.jungle.logger.FileLogger;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class AssertVisitor implements IVisitor {
@NotNull
private static final FileLogger logger = new FileLogger(AssertVisitor.class.getName());

/* TODO
* It might be possible to use reflection to provide more context on the assertion.
* For example: which method, which line, which variables, etc.
*/
@Nullable
private OperandStackContext operandStackContext;

Expand Down Expand Up @@ -52,7 +61,7 @@ public boolean canVisit(@NotNull INode ast) {

@Override
public void visit(@NotNull MethodVisitor mv, @NotNull INode ast) {
System.out.println("visit assert " + ast);
logger.debug("visit assert " + ast);

if (!canVisit(ast)) {
throw new Error("expected assert");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
import com.jungle.ast.INode;
import com.jungle.ast.NodeType;
import com.jungle.compiler.operand.OperandStackContext;
import com.jungle.logger.FileLogger;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.MethodVisitor;

public class AssignmentVisitor implements IVisitor {
@NotNull
private static final FileLogger logger = new FileLogger(AssignmentVisitor.class.getName());

@Nullable
private OperandStackContext operandStackContext;

Expand Down Expand Up @@ -49,7 +54,7 @@ public boolean canVisit(@NotNull INode ast) {

@Override
public void visit(@NotNull MethodVisitor mv, @NotNull INode ast) {
System.out.println("visit assignment " + ast);
logger.debug("visit assignment " + ast);

if (!canVisit(ast)) {
throw new Error("expected assignment");
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/com/jungle/compiler/visitor/BlockVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

import com.jungle.ast.INode;
import com.jungle.ast.NodeType;
import com.jungle.logger.FileLogger;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.MethodVisitor;

public class BlockVisitor implements IVisitor {
@NotNull
private static final FileLogger logger = new FileLogger(BlockVisitor.class.getName());

@Nullable
private MainVisitor mainVisitor;

Expand All @@ -33,7 +38,7 @@ public boolean canVisit(@NotNull INode ast) {

@Override
public void visit(@NotNull MethodVisitor mv, @NotNull INode ast) {
System.out.println("visit block " + ast);
logger.debug("visit block " + ast);

if (!canVisit(ast)) {
throw new Error("expected block");
Expand Down
Loading

0 comments on commit bb75943

Please sign in to comment.