/* * This simplified interpreter has no interpret state. * Everything that can be "interpreted" as opposed to "compiled" * is "magic", and is executed directly by this metacompiler. * It doesn't handle numbers either. */ int interpret_word(u_char *adr, cell len, cell *up) { char strbuf[32]; char *cstr = altocstr((char *)adr, len, strbuf, 32); xt_t xt; token_t pct; int immed; int number; if (ismagic(cstr, up)) return(1); if (alfind((char *)adr, len, (xt_t *)&xt, up) != 0) { /* * If the word we found is a primitive, use its primitive number * instead of its cfa */ pct = *(token_t *)xt; compile ( pct < MAXPRIM ? pct : CT_FROM_XT(xt, up) ); return(1); } if (sscanf(cstr,"%d",&number) == 1) { if (V(STATE)) { compile(PAREN_LIT); ncomma(number); } else { stack = number; } return(1); } /* Undefined */ alerror((char *)adr, len, up); FTHERROR(" ?\n"); return(0); }
static int conf(void * data, const char * key, int op, sc68_dialval_t *val) { dial_t * dial = (dial_t *) data; int res = -1; static const char * l_spr[] = { "< custom >", "11 khz","22 khz", "44.1 khz","48 khz","96 khz" }; static const int i_spr[] = { 0, 11025, 22050, 44100, 48000, 96000 }; const int sprmax = sizeof (l_spr) / sizeof (*l_spr); /* Sanity check */ if (!key || !ismagic(dial)) goto exit; /* Run user control function */ res = dial->dial.cntl(dial->dial.data, key, op, val); /* Kill special case. */ if (op == SC68_DIAL_CALL && !strcmp(key,SC68_DIAL_KILL)) { del_dial(dial); goto exit; } /* User dealt with that message. */ if (res <= 0) goto exit; /* Assume no error */ res = 0; if (keyis("sampling")) { /* This key is used for the predefined sampling rate */ switch (op) { case SC68_DIAL_CNT: val->i = sprmax; break; case SC68_DIAL_GETI: { const option68_t * opt = option68_get("sampling-rate", opt68_ISSET); if (!opt) val->i = 5; /* default to 48khz */ else { for (val->i=1; val->i<sprmax; ++val->i) if (i_spr[val->i] == opt->val.num) break; if (val->i >= sprmax) val->i = 0; } } break; case SC68_DIAL_ENUM: if (val->i >= 0 && val->i < sprmax) { val->s = l_spr[val->i]; break; } default: res = -1; } } else if (op == SC68_DIAL_CALL) { /* Other special calls like real-tiem access */ if (keyis(SC68_DIAL_NEW)) val->i = 0; else if (keyis("save")) val->i = sc68_cntl(0, SC68_CONFIG_SAVE); else if (keyis("amiga-filter")) /* $$$ TODO: realtime amiga-filter */ val->i = !!val->i; else if (keyis("amiga-blend")) /* $$$ TODO: realtime amiga-blend */ val->i = val->i; } else { /* Finally try it as an option key. * * "sampling-rate" is converted if the value is in the index range * instead of the frequency value range. */ if (op == SC68_DIAL_SETI && keyis("sampling-rate") && val->i > 0 && val->i < sprmax) val->i = i_spr[val->i]; res = getopt(key, op, val); } exit: TRACE68(dial_cat, P "%s() #%02d \"%s\" -> %d\n", __FUNCTION__, op, key, res); return res; }
/* * The "normal" argument decides if we should update the local segment * base name or not. */ void define_label(const char *label, int32_t segment, int64_t offset, bool normal) { union label *lptr; bool created, changed; int64_t size; int64_t lastdef; /* * The backend may invoke this before pass 1, so treat that as * a special "pass". */ const int64_t lpass = passn + 1; /* * Phase errors here can be one of two types: a new label appears, * or the offset changes. Increment global_offset_changed when that * happens, to tell the assembler core to make another pass. */ lptr = find_label(label, true, &created); lastdef = lptr->defn.defined; if (segment) { /* We are actually defining this label */ if (lptr->defn.type == LBL_EXTERN) { /* auto-promote EXTERN to GLOBAL */ lptr->defn.type = LBL_GLOBAL; lastdef = 0; /* We are "re-creating" this label */ } } else { /* It's a pseudo-segment (extern, common) */ segment = lptr->defn.segment ? lptr->defn.segment : seg_alloc(); } if (lastdef || lptr->defn.type == LBL_BACKEND) { /* * We have seen this on at least one previous pass, or * potentially earlier in this same pass (in which case we * will probably error out further down.) */ mangle_label_name(lptr); handle_herelabel(lptr, &segment, &offset); } if (ismagic(label) && lptr->defn.type == LBL_LOCAL) lptr->defn.type = LBL_SPECIAL; if (set_prevlabel(label) && normal) prevlabel = lptr->defn.label; if (lptr->defn.type == LBL_COMMON) { size = offset; offset = 0; } else { size = 0; /* This is a hack... */ } changed = created || !lastdef || lptr->defn.segment != segment || lptr->defn.offset != offset || lptr->defn.size != size; global_offset_changed += changed; if (lastdef == lpass) { int32_t saved_line = 0; const char *saved_fname = NULL; int noteflags; /* * Defined elsewhere in the program, seen in this pass. */ if (changed) { nasm_error(ERR_NONFATAL, "label `%s' inconsistently redefined", lptr->defn.label); noteflags = ERR_NOTE|ERR_HERE; } else { nasm_error(ERR_WARNING|WARN_LABEL_REDEF|ERR_PASS2, "label `%s' redefined to an identical value", lptr->defn.label); noteflags = ERR_NOTE|ERR_HERE|WARN_LABEL_REDEF|ERR_PASS2; } src_get(&saved_line, &saved_fname); src_set(lptr->defn.def_line, lptr->defn.def_file); nasm_error(noteflags, "label `%s' originally defined", lptr->defn.label); src_set(saved_line, saved_fname); } else if (changed && pass0 > 1 && lptr->defn.type != LBL_SPECIAL) { /* * WARN_LABEL_LATE defaults to an error, as this should never * actually happen. Just in case this is a backwards * compatibility problem, still make it a warning so that the * user can suppress or demote it. * * As a special case, LBL_SPECIAL symbols are allowed to be changed * even during the last pass. */ nasm_error(ERR_WARNING|WARN_LABEL_LATE, "label `%s' %s during code generation", lptr->defn.label, created ? "defined" : "changed"); } lptr->defn.segment = segment; lptr->defn.offset = offset; lptr->defn.size = size; lptr->defn.defined = lpass; if (changed || lastdef != lpass) src_get(&lptr->defn.def_line, &lptr->defn.def_file); if (lastdef != lpass) out_symdef(lptr); }
static int finf(void * data, const char * key, int op, sc68_dialval_t *val) { dial_t * const dial = data; int res; /* Sanity check */ if (!key || !ismagic(dial)) return -1; /* Run user control function */ res = dial->dial.cntl(dial->dial.data, key, op, val); TRACE68(dial_cat,P "user-cntl #%02d \"%s\" -> %d\n", op, key, res); /* Kill special case. */ if (op == SC68_DIAL_CALL && keyis(SC68_DIAL_KILL)) { del_dial(dial); res = 0; } /* User dealt with that message. */ if (res <= 0) goto exit; /* Assume no error */ res = 0; if (op == SC68_DIAL_CALL && keyis(SC68_DIAL_NEW)) { if (!dial->dial.cntl(dial->dial.data, "sc68", op, val)) dial->sc68 = (sc68_disk_t) val->s; if (!dial->dial.cntl(dial->dial.data, "disk", op, val)) dial->disk = (sc68_disk_t) val->s; TRACE68(dial_cat, P "\"%s\" sc68:%p disk:%p\n", key, dial->sc68, dial->disk); val->i = sc68_music_info(dial->sc68,&dial->info,1,dial->disk); if (!val->i) { TRACE68(dial_cat, P "Got info: %02d - %s - %s\n", dial->info.tracks, dial->info.album, dial->info.title); } } else if (keyis("track")) { int track; switch (op) { case SC68_DIAL_CNT: val->i = dial->info.tracks; /* get count current */ return 0; case SC68_DIAL_GETI: val->i = dial->info.trk.track - 1; /* get current */ return 0; case SC68_DIAL_SETI: track = (int) val->i + 1; if (track <= 0 || track > dial->info.tracks) track = dial->info.dsk.track; if (track != dial->info.trk.track) sc68_music_info(dial->sc68, &dial->info, track, dial->disk); val->i = dial->info.trk.track - 1; return 0; case SC68_DIAL_ENUM: track = val->i; if (track >= 0 && track < dial->info.tracks) { ++track; dial->tstr[0] = '0' + (track/10u); dial->tstr[1] = '0' + (track%10u); dial->tstr[2] = 0; val->s = dial->tstr; } else { TRACE68(dial_cat, P "invalid index \"%s[%d]\"", key,track); val->s = ""; res = -1; } break; default: res = -1; } } else { switch (op) { case SC68_DIAL_GETS: /* if (keyis("uri")) */ /* val->s = dial->uri; */ /* else */ if (keyis("format")) val->s = dial->info.format; else if (keyis("genre")) val->s = dial->info.genre; else if (keyis("title")) val->s = dial->info.title; else if (keyis("artist")) val->s = dial->info.artist; else if (keyis("album")) val->s = dial->info.album; else if (keyis("ripper")) val->s = dial->info.ripper; else if (keyis("converter")) val->s = dial->info.converter; else if (keyis("year")) val->s = dial->info.year; else res = -1; break; case SC68_DIAL_GETI: if (keyis("time")) val->i = (dial->info.trk.time_ms+500u)/1000u; else if (keyis("hw_ym")) val->i = dial->info.trk.ym; else if (keyis("hw_ste")) val->i = dial->info.trk.ste; else if (keyis("hw_asid")) val->i = dial->info.trk.asid; else if (keyis("tag-key")) val->i = 0; else res = -1; break; case SC68_DIAL_ENUM: if (keyis("tag-key") || keyis("tag-val")) { const int a = dial->info.dsk.tags; const int n = a + dial->info.trk.tags; if (val->i >= 0 && val->i<n) { val->s = val->i < a ? ( key[4] == 'k' ? dial->info.dsk.tag[val->i].key : dial->info.dsk.tag[val->i].val ) : ( key[4] == 'k' ? dial->info.trk.tag[val->i-a].key : dial->info.trk.tag[val->i-a].val ) ; break; } else { TRACE68(dial_cat, P "index out of range \"%s\"[%d] > %d\n", key,val->i,n); res = -1; } } break; default: res = -1; } } exit: if (op == SC68_DIAL_CNT) { TRACE68(dial_cat, P "%s() \"%s\"[#] -> %d (%d)\n", __FUNCTION__, key, val->i, res); } if (op == SC68_DIAL_GETI) { TRACE68(dial_cat, P "%s() \"%s\" -> %d (%d)\n", __FUNCTION__, key, val->i, res); } if (op == SC68_DIAL_GETS || op == SC68_DIAL_ENUM) { TRACE68(dial_cat, P "%s() \"%s\" -> \"%s\" (%d)\n", __FUNCTION__, key, !res?val->s:"<not-set>", res); } TRACE68(dial_cat, P "%s() #%02d \"%s\" -> %d\n", __FUNCTION__, op, key, res); return res; }