Search in sources :

Example 1 with TokenType

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);
}
Also used : Token(priv.bajdcc.util.lexer.token.Token) BigInteger(java.math.BigInteger) TokenType(priv.bajdcc.util.lexer.token.TokenType) RuntimeFuncObject(priv.bajdcc.LALR1.grammar.runtime.data.RuntimeFuncObject)

Aggregations

BigInteger (java.math.BigInteger)1 RuntimeFuncObject (priv.bajdcc.LALR1.grammar.runtime.data.RuntimeFuncObject)1 Token (priv.bajdcc.util.lexer.token.Token)1 TokenType (priv.bajdcc.util.lexer.token.TokenType)1