mirror of
https://github.com/GTNewHorizons/CraftTweaker.git
synced 2026-11-12 16:27:40 +00:00
1 parent
fd17ded261
commit
54ec75fd3d
11 files changed
+872
-571
No files matched your search
@@ -37,9 +37,9 @@ import static stanhebben.zenscript.util.ZenTypeUtil.internal;
|
||||
* Main module class. Contains a compiled module. The static methods of this
|
||||
* class can be used to compile a specific file or files.
|
||||
*
|
||||
* Modules may contain statements in their source, or define functions. Functions
|
||||
* in different scripts within the same module are accessible to each other, but
|
||||
* not to other modules.
|
||||
* Modules may contain statements in their source, or define functions.
|
||||
* Functions in different scripts within the same module are accessible to each
|
||||
* other, but not to other modules.
|
||||
*
|
||||
* @author Stan Hebben
|
||||
*/
|
||||
@@ -55,11 +55,11 @@ public class ZenModule {
|
||||
public static void compileScripts(String mainFileName, List<ZenParsedFile> scripts, IEnvironmentGlobal environmentGlobal, boolean debug) {
|
||||
ClassWriter clsMain = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
clsMain.visitSource(mainFileName, null);
|
||||
|
||||
clsMain.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, "__ZenMain__", null, internal(Object.class), new String[] {internal(Runnable.class)});
|
||||
|
||||
clsMain.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, "__ZenMain__", null, internal(Object.class), new String[] { internal(Runnable.class) });
|
||||
MethodOutput mainRun = new MethodOutput(clsMain, Opcodes.ACC_PUBLIC, "run", "()V", null, null);
|
||||
mainRun.start();
|
||||
|
||||
|
||||
for (ZenParsedFile script : scripts) {
|
||||
for (Map.Entry<String, ParsedFunction> function : script.getFunctions().entrySet()) {
|
||||
ParsedFunction fn = function.getValue();
|
||||
@@ -71,17 +71,17 @@ public class ZenModule {
|
||||
fn.getReturnType()), fn.getPosition());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (ZenParsedFile script : scripts) {
|
||||
ClassWriter clsScript = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
clsScript.visitSource(script.getFileName(), null);
|
||||
EnvironmentClass environmentScript = new EnvironmentClass(clsScript, script.getEnvironment());
|
||||
|
||||
clsScript.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, script.getClassName().replace('.', '/'), null, internal(Object.class), new String[] {internal(Runnable.class)});
|
||||
|
||||
|
||||
clsScript.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, script.getClassName().replace('.', '/'), null, internal(Object.class), new String[] { internal(Runnable.class) });
|
||||
|
||||
for (Map.Entry<String, ParsedFunction> function : script.getFunctions().entrySet()) {
|
||||
ParsedFunction fn = function.getValue();
|
||||
|
||||
|
||||
String signature = fn.getSignature();
|
||||
MethodOutput methodOutput = new MethodOutput(clsScript, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, function.getKey(), signature, null, null);
|
||||
EnvironmentMethod methodEnvironment = new EnvironmentMethod(methodOutput, environmentScript);
|
||||
@@ -101,14 +101,14 @@ public class ZenModule {
|
||||
if (statements[statements.length - 1] instanceof StatementReturn) {
|
||||
if (((StatementReturn) statements[statements.length - 1]).getExpression() != null) {
|
||||
fn.getReturnType()
|
||||
.defaultValue(fn.getPosition())
|
||||
.compile(true, methodEnvironment);
|
||||
.defaultValue(fn.getPosition())
|
||||
.compile(true, methodEnvironment);
|
||||
methodOutput.returnType(fn.getReturnType().toASMType());
|
||||
}
|
||||
} else {
|
||||
fn.getReturnType()
|
||||
.defaultValue(fn.getPosition())
|
||||
.compile(true, methodEnvironment);
|
||||
.defaultValue(fn.getPosition())
|
||||
.compile(true, methodEnvironment);
|
||||
methodOutput.returnType(fn.getReturnType().toASMType());
|
||||
}
|
||||
}
|
||||
@@ -118,25 +118,25 @@ public class ZenModule {
|
||||
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);
|
||||
//scriptOutput.enableDebug();
|
||||
// scriptOutput.enableDebug();
|
||||
scriptOutput.start();
|
||||
for (Statement statement : script.getStatements()) {
|
||||
statement.compile(functionMethod);
|
||||
}
|
||||
scriptOutput.ret();
|
||||
scriptOutput.end();
|
||||
|
||||
|
||||
mainRun.invokeStatic(script.getClassName().replace('.', '/'), "__script__", "()V");
|
||||
}
|
||||
|
||||
|
||||
clsScript.visitEnd();
|
||||
environmentGlobal.putClass(script.getClassName(), clsScript.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
mainRun.ret();
|
||||
mainRun.end();
|
||||
clsMain.visitEnd();
|
||||
|
||||
|
||||
MethodVisitor constructor = clsMain.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
|
||||
constructor.visitCode();
|
||||
constructor.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
@@ -144,7 +144,7 @@ public class ZenModule {
|
||||
constructor.visitInsn(Opcodes.RETURN);
|
||||
constructor.visitMaxs(0, 0);
|
||||
constructor.visitEnd();
|
||||
|
||||
|
||||
// debug: output classes
|
||||
if (debug) {
|
||||
try {
|
||||
@@ -153,11 +153,11 @@ public class ZenModule {
|
||||
|
||||
for (String className : environmentGlobal.getClassNames()) {
|
||||
File outputFile = new File(outputDir, className.replace('.', '/') + ".class");
|
||||
|
||||
|
||||
if (!outputFile.getParentFile().exists()) {
|
||||
outputFile.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
|
||||
FileOutputStream output = new FileOutputStream(outputFile);
|
||||
output.write(environmentGlobal.getClass(className));
|
||||
output.close();
|
||||
@@ -166,10 +166,10 @@ public class ZenModule {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
environmentGlobal.putClass("__ZenMain__", clsMain.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compiles a single script file.
|
||||
*
|
||||
@@ -186,26 +186,26 @@ public class ZenModule {
|
||||
environment,
|
||||
classes,
|
||||
nameGen
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
String filename = single.getName();
|
||||
String className = extractClassName(filename);
|
||||
|
||||
|
||||
FileInputStream input = new FileInputStream(single);
|
||||
Reader reader = new InputStreamReader(new BufferedInputStream(input));
|
||||
ZenTokener parser = new ZenTokener(reader, environment);
|
||||
ZenParsedFile file = new ZenParsedFile(filename, className, parser, environmentGlobal);
|
||||
reader.close();
|
||||
|
||||
|
||||
List<ZenParsedFile> files = new ArrayList<ZenParsedFile>();
|
||||
files.add(file);
|
||||
|
||||
|
||||
compileScripts(filename, files, environmentGlobal, false);
|
||||
|
||||
|
||||
// debug: output classes
|
||||
File outputDir = new File("generated");
|
||||
outputDir.mkdir();
|
||||
|
||||
|
||||
for (Map.Entry<String, byte[]> entry : classes.entrySet()) {
|
||||
File outputFile = new File(outputDir, entry.getKey().replace('.', '/') + ".class");
|
||||
if (!outputFile.getParentFile().exists()) {
|
||||
@@ -215,10 +215,10 @@ public class ZenModule {
|
||||
output.write(entry.getValue());
|
||||
output.close();
|
||||
}
|
||||
|
||||
|
||||
return new ZenModule(classes, baseClassLoader);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compiles a zip file as module. All containing files (inside the given
|
||||
* subdirectory) will be compiled.
|
||||
@@ -240,19 +240,19 @@ public class ZenModule {
|
||||
environment,
|
||||
classes,
|
||||
nameGen
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
List<ZenParsedFile> files = new ArrayList<ZenParsedFile>();
|
||||
|
||||
|
||||
ZipFile zipFile = new ZipFile(file);
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
|
||||
|
||||
if (entry.getName().startsWith(subdir) && !entry.getName().equals(subdir)) {
|
||||
String filename = entry.getName().substring(subdir.length());
|
||||
String className = extractClassName(filename);
|
||||
|
||||
|
||||
Reader reader = new InputStreamReader(new BufferedInputStream(zipFile.getInputStream(entry)));
|
||||
ZenTokener parser = new ZenTokener(reader, environment);
|
||||
ZenParsedFile pfile = new ZenParsedFile(filename, className, parser, environmentGlobal);
|
||||
@@ -260,30 +260,30 @@ public class ZenModule {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String filename = file.getName();
|
||||
compileScripts(filename, files, environmentGlobal, true);
|
||||
|
||||
|
||||
return new ZenModule(classes, baseClassLoader);
|
||||
}
|
||||
|
||||
|
||||
private final Map<String, byte[]> classes;
|
||||
private final MyClassLoader classLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a module for the given set of classes. Mostly intended for
|
||||
* internal use.
|
||||
*
|
||||
* @param classes
|
||||
* @param classes
|
||||
*/
|
||||
public ZenModule(Map<String, byte[]> classes, ClassLoader baseClassLoader) {
|
||||
this.classes = classes;
|
||||
classLoader = new MyClassLoader(baseClassLoader);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the main runnable. Running this runnable will execute the content
|
||||
* of the given module.
|
||||
* Retrieves the main runnable. Running this runnable will execute the
|
||||
* content of the given module.
|
||||
*
|
||||
* @return main runnable
|
||||
*/
|
||||
@@ -298,11 +298,11 @@ public class ZenModule {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ######################
|
||||
// ### Static methods ###
|
||||
// ######################
|
||||
|
||||
|
||||
/**
|
||||
* Converts a filename into a class name.
|
||||
*
|
||||
@@ -311,11 +311,12 @@ public class ZenModule {
|
||||
*/
|
||||
public static String extractClassName(String filename) {
|
||||
filename = filename.replace('\\', '/');
|
||||
if (filename.startsWith("/")) filename = filename.substring(1);
|
||||
|
||||
if (filename.startsWith("/"))
|
||||
filename = filename.substring(1);
|
||||
|
||||
int lastSlash = filename.lastIndexOf('/');
|
||||
int lastDot = filename.lastIndexOf('.');
|
||||
|
||||
|
||||
if (lastDot > lastSlash) {
|
||||
filename = filename.substring(0, lastDot);
|
||||
}
|
||||
@@ -327,11 +328,11 @@ public class ZenModule {
|
||||
return filename.substring(0, 1).toUpperCase() + filename.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #############################
|
||||
// ### Private inner classes ###
|
||||
// #############################
|
||||
|
||||
|
||||
/**
|
||||
* Custom class loader. Loads classes from this module.
|
||||
*/
|
||||
@@ -339,13 +340,13 @@ public class ZenModule {
|
||||
private MyClassLoader(ClassLoader baseClassLoader) {
|
||||
super(baseClassLoader);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
if (classes.containsKey(name)) {
|
||||
return defineClass(name, classes.get(name), 0, classes.get(name).length);
|
||||
}
|
||||
|
||||
|
||||
return super.findClass(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ import stanhebben.zenscript.value.IAny;
|
||||
*/
|
||||
public class TypeRegistry implements ITypeRegistry {
|
||||
private final Map<Class, ZenType> types;
|
||||
|
||||
|
||||
public TypeRegistry() {
|
||||
types = new HashMap<Class, ZenType>();
|
||||
|
||||
|
||||
types.put(boolean.class, ZenType.BOOL);
|
||||
types.put(byte.class, ZenTypeByte.INSTANCE);
|
||||
types.put(short.class, ZenTypeShort.INSTANCE);
|
||||
@@ -53,7 +53,7 @@ public class TypeRegistry implements ITypeRegistry {
|
||||
types.put(float.class, ZenTypeFloat.INSTANCE);
|
||||
types.put(double.class, ZenTypeDouble.INSTANCE);
|
||||
types.put(void.class, ZenTypeVoid.INSTANCE);
|
||||
|
||||
|
||||
types.put(Boolean.class, ZenTypeBoolObject.INSTANCE);
|
||||
types.put(Byte.class, ZenTypeByteObject.INSTANCE);
|
||||
types.put(Short.class, ZenTypeShortObject.INSTANCE);
|
||||
@@ -61,13 +61,13 @@ public class TypeRegistry implements ITypeRegistry {
|
||||
types.put(Long.class, ZenTypeLongObject.INSTANCE);
|
||||
types.put(Float.class, ZenTypeFloatObject.INSTANCE);
|
||||
types.put(Double.class, ZenTypeDoubleObject.INSTANCE);
|
||||
|
||||
|
||||
types.put(IAny.class, ZenTypeAny.INSTANCE);
|
||||
|
||||
|
||||
types.put(String.class, ZenTypeString.INSTANCE);
|
||||
types.put(List.class, new ZenTypeArrayBasic(ZenTypeAny.INSTANCE));
|
||||
}
|
||||
|
||||
|
||||
public ZenType getClassType(Class cls) {
|
||||
if (types.containsKey(cls)) {
|
||||
return types.get(cls);
|
||||
@@ -82,7 +82,7 @@ public class TypeRegistry implements ITypeRegistry {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ZenType getType(Type type) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
@@ -107,22 +107,22 @@ public class TypeRegistry implements ITypeRegistry {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ZenType getListType(ParameterizedType type) {
|
||||
if (type.getRawType() == List.class) {
|
||||
return new ZenTypeArrayList(getType(type.getActualTypeArguments()[0]));
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private ZenType getMapType(ParameterizedType type) {
|
||||
if (type.getRawType() == Map.class) {
|
||||
return new ZenTypeAssociative(
|
||||
getType(type.getActualTypeArguments()[1]),
|
||||
getType(type.getActualTypeArguments()[0]));
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,10 @@ import stanhebben.zenscript.util.ZenPosition;
|
||||
|
||||
public class StatementExpression extends Statement {
|
||||
private final ParsedExpression expression;
|
||||
|
||||
|
||||
public StatementExpression(ZenPosition position, ParsedExpression expression) {
|
||||
super(position);
|
||||
|
||||
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class StatementExpression extends Statement {
|
||||
public void compile(IEnvironmentMethod environment) {
|
||||
environment.getOutput().position(getPosition());
|
||||
expression.compile(environment, null)
|
||||
.eval(environment)
|
||||
.compile(false, environment);
|
||||
.eval(environment)
|
||||
.compile(false, environment);
|
||||
}
|
||||
}
|
||||
@@ -17,20 +17,20 @@ import stanhebben.zenscript.util.MethodOutput;
|
||||
*/
|
||||
public interface IJavaMethod {
|
||||
public boolean isStatic();
|
||||
|
||||
|
||||
public boolean accepts(int numArguments);
|
||||
|
||||
|
||||
public boolean accepts(IEnvironmentGlobal environment, Expression... arguments);
|
||||
|
||||
|
||||
public int getPriority(IEnvironmentGlobal environment, Expression... arguments);
|
||||
|
||||
|
||||
public void invokeVirtual(MethodOutput output);
|
||||
|
||||
|
||||
public void invokeStatic(MethodOutput output);
|
||||
|
||||
|
||||
public ZenType[] getParameterTypes();
|
||||
|
||||
|
||||
public ZenType getReturnType();
|
||||
|
||||
|
||||
public boolean isVarargs();
|
||||
}
|
||||
@@ -28,15 +28,15 @@ public class ZenNativeMember {
|
||||
private IJavaMethod getter;
|
||||
private IJavaMethod setter;
|
||||
private final List<IJavaMethod> methods = new ArrayList<IJavaMethod>();
|
||||
|
||||
|
||||
public IJavaMethod getGetter() {
|
||||
return getter;
|
||||
}
|
||||
|
||||
|
||||
public IJavaMethod getSetter() {
|
||||
return setter;
|
||||
}
|
||||
|
||||
|
||||
public void setGetter(IJavaMethod getter) {
|
||||
if (this.getter == null) {
|
||||
this.getter = getter;
|
||||
@@ -44,7 +44,7 @@ public class ZenNativeMember {
|
||||
throw new RuntimeException("already has a getter");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setSetter(IJavaMethod setter) {
|
||||
if (this.setter == null) {
|
||||
this.setter = setter;
|
||||
@@ -60,20 +60,20 @@ public class ZenNativeMember {
|
||||
public IPartialExpression instance(ZenPosition position, IEnvironmentGlobal environment) {
|
||||
return new StaticGetValue(position);
|
||||
}
|
||||
|
||||
|
||||
public void addMethod(JavaMethod method) {
|
||||
methods.add(method);
|
||||
}
|
||||
|
||||
|
||||
private class InstanceGetValue implements IPartialExpression {
|
||||
private final ZenPosition position;
|
||||
private final IPartialExpression value;
|
||||
|
||||
|
||||
public InstanceGetValue(ZenPosition position, IPartialExpression value) {
|
||||
this.position = position;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Expression eval(IEnvironmentGlobal environment) {
|
||||
return new ExpressionCallVirtual(position, environment, getter, value.eval(environment));
|
||||
@@ -99,17 +99,17 @@ public class ZenNativeMember {
|
||||
return new ExpressionCallVirtual(position, environment, method, value.eval(environment), values);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ZenType[] predictCallTypes(int numArguments) {
|
||||
return JavaMethod.predict(methods, numArguments);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IZenSymbol toSymbol() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ZenType getType() {
|
||||
return getter.getReturnType();
|
||||
@@ -121,14 +121,14 @@ public class ZenNativeMember {
|
||||
return ZenType.ANY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class StaticGetValue implements IPartialExpression {
|
||||
private final ZenPosition position;
|
||||
|
||||
|
||||
public StaticGetValue(ZenPosition position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Expression eval(IEnvironmentGlobal environment) {
|
||||
return new ExpressionCallStatic(position, environment, setter);
|
||||
@@ -154,7 +154,7 @@ public class ZenNativeMember {
|
||||
return new ExpressionCallStatic(position, environment, method, values);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ZenType[] predictCallTypes(int numArguments) {
|
||||
return JavaMethod.predict(methods, numArguments);
|
||||
@@ -164,7 +164,7 @@ public class ZenNativeMember {
|
||||
public IZenSymbol toSymbol() {
|
||||
return new StaticSymbol();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ZenType getType() {
|
||||
return getter.getReturnType();
|
||||
@@ -176,7 +176,7 @@ public class ZenNativeMember {
|
||||
return ZenType.ANY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class StaticSymbol implements IZenSymbol {
|
||||
@Override
|
||||
public IPartialExpression instance(ZenPosition position) {
|
||||
|
||||
Reference in new issue
Block a user