This commit is contained in:
jaredlll08 committed 2015-08-31 19:08:46 +02: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) {