str shortStmtRendering(MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { int i; str base, s, t, nme; size_t len= (mb->stop < 1000? 1000: mb->stop) * 128 /* max realistic line length estimate */; base = s = GDKmalloc(len); if ( s == NULL) return s; *s =0; t=s; if (p->token == REMsymbol && !( getModuleId(p) && strcmp(getModuleId(p),"querylog") == 0 && getFunctionId(p) && strcmp(getFunctionId(p),"define") == 0)) return base; if (p->barrier == LEAVEsymbol || p->barrier == REDOsymbol || p->barrier == RETURNsymbol || p->barrier == YIELDsymbol || p->barrier == EXITsymbol || p->barrier == RAISEsymbol) { snprintf(t,(len-(t-base)), "%s ", operatorName(p->barrier)); advance(t,base,len); } if( p->token == FUNCTIONsymbol) { snprintf(t,(len-(t-base)), "function %s.", getModuleId(p)); advance(t,base,len); } if (p->token == ENDsymbol ){ snprintf(t,(len-(t-base)), "end %s.%s", getModuleId(getInstrPtr(mb,0)), getFunctionId(getInstrPtr(mb,0))); return base; } // handle the result variables for (i = 0; i < p->retc; i++) if ( !isTmpVar(mb,getArg(p,i)) || isVarUsed(mb, getArg(p, i)) || isVarUDFtype(mb,getArg(p,i))) break; if (i == p->retc) // no result arguments goto short_end; /* display optional multi-assignment list */ if( getArgType(mb,p,0) != TYPE_void){ if (p->retc > 1 && t < base + len-1){ *t++ = '('; *t=0; } for (i = 0; i < p->retc; i++) { nme = shortRenderingTerm(mb, stk, p,i); snprintf(t,(len-(t-base)), "%s%s", (i?", ":""), nme); GDKfree(nme); advance(t,base,len); } if (p->retc > 1 && t< base+len) *t++ = ')'; if( t < base +len) *t++ = ':'; if( t < base +len) *t++ = '='; if( t < base +len) *t++ = ' '; } *t =0; short_end: advance(t,base,len); // handle the instruction mapping snprintf(t, (len-(t-base)),"%s", (getFunctionId(p)?getFunctionId(p):"")); advance(t,base,len); // handle the arguments, constants should be shown including their non-default type /* display optional multi-assignment list */ if( t< base + len) *t++ = '('; for (i = p->retc; i < p->argc; i++) { nme = shortRenderingTerm(mb, stk, p,i); snprintf(t,(len-(t-base)), "%s%s", (i!= p->retc? ", ":" "), nme); GDKfree(nme); advance(t,base,len); if (i < p->retc - 1 && t < base+len){ *t++ = ','; *t++ = ' '; } } if( t < base + len) *t++ = ' '; if( t < base + len) *t++ = ')'; *t=0; if (t >= s + len) throw(MAL,"instruction2str:","instruction too long"); return base; }
int inlineMALblock(MalBlkPtr mb, int pc, MalBlkPtr mc) { int i, k, l, n; InstrPtr *ns, p,q; int *nv, *np = NULL; p = getInstrPtr(mb, pc); q = getInstrPtr(mc, 0); ns = GDKzalloc((l = (mb->ssize + mc->ssize + p->retc - 3)) * sizeof(InstrPtr)); if (ns == NULL) return -1; if ( mc->ptop > 0){ np = (int*) GDKmalloc(mc->ptop * sizeof(int)); if (np == 0){ GDKfree(ns); return -1; } } nv = (int*) GDKmalloc(mc->vtop * sizeof(int)); if (nv == 0){ GDKfree(ns); if( np) GDKfree(np); return -1; } /* add all properties of the new block to the target environment */ for (n = 0; n < mc->ptop; n++) { int propid = newProperty(mb); if (propid < 0) { assert(0); return -1; } np[n] = propid; mb->prps[propid].idx = mc->prps[n].idx; mb->prps[propid].op = mc->prps[n].op; mb->prps[propid].var = mc->prps[n].var; /* fixed later */ } /* add all variables of the new block to the target environment */ for (n = 0; n < mc->vtop; n++) { VarPtr ov, v; if (isExceptionVariable(mc->var[n]->name)) { nv[n] = newVariable(mb,GDKstrdup(mc->var[n]->name),TYPE_str); if (isVarUDFtype(mc,n)) setVarUDFtype(mb,nv[n]); if (isVarUsed(mc,n)) setVarUsed(mb,nv[n]); } else if (isVarTypedef(mc,n)) { nv[n] = newTypeVariable(mb,getVarType(mc,n)); } else if (isVarConstant(mc,n)) { nv[n] = cpyConstant(mb,getVar(mc,n)); } else { nv[n] = newTmpVariable(mb, getVarType(mc, n)); if (isVarUDFtype(mc,n)) setVarUDFtype(mb,nv[n]); if (isVarUsed(mc,n)) setVarUsed(mb,nv[n]); } /* remap the properties */ ov = getVar(mc, n); v = getVar(mb, nv[n]); if (ov->propc > v->maxprop) { int size = sizeof(VarRecord); VarPtr vnew = (VarPtr) GDKzalloc(size + ov->propc * sizeof(int)); memcpy((char*) vnew, (char*) v, size); vnew->maxprop = ov->propc; mb->var[nv[n]] = vnew; GDKfree(v); v = getVar(mb, nv[n]); } for (i = 0; i < ov->propc; i++) v->prps[i] = np[ov->prps[i]]; v->propc = ov->propc; } /* change the property variables to the new context */ for (n = 0; n < mc->ptop; n++) { if (mc->prps[n].var) mb->prps[np[n]].var = nv[mc->prps[n].var]; assert( mb->prps[np[n]].var >= 0); } /* use an alias mapping to keep track of the actual arguments */ for (n = p->retc; n < p->argc; n++) nv[getArg(q,n)] = getArg(p, n); k = 0; /* find the return statement of the inline function */ for (i = 1; i < mc->stop - 1; i++) { q = mc->stmt[i]; if( q->barrier== RETURNsymbol || q->barrier== YIELDsymbol){ /* add the mapping of the return variables */ for(n=0; n<p->retc; n++) nv[getArg(q,n)] = getArg(p,n); } } /* copy the stable part */ for (i = 0; i < pc; i++) ns[k++] = mb->stmt[i]; for (i = 1; i < mc->stop - 1; i++) { q = mc->stmt[i]; if( q->token == ENDsymbol) break; /* copy the instruction and fix variable references */ ns[k] = copyInstruction(q); for (n = 0; n < q->argc; n++) getArg(ns[k], n) = nv[getArg(q, n)]; if (q->barrier == RETURNsymbol || q->barrier == YIELDsymbol) { for(n=0; n<q->retc; n++) clrVarFixed(mb,getArg(ns[k],n)); /* for typing */ setModuleId(ns[k],getModuleId(q)); setFunctionId(ns[k],getFunctionId(q)); ns[k]->barrier = 0; ns[k]->token = ASSIGNsymbol; } k++; } /* copy the remainder of the stable part */ freeInstruction(p); for (i = pc + 1; i < mb->stop; i++){ ns[k++] = mb->stmt[i]; } /* remove any free instruction */ for(; i<mb->ssize; i++) if( mb->stmt[i]){ freeInstruction(mb->stmt[i]); mb->stmt[i]= 0; } GDKfree(mb->stmt); mb->stmt = ns; mb->ssize = l; mb->stop = k; GDKfree(np); GDKfree(nv); return pc; }
str instruction2str(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int flg) { int i; str base, t; size_t len = 512 + (p->argc * 128); /* max realistic line length estimate */ str arg; t = base = GDKmalloc(len); if ( base == NULL) return NULL; if (!flg) { *t++ = '#'; len--; if (p->typechk == TYPE_UNKNOWN) { *t++ = '!'; /* error */ len--; } } *t = 0; if (p->token == REMsymbol && !( getModuleId(p) && strcmp(getModuleId(p),"querylog") == 0 && getFunctionId(p) && strcmp(getFunctionId(p),"define") == 0)) { /* do nothing */ } else if (p->barrier) { if (p->barrier == LEAVEsymbol || p->barrier == REDOsymbol || p->barrier == RETURNsymbol || p->barrier == YIELDsymbol || p->barrier == RAISEsymbol) { if (!copystring(&t, " ", &len)) return base; } arg = operatorName(p->barrier); if (!copystring(&t, arg, &len) || !copystring(&t, " ", &len)) return base; } else if( functionStart(p) && flg != LIST_MAL_CALL ){ return fcnDefinition(mb, p, t, flg, base, len + (t - base)); } else if (!functionExit(p) && flg!=LIST_MAL_CALL) { // beautify with tabs if (!copystring(&t, " ", &len)) return base; } switch (p->token<0?-p->token:p->token) { case FCNcall: case FACcall: case PATcall: case CMDcall: case ASSIGNsymbol : // is any variable explicit or used for (i = 0; i < p->retc; i++) if ( !isTmpVar(mb,getArg(p,i)) || isVarUsed(mb, getArg(p, i)) || isVarUDFtype(mb,getArg(p,i))) break; if (i == p->retc) break; /* display multi-assignment list */ if (p->retc > 1 && !copystring(&t, "(", &len)) return base; for (i = 0; i < p->retc; i++) { arg= renderTerm(mb, stk, p, i, flg); if (arg) { if (!copystring(&t, arg, &len)) { GDKfree(arg); return base; } GDKfree(arg); } if (i < p->retc - 1 && !copystring(&t, ", ", &len)) return base; } if (p->retc > 1 && !copystring(&t, ")", &len)) return base; if (p->argc > p->retc || getFunctionId(p)) { if (!copystring(&t, " := ", &len)) return base; } break; case ENDsymbol: if (!copystring(&t, "end ", &len) || !copystring(&t, getModuleId(getInstrPtr(mb,0)), &len) || !copystring(&t, ".", &len) || !copystring(&t, getFunctionId(getInstrPtr(mb, 0)), &len)) return base; break; case COMMANDsymbol: case FUNCTIONsymbol: case FACTORYsymbol: case PATTERNsymbol: if (flg & LIST_MAL_VALUE) { if (!copystring(&t, operatorName(p->token), &len) || !copystring(&t, " ", &len)) return base; } return fcnDefinition(mb, p, t, flg, base, len + (t - base)); case REMsymbol: case NOOPsymbol: if (!copystring(&t, "#", &len)) return base; if (getVar(mb, getArg(p, 0))->value.val.sval && getVar(mb, getArg(p, 0))->value.len > 0 && !copystring(&t, getVar(mb, getArg(p, 0))->value.val.sval, &len)) return base; if (!copystring(&t, " ", &len)) return base; break; default: i = snprintf(t, len, " unknown symbol ?%d? ", p->token); if (i < 0 || (size_t) i >= len) return base; len -= (size_t) i; t += i; break; } if (getModuleId(p)) { if (!copystring(&t, getModuleId(p), &len) || !copystring(&t, ".", &len)) return base; } if (getFunctionId(p)) { if (!copystring(&t, getFunctionId(p), &len) || !copystring(&t, "(", &len)) return base; } else if (p->argc > p->retc + 1) { if (!copystring(&t, "(", &len)) return base; } for (i = p->retc; i < p->argc; i++) { arg= renderTerm(mb, stk, p, i, flg); if (arg) { if (!copystring(&t, arg, &len)) { GDKfree(arg); return base; } GDKfree(arg); } if (i < p->argc -1 && !copystring(&t, ", ", &len)) return base; } if (getFunctionId(p) || p->argc > p->retc + 1) { if (!copystring(&t, ")", &len)) return base; } if (p->token != REMsymbol){ if (!copystring(&t, ";", &len)) return base; } return base; }
str instruction2str(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int flg) { int i, tab = 4; str base, s, t; size_t len= (mb->stop < 1000? 1000: mb->stop) * 128 /* max realistic line length estimate */; str arg; base = s = GDKmalloc(len); if ( s == NULL) return s; if (flg) { s[0] = 0; t = s; } else { s[0] = '#'; if (p->typechk == TYPE_UNKNOWN) { s[1] = '!'; /* error */ s[2] = 0; t = s + 2; } else { s[1] = 0; t = s + 1; } } advance(t,base,len); if (p->token == REMsymbol) { /* do nothing */ } else if (p->barrier) { if (p->barrier == LEAVEsymbol || p->barrier == REDOsymbol || p->barrier == RETURNsymbol || p->barrier == YIELDsymbol || p->barrier == RAISEsymbol) { for(;tab>0;tab--) *t++= ' '; *t= 0; advance(t,base,len); } snprintf(t,(len-(t-base)), "%s ", operatorName(p->barrier)); advance(t,base,len); } else if( functionStart(p) && flg != LIST_MAL_CALL ){ return fcnDefinition(mb, p, s, flg, base, len); } else if (!functionExit(p) && flg!=LIST_MAL_CALL) { // beautify with tabs for(;tab>0;tab--) *t++= ' '; *t= 0; advance(t,base,len); } switch (p->token<0?-p->token:p->token) { case FCNcall: case FACcall: case PATcall: case CMDcall: case ASSIGNsymbol : // is any variable explicit or used for (i = 0; i < p->retc; i++) if (!getVarTmp(mb, getArg(p, i)) || isVarUsed(mb, getArg(p, i)) || isVarUDFtype(mb,getArg(p,i))) break; if (i == p->retc) break; /* display multi-assignment list */ if (p->retc > 1) *t++ = '('; for (i = 0; i < p->retc; i++) { arg= renderTerm(mb, stk, p, i, flg); snprintf(t,(len-(t-base)), "%s", arg); GDKfree(arg); advance(t,base,len); if (i < p->retc - 1) *t++ = ','; } if (p->retc > 1) *t++ = ')'; if (p->argc > p->retc || getFunctionId(p)) { sprintf(t, " := "); t += 4; } *t = 0; break; case ENDsymbol: snprintf(t,(len-(t-base)), "end %s.%s", getModuleId(getInstrPtr(mb,0)), getFunctionId(getInstrPtr(mb, 0))); advance(t,base,len); break; case COMMANDsymbol: case FUNCTIONsymbol: case FACTORYsymbol: case PATTERNsymbol: if (flg & LIST_MAL_VALUE) { snprintf(t,(len-(t-base)), "%s ", operatorName(p->token)); advance(t,base,len); break; } return fcnDefinition(mb, p, s, flg, base, len); case REMsymbol: case NOOPsymbol: if(getVar(mb, getArg(p, 0))->value.val.sval) snprintf(t,(len-(t-base)), "#%s ", getVar(mb, getArg(p, 0))->value.val.sval); else snprintf(t, (len-(t-base)), "# "); break; default: snprintf(t, (len-(t-base))," unknown symbol ?%d? ", p->token); } advance(t,base,len); if (getModuleId(p)) snprintf(t, (len-(t-base)),"%s.", getModuleId(p)); advance(t,base,len); if (getFunctionId(p)) { snprintf(t, (len-(t-base)), "%s(", getFunctionId(p)); } else if (p->argc > p->retc + 1) snprintf(t, (len-(t-base)), "("); advance(t,base,len); for (i = p->retc; i < p->argc; i++) { arg= renderTerm(mb, stk, p, i, flg); snprintf(t,(len-(t-base)), "%s", arg); GDKfree(arg); advance(t,base,len); if (i < p->argc -1){ snprintf(t, (len-(t-base)), ","); advance(t,base,len); } } if (getFunctionId(p) || p->argc > p->retc + 1) snprintf(t,(len-(t-base)), ")"); advance(t,base,len); if (p->token != REMsymbol){ snprintf(t,(len-(t-base)), ";"); advance(t,base,len); } /* we may accidentally overwrite */ if (t > s + len) GDKfatal("instruction2str:"); return base; }