Changeset: 00c355592bac for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=00c355592bac Modified Files: monetdb5/mal/mal_client.c monetdb5/mal/mal_client.h monetdb5/mal/mal_parser.c monetdb5/mal/mal_session.c Branch: malparsing Log Message:
Revert backup malblock for parsing The MAL function statements should be assembled in their own block to avoid scoping issues. diffs (242 lines): diff --git a/monetdb5/mal/mal_client.c b/monetdb5/mal/mal_client.c --- a/monetdb5/mal/mal_client.c +++ b/monetdb5/mal/mal_client.c @@ -215,6 +215,7 @@ MCinitClientRecord(Client c, oid user, b c->mdb = 0; c->history = 0; c->curprg = 0; + c->backup = 0; c->glb = 0; /* remove garbage from previous connection diff --git a/monetdb5/mal/mal_client.h b/monetdb5/mal/mal_client.h --- a/monetdb5/mal/mal_client.h +++ b/monetdb5/mal/mal_client.h @@ -148,6 +148,7 @@ typedef struct CLIENT { Module usermodule; /* private user scope */ Module curmodule; /* where to deliver the symbol, used by parser , only freed globally */ Symbol curprg; /* container for the malparser */ + Symbol backup; /* saving the parser context for functions,commands/patterns */ MalStkPtr glb; /* global variable stack */ /* * Some statistics on client behavior becomes relevant for server diff --git a/monetdb5/mal/mal_parser.c b/monetdb5/mal/mal_parser.c --- a/monetdb5/mal/mal_parser.c +++ b/monetdb5/mal/mal_parser.c @@ -956,7 +956,12 @@ fcnHeader(Client cntxt, int kind) advance(cntxt, l); } else modnme= cntxt->curmodule->name; - cntxt->curprg->name = fnme; + + if (cntxt->backup){ + parseError(cntxt, "mal_parser: unexpected recursion\n"); + return 0; + } + if (*cntxt->lineptr != '('){ parseError(cntxt, "function header '(' expected\n"); @@ -964,13 +969,12 @@ fcnHeader(Client cntxt, int kind) } advance(cntxt, 1); - curInstr = getInstrPtr(cntxt->curprg->def,0); - setModuleId(curInstr,modnme); - setFunctionId(curInstr,fnme); - curInstr->token = kind; - cntxt->curprg->kind = kind; + cntxt->backup = cntxt->curprg; + cntxt->curprg = newFunction( modnme, fnme, kind); + curBlk = cntxt->curprg->def; + curInstr = getInstrPtr(curBlk, 0); - /* get calling parameters */ + /*get calling parameters */ ch = *cntxt->lineptr; while (ch != ')' && ch && !NL(ch)) { curInstr = binding(cntxt, curBlk, curInstr, 1); @@ -984,6 +988,11 @@ fcnHeader(Client cntxt, int kind) if ((ch = *cntxt->lineptr) != ',') { if (ch == ')') break; + if (cntxt->backup) { + freeSymbol(cntxt->curprg); + cntxt->curprg = cntxt->backup; + cntxt->backup = 0; + } parseError(cntxt, "',' expected\n"); return 1; } else @@ -991,6 +1000,12 @@ fcnHeader(Client cntxt, int kind) ch = *cntxt->lineptr; } if (*cntxt->lineptr != ')') { + if (cntxt->backup) { + freeSymbol(cntxt->curprg); + cntxt->curprg = cntxt->backup; + cntxt->backup = 0; + } + parseError(cntxt, "')' expected\n"); return 1; } @@ -1028,6 +1043,12 @@ fcnHeader(Client cntxt, int kind) if ((ch = *cntxt->lineptr) != ',') { if (ch == ')') break; + if (cntxt->backup) { + freeSymbol(cntxt->curprg); + cntxt->curprg = cntxt->backup; + cntxt->backup = 0; + } + parseError(cntxt, "',' expected\n"); return 1; } else { @@ -1039,6 +1060,11 @@ fcnHeader(Client cntxt, int kind) max = curInstr->maxarg; newarg = (short *) GDKmalloc(max * sizeof(curInstr->argv[0])); if (newarg == NULL){ + if (cntxt->backup) { + freeSymbol(cntxt->curprg); + cntxt->curprg = cntxt->backup; + cntxt->backup = 0; + } parseError(cntxt, MAL_MALLOC_FAIL); return 1; } @@ -1054,6 +1080,11 @@ fcnHeader(Client cntxt, int kind) curInstr->argv[i1] = newarg[i1]; GDKfree(newarg); if (*cntxt->lineptr != ')') { + if (cntxt->backup) { + freeSymbol(cntxt->curprg); + cntxt->curprg = cntxt->backup; + cntxt->backup = 0; + } parseError(cntxt, "')' expected\n"); return 1; } @@ -1071,7 +1102,7 @@ fcnHeader(Client cntxt, int kind) static MalBlkPtr parseCommandPattern(Client cntxt, int kind) { - MalBlkPtr curBlk = cntxt->curprg->def; + MalBlkPtr curBlk; Symbol curPrg = 0; InstrPtr curInstr = 0; str modnme = NULL; @@ -1079,7 +1110,7 @@ parseCommandPattern(Client cntxt, int ki if( fcnHeader(cntxt, kind)) return 0; - getInstrPtr(curBlk, 0)->token = kind; + curBlk = cntxt->curprg->def; curPrg = cntxt->curprg; curPrg->kind = kind; curInstr = getInstrPtr(curBlk, 0); @@ -1089,13 +1120,22 @@ parseCommandPattern(Client cntxt, int ki l = strlen(modnme); modnme = putNameLen(modnme, l); - if( strcmp(modnme,"user") ==0 ){ - insertSymbol(cntxt->usermodule, curPrg); - } else - if( getModule(modnme) ){ - insertSymbol( getModule(modnme), curPrg); + if ( strcmp(modnme,"user")== 0 || getModule(modnme)){ + if ( strcmp(modnme,"user") == 0) + insertSymbol(cntxt->usermodule, curPrg); + else + insertSymbol(getModule(modnme), curPrg); + chkProgram(cntxt->usermodule, curBlk); + cntxt->curprg->def->errors = cntxt->backup->def->errors; + cntxt->backup->def->errors = 0; + cntxt->curprg = cntxt->backup; + cntxt->backup = 0; } else { + freeSymbol(curPrg); + cntxt->curprg = cntxt->backup; + cntxt->backup = 0; parseError(cntxt, "<module> not found\n"); + return 0; } /* * Short-cut function calls @@ -1214,12 +1254,23 @@ parseEnd(Client cntxt) } if ((l == (int) strlen(getFunctionId(sig)) && strncmp(cntxt->lineptr, getFunctionId(sig), l) == 0) || l == 0) {} else { + advance(cntxt, l); parseError(cntxt, "non matching end label\n"); return 0; } advance(cntxt, l); pushEndInstruction(cntxt->curprg->def); cntxt->blkmode = 0; + if ( strcmp(getModuleId(sig),"user")== 0 ) + insertSymbol(cntxt->usermodule, cntxt->curprg); + else + insertSymbol(getModule(getModuleId(sig)), cntxt->curprg); + chkProgram(cntxt->usermodule, cntxt->curprg->def); + if (cntxt->backup) { + cntxt->backup->def->errors = GDKstrdup(cntxt->curprg->def->errors); + cntxt->curprg = cntxt->backup; + cntxt->backup = 0; + } return 1; } return 0; diff --git a/monetdb5/mal/mal_session.c b/monetdb5/mal/mal_session.c --- a/monetdb5/mal/mal_session.c +++ b/monetdb5/mal/mal_session.c @@ -487,6 +487,10 @@ MSserveClient(void *dummy) /* * At this stage we should clean out the MAL block */ + if (c->backup) { + freeSymbol(c->backup); + c->backup = 0; + } if (c->curprg) { Symbol s = c->curprg; assert(0); @@ -540,6 +544,10 @@ MALexitClient(Client c) if (c->glb && c->curprg->def->errors == MAL_SUCCEED) garbageCollector(c, c->curprg->def, c->glb, TRUE); c->mode = FINISHCLIENT; + if (c->backup) { + freeSymbol(c->backup); + c->backup = 0; + } c->curprg = NULL; c->usermodule = NULL; // only clear out the private module @@ -700,8 +708,8 @@ MALparser(Client cntxt) msg = cntxt->curprg->def->errors; if( msg != MAL_SUCCEED){ cntxt->curprg->def->errors = MAL_SUCCEED; - MSresetVariables(cntxt, cntxt->curprg->def, cntxt->glb, oldstate.vtop); - resetMalBlk(cntxt->curprg->def, 1); + //MSresetVariables(cntxt, cntxt->curprg->def, cntxt->glb, oldstate.vtop); + //resetMalBlk(cntxt->curprg->def, 1); return msg; } @@ -737,6 +745,7 @@ MALparser(Client cntxt) getFunctionId(getSignature(cntxt->curprg)), cntxt->usermodule->name); #endif +/* insertSymbol(cntxt->usermodule, cntxt->curprg); chkProgram(cntxt->usermodule, cntxt->curprg->def); msg = cntxt->curprg->def->errors; @@ -744,6 +753,7 @@ MALparser(Client cntxt) if (msg) { } (void) MSinitClientPrg(cntxt,"user","main"); +*/ } return msg; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list