Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LocalVariableTable for output to support debug #44

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions src/main/java/stanhebben/zenscript/ZenModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import stanhebben.zenscript.symbols.*;
import stanhebben.zenscript.type.ZenType;
import stanhebben.zenscript.util.*;
import stanhebben.zenscript.util.localvariabletable.LocalVariable;
import stanhebben.zenscript.util.localvariabletable.LocalVariableTable;

import java.io.*;
import java.util.*;
Expand Down Expand Up @@ -114,10 +116,14 @@ public static void compileScripts(String mainFileName, List<ZenParsedFile> scrip
MethodOutput methodOutput = new MethodOutput(clsScript, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, function.getKey(), signature, null, null);
EnvironmentMethod methodEnvironment = new EnvironmentMethod(methodOutput, environmentScript);

LocalVariableTable localVariableTable = methodEnvironment.getLocalVariableTable();
localVariableTable.beginScope();
List<ParsedFunctionArgument> arguments = function.getValue().getArguments();
for(int i = 0, j = 0; i < arguments.size(); i++) {
ParsedFunctionArgument argument = arguments.get(i);
methodEnvironment.putValue(argument.getName(), new SymbolArgument(i + j, argument.getType()), fn.getPosition());
SymbolArgument symbolArgument = new SymbolArgument(i + j, argument.getType());
methodEnvironment.putValue(argument.getName(), symbolArgument, fn.getPosition());
localVariableTable.put(LocalVariable.parameter(argument.getName(), symbolArgument));
if(argument.getType().isLarge())
++j;
}
Expand All @@ -127,6 +133,8 @@ public static void compileScripts(String mainFileName, List<ZenParsedFile> scrip
for(Statement statement : statements) {
statement.compile(methodEnvironment);
}

localVariableTable.ensureFirstLabel(methodOutput, fn.getPosition());
if(function.getValue().getReturnType() != ZenType.VOID) {
if(statements.length > 0 && statements[statements.length - 1] instanceof StatementReturn) {
if(((StatementReturn) statements[statements.length - 1]).getExpression() != null) {
Expand All @@ -140,18 +148,26 @@ public static void compileScripts(String mainFileName, List<ZenParsedFile> scrip
} else if(statements.length == 0 || !(statements[statements.length - 1] instanceof StatementReturn)) {
methodOutput.ret();
}
localVariableTable.endMethod(methodOutput);
localVariableTable.writeLocalVariables(methodOutput);
methodOutput.end();
}

if(script.getStatements().size() > 0) {
MethodOutput scriptOutput = new MethodOutput(clsScript, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "__script__", "()V", null, null);
IEnvironmentMethod functionMethod = new EnvironmentMethod(scriptOutput, environmentScript);

LocalVariableTable localVariableTable = functionMethod.getLocalVariableTable();
localVariableTable.beginScope();
// scriptOutput.enableDebug();
scriptOutput.start();
for(Statement statement : script.getStatements()) {
statement.compile(functionMethod);
}
localVariableTable.ensureFirstLabel(scriptOutput, null);
scriptOutput.ret();
localVariableTable.endMethod(scriptOutput);
localVariableTable.writeLocalVariables(scriptOutput);
scriptOutput.end();

mainRun.invokeStatic(script.getClassName().replace('.', '/'), "__script__", "()V");
Expand Down Expand Up @@ -204,7 +220,6 @@ public static void compileScripts(String mainFileName, List<ZenParsedFile> scrip
* @param single file to be compiled
* @param environment compile environment
* @param baseClassLoader class loader
*
* @return compiled module
* @throws IOException if the file could not be read
*/
Expand Down Expand Up @@ -239,7 +254,6 @@ public static ZenModule compileScriptFile(File single, IZenCompileEnvironment en
* @param name name of the script to be compiled
* @param environment compile environment
* @param baseClassLoader class loader
*
* @return compiled module
* @throws IOException if the file could not be read
*/
Expand Down Expand Up @@ -273,7 +287,6 @@ public static ZenModule compileScriptString(String script, String name, IZenComp
* @param file zip file
* @param subdir subdirectory (use empty string to compile all)
* @param environment compile environment
*
* @return compiled module
* @throws IOException if the file could not be read properly
*/
Expand Down Expand Up @@ -327,7 +340,6 @@ private static void generateDebug(Map<String, byte[]> classes) throws IOExceptio
* Converts a filename into a class name.
*
* @param filename filename to convert
*
* @return class name
*/
public static String extractClassName(String filename) {
Expand Down
74 changes: 47 additions & 27 deletions src/main/java/stanhebben/zenscript/compiler/EnvironmentMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import stanhebben.zenscript.symbols.*;
import stanhebben.zenscript.type.ZenType;
import stanhebben.zenscript.util.*;
import stanhebben.zenscript.util.localvariabletable.LocalVariableTable;

import java.lang.reflect.Type;
import java.util.*;
Expand All @@ -15,135 +16,154 @@
* @author Stanneke
*/
public class EnvironmentMethod implements IEnvironmentMethod {

private final MethodOutput output;
private final HashMap<SymbolLocal, Integer> locals;
final IEnvironmentClass environment;
final Map<String, IZenSymbol> local;


protected final LocalVariableTable localVariableTable;

public EnvironmentMethod(MethodOutput output, IEnvironmentClass environment) {
this.output = output;
this.locals = new HashMap<>();
this.environment = environment;
this.local = new HashMap<>();
this.localVariableTable = new LocalVariableTable(environment);
}

@Override
public MethodOutput getOutput() {
return output;
}

@Override
public ClassVisitor getClassOutput() {
return environment.getClassOutput();
}


@Override
public LocalVariableTable getLocalVariableTable() {
return localVariableTable;
}

@Override
public int getLocal(SymbolLocal variable) {
if(!locals.containsKey(variable)) {
if (!locals.containsKey(variable)) {
locals.put(variable, output.local(variable.getType().toASMType()));
}
return locals.get(variable);
}


@Override
public int getLocal(SymbolLocal variable, boolean create) {
if (!locals.containsKey(variable)) {
if (!create) {
return -1;
}
Comment on lines +61 to +63
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default value vs. Exception/Error?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

o, right,error here would be better

locals.put(variable, output.local(variable.getType().toASMType()));
}
return locals.get(variable);
}

@Override
public ZenType getType(Type type) {
return environment.getType(type);
}

@Override
public void error(ZenPosition position, String message) {
environment.error(position, message);
}

@Override
public void warning(ZenPosition position, String message) {
environment.warning(position, message);
}

@Override
public void info(ZenPosition position, String message) {
environment.info(position, message);
}

@Override
public IZenCompileEnvironment getEnvironment() {
return environment.getEnvironment();
}

@Override
public TypeExpansion getExpansion(String name) {
return environment.getExpansion(name);
}

@Override
public ClassNameGenerator getClassNameGenerator() {
return environment.getClassNameGenerator();
}

@Override
public String makeClassName() {
return environment.makeClassName();
}

@Override
public String makeClassNameWithMiddleName(String middleName) {
return environment.makeClassNameWithMiddleName(middleName);
}

@Override
public void putClass(String name, byte[] data) {
environment.putClass(name, data);
}

@Override
public boolean containsClass(String name) {
return environment.containsClass(name);
}

@Override
public IPartialExpression getValue(String name, ZenPosition position) {
if(local.containsKey(name)) {
if (local.containsKey(name)) {
return local.get(name).instance(position);
} else {
return environment.getValue(name, position);
}
}

@Override
public void putValue(String name, IZenSymbol value, ZenPosition position) {
if(local.containsKey(name)) {
if (local.containsKey(name)) {
error(position, "Value already defined in this scope: " + name);
} else {
local.put(name, value);
}
}

@Override
public Set<String> getClassNames() {
return environment.getClassNames();
}

@Override
public byte[] getClass(String name) {
return environment.getClass(name);
}

@Override
public void error(String message) {
environment.error(message);
}

@Override
public void error(String message, Throwable e) {
environment.error(message, e);
}

@Override
public void warning(String message) {
environment.warning(message);
}

@Override
public void info(String message) {
environment.info(message);
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/stanhebben/zenscript/compiler/EnvironmentScope.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import stanhebben.zenscript.symbols.*;
import stanhebben.zenscript.type.ZenType;
import stanhebben.zenscript.util.*;
import stanhebben.zenscript.util.localvariabletable.LocalVariableTable;

import java.lang.reflect.Type;
import java.util.*;
Expand All @@ -30,6 +31,11 @@ public MethodOutput getOutput() {
return outer.getOutput();
}

@Override
public LocalVariableTable getLocalVariableTable() {
return outer.getLocalVariableTable();
}

@Override
public int getLocal(SymbolLocal variable) {
if(locals.containsKey(variable)) {
Expand All @@ -39,6 +45,15 @@ public int getLocal(SymbolLocal variable) {
}
}


@Override
public int getLocal(SymbolLocal variable, boolean create) {
if(locals.containsKey(variable)) {
return locals.get(variable);
}
return outer.getLocal(variable, create);
}

@Override
public ClassVisitor getClassOutput() {
return outer.getClassOutput();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

import stanhebben.zenscript.symbols.SymbolLocal;
import stanhebben.zenscript.util.MethodOutput;
import stanhebben.zenscript.util.localvariabletable.LocalVariableTable;

/**
* @author Stan
*/
public interface IEnvironmentMethod extends IEnvironmentClass {

MethodOutput getOutput();

int getLocal(SymbolLocal variable);
int getLocal(SymbolLocal variable, boolean create);


LocalVariableTable getLocalVariableTable();

}
Loading