📄 mal_function.c
字号:
#line 93 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_function.mx"#include "mal_config.h"#include "mal_function.h"#include "mal_resolve.h" /* for isPolymorphic() & chkProgram() */#include "mal_interpreter.h" /* for showErrors() */#include "mal_namespace.h"Symbol newFunction(str nme,int kind){ Symbol s; InstrPtr p; s = newSymbol(nme,kind); p = newInstruction(NULL,kind); setFunctionId(p, nme); /* name already in namespace */ setDestVar(p, newVariable(s->def,GDKstrdup(nme),TYPE_any)); pushInstruction(s->def,p); return s;}InstrPtr newCall(Module scope, str fcnname, int kind){ InstrPtr p; p= newInstruction(NULL,kind); setModuleScope(p, scope); setFunctionId(p, putName(fcnname,strlen(fcnname))); return p;}#line 123 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_function.mx"Symbol getFunctionSymbol(Module scope, InstrPtr p){ Module m; Symbol s; for(m= findModule(scope,getModuleId(p)); m; m= m->outer) if(idcmp(m->name, getModuleId(p))==0 ) { s= m->subscope[(int)(getSubScope(getFunctionId(p)))]; for(; s; s= s->peer) if( getSignature(s)->fcn == p->fcn) return s; } return 0;} #line 138 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_function.mx"void renameFunction(str oldmod, str oldfcn, str modnme, str name){ Module root,scope; Symbol s,prev; InstrPtr p; root= scope= MCgetClient()->nspace; while( scope != NULL){ if( oldmod && strcmp(oldmod, scope->name) ){ scope= scope->outer; continue; } s= scope->subscope[(int)(*oldfcn)]; prev= NULL; while(s != NULL){ if( idcmp(s->name,oldfcn) == 0) break; prev= s; s= s->skip; } if( s) { if( prev == 0){ scope->subscope[(int)(*oldfcn)]= s->skip; } else { prev->peer= s->skip; } while(s){ prev= s->peer; s->peer= NULL; s->name= GDKstrdup(name); p= getInstrPtr(s->def,0); setModuleId(p,putName(modnme,strlen(modnme))); setFunctionId(p,putName(name,strlen(name))); insertSymbol(root,s); s= prev; } return; } scope=scope->outer; }}#line 197 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_function.mx"int getPC(MalBlkPtr mb, InstrPtr p){ int i; for( i=0;i<mb->stop; i++) if( getInstrPtr(mb,i)==p) return i; return -1;}#line 210 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_function.mx"#define DEPTH 128void chkFlow(MalBlkPtr mb){ int i,j,k, v,lastInstruction; int pc[DEPTH]; int var[DEPTH]; InstrPtr stmt[DEPTH]; int btop=0; int retseen=0; int fixed=1; InstrPtr p; lastInstruction = mb->stop-1; for(i= 0; i<mb->stop; i++){ p= getInstrPtr(mb,i); switch( p->barrier){ case BARRIERsymbol: case CATCHsymbol: if(btop== DEPTH){ showScriptException(mb,i,SYNTAX, "Too many nested MAL blocks"); mb->errors++; return; } pc[btop]= i; v= var[btop]= getDestVar(p); stmt[btop]=p; for(j=btop-1;j>=0;j--) if( v==var[j]){ showScriptException(mb,i,SYNTAX, "recursive %s[%d] shields %s[%d]", getVarName(mb,v), pc[j], getFcnName(mb),pc[i]); mb->errors++; return; } if( getVarType(mb,v) != TYPE_bit && getVarType(mb,v) != TYPE_int && getVarType(mb,v) != TYPE_str && getVarType(mb,v) != TYPE_lng && getVarType(mb,v) != TYPE_oid && getVarType(mb,v) != TYPE_sht && !isaBatType(getVarType(mb,v)) && getVarType(mb,v) != TYPE_chr && getVarType(mb,v) != TYPE_bte && getVarType(mb,v) != TYPE_wrd ){ showScriptException(mb,i,TYPE, "barrier '%s' should be of type bit, str or number", getVarName(mb, v)); mb->errors++; } btop++; if( p->typechk != TYPE_RESOLVED) fixed =0; break; case EXITsymbol: v= getDestVar(p); if( btop>0 && var[btop-1] != v){ mb->errors++; showScriptException(mb,i,SYNTAX, "exit-label '%s' doesnot match '%s'", getVarName(mb,v), getVarName(mb,var[btop-1])); } if(btop==0){ showScriptException(mb,i,SYNTAX, "exit-label '%s' without begin-label", getVarName(mb,v)); mb->errors++; continue; } /* search the matching block */ for(j=btop-1;j>=0;j--) if( var[j]==v) break; if(j>=0) btop= j; else btop--; /* retrofit LEAVE/REDO instructions */ stmt[btop]->jump= i; for(k=pc[btop]; k<i; k++){ InstrPtr p1= getInstrPtr(mb,k); if( getDestVar(p1)==v ) { /* handle assignments with leave/redo option*/ if(p1->barrier== LEAVEsymbol ) p1->jump= i; if( p1->barrier==REDOsymbol ) p1->jump= pc[btop]+1; } } if( p->typechk != TYPE_RESOLVED) fixed =0; break; case LEAVEsymbol: case REDOsymbol: v= getDestVar(p); for(j=btop-1;j>=0;j--) if( var[j]==v) break; if(j<0){ str nme= getVarName(mb,v); showScriptException(mb,i,SYNTAX, "label '%s' not in guarded block",nme); mb->errors++; } else if( p->typechk != TYPE_RESOLVED) fixed =0; break; case YIELDsymbol: { InstrPtr ps= getInstrPtr(mb,0); if( ps->token != FACTORYsymbol){ showScriptException(mb,i,SYNTAX,"yield misplaced!"); mb->errors++; } } case RETURNsymbol: { InstrPtr ps= getInstrPtr(mb,0); int e; if( ps->retc != p->retc){ showScriptException(mb,i,SYNTAX, "invalid return target!"); mb->errors++; } else if(ps->typechk == TYPE_RESOLVED) for(e=0;e<p->retc; e++){ if( resolveType(getArgType(mb,ps,e),getArgType(mb,p,e)) <0 ){ showScriptException(mb,i,TYPE, "%s type mismatch at type %d", (p->barrier==RETURNsymbol?"RETURN":"YIELD"), getArgType(mb,p,e)); mb->errors++; } } if(ps->typechk != TYPE_RESOLVED) fixed =0; } retseen = 1; break; case ENDsymbol: lastInstruction = lastInstruction < mb->stop?i:lastInstruction; i= mb->stop; break; case RAISEsymbol: break; default: if( isaSignature(p) ){ if( p->token == REMsymbol){ /* do nothing */ } else if( i) { str msg=instruction2str(mb,p,TRUE); showScriptException(mb,i,SYNTAX,"signature misplaced\n!%s",msg); GDKfree(msg); mb->errors++; } } } } if( lastInstruction < mb->stop-1 ){ showScriptException(mb,lastInstruction,SYNTAX, "instructions after END");#ifdef DEBUG_MAL_FCN printFunction(GDKout, mb, LIST_MAL_ALL);#endif mb->errors++; } for(btop--; btop>=0;btop--){ showScriptException(mb,lastInstruction, SYNTAX, "begin '%s' without exit in %s[%d]", getVarName(mb,var[btop]),getFcnName(mb),i); mb->errors++; } p= getInstrPtr(mb,0); if( !isaSignature(p)){ showScriptException(mb,0,SYNTAX,"signature missing"); mb->errors++; } if( retseen == 0){ if( getArgType(mb,p,0)!= TYPE_void && (p->token==FUNCTIONsymbol || p->token==FACTORYsymbol)){ showScriptException(mb,0,SYNTAX,"RETURN missing"); mb->errors++; } } if( mb->errors == 0 ) mb->flowfixed = fixed; /* we might not have to come back here */}#line 398 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_function.mx"int getBarrierEnvelop(MalBlkPtr mb){ int pc; InstrPtr p; for(pc= mb->stop-2 ; pc>=0; pc--){ p= getInstrPtr(mb,pc); if( blockExit(p)){ int l= p->argv[0]; for(; pc>=0;pc--){ p= getInstrPtr(mb,pc); if( blockStart(p) && p->argv[0]==l) break; } continue; } if( blockStart(p) ) return p->argv[0]; } return newTmpVariable(mb,TYPE_any);}#line 416 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_function.mx"#line 491 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_function.mx"void replaceTypeVar(MalBlkPtr mb, InstrPtr p, int v, malType t){ int j,i,x,y;#ifdef DEBUG_MAL_FCN stream_printf(GDKout,"replace type _%d by type %s\n",v, getTypeName(t));#endif for(j=0; j<mb->stop; j++){ p= getInstrPtr(mb,j);#ifdef DEBUG_MAL_FCN printInstruction(GDKout,mb,p,LIST_MAL_ALL);#endif if( p->polymorphic) for(i=0;i<p->argc; i++) if( isPolymorphic(x= getArgType(mb,p,i))) { if( isaBatType(x)){ int head,tail; int hx,tx; head = getHeadType(x); tail = getTailType(x); hx = getHeadIndex(x); tx = getTailIndex(x); if(v && hx == v && head == TYPE_any){ hx =0; head =t; } if(v && tx == v && tail == TYPE_any){ tx= 0; tail = t; } y= newBatType(head,tail); setAnyHeadIndex(y,hx); setAnyTailIndex(y,tx); setArgType(mb,p,i,y);#ifdef DEBUG_MAL_FCN stream_printf(GDKout," %d replaced %s->%s \n",i,getTypeName(x),getTypeName(y));#endif } else if(v>0 && getTailIndex(x) == v){#ifdef DEBUG_MAL_FCN stream_printf(GDKout," replace x= %s polymorphic\n",getTypeName(x));#endif setArgType(mb,p,i,t); } #ifdef DEBUG_MAL_FCN else stream_printf(GDKout," non x= %s %d\n",getTypeName(x),getTailIndex(x));#endif }#ifdef DEBUG_MAL_FCN printInstruction(GDKout,mb,p,LIST_MAL_ALL);#endif }}#line 548 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_function.mx"Symbol cloneFunction(Module scope, Symbol proc, MalBlkPtr mb, InstrPtr p){ Symbol new; int i,v; InstrPtr pp;#ifdef DEBUG_CLONE stream_printf(GDKout,"clone the function %s to scope %s\n", proc->name,scope->name); printInstruction(GDKout,mb, p,LIST_MAL_ALL);#endif new= newFunction(putName(proc->name,strlen(proc->name)), getSignature(proc)->token ); new->def = copyMalBlk(proc->def); /* now change the definition of the original proc *//*printf("CLONED VERSION\n");printFunction(GDKout, new->def, LIST_MAL_ALL);*/ /* check for errors after fixation , TODO*/ pp = getSignature(new); for(i=0;i<pp->argc;i++) if( isPolymorphic(v= getArgType(new->def,pp,i)) ){ int t = getArgType(mb,p,i); if( isaBatType(t) ){ if( getHeadIndex(v) ) replaceTypeVar(new->def, pp, getHeadIndex(v), getHeadType(t)); if( getTailIndex(v) ) replaceTypeVar(new->def, pp, getTailIndex(v), getTailType(t)); } else replaceTypeVar(new->def, pp, getTailIndex(v), t); } #ifdef DEBUG_MAL_FCN else stream_printf(GDKout,"%d remains %s\n",i, getTypeName(v));#endif /* include the function at the proper place in the scope */ insertSymbol(scope,new);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -