int Compiler::recglobal(int val,Prodbuffer *b) { if (val==NIL) { b->addint(-1); // printf("nil\n"); } else if (ISVALPNT(val)) { int *p=VALTOPNT(val); if (HEADER_TYPE(p)==TYPE_TAB) { b->addint((TABLEN(p)<<2)+3); // printf("tuple %d @ %x : %x\n",TABLEN(p),val,*p); for(int i=0;i<TABLEN(p);i++) recglobal(TABGET(p,i),b); } else { b->addint((STRLEN(p)<<2)+1); b->addstr(STRSTART(p),STRLEN(p)); // printf("'%s'\n",STRSTART(p)); } } else { b->addint(val); // printf("%d\n",VALTOINT(val)); } return 0; }
void rd_field(struct field *f, char *val, int merge) { struct wscons_keymap *mp; struct field_pc *pc; u_int u, r, fr; char *p; int i; switch (f->format) { case FMT_UINT: if (sscanf(val, "%u", &u) != 1) errx(1, "%s: not a number", val); if (merge) *((u_int *) f->valp) += u; else *((u_int *) f->valp) = u; break; case FMT_INT: if (sscanf(val, "%d", &i) != 1) errx(1, "%s: not a number", val); if (merge) *((int *) f->valp) += i; else *((int *) f->valp) = i; break; case FMT_BOOL: if (*val != 'o' || (val[1] != 'n' && (val[1] != 'f' || val[2] != 'f'))) errx(1, "%s: invalid value (on/off)", val); *((u_int *) f->valp) = val[1] == 'n'? 1 : 0; break; case FMT_PC: fr = 0; if ((i = sscanf(val, "%u.%u%%", &u, &fr)) != 2 && i != 1) errx(1, "%s: not a valid number", val); pc = f->valp; r = pc->max - pc->min; i = pc->min + (r * u) / 100 + (r * fr) / 100 / 100; if (merge == '+') pc->cur += i; else if (merge == '-') pc->cur -= i; else pc->cur = i; if (pc->cur > pc->max) pc->cur = pc->max; if (pc->cur < pc->min) pc->cur = pc->min; break; case FMT_KBDENC: p = strchr(val, '.'); if (p != NULL) *p++ = '\0'; i = name2int(val, kbdenc_tab, TABLEN(kbdenc_tab)); if (i == -1) errx(1, "%s: not a valid encoding", val); *((u_int *) f->valp) = i; while (p) { val = p; p = strchr(p, '.'); if (p != NULL) *p++ = '\0'; i = name2int(val, kbdvar_tab, TABLEN(kbdvar_tab)); if (i == -1) errx(1, "%s: not a valid variant", val); *((u_int *) f->valp) |= i; } break; case FMT_KBMAP: if (! merge) kbmap.maplen = 0; map_scan_setinput(val); yyparse(); if (merge) { if (newkbmap.maplen < kbmap.maplen) newkbmap.maplen = kbmap.maplen; for (i = 0; i < kbmap.maplen; i++) { mp = newkbmap.map + i; if (mp->command == KS_voidSymbol && mp->group1[0] == KS_voidSymbol && mp->group1[1] == KS_voidSymbol && mp->group2[0] == KS_voidSymbol && mp->group2[1] == KS_voidSymbol) *mp = kbmap.map[i]; } } kbmap.maplen = newkbmap.maplen; bcopy(newkbmap.map, kbmap.map, kbmap.maplen*sizeof(struct wscons_keymap)); break; case FMT_SCALE: { const char *errstr = 0; /* Unspecified values default to 0. */ bzero(&wmcoords, sizeof(wmcoords)); val = (void *)strtok(val, ","); if (val != NULL) { wmcoords.minx = (int)strtonum(val, -32768, 32767, &errstr); val = (void *)strtok(NULL, ","); } if (!errstr && val != NULL) { wmcoords.maxx = (int)strtonum(val, -32768, 32767, &errstr); val = (void *)strtok(NULL, ","); } if (!errstr && val != NULL) { wmcoords.miny = (int)strtonum(val, -32768, 32767, &errstr); val = (void *)strtok(NULL, ","); } if (!errstr && val != NULL) { wmcoords.maxy = (int)strtonum(val, -32768, 32767, &errstr); val = (void *)strtok(NULL, ","); } if (!errstr && val != NULL) { wmcoords.swapxy = (int)strtonum(val, -32768, 32767, &errstr); val = (void *)strtok(NULL, ","); } if (!errstr && val != NULL) { wmcoords.resx = (int)strtonum(val, 0, 32767, &errstr); val = (void *)strtok(NULL, ","); } if (!errstr && val != NULL) { wmcoords.resy = (int)strtonum(val, 0, 32767, &errstr); val = (void *)strtok(NULL, ","); } if (errstr) errx(1, "calibration value is %s", errstr); if (val != NULL) errx(1, "too many calibration values"); break; } case FMT_STRING: strlcpy(f->valp, val, WSFONT_NAME_SIZE); break; default: errx(1, "internal error: rd_field: no format %d", f->format); break; } }
void pr_field(const char *pre, struct field *f, const char *sep) { struct field_pc *pc; u_int flags; int i, n; char *p; if (sep) printf("%s.%s%s", pre, f->name, sep); switch (f->format) { case FMT_UINT: printf("%u", *((u_int *) f->valp)); break; case FMT_INT: printf("%d", *((int *) f->valp)); break; case FMT_BOOL: printf("%s", *((u_int *) f->valp)? "on" : "off"); break; case FMT_PC: pc = f->valp; i = pc->max - pc->min; n = pc->cur - pc->min; printf("%u.%02u%%", n * 100 / i, ((n * 100) % i) * 100 / i); break; case FMT_KBDTYPE: p = int2name(*((u_int *) f->valp), 1, kbtype_tab, TABLEN(kbtype_tab)); printf("%s", p); break; case FMT_MSTYPE: p = int2name(*((u_int *) f->valp), 1, mstype_tab, TABLEN(mstype_tab)); printf("%s", p); break; case FMT_DPYTYPE: p = int2name(*((u_int *) f->valp), 1, dpytype_tab, TABLEN(dpytype_tab)); printf("%s", p); break; case FMT_KBDENC: p = int2name(KB_ENCODING(*((u_int *) f->valp)), 1, kbdenc_tab, TABLEN(kbdenc_tab)); printf("%s", p); flags = KB_VARIANT(*((u_int *) f->valp)); for (i = 0; i < 32; i++) { if (!(flags & (1 << i))) continue; p = int2name(flags & (1 << i), 1, kbdvar_tab, TABLEN(kbdvar_tab)); printf(".%s", p); } break; case FMT_KBMAP: print_kmap((struct wskbd_map_data *) f->valp); break; case FMT_SCALE: printf("%d,%d,%d,%d,%d,%d,%d", wmcoords.minx, wmcoords.maxx, wmcoords.miny, wmcoords.maxy, wmcoords.swapxy, wmcoords.resx, wmcoords.resy); break; case FMT_EMUL: print_emul((struct wsdisplay_emultype *) f->valp); break; case FMT_SCREEN: print_screen((struct wsdisplay_screentype *) f->valp); break; case FMT_STRING: printf("%s", (const char *)f->valp); break; default: errx(1, "internal error: pr_field: no format %d", f->format); break; } printf("\n"); }
// compilation d'un prototype // [name] -> 0 int Compiler::parseproto() { int k; if (!parser->next(0)) { PRINTF(m)(LOG_COMPILER,"Compiler : integer or '=' expected (found EOF)\n"); return MTLERR_SN; } int nbarg=-1; if (!strcmp(parser->token,"=")) { if (k=creategraph(parser,PNTTOVAL(newpackage),0)) return k; int vp=STACKGET(m,0); if (vp!=NIL) { int* p=VALTOPNT(vp); if (TABGET(p,TYPEHEADER_CODE)==INTTOVAL(TYPENAME_FUN)) { vp=TABGET(p,TYPEHEADER_LENGTH); if (vp!=NIL) { int* p=VALTOPNT(vp); if (TABGET(p,TYPEHEADER_CODE)==INTTOVAL(TYPENAME_TUPLE)) { nbarg=TABLEN(p)-TYPEHEADER_LENGTH; } } } } if (nbarg<0) { PRINTF(m)(LOG_COMPILER,"Compiler : function type expected\n"); return MTLERR_SN; } } else if (isdecimal(parser->token)) { nbarg=mtl_atoi(parser->token); if (k=createnodetype(TYPENAME_FUN)) return k; int i;for(i=0;i<nbarg;i++) if (k=createnodetype(TYPENAME_WEAK)) return k; if (k=createnodetuple(nbarg)) return k; TABSET(m,VALTOPNT(STACKGET(m,1)),TYPEHEADER_LENGTH,STACKGET(m,0)); // attachement du noeud tuple au noeud fun STACKDROP(m); if (k=createnodetype(TYPENAME_WEAK)) return k; // noeud résultat TABSET(m,VALTOPNT(STACKGET(m,1)),TYPEHEADER_LENGTH+1,STACKGET(m,0)); // attachement du noeud resultat au noeud fun STACKDROP(m); } if (nbarg<0) { PRINTF(m)(LOG_COMPILER,"Compiler : integer or '=' expected (found '%s')\n",parser->token); return MTLERR_SN; } if (k=parser->parsekeyword(";;")) return k; // on crée le bloc fonction newref=MALLOCCLEAR(m,REF_LENGTH); if (!newref) return MTLERR_OM; TABSET(m,newref,REF_TYPE,STACKPULL(m)); TABSET(m,newref,REF_NAME,STACKPULL(m)); TABSET(m,newref,REF_CODE,INTTOVAL(nbarg)); TABSET(m,newref,REF_PACKAGE,INTTOVAL(ifuns++)); if (k=STACKPUSH(m,PNTTOVAL(newref))) return MTLERR_OM; // [newref] addreftopackage(newref,newpackage); STACKDROP(m); outputbuf->reinit(); outputbuf->printf("Compiler : proto %s : ",STRSTART(VALTOPNT(TABGET(newref,REF_NAME)))); echograph(outputbuf,VALTOPNT(TABGET(newref,REF_TYPE))); PRINTF(m)(LOG_COMPILER,"%s\n",outputbuf->getstart()); return 0; }
// compilation // [filename/src packages] -> [packages] int Compiler::gocompile(int type) { int k; if (STACKGET(m,0)==NIL) { STACKDROP(m); return 0; } char* name=STRSTART(VALTOPNT(STACKGET(m,0))); if (type==COMPILE_FROMFILE) { parser=new Parser(m->term,m->filesystem,name); PRINTF(m)(LOG_COMPILER,"Compiler : compiling file '%s'\n",name); } else { parser=new Parser(m->term,name); name="..."; PRINTF(m)(LOG_COMPILER,"Compiler : compiling string buffer\n"); } if (k=createpackage(name,4)) return k; // [package nom_fichier env] TABSET(m,VALTOPNT(STACKGET(m,0)),PACK_NEXT,STACKGET(m,2)); STACKSET(m,2,STACKGET(m,0)); // [newenv nom_fichier newenv] STACKDROPN(m,2); // [newenv] newpackage=VALTOPNT(STACKGET(m,0)); // parsing //### ici on doit pouvoir ajouter la liste des globales et la liste des fonctions //### c'est ici également qu'on va réinitialiser la structure bc if (k=STACKPUSH(m,NIL)) return k; // GLOBALS globals=STACKREF(m); ifuns=0; k=parsefile(0); //### c'est fait, on a le bytecode, la liste des fonctions, et la liste des globales if (!k) { Prodbuffer* btab=new Prodbuffer(); int n=nblabels(globals); brelease->addint(0); recglobals(STACKGETFROMREF(m,globals,0),brelease); brelease->setint(0,brelease->getsize()); int sizebc=brelease->getsize(); brelease->addint(0); // on prépare le champ pour la taille du bytecode int* p=VALTOPNT(TABGET(newpackage,PACK_HACH)); int vref=TABGET(p,TABLEN(p)-1); int nfun=recbc(vref,brelease,btab,sizebc+4); if (nfun<0) return nfun; brelease->setint(sizebc,brelease->getsize()-sizebc-4); brelease->addshort(nfun+1); brelease->addstr(btab->getstart(),btab->getsize()); delete btab; } if (k) parser->echoposition(); PRINTF(m)(LOG_COMPILER,"\n"); // dumppackage(STACKGET(m,0)); delete parser; return k; }