use of priv.bajdcc.util.lexer.token.TokenType in project jMiniLang by bajdcc.
the class RuntimeMachine method opCallExtern.
@Override
public void opCallExtern(boolean invoke) throws Exception {
int idx = loadInt();
String name = "";
if (invoke) {
RuntimeStack itStack = stack;
RuntimeObject obj = null;
while (obj == null && itStack != null) {
obj = itStack.findVariable(pageName, idx);
itStack = itStack.prev;
}
if (obj == null) {
err(RuntimeError.WRONG_LOAD_EXTERN, String.valueOf(idx));
}
if (obj.getType() == RuntimeObjectType.kFunc) {
RuntimeFuncObject func = (RuntimeFuncObject) obj.getObj();
Map<Integer, RuntimeObject> env = func.getEnv();
if (env != null) {
for (Entry<Integer, RuntimeObject> entry : env.entrySet()) {
int id = entry.getKey();
RuntimeObject o = entry.getValue();
if (o != null) {
if (o.getSymbol() == null)
o.setSymbol(currentPage.getData().get(id));
o.setReadonly(false);
}
stack.storeClosure(id, o);
}
stack.pushData(obj);
}
int address = func.getAddr();
stack.opCall(address, func.getPage(), stack.reg.execId, pageName, pageMap.get(func.getPage()).getInfo().getFuncNameByAddress(address));
stack.reg.execId = address;
stack.reg.pageId = func.getPage();
switchPage();
pop();
return;
} else if (obj.getType() == RuntimeObjectType.kString) {
name = obj.getObj().toString();
} else {
err(RuntimeError.WRONG_LOAD_EXTERN, obj.toString());
}
} else {
RuntimeObject obj = fetchFromGlobalData(idx);
name = obj.getObj().toString();
}
List<RuntimeCodePage> refers = pageRefer.get(pageName);
for (RuntimeCodePage page : refers) {
int address = page.getInfo().getAddressOfExportFunc(name);
if (address != -1) {
String jmpPage = page.getInfo().getDataMap().get("name").toString();
stack.opCall(address, jmpPage, stack.reg.execId, stack.reg.pageId, name);
stack.reg.execId = address;
stack.reg.pageId = jmpPage;
switchPage();
return;
}
}
for (RuntimeCodePage page : refers) {
IRuntimeDebugExec exec = page.getInfo().getExecCallByName(name);
if (exec != null) {
int argsCount = stack.getFuncArgsCount();
RuntimeObjectType[] types = exec.getArgsType();
if ((types == null && argsCount != 0) || (types != null && types.length != argsCount)) {
err(RuntimeError.WRONG_ARGCOUNT, name + " " + String.valueOf(argsCount));
}
List<RuntimeObject> args = new ArrayList<>();
for (int i = 0; i < argsCount; i++) {
RuntimeObjectType type = types[i];
RuntimeObject objParam = stack.loadFuncArgs(i);
if (type != RuntimeObjectType.kObject) {
RuntimeObjectType objType = objParam.getType();
if (objType != type) {
Token token = Token.createFromObject(objParam.getObj());
TokenType objTokenType = RuntimeObject.toTokenType(type);
if (objTokenType == TokenType.ERROR) {
err(RuntimeError.WRONG_ARGTYPE, name + " " + objTokenType.getName());
}
if (!TokenTools.promote(objTokenType, token)) {
err(RuntimeError.UNDEFINED_CONVERT, name + " " + token.toString() + " " + objTokenType.getName());
} else {
objParam.setObj(token.object);
}
}
}
args.add(objParam);
}
stack.opCall(stack.reg.execId, stack.reg.pageId, stack.reg.execId, stack.reg.pageId, name);
RuntimeObject retVal = exec.ExternalProcCall(args, this);
if (retVal == null) {
store(new RuntimeObject(null));
} else {
store(retVal);
}
opReturn();
return;
}
}
err(RuntimeError.WRONG_LOAD_EXTERN, name);
}
Aggregations