@Override public int check(final int locals) throws ContextError, HeapTooSmallError { if (locals >= 0) { throw new ContextError("Function declarations are only allowed globally!", ident.getLine()); } Routine routine = IMLCompiler.getRoutineTable().getRoutine(ident.getIdent().toString()); IMLCompiler.setScope(routine.getScope()); Store retStore = returnDecl.check(); retStore.setAddress(-routine.getParamList().size() - 1); retStore.setReference(false); retStore.setRelative(true); globImp.check(routine); int localsCount = param.calculateAddress(routine.getParamList().size(), 0); cpsDecl.check(localsCount); cmd.check(false); if (!routine.getScope().getStoreTable().getStore(returnDecl.getIdent()).isInitialized()) { throw new ContextError( "Return value never initialized! Function: " + ident.getIdent(), ident.getLine()); } IMLCompiler.setScope(null); return -1; }
@Override public void checkDeclaration() throws ContextError { Function function = new Function(ident.getIdent().toString(), returnDecl.getType()); IMLCompiler.setScope(function.getScope()); if (!IMLCompiler.getRoutineTable().addRoutine(function)) { throw new ContextError("Routine already declared: " + ident.getIdent(), ident.getLine()); } param.check(function); IMLCompiler.setScope(null); }
@Override public String toString(final String indent) { return indent + "<FunDecl>\n" + ident.toString(indent + '\t') + param.toString(indent + '\t') + returnDecl.toString(indent + '\t') + globImp.toString(indent + '\t') + cpsDecl.toString(indent + '\t') + cmd.toString(indent + '\t') + indent + "</FunDecl>\n"; }
@Override public int code(final int loc) throws CodeTooSmallError { int loc1 = loc; Routine routine = IMLCompiler.getRoutineTable().getRoutine(ident.getIdent().toString()); IMLCompiler.setScope(routine.getScope()); routine.setAddress(loc1); IMLCompiler.getVM().Enter(loc1++, routine.getInOutCopyCount() + cpsDecl.getCount(), 0); loc1 = param.codeIn(loc1, routine.getParamList().size(), 0); loc1 = cmd.code(loc1); loc1 = param.codeOut(loc1, routine.getParamList().size(), 0); IMLCompiler.getVM().Return(loc1++, 1); IMLCompiler.setScope(null); return loc1; }
@Override public int getLine() { return ident.getLine(); }