コード例 #1
0
ファイル: postfunc.c プロジェクト: steinarb/interviews
void ForFunc::execute() {
    static int body_symid = symbol_add("body");
    ComValue initexpr(stack_arg_post_eval(0));
    ComValue* bodyexpr = nil;
    while (1) {
        ComValue whileexpr(stack_arg_post_eval(1));
        if (whileexpr.is_false()) break;
        delete bodyexpr;
        ComValue keybody(stack_key_post_eval(body_symid, false, ComValue::unkval(), true));
        if (keybody.is_unknown() && nargsfixed()>= 4)
            bodyexpr = new ComValue(stack_arg_post_eval(3));
        else
            bodyexpr = new ComValue(keybody);
        ComValue nextexpr(stack_arg_post_eval(2));
    }
    reset_stack();
    if (bodyexpr) {
        push_stack(*bodyexpr);
        delete bodyexpr;
    } else
        push_stack(ComValue::nullval());
}
コード例 #2
0
ファイル: syntax.c プロジェクト: k0gaMSX/mcm
int syntaxan (int token,symbol * sym)
{
  static unsigned char num_channel;
  static unsigned char channels[12]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  static symbol ptr;

  switch (status)
    {
    case STATUS_INIT:     /* Initial status */
      recst = STATUS_INIT;    /*Save actual state for error handling  */
      switch (token)
        {
        case VAR:            /* Begin variable declaration */
          status = STATUS_BEGIN_VAR_DECL;
          return 0;

        case CHANNEL:        /* Begin channel declaration */
          status = STATUS_BEGIN_CHN_DECL;
          return 0;

        case IDEN:            /* Begin assign statement */
          status = STATUS_BEGIN_GLOBAL_ASGN; /* TODO: Join to local assign */
          if ((*sym = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);
          return 0;

        case LN:              /* Empty sentence  */
          return 1;

        default:
          rerror(ESYNTAX, E_INI, 0);
        }

      /* Variable declaration states  */

    case STATUS_BEGIN_VAR_DECL: /* VAR ; variable declaration */
      switch (token)
        {
        case IDEN:            /* Name of the variable */
          status = STATUS_NAME_VAR_DECL;
          *sym = newsymbol(lexcad);
          return 0;

        default:
          rerror(ESYNTAX, E_VAR_DECL, 0);
        }

    case STATUS_NAME_VAR_DECL: /* VAR IDEN ; variable declaration */
      switch (token)
        {
        case LN:             /* end of declaration */
          status = STATUS_INIT;
          insvar(*sym);
          return 1;

        case COMA:            /* multiple declaration */
          status = STATUS_BEGIN_VAR_DECL;
          insvar(*sym);
          return 0;

        default:
          rerror(ESYNTAX, E_VAR_DECL, 0);
        }

      /* Channel declaration states */

    case STATUS_BEGIN_CHN_DECL: /* CHANNEL ; channel declaration */
      switch (token)
        {
        case NUMBER:         /* Number of the channel */
          status = STATUS_END_OF_CHANNEL;
          num_channel = atoi(lexcad) - 1;

          if(num_channel >= 12)
            rerror(ESYNTAX, E_BAD_CH, 0);
          else
            {
              ssymval(syms1, num_channel);
              *sym = syms1;
            }

          if(channels[num_channel])
            rerror(ESYNTAX, E_DECL_CH, 0);

          channels[num_channel]=1;
          return 0;

        case IDEN:           /* Variable with the name of the channel */
          status = STATUS_END_OF_CHANNEL;
          if ((*sym = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);
          else if ((num_channel = gsymval(*sym)) >= 12)
            rerror(ESYNTAX, E_BAD_CH, 0);

          if (channels[num_channel])
            rerror(ESYNTAX, E_DECL_CH, 0);

          channels[num_channel] = 1;
          return 0;

        default: rerror(ESYNTAX, E_CHANNEL, 0);
        }

      /* end of channel declaration */
    case STATUS_END_OF_CHANNEL: /* CHANNEL IDEN | NUMBER ; end of channl dcl*/
      switch (token)
        {
        case LN:             /* finish channel dcl */
          status = STATUS_BEGIN_CHN_BODY;
          inscode2(CHANNEL, gsymval(*sym));
          return 1;

        default:
          rerror(ESYNTAX, E_CHANNEL, 0);
        }

      /* Begin channel body */
    case STATUS_BEGIN_CHN_BODY:      /* CHANNEL IDEN | NUMBER LN ; chl body*/
      recst = STATUS_BEGIN_CHN_BODY;   /*Save state for error handling*/
      switch (token)
        {
        case LN:
          return 1;

        case ENDC:           /* end of channel statement */
          status = STATUS_BEGIN_ENDC;
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case PLAY:
          status = 11;          /* play statement */
          initexpr();
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case SIL:               /* silence statement  */
        case DECOC:             /* dec octave statement */
        case INCOC:             /* inc octave statement */
        case ENDL:              /* end of loop statement */
        case DECV:              /* dec volume */
        case INCV:              /* inc volume */
          status = STATUS_END_OF_1CMD;
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case OCT:               /* octave statement */
        case VOL:               /* volume statement */
        case BAT:               /* battery statement */
        case INST:              /* instrument statement */
        case LOOP:              /* loop statement */
        case AMPL:
        case VIB:               /* vibrato statement */
        case TIMES:             /* time short format statement */
        case TIMEL:             /* time long format statement */
        case DIVSUS:
        case BATL:              /* battery long format statement */
        case INSTL:             /* instrument long format statement */
        case FREC:              /* set frequency statement */
          status = STATUS_BEGIN_EXP_2CMD;
          initexpr();
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case TIMEP:
          status = 39;
          initexpr();
          initsym(syms1, token, token);
          initsym(syms2, NUMBER, 0);
          ssymsig(syms2, syms1);
          *sym = syms2;
          return 0;

        case REGFM:             /* write to fm register statement */
          status = 8;
          initexpr();
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case PAR:               /* parameter statement */
          status = 9;
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case IDEN:              /* Begin a assign statement */
          status = 10;
          if ((*sym = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);

          return 0;

        default:
          rerror(ESYNTAX, E_UNK_COMM, 0);
        }

      /* End of 1 word statement */
    case STATUS_END_OF_1CMD:
      switch (token)
        {
        case LN:
          status = STATUS_BEGIN_CHN_BODY;
          inscodeI(*sym, NULL, num_channel);
          return 1;

        default:
          rerror(ESYNTAX, E_BAD_COMM, 0);
        }

    case 8:
      switch (token)
        {
        case NUMBER:
          status = 21;
          initsym(syms3, NUMBER, 0);
          ssymsig(syms3,*sym);
          *sym = syms3;
          pushexp(NUMBER, atoi(lexcad));
          return 0;

        case IDEN:
          status = 21;
          if((ptr = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);

          initsym(syms3, NUMBER, 0);
          ssymsig(syms3,*sym);
          *sym = syms3;
          pushexp(NUMBER, gsymval(ptr));
          return 0;

        case PARI:
          status = 22;
          ssymsig(syms3,*sym);
          *sym = syms3;
          pushexp(token, 0);
          return 0;

        default:
          rerror(ESYNTAX, E_EXP, 0);
        }

    case 9:
      switch (token)
        {
        case ENVLOFF:
        case ENVLON:
        case SUSON:
        case HFNUM:
        case LFNUM:
        case NOISE:
        case TONE:
          status = STATUS_END_OF_1CMD;
          initsym(syms2, token, token);
          ssymsig(syms2,*sym);
          *sym = syms2;
          return 0;

        case DECO:
          status = STATUS_BEGIN_EXP_2CMD;
          initexpr();
          initsym(syms3, token, token);
          ssymsig(syms3,*sym);
          *sym = syms3;
          return 0;

        case TAMP:
          status = STATUS_BEGIN_EXP_2CMD;
          initexpr();
          initsym(syms3, token, token);
          ssymsig(syms3,*sym);
          *sym = syms3;
          return 0;

        case RITMON:
          status = STATUS_END_OF_1CMD;
          initsym(syms2, token, token);
          ssymsig(syms2,*sym);
          *sym = syms2;
          return 0;

        case MELON:
          status = STATUS_END_OF_1CMD;
          initsym(syms2, token, token);
          ssymsig(syms2,*sym);
          *sym = syms2;
          return 0;

        default:
          rerror(ESYNTAX, E_PAR, 0);
        }
    case 10:
      switch (token)
        {
        case EQ:
          status = STATUS_BEGIN_EXP_2CMD;
          initexpr();
          initsym(syms3, EQ, EQ);
          ssymsig(syms3, *sym);
          *sym = syms3;
          return 0;

        default:
          rerror(ESYNTAX, E_ASIG, 0);
        }

    case 11:
      switch(token)
        {
        case NUMBER:
          status = STATUS_PLAY_EXPRESION;
          initsym(syms2, NUMBER, 0);
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(NUMBER, atoi(lexcad));
          return 0;

        case IDEN:
          status = STATUS_PLAY_EXPRESION;
          if((ptr = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);

          initsym(syms2, NUMBER, 0);
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(NUMBER, gsymval(ptr));
          return 0;

        case PARI:
          status = STATUS_PLAY_EXPRESION;
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(token, 0);
          return 0;

        default:
          rerror(ESYNTAX, E_EXP, 0);
        }

      /* Begin end of channel statement */
    case STATUS_BEGIN_ENDC:   /* ENDC ; endc command */
      switch(token)
        {
        case LN:
          status = 13;
          inscode(gsymval(*sym));
          execute();
          return 1;

        default:
          rerror(ESYNTAX, E_BAD_COMM, 0);
        }


    case 13:
      recst = 13;

      switch(token)
        {
        case WRITE:
          status = 38;
          return 0;

        case CHANNEL:
          status = STATUS_BEGIN_CHN_DECL;
          return 0;

        case LN:
          return 1;

        default:
          rerror(ESYNTAX, E_INI, 0);
        }



    case STATUS_BEGIN_GLOBAL_ASGN:
      switch(token)
        {
        case EQ:
          status = 15;
          initexpr();
          return 0;

        default: rerror(ESYNTAX, E_ASIG, 0);
        }

    case 15:
      switch(token)
        {
        case NUMBER:
          status = 26;
          {pushexp(NUMBER, atoi(lexcad));};
          return 0;
        case IDEN:
          status = 26;
          (ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);
          return 0;
        case PARI:
          status = 27;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }


      /*******************************************************************/
    case STATUS_BEGIN_EXP_2CMD:
      switch (token)
        {
        case PARI:
          status = STATUS_EXP2_OPERAND;
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(token, 0);
          return 0;

        case NUMBER:
          status = STATUS_EXP2_OPERAND;
          initsym(syms2, NUMBER, 0);
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(NUMBER, atoi(lexcad));
          return 0;

        case IDEN:
          status = STATUS_EXP2_OPERAND;
          if(!(ptr = searchsym(lexcad)))
            rerror(ESYNTAX, EIDEN_NAME, 0);

          initsym(syms2, NUMBER, 0);
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(NUMBER, gsymval(ptr));
          return 0;

        default:
          rerror(ESYNTAX, E_EXP, 0);

        }


    case STATUS_EXP2_OPERAND:
      switch(token)
        {
        case NUMBER:
          status = STATUS_EXP2_OPERAND;
          pushexp(NUMBER, atoi(lexcad));
          return 0;

        case IDEN:
          status = STATUS_EXP2_OPERAND;
          if ((ptr = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);

          pushexp(NUMBER, gsymval(ptr));
          return 0;

        case ADD:
        case SUB:
        case MUL:
        case DIV:
        case PARD:
        case PARI:              /* left parenthesis  */
          status = STATUS_EXP2_OPERAND;
          pushexp(token, 0);
          return 0;

        case LN:
          status = recst;
          pushexp(token, 0);
          ssymval(*sym, evalexpr());
          inscodeI(*sym, NULL, num_channel);
          return 1;

        default:
          rerror(ESYNTAX, E_EXP, 0);
        }


      /***********************************************/

      /* initial assign expression*/
    case 26:
      switch(token)
        {
        case ADD:
          status = 15;
          pushexp(token, 0);
          return 0;
        case SUB:
          status = 15;
          pushexp(token, 0);
          return 0;
        case MUL:
          status = 15;
          pushexp(token, 0);
          return 0;
        case DIV:
          status = 15;
          pushexp(token, 0);
          return 0;
        case LN:
          status = STATUS_INIT;{pushexp(token, 0);ssymval(*sym, evalexpr());}  return 1;
        default: rerror(ESYNTAX, E_EXP, 0);
        }
    case 27:
      switch(token)
        {
        case NUMBER:
          status = 28;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = 28;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 27;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case 28:
      switch(token)
        {
        case PARD:
          status = 28;
          pushexp(token, 0);
          return 0;
        case ADD:
          status = 27;
          pushexp(token, 0);
          return 0;
        case SUB:
          status = 27;
          pushexp(token, 0);
          return 0;
        case MUL:
          status = 27;
          pushexp(token, 0);
          return 0;
        case DIV:
          status = 27;
          pushexp(token, 0);
          return 0;
        case LN:
          status = STATUS_INIT;{pushexp(token, 0);ssymval(*sym, evalexpr());}return 1;
        default: rerror(ESYNTAX, E_EXP, 0);
        }


    case 30:


      /*Expresion de play*/

    case STATUS_PLAY_EXPRESION:
            switch(token) {
            case ADD:
            case SUB:
            case MUL:
            case DIV:
                    status = 32;
                    pushexp(token, 0);
                    return 0;

            case SOS:
                    status = STATUS_PLAY_SOST;
                    return 0;

            case BEMOL:
                    status = STATUS_PLAY_BEMOL;
                    return 0;

            case COMA:
            case LN:
                    pushexp(LN, 0);
                    ssymval(*sym, evalexpr());
                    inscodeI(*sym, NULL, num_channel);
                    if (token == COMA) {
                            status = 32;
                            initexpr();
                            return 0;
                    } else {
                            status = STATUS_BEGIN_CHN_BODY;
                            return 1;
                    }


            default:
                    rerror(ESYNTAX, E_EXP, 0);
            }


    case 32:
      switch(token)
        {
        case NUMBER:
          status = 33;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = 33;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 32;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case 33:
      switch(token)
        {
        case PARD:
          status = 33;
          pushexp(token, 0);
          return 0;
        case ADD:
          status = 34;
          pushexp(token, 0);
          return 0;
        case SUB:
          status = 34;
          pushexp(token, 0);
          return 0;
        case MUL:
          status = 34;
          pushexp(token, 0);
          return 0;
        case DIV:
          status = 34;
          pushexp(token, 0);
          return 0;
        case SOS:
          status = STATUS_PLAY_SOST;{pushexp(token, 0);ssymval(*sym, evalexpr());}return 0;
        case BEMOL:
          status = STATUS_PLAY_BEMOL;{pushexp(token, 0);ssymval(*sym, evalexpr());}return 0;
        case COMA:
          status = 32;{pushexp(LN, 0);ssymval(*sym, evalexpr());inscodeI(*sym, NULL, num_channel);initexpr();} return 0;
        case LN:
          status = STATUS_BEGIN_CHN_BODY;{pushexp(token, 0);ssymval(*sym, evalexpr());inscodeI(*sym, NULL, num_channel);}return 1;
        default: rerror(ESYNTAX, E_EXP, 0);
        }
    case 34:
      switch(token)
        {
        case NUMBER:
          status = STATUS_PLAY_EXPRESION;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = STATUS_PLAY_EXPRESION;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 32;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case STATUS_PLAY_BEMOL:
      switch(token) {
      case BEMOL:
              pushexp(SUB, 0);
              pushexp(NUMBER, 3);
              return 0;

      case COMA:
      case LN:
              pushexp(LN, 0);
              ssymval(*sym, evalexpr() - 3);
              inscodeI(*sym, NULL, num_channel);
              if (token == LN) {
                      status = STATUS_BEGIN_CHN_BODY;
                      return 1;
              } else {
                      status = 32;
                      initexpr();
                      return 0;
              }

      default: rerror(ESYNTAX, E_BEMOL, 0);
      }

    case STATUS_PLAY_SOST:
      switch(token) {
      case SOS:
              pushexp(ADD, 0);
              pushexp(NUMBER, 3);
              return 0;

      case COMA:
      case LN:
              pushexp(LN, 0);
              ssymval(*sym, evalexpr() + 3);
              inscodeI(*sym, NULL, num_channel);
              if (token == LN) {
                      status = STATUS_BEGIN_CHN_BODY;
                      return 1;
              } else {
                      status = 32;
                      initexpr();
                      return 0;
              }


      default: rerror(ESYNTAX, E_SOS, 0);
      }


    case 38:
      switch(token)
        {
        case LN:
          status = 37;{errorg?rerror(EERROR, 0, 0):writesong();}return 2;            /*Fin de entrada*/
        default: rerror(ESYNTAX, E_BAD_COMM, 0);
        }


    case 39:
      switch (token)
        {
        case NUMBER:
          status = 40;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = 40;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 41;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }


    case 40:
      switch(token)
        {
        case ADD:
          status = 39;
          pushexp(token, 0);
          return 0;
        case SUB:
          status = 39;
          pushexp(token, 0);
          return 0;
        case MUL:
          status = 39;
          pushexp(token, 0);
          return 0;
        case DIV:
          status = 39;
          pushexp(token, 0);
          return 0;
        case POINT:
          status = 43;{pointp = point=32;};
          return 0;
        case LN:
          status = STATUS_BEGIN_CHN_BODY;
          {
            float time;

            pushexp(token, 0);
            time = evalexpr();
            time/=64.0;
            time*=(240.0*((float)(gsymval(hz))))/((float)(gsymval(tempo)));
            if((time-((float)((unsigned char)time))) > 0.5)
              time=((float)((unsigned char)time))+1.0;
            else
              time=(float)((unsigned char)time);

            ssymval(*sym,(unsigned char)time);
            inscodeI(*sym, NULL, num_channel);
          }return 1;


        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case 41:
      switch(token)
        {
        case NUMBER:
          status = 42;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = 42;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 41;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case 42:
      switch(token)
        {
        case PARD:
          status = 42;
          pushexp(token, 0);
          return 0;
        case ADD:
        case SUB:
        case MUL:
        case DIV:
          status = 41;
          pushexp(token, 0);
          return 0;

        case POINT:
          status = 43;{pointp = point=32;} return 0;
        case LN:
          status = STATUS_BEGIN_CHN_BODY;
          {
            float time, timei;

            pushexp(token, 0);
            time = evalexpr();
            time/=64.0;
            time*=(240.0*((float)(gsymval(hz))))/((float)(gsymval(tempo)));
            time = fabs(time);

            timei = floor(time);
            if(time-timei)
              time = timei+1.0;
            else
              time = timei;

            ssymval(*sym,(unsigned char)time);
            inscodeI(*sym, NULL, num_channel);
          }return 1;
        default: rerror(ESYNTAX, E_EXP, 0);
        }
    case 43:
      switch(token)
        {
        case POINT:
          pointp >>= 1;
          point += pointp;
          return 0;

        case LN:
          status = STATUS_BEGIN_CHN_BODY;
          {
            float time, timei;

            pushexp(token, 0);
            time = evalexpr();
            time/=64;
            time*=(240.0*((float)(gsymval(hz))))/((float)(gsymval(tempo)));
            time = fabs(time);
            time+=time*(((float)point)/64.0);


            timei = floor(time);
            if(time-timei)
              time = timei+1.0;
            else
              time = timei;

            ssymval(*sym,(unsigned char)time);
            inscodeI(*sym, NULL, num_channel);
          }return 1;
        }
    default:
      rerror(ESYNTAX, E_POINT, 0);

    }
}