str MALparser(Client c) { InstrPtr p; MalBlkRecord oldstate; c->curprg->def->errors = 0; oldstate = *c->curprg->def; prepareMalBlk(c->curprg->def, CURRENT(c)); if (parseMAL(c, c->curprg, 0) || c->curprg->def->errors) { /* just complete it for visibility */ pushEndInstruction(c->curprg->def); /* caught errors */ showErrors(c); if (c->listing) printFunction(c->fdout, c->curprg->def, 0, c->listing); MSresetVariables(c, c->curprg->def, c->glb, oldstate.vtop); resetMalBlk(c->curprg->def, 1); /* now the parsing is done we should advance the stream */ c->fdin->pos += c->yycur; c->yycur = 0; throw(SYNTAX, "mal.parser", SYNTAX_GENERAL MANUAL_HELP); } /* now the parsing is done we should advance the stream */ c->fdin->pos += c->yycur; c->yycur = 0; /* check for unfinished blocks */ if (c->blkmode) return MAL_SUCCEED; /* empty files should be skipped as well */ if (c->curprg->def->stop == 1) return MAL_SUCCEED; p = getInstrPtr(c->curprg->def, 0); if (p->token != FUNCTIONsymbol) { if (c->listing) printFunction(c->fdout, c->curprg->def, 0, c->listing); MSresetVariables(c, c->curprg->def, c->glb, oldstate.vtop); resetMalBlk(c->curprg->def, 1); throw(SYNTAX, "mal.parser", SYNTAX_SIGNATURE); } pushEndInstruction(c->curprg->def); chkProgram(c->fdout, c->nspace, c->curprg->def); if (c->curprg->def->errors) { showErrors(c); if (c->listing) printFunction(c->fdout, c->curprg->def, 0, c->listing); MSresetVariables(c, c->curprg->def, c->glb, oldstate.vtop); resetMalBlk(c->curprg->def, 1); throw(MAL, "MAL.parser", SEMANTIC_GENERAL); } return MAL_SUCCEED; }
str shutdownFactoryByName(Client cntxt, Module m, str nme){ Plant pl, plim; InstrPtr p; Symbol s; plim = plants + lastPlant; for (pl = plants; pl < plim; pl++) if (pl->factory ) { MalStkPtr stk; p= getInstrPtr(pl->factory,0); if( strcmp(nme, getFunctionId(p)) != 0) continue; s = findSymbolInModule(m, nme ); if (s == NULL){ throw(MAL, "factory.remove", OPERATION_FAILED " SQL entry '%s' not found", putName(nme)); } stk = pl->stk; MSresetVariables(cntxt, pl->factory, stk, 0); shutdownFactory(cntxt, pl->factory); freeStack(stk); deleteSymbol(m,s); return MAL_SUCCEED; } return MAL_SUCCEED; }
str MALengine(Client c) { Symbol prg; str msg = MAL_SUCCEED; MalBlkRecord oldstate = *c->curprg->def; oldstate.stop = 0; if (c->blkmode) return MAL_SUCCEED; prg = c->curprg; if (prg == NULL) throw(SYNTAX, "mal.engine", SYNTAX_SIGNATURE); if (prg->def == NULL) throw(SYNTAX, "mal.engine", SYNTAX_SIGNATURE); if (prg->def->errors > 0) { showErrors(c); if (c->listing) printFunction(c->fdout, c->curprg->def, 0, c->listing); MSresetVariables(c, c->curprg->def, c->glb, oldstate.vtop); resetMalBlk(c->curprg->def, 1); throw(MAL, "mal.engine", PROGRAM_GENERAL); } if (prg->def->stop == 1 || MALcommentsOnly(prg->def)) return 0; /* empty block */ if (c->glb) { if (prg->def && c->glb->stksize < prg->def->vsize){ c->glb = reallocGlobalStack(c->glb, prg->def->vsize); if( c->glb == NULL) throw(MAL, "mal.engine", MAL_MALLOC_FAIL); } c->glb->stktop = prg->def->vtop; c->glb->blk = prg->def; c->glb->cmd = (c->itrace && c->itrace != 'C') ? 'n' : 0; } if (c->listing > 1) printFunction(c->fdout, c->curprg->def, 0, c->listing); /* * In interactive mode we should avoid early garbage collection of values. * This can be controlled by the clean up control at the instruction level * and marking all non-temporary variables as being (potentially) used. */ if (c->glb) { c->glb->pcup = 0; c->glb->keepAlive = TRUE; /* no garbage collection */ } if (prg->def->errors == 0) msg = (str) runMAL(c, prg->def, 0, c->glb); if (msg) { /* ignore "internal" exceptions */ str fcn = getExceptionPlace(msg); /* retrieves from "first" exception */ if (strcmp(fcn, "client.quit") != 0) dumpExceptionsToStream(c->fdout, msg); GDKfree(fcn); if (!c->listing) printFunction(c->fdout, c->curprg->def, 0, c->listing); showErrors(c); } MSresetVariables(c, prg->def, c->glb, 0); resetMalBlk(prg->def, 1); if (c->glb) { /* for global stacks avoid reinitialization from this point */ c->glb->stkbot = prg->def->vtop; } prg->def->errors = 0; if (c->itrace) mnstr_printf(c->fdout, "mdb>#EOD\n"); return msg; }