use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.
the class ParsedExpression method readPrimaryExpression.
private static ParsedExpression readPrimaryExpression(ZenPosition position, ZenTokener parser, IEnvironmentGlobal environment) {
switch(parser.peek().getType()) {
case T_INTVALUE:
long l = Long.decode(parser.next().getValue());
return new ParsedExpressionValue(position, new ExpressionInt(position, l, Long.bitCount(l) > 32 ? ZenType.LONG : ZenTypeInt.INSTANCE));
case T_FLOATVALUE:
String value = parser.next().getValue();
ZenType zenType = ZenTypeDouble.INSTANCE;
if (value.endsWith("f") || value.endsWith("F")) {
zenType = ZenTypeFloat.INSTANCE;
value = value.substring(0, value.length() - 1);
}
return new ParsedExpressionValue(position, new ExpressionFloat(position, Double.parseDouble(value), zenType));
case T_STRINGVALUE:
return new ParsedExpressionValue(position, new ExpressionString(position, unescapeString(parser.next().getValue())));
/*
* case T_DOLLAR: { Expression result = new
* ExpressionDollar(position); if (parser.isNext(T_STRINGVALUE))
* { return new ExpressionIndexString(position, result,
* unescapeString(parser.next().getValue())); } return result; }
*/
case T_ID:
return new ParsedExpressionVariable(position, parser.next().getValue());
case T_FUNCTION:
// function (argname, argname, ...) { ...contents... }
parser.next();
parser.required(T_BROPEN, "( expected");
List<ParsedFunctionArgument> arguments = new ArrayList<>();
if (parser.optional(T_BRCLOSE) == null) {
do {
String name = parser.required(T_ID, "identifier expected").getValue();
ZenType type = ZenTypeAny.INSTANCE;
if (parser.optional(T_AS) != null) {
type = ZenType.read(parser, environment);
}
arguments.add(new ParsedFunctionArgument(name, type));
} while (parser.optional(T_COMMA) != null);
parser.required(T_BRCLOSE, ") expected");
}
ZenType returnType = ZenTypeAny.INSTANCE;
if (parser.optional(T_AS) != null) {
returnType = ZenType.read(parser, environment);
}
parser.required(T_AOPEN, "{ expected");
List<Statement> statements = new ArrayList<>();
if (parser.optional(T_ACLOSE) == null) {
while (parser.optional(T_ACLOSE) == null) {
statements.add(Statement.read(parser, environment, returnType));
}
}
return new ParsedExpressionFunction(position, returnType, arguments, statements);
case T_LT:
{
Token start = parser.next();
List<Token> tokens = new ArrayList<>();
Token next = parser.next();
while (next.getType() != ZenTokener.T_GT) {
tokens.add(next);
next = parser.next();
}
IZenSymbol resolved = parser.getEnvironment().getBracketed(environment, tokens);
if (resolved == null) {
StringBuilder builder = new StringBuilder();
builder.append('<');
Token last = null;
for (Token token : tokens) {
if (last != null)
builder.append(' ');
builder.append(token.getValue());
last = token;
}
builder.append('>');
if (!parser.ignoreBracketErrors) {
parser.getEnvironment().getErrorLogger().error(start.getPosition(), "Could not resolve " + builder.toString());
} else {
parser.getEnvironment().getErrorLogger().info(start.getPosition(), "Could not resolve " + builder.toString());
}
return new ParsedExpressionInvalid(start.getPosition());
} else {
return new ParsedExpressionValue(start.getPosition(), parser.getEnvironment().getBracketed(environment, tokens).instance(start.getPosition()));
}
}
case T_SQBROPEN:
{
parser.next();
List<ParsedExpression> contents = new ArrayList<>();
if (parser.optional(T_SQBRCLOSE) == null) {
while (parser.optional(T_SQBRCLOSE) == null) {
contents.add(readAssignExpression(parser, environment));
if (parser.optional(T_COMMA) == null) {
parser.required(T_SQBRCLOSE, "] or , expected");
break;
}
}
}
return new ParsedExpressionArray(position, contents);
}
case T_AOPEN:
{
parser.next();
List<ParsedExpression> keys = new ArrayList<>();
List<ParsedExpression> values = new ArrayList<>();
if (parser.optional(T_ACLOSE) == null) {
while (parser.optional(T_ACLOSE) == null) {
keys.add(readAssignExpression(parser, environment));
parser.required(T_COLON, ": expected");
values.add(readAssignExpression(parser, environment));
if (parser.optional(T_COMMA) == null) {
parser.required(T_ACLOSE, "} or , expected");
break;
}
}
}
return new ParsedExpressionMap(position, keys, values);
}
case T_TRUE:
parser.next();
return new ParsedExpressionBool(position, true);
case T_FALSE:
parser.next();
return new ParsedExpressionBool(position, false);
case T_NULL:
parser.next();
return new ParsedExpressionNull(position);
case T_BROPEN:
parser.next();
ParsedExpression result = readAssignExpression(parser, environment);
parser.required(T_BRCLOSE, ") expected");
return result;
default:
Token last = parser.next();
throw new ParseException(last, "Invalid expression, last token: " + last.getValue());
}
}
use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.
the class ParsedFunction method parse.
public static ParsedFunction parse(ZenTokener parser, IEnvironmentGlobal environment) {
parser.next();
Token tName = parser.required(ZenTokener.T_ID, "identifier expected");
// function (argname [as type], argname [as type], ...) [as type] {
// ...contents... }
parser.required(T_BROPEN, "( expected");
List<ParsedFunctionArgument> arguments = new ArrayList<>();
if (parser.optional(T_BRCLOSE) == null) {
Token argName = parser.required(T_ID, "identifier expected");
ZenType type = ZenTypeAny.INSTANCE;
if (parser.optional(T_AS) != null) {
type = ZenType.read(parser, environment);
}
arguments.add(new ParsedFunctionArgument(argName.getValue(), type));
while (parser.optional(T_COMMA) != null) {
Token argName2 = parser.required(T_ID, "identifier expected");
ZenType type2 = ZenTypeAny.INSTANCE;
if (parser.optional(T_AS) != null) {
type2 = ZenType.read(parser, environment);
}
arguments.add(new ParsedFunctionArgument(argName2.getValue(), type2));
}
parser.required(T_BRCLOSE, ") expected");
}
ZenType type = ZenTypeAny.INSTANCE;
if (parser.optional(T_AS) != null) {
type = ZenType.read(parser, environment);
}
parser.required(T_AOPEN, "{ expected");
Statement[] statements;
if (parser.optional(T_ACLOSE) != null) {
statements = new Statement[0];
} else {
ArrayList<Statement> statementsAL = new ArrayList<>();
while (parser.optional(T_ACLOSE) == null) {
statementsAL.add(Statement.read(parser, environment, type));
}
statements = statementsAL.toArray(new Statement[statementsAL.size()]);
}
return new ParsedFunction(tName.getPosition(), tName.getValue(), arguments, type, statements);
}
use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.
the class ExpressionFunction method compile.
@Override
public void compile(boolean result, IEnvironmentMethod environment) {
if (!result)
return;
ClassWriter cw = new ZenClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", new String[0]);
MethodOutput constructor = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
constructor.start();
constructor.loadObject(0);
constructor.invokeSpecial("java/lang/Object", "<init>", "()V");
constructor.ret();
constructor.end();
MethodOutput output = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "accept", makeDescriptor(), null, null);
IEnvironmentClass environmentClass = new EnvironmentClass(cw, environment);
IEnvironmentMethod environmentMethod = new EnvironmentMethod(output, environmentClass);
for (int i = 0; i < arguments.size(); i++) {
environmentMethod.putValue(arguments.get(i).getName(), new SymbolArgument(i + 1, arguments.get(i).getType()), getPosition());
}
output.start();
for (Statement statement : statements) {
statement.compile(environmentMethod);
}
output.ret();
output.end();
environment.putClass(className, cw.toByteArray());
// make class instance
environment.getOutput().newObject(className);
environment.getOutput().dup();
environment.getOutput().construct(className);
}
use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.
the class ExpressionJavaLambdaSimpleGeneric method compile.
@Override
public void compile(boolean result, IEnvironmentMethod environment) {
if (!result)
return;
Method method = interfaceClass.getMethods()[0];
// generate class
String clsName = environment.makeClassName();
ClassWriter cw = new ZenClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, clsName, createMethodSignature(), "java/lang/Object", new String[] { internal(interfaceClass) });
MethodOutput constructor = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
constructor.start();
constructor.loadObject(0);
constructor.invokeSpecial("java/lang/Object", "<init>", "()V");
constructor.ret();
constructor.end();
MethodOutput output = new MethodOutput(cw, Opcodes.ACC_PUBLIC, method.getName(), descriptor, null, null);
IEnvironmentClass environmentClass = new EnvironmentClass(cw, environment);
IEnvironmentMethod environmentMethod = new EnvironmentMethod(output, environmentClass);
for (int i = 0; i < arguments.size(); i++) {
ZenType typeToPut = arguments.get(i).getType();
if (typeToPut.equals(ZenType.ANY))
typeToPut = environment.getType(method.getGenericParameterTypes()[i]);
if (typeToPut == null)
typeToPut = environment.getType(method.getParameterTypes()[i]);
environmentMethod.putValue(arguments.get(i).getName(), new SymbolArgument(i + 1, typeToPut), getPosition());
}
output.start();
for (Statement statement : statements) {
statement.compile(environmentMethod);
}
output.ret();
output.end();
if (!Objects.equals(genericClass, Object.class)) {
MethodOutput bridge = new MethodOutput(cw, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE, method.getName(), ZenTypeUtil.descriptor(method), null, null);
bridge.loadObject(0);
bridge.loadObject(1);
bridge.checkCast(internal(genericClass));
if (arguments.size() > 1) {
for (int i = 1; i < arguments.size(); ) {
bridge.load(org.objectweb.asm.Type.getType(method.getParameterTypes()[i]), ++i);
}
}
bridge.invokeVirtual(clsName, method.getName(), descriptor);
bridge.returnType(org.objectweb.asm.Type.getReturnType(method));
bridge.end();
}
environment.putClass(clsName, cw.toByteArray());
// make class instance
environment.getOutput().newObject(clsName);
environment.getOutput().dup();
environment.getOutput().construct(clsName);
}
use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.
the class ExpressionJavaLambda method compile.
@Override
public void compile(boolean result, IEnvironmentMethod environment) {
if (!result)
return;
Method method = interfaceClass.getMethods()[0];
// generate class
String clsName = environment.makeClassName();
ClassWriter cw = new ZenClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, clsName, null, "java/lang/Object", new String[] { internal(interfaceClass) });
MethodOutput constructor = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
constructor.start();
constructor.loadObject(0);
constructor.invokeSpecial("java/lang/Object", "<init>", "()V");
constructor.ret();
constructor.end();
MethodOutput output = new MethodOutput(cw, Opcodes.ACC_PUBLIC, method.getName(), descriptor(method), null, null);
IEnvironmentClass environmentClass = new EnvironmentClass(cw, environment);
IEnvironmentMethod environmentMethod = new EnvironmentMethod(output, environmentClass);
for (int i = 0; i < arguments.size(); i++) {
environmentMethod.putValue(arguments.get(i).getName(), new SymbolArgument(i + 1, environment.getType(method.getGenericParameterTypes()[i])), getPosition());
}
output.start();
for (Statement statement : statements) {
statement.compile(environmentMethod);
}
output.ret();
output.end();
environment.putClass(clsName, cw.toByteArray());
// make class instance
environment.getOutput().newObject(clsName);
environment.getOutput().dup();
environment.getOutput().construct(clsName);
}
Aggregations