use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writeExpression.
@SuppressWarnings("unchecked")
public Memory writeExpression(ExprStmtToken expression, boolean returnValue, boolean returnMemory, boolean writeOpcode) {
int initStackSize = method.getStackCount();
exprStackInit.push(initStackSize);
if (expression == null) {
throw new CriticalException("Invalid expression token expr, on line unknown, expr = null");
}
if (!expression.isStmtList()) {
if (expression.getAsmExpr() == null) {
throw new CriticalException("Invalid expression token without asm expr, on line " + expression.getMeta().getStartLine() + ", expr = " + expression.getWord());
}
// new ASMExpression(compiler.getEnvironment(), compiler.getContext(), expression).getResult();
expression = expression.getAsmExpr();
}
List<Token> tokens = expression.getTokens();
int operatorCount = 0;
for (Token token : tokens) {
if (token instanceof OperatorExprToken)
operatorCount++;
}
boolean invalid = false;
for (Token token : tokens) {
if (token == null)
continue;
writeTickTrigger(token);
if (writeOpcode) {
if (token instanceof StmtToken) {
if (!(token instanceof ReturnStmtToken))
method.entity.setImmutable(false);
}
BaseStatementCompiler cmp = getCompiler(token.getClass());
if (cmp != null && !(cmp instanceof BaseExprCompiler)) {
cmp.write(token);
continue;
}
}
if (token instanceof ValueExprToken) {
// mixed, calls, numbers, strings, vars, etc.
if (token instanceof CallExprToken && ((CallExprToken) token).getName() instanceof OperatorExprToken) {
if (writeOpcode) {
writePush((ValueExprToken) token, true, true);
method.entity.setImmutable(false);
} else
break;
} else
stackPush((ValueExprToken) token);
} else if (token instanceof OperatorExprToken) {
// + - * / % && || or ! and == > < etc.
operatorCount--;
if (operatorCount >= 0) {
Memory result;
if (operatorCount == 0) {
result = writeOperator((OperatorExprToken) token, returnValue, writeOpcode);
} else
result = writeOperator((OperatorExprToken) token, true, writeOpcode);
if (!writeOpcode && result == null) {
invalid = true;
break;
}
if (result == null)
method.entity.setImmutable(false);
}
} else
break;
}
Memory result = null;
if (!invalid && returnMemory && returnValue && !stackEmpty(false) && stackPeek().isConstant()) {
result = stackPop().memory;
invalid = true;
}
if (!invalid) {
if (returnValue && !stackEmpty(false) && stackPeek().isKnown()) {
if (returnMemory)
result = tryWritePush(stackPop(), writeOpcode, returnValue, true);
else
writePush(stackPop());
} else if (method.getStackCount() > 0) {
if (stackPeekToken() instanceof CallableExprToken) {
if (returnMemory)
result = tryWritePush(stackPopToken(), returnValue, writeOpcode, true);
else
writePush(stackPopToken(), returnValue, true);
} else if (stackPeek().isConstant()) {
stackPop();
}
}
}
if (!returnValue && writeOpcode) {
writePopAll(method.getStackCount() - initStackSize);
} else if (!writeOpcode) {
int count = method.getStackCount() - initStackSize;
for (int i = 0; i < count; i++) {
stackPop();
}
}
exprStackInit.pop();
return result;
}
use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class JvmCompiler method process.
public List<ExprStmtToken> process(List<Token> tokens, NamespaceStmtToken namespace) {
List<ExprStmtToken> externalCode = new ArrayList<ExprStmtToken>();
// write constants
for (ConstStmtToken constant : analyzer.getConstants()) {
List<ConstantEntity> items = compileConstant(constant);
for (ConstantEntity el : items) {
if (!constants.containsKey(el.getLowerName())) {
module.addConstant(el);
if (scope.findUserConstant(el.getName()) != null) {
environment.error(el.getTrace(), ErrorType.E_ERROR, Messages.ERR_CANNOT_REDECLARE_CONSTANT, el.getName());
}
constants.put(el.getLowerName(), el);
} else {
environment.error(el.getTrace(), ErrorType.E_ERROR, Messages.ERR_CANNOT_REDECLARE_CONSTANT, el.getName());
}
}
}
// write closures
for (ClosureStmtToken closure : analyzer.getClosures()) {
ClosureEntity closureEntity = new ClosureStmtCompiler(this, closure).compile();
module.addClosure(closureEntity);
}
for (FunctionStmtToken function : analyzer.getFunctions()) {
if (!function.isStatic()) {
FunctionEntity entity = compileFunction(function);
entity.setStatic(function.isStatic());
module.addFunction(entity);
}
}
for (Token token : tokens) {
if (token instanceof NamespaceStmtToken) {
setNamespace((NamespaceStmtToken) token);
}
if (token instanceof DeclareStmtToken) {
declareStmtTokens.add((DeclareStmtToken) token);
}
if (token instanceof ClassStmtToken) {
ClassStmtCompiler cmp = new ClassStmtCompiler(this, (ClassStmtToken) token);
ClassEntity entity = cmp.compile();
classes.put(entity.getLowerName(), entity);
entity.setStatic(true);
module.addClass(entity);
if (cmp.isInitDynamicExists()) {
externalCode.add(new ExprStmtToken(getEnvironment(), getContext(), new ClassInitEnvironment((ClassStmtToken) token, entity)));
}
} else if (token instanceof FunctionStmtToken) {
FunctionEntity entity = compileFunction((FunctionStmtToken) token);
entity.setStatic(true);
module.addFunction(entity);
functions.put(entity.getLowerName(), entity);
} else if (token instanceof ExprStmtToken) {
externalCode.add((ExprStmtToken) token);
} else
externalCode.add(new ExprStmtToken(getEnvironment(), getContext(), token));
}
// write anon classes
for (ClassStmtToken aClass : analyzer.getClasses()) {
if (aClass.isAnonymous()) {
ClassStmtCompiler cmp = new ClassStmtCompiler(this, aClass);
ClassEntity entity = cmp.compile();
entity.setStatic(true);
entity.setAnonymous(true);
module.addClass(entity);
if (cmp.isInitDynamicExists()) {
externalCode.add(new ExprStmtToken(getEnvironment(), getContext(), new ClassInitEnvironment((ClassStmtToken) aClass, entity)));
}
}
}
return externalCode;
}
use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class CallCompiler method writeByName.
/**
* functionName()
*/
protected Memory writeByName(CallExprToken function, boolean returnValue, boolean writeOpcode, PushCallStatistic statistic) {
Token name = function.getName();
String realName = ((NameToken) name).getName();
CompileFunction compileFunction = compiler.getScope().findCompileFunction(realName);
// try find system function, like max, sin, cos, etc.
if (compileFunction == null && name instanceof FulledNameToken && compiler.getEnvironment().fetchFunction(realName) == null && compiler.findFunction(realName) == null) {
String tryName = ((FulledNameToken) name).getLastName().getName();
compileFunction = compiler.getScope().findCompileFunction(tryName);
}
if (compileFunction != null) {
return expr.writePushCompileFunction(function, compileFunction, returnValue, writeOpcode, statistic);
} else {
FunctionEntity localFunction = compiler.findFunction(realName);
if (localFunction != null) {
if (localFunction.isLikeConstant() && function.getParameters().isEmpty()) {
if (!writeOpcode) {
if (statistic != null) {
statistic.returnType = StackItem.Type.valueOf(Memory.class);
}
return localFunction.getResult();
} else {
if (returnValue) {
expr.writePushMemory(localFunction.getResult());
}
return null;
}
}
}
if (!writeOpcode) {
return null;
}
expr.getMethod().getEntity().setImmutable(false);
int index = expr.getMethod().clazz.getAndIncCallFuncCount();
expr.writePushEnv();
expr.writePushTraceInfo(function);
expr.writePushString(realName.toLowerCase());
expr.writePushString(realName);
expr.writePushParameters(function.getParameters());
expr.writeGetStatic("$CALL_FUNC_CACHE", FunctionCallCache.class);
expr.writePushConstInt(index);
expr.writeSysStaticCall(InvokeHelper.class, "call", Memory.class, Environment.class, TraceInfo.class, String.class, String.class, Memory[].class, FunctionCallCache.class, Integer.TYPE);
if (!returnValue) {
expr.writePopAll(1);
}
}
return null;
}
use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class ASMExpression method processToken.
protected void processToken(Token token, Stack<Token> stack, List<Token> result) {
if (token instanceof CallExprToken) {
CallExprToken call = (CallExprToken) token;
if (call.getName() instanceof OperatorExprToken) {
processOperator(stack, result, (OperatorExprToken) call.getName());
}
result.add(token);
} else if (token instanceof ValueExprToken) {
result.add(token);
} else if (token instanceof BraceExprToken) {
BraceExprToken brace = (BraceExprToken) token;
if (brace.isSimpleOpened()) {
stack.push(brace);
} else if (brace.isSimpleClosed()) {
if (stack.empty())
unexpectedToken(brace);
boolean done = false;
do {
Token el = stack.pop();
if (el instanceof BraceExprToken && ((BraceExprToken) el).isSimpleOpened()) {
done = true;
break;
}
result.add(el);
} while (!stack.isEmpty());
if (!done)
unexpectedToken(brace);
} else
unexpectedToken(brace);
} else if (token instanceof OperatorExprToken) {
OperatorExprToken operator = (OperatorExprToken) token;
/*boolean done = !stack.empty();
if (done){
if (operator.isRightSide())
done = getPriority(stack.peek()) > prior;
else
done = getPriority(stack.peek()) > prior;
}
if (done){
if (prior == 1){
processOperator(stack, result, prior);
result.add(token);
return;
}
stack.push(token);
return;
}*/
processOperator(stack, result, operator);
stack.push(token);
}
}
use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class NamespaceSyntaxTest method testSimple.
@Test
public void testSimple() {
List<Token> tree = getSyntaxTree("namespace; 123;");
Assert.assertTrue(tree.size() == 2);
Assert.assertTrue(tree.get(0) instanceof NamespaceStmtToken);
Assert.assertTrue(tree.get(1) instanceof ExprStmtToken);
NamespaceStmtToken token = (NamespaceStmtToken) tree.get(0);
Assert.assertNull(token.getTree());
Assert.assertNull(token.getName());
}
Aggregations