use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class SimpleExprGenerator method processList.
@SuppressWarnings("unchecked")
protected ListExprToken processList(Token current, ListIterator<Token> iterator, List indexes, BraceExprToken.Kind closedBraceKind, int braceOpened) {
boolean arraySyntax = isOpenedBrace(current, BraceExprToken.Kind.ARRAY);
ListExprToken result = arraySyntax ? new ListExprToken(current.getMeta()) : (ListExprToken) current;
Token next;
if (!arraySyntax) {
next = nextToken(iterator);
if (!isOpenedBrace(next, SIMPLE)) {
unexpectedToken(next, "(");
}
}
int i = 0;
boolean withKeys = false;
boolean isRef = false;
ExprStmtToken keyExpr = null;
while (true) {
next = nextToken(iterator);
if (next instanceof ListExprToken || isOpenedBrace(next, ARRAY)) {
isRef = false;
if ((arraySyntax && next instanceof ListExprToken) || (!arraySyntax && isOpenedBrace(next, ARRAY))) {
analyzer.getEnvironment().error(next.toTraceInfo(analyzer.getContext()), ErrorType.E_ERROR, Messages.ERR_CANNOT_MIX_ARRAY_AND_LIST);
}
List indexes_ = new ArrayList();
if (indexes != null) {
indexes_.addAll(indexes);
}
indexes_.add(keyExpr == null ? i : keyExpr);
ListExprToken tmp = processList(next, iterator, indexes_, null, -1);
result.addList(tmp);
if (nextTokenAndPrev(iterator) instanceof CommaToken) {
iterator.next();
}
i++;
} else if (isClosedBrace(next, arraySyntax ? ARRAY : SIMPLE)) {
break;
} else if (next instanceof CommaToken) {
i++;
} else if (next instanceof AmpersandRefToken) {
result.setHasRef(true);
isRef = true;
} else {
SimpleExprGenerator generator = analyzer.generator(SimpleExprGenerator.class);
int currIndex = iterator.nextIndex() - 1;
ExprStmtToken var = generator.getToken(next, iterator, Separator.COMMA, arraySyntax ? ARRAY : SIMPLE);
if (var.isVariadic()) {
analyzer.getEnvironment().error(next.toTraceInfo(analyzer.getContext()), ErrorType.E_ERROR, Messages.ERR_SPREAD_OPERATOR_NOT_SUPPORTED_IN_ASSIGN);
}
int k = 0;
keyExpr = null;
ExprStmtToken valueExpr = var;
for (Token token : var.getTokens()) {
if (token instanceof KeyValueExprToken) {
keyExpr = new ExprStmtToken(analyzer.getEnvironment(), analyzer.getContext(), var.getTokens().subList(0, k));
valueExpr = new ExprStmtToken(analyzer.getEnvironment(), analyzer.getContext(), var.getTokens().subList(k + 1, var.getTokens().size()));
isRef = valueExpr.getSingle() instanceof AmpersandRefToken;
AmpersandRefToken isRefToken = null;
if (isRef) {
result.setHasRef(true);
isRefToken = (AmpersandRefToken) valueExpr.getSingle();
valueExpr = new ExprStmtToken(analyzer.getEnvironment(), analyzer.getContext(), valueExpr.getTokens().subList(1, valueExpr.getTokens().size()));
}
if (valueExpr.getSingle() instanceof ArrayExprToken || valueExpr.getSingle() instanceof ListExprToken) {
if (isRef) {
unexpectedToken(isRefToken);
}
if (valueExpr.getSingle() instanceof ListExprToken && ((ListExprToken) valueExpr.getSingle()).isHasRef()) {
result.setHasRef(true);
}
if ((arraySyntax && valueExpr.getSingle() instanceof ListExprToken) || (!arraySyntax && valueExpr.getSingle() instanceof ArrayExprToken)) {
analyzer.getEnvironment().error(next.toTraceInfo(analyzer.getContext()), ErrorType.E_ERROR, Messages.ERR_CANNOT_MIX_ARRAY_AND_LIST);
}
int doneIndex = iterator.nextIndex() - 1;
int prevCount = doneIndex - currIndex;
for (int m = 0; m < prevCount; m++) {
iterator.previous();
}
do {
current = iterator.next();
if (current instanceof KeyValueExprToken) {
current = iterator.next();
break;
}
} while (iterator.hasNext());
List indexes_ = new ArrayList();
if (indexes != null) {
indexes_.addAll(indexes);
}
indexes_.add(keyExpr);
ListExprToken listExprToken = processList(current, iterator, indexes_, null, -1);
result.addList(listExprToken);
if (nextTokenAndPrev(iterator) instanceof CommaToken) {
iterator.next();
}
}
break;
}
k++;
}
Token single = valueExpr.getLast();
if (single instanceof ArrayExprToken || single instanceof ListExprToken) {
i++;
continue;
}
if (!(single instanceof VariableExprToken || single instanceof ArrayGetExprToken || single instanceof DynamicAccessExprToken || single instanceof ArrayPushExprToken || (single instanceof StaticAccessExprToken && ((StaticAccessExprToken) single).isGetStaticField()))) {
unexpectedToken(single);
}
if (single instanceof ArrayGetExprToken) {
single = new ArrayGetRefExprToken((ArrayGetExprToken) single);
valueExpr.getTokens().set(var.getTokens().size() - 1, single);
valueExpr.updateAsmExpr(analyzer.getEnvironment(), analyzer.getContext());
}
if (keyExpr == null) {
if (withKeys) {
analyzer.getEnvironment().error(next.toTraceInfo(analyzer.getContext()), ErrorType.E_ERROR, Messages.ERR_CANNOT_MIX_KEYED_AND_UNKEYED_ARRAY_ENTRIES);
}
result.addVariable(valueExpr, i, indexes, isRef);
} else {
if (!withKeys && i > 0) {
analyzer.getEnvironment().error(next.toTraceInfo(analyzer.getContext()), ErrorType.E_ERROR, Messages.ERR_CANNOT_MIX_KEYED_AND_UNKEYED_ARRAY_ENTRIES);
}
withKeys = true;
result.addVariable(valueExpr, keyExpr, indexes, isRef);
}
if (isRef && analyzer.getFunction() != null && valueExpr.isSingle() && valueExpr.getSingle() instanceof ValueExprToken) {
analyzer.getFunction().variable((VariableExprToken) valueExpr.getSingle()).setReference(true);
}
cont: isRef = false;
i++;
}
}
if (braceOpened != -1) {
next = nextToken(iterator);
if (!(next instanceof AssignExprToken)) {
iterator.previous();
return result;
// unexpectedToken(next, "=");
}
ExprStmtToken value = analyzer.generator(SimpleExprGenerator.class).getNextExpression(nextToken(iterator), iterator, BraceExprToken.Kind.ANY);
result.setValue(value);
}
return result;
}
use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class StringBuilderValueCompiler method writeBuilder.
public void writeBuilder(List<Token> tokens, boolean binary) {
expr.writePushNewObject(StringBuilder.class);
for (Token el : tokens) {
// writePushDup();
if (el instanceof ValueExprToken) {
expr.writePush((ValueExprToken) el, true, false);
} else if (el instanceof ExprStmtToken) {
// unexpectedToken(el);
expr.writeExpression((ExprStmtToken) el, true, false, true);
} else
expr.unexpectedToken(el);
StackItem.Type peek = expr.stackPeek().type;
if (!peek.isConstant()) {
expr.writeSysDynamicCall(StringBuilder.class, "append", StringBuilder.class, Object.class);
} else
expr.writeSysDynamicCall(StringBuilder.class, "append", StringBuilder.class, peek.toClass());
}
expr.writeSysDynamicCall(StringBuilder.class, "toString", String.class);
if (binary) {
expr.writeSysStaticCall(BinaryMemory.class, "valueOf", Memory.class, String.class);
}
}
use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class ConstGenerator method getToken.
/*@SuppressWarnings("unchecked")
protected void processBody(ConstStmtToken result, ListIterator<Token> iterator){
Token current = nextToken(iterator);
if (!(current instanceof AssignExprToken))
unexpectedToken(current, "=");
ExprStmtToken value = analyzer.generator(SimpleExprGenerator.class).getToken(nextToken(iterator), iterator);
if (value == null)
unexpectedToken(nextToken(iterator));
result.setValue(value);
}*/
@Override
@SuppressWarnings("unchecked")
public ConstStmtToken getToken(Token current, ListIterator<Token> iterator) {
if (current instanceof ConstStmtToken) {
ConstStmtToken result = (ConstStmtToken) current;
Token prev = null;
if (analyzer.getClazz() == null)
result.setNamespace(analyzer.getNamespace());
while (true) {
Token next = analyzer.getClazz() == null ? nextToken(iterator) : nextTokenSensitive(iterator, ClassStmtToken.class);
if (next instanceof NameToken) {
if (next instanceof FulledNameToken && !((FulledNameToken) next).isProcessed(NamespaceUseStmtToken.UseType.CONSTANT))
unexpectedToken(next, TokenType.T_STRING);
Token token = nextToken(iterator);
if (!(token instanceof AssignExprToken))
unexpectedToken(token, "=");
ExprStmtToken value = analyzer.generator(SimpleExprGenerator.class).getToken(nextToken(iterator), iterator, Separator.COMMA_OR_SEMICOLON, null);
if (!isBreak(iterator.previous())) {
iterator.next();
}
if (value == null)
unexpectedToken(iterator.previous());
result.add((NameToken) next, value);
} else if (next instanceof CommaToken) {
if (prev instanceof CommaToken)
unexpectedToken(next);
prev = next;
} else if (isBreak(next)) {
break;
} else
unexpectedToken(next, TokenType.T_STRING);
}
return result;
}
return null;
}
use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class Generator method prevToken.
protected Token prevToken(ListIterator<Token> iterator) {
checkUnexpectedStart(iterator);
Token tk = iterator.previous();
if (tk instanceof CommentToken) {
return prevToken(iterator);
}
return tk;
}
use of org.develnext.jphp.core.tokenizer.token.Token in project jphp by jphp-compiler.
the class ForeachCompiler method write.
@Override
public void write(ForeachStmtToken token) {
expr.writeDefineVariables(token.getLocal());
LabelNode start = new LabelNode();
LabelNode end = new LabelNode();
LabelNode l = new LabelNode();
add(l);
expr.writePushEnv();
expr.writePushTraceInfo(token);
expr.writeExpression(token.getIterator(), true, false, true);
expr.writePopBoxing();
expr.writePushConstBoolean(token.isValueReference());
expr.writePushConstBoolean(token.isKeyReference());
expr.writeSysDynamicCall(Environment.class, "__getIterator", ForeachIterator.class, TraceInfo.class, Memory.class, Boolean.TYPE, Boolean.TYPE);
String name = "~foreach~" + method.nextStatementIndex(ForeachIterator.class);
LocalVariable foreachVariable = method.getLocalVariable(name);
if (foreachVariable == null)
foreachVariable = method.addLocalVariable(name, l, ForeachIterator.class);
/*LocalVariable foreachVariable = method.addLocalVariable(
"~foreach~" + method.nextStatementIndex(ForeachIterator.class), l, ForeachIterator.class
);*/
foreachVariable.setEndLabel(end);
expr.writeVarStore(foreachVariable, false, false);
method.pushJump(end, start);
add(start);
expr.writeVarLoad(foreachVariable);
expr.writeSysDynamicCall(ForeachIterator.class, "next", Boolean.TYPE);
add(new JumpInsnNode(IFEQ, end));
expr.stackPop();
// $key
if (token.getKey() != null) {
LocalVariable key = method.getLocalVariable(token.getKey().getName());
expr.checkAssignableVar(token.getKey());
expr.writeVarLoad(foreachVariable);
expr.writeSysDynamicCall(ForeachIterator.class, "getMemoryKey", Memory.class);
if (token.isKeyReference()) {
throw new FatalException("Key element cannot be a reference", token.getKey().toTraceInfo(compiler.getContext()));
// writeVarStore(key, false, false);
} else
expr.writeVarAssign(key, null, false, false);
}
// $var
// LocalVariable variable = method.getLocalVariable(token.getValue().getName());
Token last = token.getValue().getLast();
VariableExprToken var = null;
if (last instanceof DynamicAccessExprToken) {
DynamicAccessExprToken setter = (DynamicAccessExprToken) last;
ExprStmtToken value = new ExprStmtToken(this.env, this.compiler.getContext(), token.getValue().getTokens());
value.getTokens().remove(value.getTokens().size() - 1);
value.updateAsmExpr(this.env, this.compiler.getContext());
expr.writeExpression(value, true, false);
expr.writeVarLoad(foreachVariable);
expr.writeSysDynamicCall(ForeachIterator.class, "getValue", Memory.class);
if (!token.isValueReference())
expr.writePopImmutable();
expr.writeDynamicAccessInfo(setter, false);
expr.writeGetStatic("$CALL_PROP_CACHE", PropertyCallCache.class);
expr.writePushConstInt(method.clazz.getAndIncCallPropCount());
expr.writeSysStaticCall(ObjectInvokeHelper.class, "assignProperty", Memory.class, Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
} else {
if (token.getValue().getSingle() instanceof VariableExprToken)
expr.checkAssignableVar(var = (VariableExprToken) token.getValue().getSingle());
ExprStmtToken value = token.getValue();
expr.writeVarLoad(foreachVariable);
expr.writeSysDynamicCall(ForeachIterator.class, "getValue", Memory.class);
if (value.isSingle() && value.getSingle() instanceof ListExprToken) {
ListExprToken listExprToken = (ListExprToken) value.getSingle();
if (!token.isValueReference() && !listExprToken.isHasRef()) {
expr.writePopImmutable();
}
ListCompiler listCompiler = (ListCompiler) expr.getCompiler(ListExprToken.class);
listCompiler.write(listExprToken, false, false);
} else {
if (!token.isValueReference())
expr.writePopImmutable();
expr.writeExpression(value, true, false);
if (expr.stackPeek().immutable)
expr.unexpectedToken(value.getLast());
expr.writeSysStaticCall(Memory.class, token.isValueReference() ? "assignRefRight" : "assignRight", Memory.class, Memory.class, Memory.class);
}
}
expr.writePopAll(1);
/*
if (token.isValueReference())
writeVarStore(variable, false, false);
else
writeVarAssign(variable, false, true); */
// body
expr.write(BodyStmtToken.class, token.getBody());
add(new JumpInsnNode(GOTO, start));
add(end);
/*if (compiler.getLangMode() == LangMode.JPHP){
if (token.isValueReference() && var != null){
expr.writeVarLoad(var.getName());
expr.writeSysDynamicCall(Memory.class, "unset", void.class);
}
}*/
method.popJump();
expr.writeUndefineVariables(token.getLocal());
method.prevStatementIndex(ForeachIterator.class);
}
Aggregations