use of org.mvel2.ast.And in project mvel by mikebrock.
the class MVEL method analysisCompile.
/**
* Performs an analysis compileShared, which will populate the ParserContext with type, input and variable information,
* but will not produce a payload.
*
* @param expression - the expression to analyze
* @param ctx - the parser context
*/
public static void analysisCompile(char[] expression, ParserContext ctx) {
ExpressionCompiler compiler = new ExpressionCompiler(expression);
compiler.setVerifyOnly(true);
compiler.compile(ctx);
}
use of org.mvel2.ast.And in project mvel by mikebrock.
the class MVELRuntime method execute.
/**
* Main interpreter.
*
* @param debugger Run in debug mode
* @param expression The compiled expression object
* @param ctx The root context object
* @param variableFactory The variable factory to be injected
* @return The resultant value
* @see org.mvel2.MVEL
*/
public static Object execute(boolean debugger, final CompiledExpression expression, final Object ctx, VariableResolverFactory variableFactory) {
Object v1, v2;
ExecutionStack stk = new ExecutionStack();
variableFactory.setTiltFlag(false);
ASTNode tk = expression.getFirstNode();
Integer operator;
if (tk == null)
return null;
try {
do {
if (tk.fields == -1) {
/**
* This may seem silly and redundant, however, when an MVEL script recurses into a block
* or substatement, a new runtime loop is entered. Since the debugger state is not
* passed through the AST, it is not possible to forward the state directly. So when we
* encounter a debugging symbol, we check the thread local to see if there is are registered
* breakpoints. If we find them, we assume that we are debugging.
*
* The consequence of this of course, is that it's not ideal to compileShared expressions with
* debugging symbols which you plan to use in a production enviroment.
*/
if (debugger || (debugger = hasDebuggerContext())) {
try {
debuggerContext.get().checkBreak((LineLabel) tk, variableFactory, expression);
} catch (NullPointerException e) {
// do nothing for now. this isn't as calus as it seems.
}
}
continue;
} else if (stk.isEmpty()) {
stk.push(tk.getReducedValueAccelerated(ctx, ctx, variableFactory));
}
if (variableFactory.tiltFlag()) {
return stk.pop();
}
switch(operator = tk.getOperator()) {
case RETURN:
variableFactory.setTiltFlag(true);
return stk.pop();
case NOOP:
continue;
case TERNARY:
if (!stk.popBoolean()) {
// noinspection StatementWithEmptyBody
while (tk.nextASTNode != null && !(tk = tk.nextASTNode).isOperator(TERNARY_ELSE)) ;
}
stk.clear();
continue;
case TERNARY_ELSE:
return stk.pop();
case END_OF_STMT:
/**
* If the program doesn't end here then we wipe anything off the stack that remains.
* Althought it may seem like intuitive stack optimizations could be leveraged by
* leaving hanging values on the stack, trust me it's not a good idea.
*/
if (tk.nextASTNode != null) {
stk.clear();
}
continue;
}
stk.push(tk.nextASTNode.getReducedValueAccelerated(ctx, ctx, variableFactory), operator);
try {
while (stk.isReduceable()) {
if ((Integer) stk.peek() == CHOR) {
stk.pop();
v1 = stk.pop();
v2 = stk.pop();
if (!isEmpty(v2) || !isEmpty(v1)) {
stk.clear();
stk.push(!isEmpty(v2) ? v2 : v1);
} else
stk.push(null);
} else {
stk.op();
}
}
} catch (ClassCastException e) {
throw new CompileException("syntax error or incomptable types", new char[0], 0, e);
} catch (CompileException e) {
throw e;
} catch (Exception e) {
throw new CompileException("failed to compileShared sub expression", new char[0], 0, e);
}
} while ((tk = tk.nextASTNode) != null);
return stk.peek();
} catch (NullPointerException e) {
if (tk != null && tk.isOperator() && tk.nextASTNode != null) {
throw new CompileException("incomplete statement: " + tk.getName() + " (possible use of reserved keyword as identifier: " + tk.getName() + ")", tk.getExpr(), tk.getStart());
} else {
throw e;
}
}
}
use of org.mvel2.ast.And in project mvel by mikebrock.
the class ProtoParser method parse.
public Proto parse() {
Proto proto = new Proto(protoName);
Mainloop: while (cursor < endOffset) {
cursor = ParseTools.skipWhitespace(expr, cursor);
int start = cursor;
if (tk2 == null) {
while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
if (cursor > start) {
tk1 = new String(expr, start, cursor - start);
if ("def".equals(tk1) || "function".equals(tk1)) {
cursor++;
cursor = ParseTools.skipWhitespace(expr, cursor);
start = cursor;
while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
if (start == cursor) {
throw new CompileException("attempt to declare an anonymous function as a prototype member", expr, start);
}
FunctionParser parser = new FunctionParser(new String(expr, start, cursor - start), cursor, endOffset, expr, 0, pCtx, null);
proto.declareReceiver(parser.getName(), parser.parse());
cursor = parser.getCursor() + 1;
tk1 = null;
continue;
}
}
cursor = ParseTools.skipWhitespace(expr, cursor);
}
if (cursor > endOffset) {
throw new CompileException("unexpected end of statement in proto declaration: " + protoName, expr, start);
}
switch(expr[cursor]) {
case ';':
cursor++;
calculateDecl();
if (interpreted && type == DeferredTypeResolve.class) {
/**
* If this type could not be immediately resolved, it may be a look-ahead case, so
* we defer resolution of the type until later and place it in the wait queue.
*/
enqueueReceiverForLateResolution(deferredName, proto.declareReceiver(name, Proto.ReceiverType.DEFERRED, null), null);
} else {
proto.declareReceiver(name, type, null);
}
break;
case '=':
cursor++;
cursor = ParseTools.skipWhitespace(expr, cursor);
start = cursor;
Loop: while (cursor < endOffset) {
switch(expr[cursor]) {
case '{':
case '[':
case '(':
case '\'':
case '"':
cursor = balancedCaptureWithLineAccounting(expr, cursor, endOffset, expr[cursor], pCtx);
break;
case ';':
break Loop;
}
cursor++;
}
calculateDecl();
String initString = new String(expr, start, cursor++ - start);
if (interpreted && type == DeferredTypeResolve.class) {
enqueueReceiverForLateResolution(deferredName, proto.declareReceiver(name, Proto.ReceiverType.DEFERRED, null), initString);
} else {
proto.declareReceiver(name, type, (ExecutableStatement) subCompileExpression(initString, pCtx));
}
break;
default:
start = cursor;
while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
if (cursor > start) {
tk2 = new String(expr, start, cursor - start);
}
}
}
cursor++;
/**
* Check if the function is manually terminated.
*/
if (splitAccumulator != null && ParseTools.isStatementNotManuallyTerminated(expr, cursor)) {
/**
* Add an EndOfStatement to the split accumulator in the parser.
*/
splitAccumulator.add(new EndOfStatement());
}
return proto;
}
use of org.mvel2.ast.And in project mvel by mikebrock.
the class AbstractTest method _test.
protected static Object _test(String ex) {
ExpressionCompiler compiler = new ExpressionCompiler(ex);
StringAppender failErrors = new StringAppender();
CompiledExpression compiled = compiler.compile();
Object first = null, second = null, third = null, fourth = null, fifth = null, sixth = null, seventh = null, eighth = null;
System.out.println(DebugTools.decompile((Serializable) compiled));
if (!Boolean.getBoolean("mvel2.disable.jit")) {
setDefaultOptimizer("ASM");
try {
first = executeExpression(compiled, new Base(), createTestMap());
} catch (Exception e) {
failErrors.append("\nFIRST TEST: { " + ex + " }: EXCEPTION REPORT: \n\n");
CharArrayWriter writer = new CharArrayWriter();
e.printStackTrace(new PrintWriter(writer));
failErrors.append(writer.toCharArray());
}
try {
second = executeExpression(compiled, new Base(), createTestMap());
} catch (Exception e) {
failErrors.append("\nSECOND TEST: { " + ex + " }: EXCEPTION REPORT: \n\n");
CharArrayWriter writer = new CharArrayWriter();
e.printStackTrace(new PrintWriter(writer));
failErrors.append(writer.toCharArray());
}
}
try {
third = MVEL.eval(ex, new Base(), createTestMap());
} catch (Exception e) {
failErrors.append("\nTHIRD TEST: { " + ex + " }: EXCEPTION REPORT: \n\n");
CharArrayWriter writer = new CharArrayWriter();
e.printStackTrace(new PrintWriter(writer));
failErrors.append(writer.toCharArray());
}
if (first != null && !first.getClass().isArray()) {
if (!first.equals(second)) {
System.out.println(failErrors.toString());
throw new AssertionError("Different result from test 1 and 2 (Compiled Re-Run / JIT) [first: " + valueOf(first) + "; second: " + valueOf(second) + "]");
}
if (!first.equals(third)) {
if (failErrors != null)
System.out.println(failErrors.toString());
throw new AssertionError("Different result from test 1 and 3 (Compiled to Interpreted) [first: " + valueOf(first) + " (" + (first != null ? first.getClass().getName() : null) + "); third: " + valueOf(third) + " (" + (third != null ? third.getClass().getName() : "null") + ")]");
}
}
setDefaultOptimizer("reflective");
Serializable compiled2 = compileExpression(ex);
try {
fourth = executeExpression(compiled2, new Base(), createTestMap());
} catch (Exception e) {
if (failErrors == null)
failErrors = new StringAppender();
failErrors.append("\nFOURTH TEST: { " + ex + " }: EXCEPTION REPORT: \n\n");
CharArrayWriter writer = new CharArrayWriter();
e.printStackTrace(new PrintWriter(writer));
failErrors.append(writer.toCharArray());
}
try {
fifth = executeExpression(compiled2, new Base(), createTestMap());
} catch (Exception e) {
e.printStackTrace();
if (failErrors == null)
failErrors = new StringAppender();
failErrors.append("\nFIFTH TEST: { " + ex + " }: EXCEPTION REPORT: \n\n");
CharArrayWriter writer = new CharArrayWriter();
e.printStackTrace(new PrintWriter(writer));
failErrors.append(writer.toCharArray());
}
if (fourth != null && !fourth.getClass().isArray()) {
if (!fourth.equals(fifth)) {
throw new AssertionError("Different result from test 4 and 5 (Compiled Re-Run X2) [fourth: " + valueOf(fourth) + "; fifth: " + valueOf(fifth) + "]");
}
}
ParserContext ctx = new ParserContext();
ctx.setSourceFile("unittest");
ctx.setDebugSymbols(true);
ExpressionCompiler debuggingCompiler = new ExpressionCompiler(ex);
// debuggingCompiler.setDebugSymbols(true);
CompiledExpression compiledD = debuggingCompiler.compile(ctx);
try {
sixth = executeExpression(compiledD, new Base(), createTestMap());
} catch (Exception e) {
if (failErrors == null)
failErrors = new StringAppender();
failErrors.append("\nSIXTH TEST: { " + ex + " }: EXCEPTION REPORT: \n\n");
CharArrayWriter writer = new CharArrayWriter();
e.printStackTrace(new PrintWriter(writer));
failErrors.append(writer.toCharArray());
}
if (sixth != null && !sixth.getClass().isArray()) {
if (!fifth.equals(sixth)) {
System.out.println("Payload 1 -- No Symbols: ");
System.out.println(decompile(compiled));
System.out.println();
System.out.println("Payload 2 -- With Symbols: ");
System.out.println(decompile(compiledD));
System.out.println();
throw new AssertionError("Different result from test 5 and 6 (Compiled to Compiled+DebuggingSymbols) [first: " + valueOf(fifth) + "; second: " + valueOf(sixth) + "]");
}
}
try {
seventh = executeExpression(compiledD, new Base(), createTestMap());
} catch (Exception e) {
if (failErrors == null)
failErrors = new StringAppender();
failErrors.append("\nSEVENTH TEST: { " + ex + " }: EXCEPTION REPORT: \n\n");
CharArrayWriter writer = new CharArrayWriter();
e.printStackTrace(new PrintWriter(writer));
failErrors.append(writer.toCharArray());
}
if (seventh != null && !seventh.getClass().isArray()) {
if (!seventh.equals(sixth)) {
throw new AssertionError("Different result from test 4 and 5 (Compiled Re-Run / Reflective) [first: " + valueOf(first) + "; second: " + valueOf(second) + "]");
}
}
try {
Serializable xx = serializationTest(compiledD);
AbstractParser.resetParserContext();
eighth = executeExpression(xx, new Base(), new MapVariableResolverFactory(createTestMap()));
} catch (Exception e) {
if (failErrors == null)
failErrors = new StringAppender();
failErrors.append("\nEIGHTH TEST (Serializability): { " + ex + " }: EXCEPTION REPORT: \n\n");
CharArrayWriter writer = new CharArrayWriter();
e.printStackTrace(new PrintWriter(writer));
failErrors.append(writer.toCharArray());
}
if (eighth != null && !eighth.getClass().isArray()) {
if (!eighth.equals(seventh)) {
throw new AssertionError("Different result from test 7 and 8 (Compiled Re-Run / Reflective) [first: " + valueOf(first) + "; second: " + valueOf(second) + "]");
}
}
if (failErrors.length() > 0) {
System.out.println(decompile(compiledD));
throw new AssertionError("Detailed Failure Report:\n" + failErrors.toString());
}
return fourth;
}
use of org.mvel2.ast.And in project mvel by mikebrock.
the class TemplateCompiler method compileFrom.
public Node compileFrom(Node root, ExecutionStack stack) {
line = 1;
Node n = root;
if (root == null) {
n = root = new TextNode(0, 0);
}
IfNode last;
Integer opcode;
String name;
int x;
try {
while (cursor < length) {
switch(template[cursor]) {
case '\n':
line++;
colStart = cursor + 1;
break;
case '@':
case '$':
if (isNext(template[cursor])) {
start = ++cursor;
(n = markTextNode(n)).setEnd(n.getEnd() + 1);
start = lastTextRangeEnding = ++cursor;
continue;
}
if ((x = captureOrbToken()) != -1) {
start = x;
switch((opcode = OPCODES.get(name = new String(capture()))) == null ? 0 : opcode) {
case Opcodes.IF:
/**
* Capture any residual text node, and push the if statement on the nesting stack.
*/
stack.push(n = markTextNode(n).next = codeCache ? new CompiledIfNode(start, name, template, captureOrbInternal(), start, parserContext) : new IfNode(start, name, template, captureOrbInternal(), start));
n.setTerminus(new TerminalNode());
break;
case Opcodes.ELSE:
if (!stack.isEmpty() && stack.peek() instanceof IfNode) {
markTextNode(n).next = (last = (IfNode) stack.pop()).getTerminus();
last.demarcate(last.getTerminus(), template);
last.next = n = codeCache ? new CompiledIfNode(start, name, template, captureOrbInternal(), start, parserContext) : new IfNode(start, name, template, captureOrbInternal(), start);
n.setTerminus(last.getTerminus());
stack.push(n);
}
break;
case Opcodes.FOREACH:
stack.push(n = markTextNode(n).next = codeCache ? new CompiledForEachNode(start, name, template, captureOrbInternal(), start, parserContext) : new ForEachNode(start, name, template, captureOrbInternal(), start));
n.setTerminus(new TerminalNode());
break;
case Opcodes.INCLUDE_FILE:
n = markTextNode(n).next = codeCache ? new CompiledIncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new IncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1);
break;
case Opcodes.INCLUDE_NAMED:
n = markTextNode(n).next = codeCache ? new CompiledNamedIncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new NamedIncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1);
break;
case Opcodes.CODE:
n = markTextNode(n).next = codeCache ? new CompiledCodeNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new CodeNode(start, name, template, captureOrbInternal(), start = cursor + 1);
break;
case Opcodes.EVAL:
n = markTextNode(n).next = codeCache ? new CompiledEvalNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new EvalNode(start, name, template, captureOrbInternal(), start = cursor + 1);
break;
case Opcodes.COMMENT:
n = markTextNode(n).next = new CommentNode(start, name, template, captureOrbInternal(), start = cursor + 1);
break;
case Opcodes.DECLARE:
stack.push(n = markTextNode(n).next = codeCache ? new CompiledDeclareNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new DeclareNode(start, name, template, captureOrbInternal(), start = cursor + 1));
n.setTerminus(new TerminalNode());
break;
case Opcodes.END:
n = markTextNode(n);
Node end = (Node) stack.pop();
Node terminal = end.getTerminus();
terminal.setCStart(captureOrbInternal());
terminal.setEnd((lastTextRangeEnding = start) - 1);
terminal.calculateContents(template);
if (end.demarcate(terminal, template))
n = n.next = terminal;
else
n = terminal;
break;
default:
if (name.length() == 0) {
n = markTextNode(n).next = codeCache ? new CompiledExpressionNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new ExpressionNode(start, name, template, captureOrbInternal(), start = cursor + 1);
} else if (customNodes != null && customNodes.containsKey(name)) {
Class<? extends Node> customNode = customNodes.get(name);
try {
(n = markTextNode(n).next = (customNode.newInstance())).setBegin(start);
n.setName(name);
n.setCStart(captureOrbInternal());
n.setCEnd(start = cursor + 1);
n.setEnd(n.getCEnd());
n.setContents(subset(template, n.getCStart(), n.getCEnd() - n.getCStart() - 1));
if (n.isOpenNode()) {
stack.push(n);
}
} catch (InstantiationException e) {
throw new RuntimeException("unable to instantiate custom node class: " + customNode.getName());
} catch (IllegalAccessException e) {
throw new RuntimeException("unable to instantiate custom node class: " + customNode.getName());
}
} else {
throw new RuntimeException("unknown token type: " + name);
}
}
}
break;
}
cursor++;
}
} catch (RuntimeException e) {
CompileException ce = new CompileException(e.getMessage(), template, cursor, e);
ce.setExpr(template);
if (e instanceof CompileException) {
CompileException ce2 = (CompileException) e;
if (ce2.getCursor() != -1) {
ce.setCursor(ce2.getCursor());
if (ce2.getColumn() == -1)
ce.setColumn(ce.getCursor() - colStart);
else
ce.setColumn(ce2.getColumn());
}
}
ce.setLineNumber(line);
throw ce;
}
if (!stack.isEmpty()) {
CompileException ce = new CompileException("unclosed @" + ((Node) stack.peek()).getName() + "{} block. expected @end{}", template, cursor);
ce.setColumn(cursor - colStart);
ce.setLineNumber(line);
throw ce;
}
if (start < template.length) {
n = n.next = new TextNode(start, template.length);
}
n.next = new EndNode();
n = root;
do {
if (n.getLength() != 0) {
break;
}
} while ((n = n.getNext()) != null);
if (n != null && n.getLength() == template.length - 1) {
if (n instanceof ExpressionNode) {
return codeCache ? new CompiledTerminalExpressionNode(n, parserContext) : new TerminalExpressionNode(n);
} else {
return n;
}
}
return root;
}
Aggregations