Beispiel #1
0
/*
 * 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);
}
Beispiel #2
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);
}
Beispiel #4
0
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;
}