use of priv.bajdcc.LALR1.syntax.token.Token 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);
}
use of priv.bajdcc.LALR1.syntax.token.Token in project jMiniLang by bajdcc.
the class TokenTools method sinop.
/**
* 单目运算
*
* @param recorder 错误记录
* @param exp 表达式
* @return 运算是否合法
*/
public static boolean sinop(ISemanticRecorder recorder, ExpSinop exp) {
ExpValue value = (ExpValue) exp.getOperand();
Token token = value.getToken();
OperatorType type = (OperatorType) exp.getToken().object;
if (sin(type, token)) {
return true;
}
recorder.add(SemanticError.INVALID_OPERATOR, token);
return false;
}
use of priv.bajdcc.LALR1.syntax.token.Token in project jMiniLang by bajdcc.
the class TokenTools method triop.
/**
* 三目运算(当前只有一种形式)
*
* @param recorder 错误记录
* @param exp 表达式
* @return 运算是否合法
*/
public static int triop(ISemanticRecorder recorder, ExpTriop exp) {
ExpValue firstValue = (ExpValue) exp.getFirstOperand();
Token firstToken = exp.getFirstToken();
Token secondToken = exp.getSecondToken();
int branch = tri(firstToken, secondToken, firstValue.getToken());
if (branch != 0) {
return branch;
}
recorder.add(SemanticError.INVALID_OPERATOR, firstToken);
return 0;
}
use of priv.bajdcc.LALR1.syntax.token.Token in project jMiniLang by bajdcc.
the class StmtTry method genCode.
@Override
public void genCode(ICodegen codegen) {
RuntimeInstUnary t = codegen.genCode(RuntimeInst.itry, -1);
codegen.genCode(RuntimeInst.iscpi);
tryBlock.genCode(codegen);
RuntimeInstUnary jmp = codegen.genCode(RuntimeInst.ijmp, -1);
t.op1 = codegen.getCodeIndex();
if (token != null) {
// 'throw' push exp to stack top
codegen.genCode(RuntimeInst.ipush, codegen.genDataRef(token.object));
codegen.genCode(RuntimeInst.ialloc);
}
catchBlock.genCode(codegen);
jmp.op1 = codegen.getCodeIndex();
codegen.genCode(RuntimeInst.ipop);
codegen.genCode(RuntimeInst.iscpo);
codegen.genCode(RuntimeInst.itry, -1);
}
use of priv.bajdcc.LALR1.syntax.token.Token in project jMiniLang by bajdcc.
the class Semantic method run.
/**
* 进行语义处理
*/
private void run() throws SyntaxException {
if (!arrErrors.isEmpty()) {
System.err.println(getTrackerError());
throw new SyntaxException(SyntaxError.COMPILE_ERROR, arrErrors.get(0).position, "出现语法错误");
}
/* 规则集合 */
ArrayList<RuleItem> items = npa.getRuleItems();
/* 符号表查询接口 */
IQuerySymbol query = getQuerySymbolService();
/* 符号表管理接口 */
IManageSymbol manage = getManageSymbolService();
/* 语义错误处理接口 */
ISemanticRecorder recorder = getSemanticRecorderService();
/* 复制单词流 */
ArrayList<Token> tokens = arrTokens.stream().map(Token::copy).collect(Collectors.toCollection(ArrayList::new));
/* 运行时自动机 */
SemanticMachine machine = new SemanticMachine(items, arrActions, tokens, query, manage, recorder, debug);
/* 遍历所有指令 */
arrInsts.forEach(machine::run);
object = machine.getObject();
if (object != null) {
Function entry = (Function) object;
manage.getManageScopeService().registerFunc(entry);
}
}
Aggregations