Ejemplo n.º 1
0
/* returns TRUE if "t", an alias type, `defines a new type' by explicitly specifying a type UID */
static boolean
  redef_needed (Type t)
{
  if (type_kind(t) != alias_Type)
    return FALSE;
  if (type_uid(t) == NIL)
    return FALSE;
  else if (type_uid(ur_type(t)) == NIL)
    return TRUE;
  else
    return (strcmp(type_uid(t), type_uid(ur_type(t))) != 0);
}
Ejemplo n.º 2
0
static int thread_write( UThread* ut, UBuffer* port, const UCell* data )
{
    UBuffer* buf;
    ThreadExt* ext = (ThreadExt*) port->ptr.v;
    ThreadQueue* queue;
    int type = ur_type(data);

    if( ur_isSeriesType(type) && ! ur_isShared( data->series.buf ) )
    {
        buf = ur_bufferSerM( data );
        if( ! buf )
            return UR_THROW;

        if( ur_isBlockType(type) )
        {
            UCell* it  = buf->ptr.cell;
            UCell* end = it + buf->used;
            while( it != end )
            {
                type = ur_type(it);
                if( ur_isWordType(type) )
                {
                    if( ur_binding(it) == UR_BIND_THREAD )
                        ur_unbind(it);
                }
                else if( ur_isSeriesType(type) )
                {
                    return ur_error( ut, UR_ERR_INTERNAL,
                        "Cannot write block containing series to thread port" );
                }
                ++it;
            }
        }
    }
    else
        buf = 0;

    queue = (port->SIDE == SIDE_A) ? &ext->A : &ext->B;

    mutexLock( queue->mutex );
    if( queue->END_OPEN )
    {
        thread_queue( &queue->buf, data, buf );
        condSignal( queue->cond );
        writeEvent( queue );
    }
    mutexUnlock( queue->mutex );

    return UR_OK;
}
Ejemplo n.º 3
0
static void cellToQString( const UCell* val, QString& str )
{
    switch( ur_type(val) )
    {
        case UT_NONE:
            str.clear();
            break;

        case UT_CHAR:
            str = QChar( ur_int(val) );
            break;

        case UT_INT:
            str.setNum( ur_int(val) );
            break;

        case UT_DECIMAL:
            str.setNum( ur_decimal(val) );
            break;

        case UT_BIGNUM:
            str.setNum( bignum_l(val) );
            break;

        case UT_STRING:
        case UT_FILE:
        {
            USeriesIter si;
            int len;
            ur_seriesSlice( UT, &si, val );
            len = si.end - si.it;
            switch( si.buf->form )
            {
                case UR_ENC_LATIN1:
                    str = QString::fromLatin1( si.buf->ptr.c + si.it, len );
                    break;
                case UR_ENC_UTF8:
                    str = QString::fromUtf8( si.buf->ptr.c + si.it, len );
                    break;
                case UR_ENC_UCS2:
                    str = QString::fromUtf16( si.buf->ptr.u16 + si.it, len );
                    break;
            }
        }
            break;

        default:
        {
            UBuffer buf;
            ur_strInit( &buf, UR_ENC_LATIN1, 0 );
            ur_toStr( UT, val, &buf, 0 );
            str = QString::fromLatin1( buf.ptr.c, buf.used );
            ur_strFree( &buf );
        }
            break;
    }
}
Ejemplo n.º 4
0
/* module;  within module fwd exception defs first, defs last        */
int get_exc_deps(Exception e, list dl)  {

    if(e->type != NULL) {
         if(member_type_dependency(e->type)) 
              BUILD_DEP_ENT(dl, CatType, 0, ur_type(e->type), CatExc, 0, e) ;
         else BUILD_DEP_ENT(dl, CatType, 1, e->type, CatExc, 0, e) ;
         /* another dep needed here? */ 
         return 1; 
     }    

   else return 0;
}
Ejemplo n.º 5
0
/* MAY NEED REFINEMENT */
int member_type_dependency(Type type) {
   Type t, t1;
   
   t = ur_type(type);
    
   if( is_substantive_typedef(t)  &&
       (t->description->type == record_Type ||
        t->description->type == union_Type || 
        t->description->type == sequence_Type || 
        t->description->type == array_Type ) )
      return 1;

   else if (t->description->type == optional_Type) {
        /* because optional types stored as vars */
        /* and initial defs of array vars are fwd */
        t1 =  ur_type(t->description->structuredDes.optional);
        if(is_substantive_typedef(t1) && t1->description->type==array_Type ) 
           return 1;
   }
   return 0;
}
Ejemplo n.º 6
0
static int thread_read( UThread* ut, UBuffer* port, UCell* dest, int part )
{
    UBuffer tbuf;
    ThreadExt* ext = (ThreadExt*) port->ptr.v;
    ThreadQueue* queue;
    (void) part;

    tbuf.type = 0;

    queue = (port->SIDE == SIDE_A) ? &ext->B : &ext->A;

    if( ! queue->readIt )
        readEvent( queue );     // Waits until data is available.

    mutexLock( queue->mutex );
    while( queue->readIt >= queue->buf.used )
    {
        if( condWaitF( queue->cond, queue->mutex ) )
        {
            mutexUnlock( queue->mutex );
            goto waitError;
        }
    }
    queue->readIt = thread_dequeue( &queue->buf, queue->readIt, dest, &tbuf );
    mutexUnlock( queue->mutex );

    if( tbuf.type )
    {
        UIndex bufN;

        dest->series.buf = UR_INVALID_BUF;
        ur_genBuffers( ut, 1, &bufN );
        dest->series.buf = bufN;

        memCpy( ur_buffer( bufN ), &tbuf, sizeof(UBuffer) );
    }
    else
    {
        int type = ur_type(dest);
        if( ur_isWordType(type) )
        {
            if( ur_binding(dest) == UR_BIND_THREAD )
                ur_unbind(dest);
        }
    }

    return UR_OK;

waitError:

    return ur_error( ut, UR_ERR_INTERNAL, "thread_read condWait failed" );
}
Ejemplo n.º 7
0
static UIndex thread_dequeue( UBuffer* qbuf, UIndex it, UCell* dest,
                              UBuffer* transitBuf )
{
    *dest = qbuf->ptr.cell[ it ];
    ++it;
    if( ur_isSeriesType(ur_type(dest)) && ! ur_isShared( dest->series.buf ) )
    {
        memCpy( transitBuf, qbuf->ptr.cell + it, sizeof(UBuffer) );
        ++it;
    }
    if( it == qbuf->used )
        it = qbuf->used = 0;
    return it;
}
Ejemplo n.º 8
0
void setUniform( UThread* ut, UAtom name, UCell* cell )
{
    GLint loc;

    loc = glGetUniformLocation( grState.shaderProg, ur_atomCStr(name, 0) );
    if( loc == -1 )
    {
        printf( "KR setUniform failed %d\n", grState.shaderProg );
        return;
    }

    switch( ur_type(cell) )
    {
        case UT_LOGIC:
        case UT_INT:
            glUniform1i( loc, ur_int(cell) );
            break;
    }
}
Ejemplo n.º 9
0
/* use objmodule only if processing module represeting CORBA interface  */
int get_type_deps(Type t, list dl, Module objmodule) {

 list         l1, l2;  
 Type         t1; 
 listElement *ptr, *ptr1, *ptr2;
 int          retval; 

 /* if is an alias type, has only fwd def, and dep only on target */ 
 if(t->supertype != NULL) {
          BUILD_DEP_ENT(dl, CatType, 1, t->supertype, CatType, 1, t);
          if(!is_substantive_typedef(t->supertype)) return 1;
 return 0;
 }

 retval = 0;
 /* self dep */
  if(objmodule == NULL)
      BUILD_DEP_ENT(dl, CatType, 1, t, CatType, 0, t) ;


 switch(t->description->type) {

    case array_Type:
     BUILD_DEP_ENT(dl, CatType, 1,
              t->description->structuredDes.array.type, CatType, 1, t); 
     /* arrays have access code in .hpp file */ 
     t1 = ur_type(t->description->structuredDes.array.type);
     if(member_type_dependency(t1)) 
                   BUILD_DEP_ENT(dl, CatType, 0, t1, CatType, 0, t) ;
     break;

    case sequence_Type:
      BUILD_DEP_ENT(dl, CatType, 1,
              t->description->structuredDes.sequence.type, CatType, 1, t);
      break;

    case optional_Type:
       if(is_substantive_typedef(
               ur_type( t->description->structuredDes.optional))) { 
             BUILD_DEP_ENT(dl, CatType, 0,
               ur_type(t->description->structuredDes.optional), CatType, 0, t);
      }
       BUILD_DEP_ENT(dl, CatType, 1,
               t->description->structuredDes.optional, CatType, 1, t);
     break;

    case object_Type:
         l1 = t->description->structuredDes.object->superclasses;
         if( (l1 != NULL) && l1->head != NULL) {
            for(ptr = l1->head; ptr; ptr = ptr->next) {
               t1= ur_type((Type)(ptr->data));
               BUILD_DEP_ENT(dl, CatType, 1, ptr->data, CatType, 1, t); 
               BUILD_DEP_ENT(dl, CatType, 0, t1, CatType, 0, t);
            }
          } 
          l1 = t->description->structuredDes.object->methods;
          for(ptr = l1->head; ptr; ptr=ptr->next) {
               l2 = ((Procedure)(ptr->data))->arguments;
               if(l2 != NULL) {
                 for(ptr1 = l2->head; ptr1; ptr1 = ptr1->next) { 
                   t1 = ((Argument)(ptr1->data))->type;
                   /* if dealing with module obj, don't inc self refs */
                   if(!ref_to_objmodule(t1, objmodule)) 
                       BUILD_DEP_ENT(dl,CatType, 1, t1, CatType, 0, t);
                  }
               }
               t1 = ((Procedure)(ptr->data))->returnType;
               if(t1 != NULL) { 
                 /* if dealing with module obj, don't inc local refs */
                 if(!ref_to_objmodule(t1, objmodule)) 
                    BUILD_DEP_ENT(dl,CatType, 1, t1, CatType, 0, t);
               }

               l2 = ((Procedure) (ptr->data))->exceptions;
               if(l2 != NULL) {
                 for(ptr1 = l2->head; ptr1; ptr1= ptr1->next) { 
                   /* if dealing with module object, don't inc lcl refs */
                   if( (objmodule != NULL) &&
                        objmodule->contained_exceptions != NULL) {
                      for(ptr2 =objmodule->contained_exceptions->head;ptr2;
                               ptr2=ptr2->next) {
                        if(ptr2->data != ptr1->data) continue;
                         else break;
                      } 
                      if(ptr2 != NULL) continue;
                    } 
                    BUILD_DEP_ENT(dl, CatExc,1, ptr1->data, CatType, 0, t);
                  }
                }     
          }
          break;

    case record_Type:
         l1 = t->description->structuredDes.record.fields;
         if( (l1 != NULL) && l1->head != NULL) {
            for(ptr = l1->head; ptr; ptr = ptr->next) {
               t1 = ur_type( ((Argument)(ptr->data))->type);
               if(member_type_dependency(t1))  
                   BUILD_DEP_ENT(dl, CatType, 0, t1, CatType, 0, t) ;
               else
                  BUILD_DEP_ENT(dl, CatType, 1, t1, CatType, 0, t) ;
            }
         }  
         break;  

  case union_Type:
         t1 =t->description->structuredDes.uniond.discriminator_type;
         if(t1 != NULL)
             BUILD_DEP_ENT(dl, CatType, 1, t1, CatType, 0, t) ;
         l1 = t->description->structuredDes.uniond.types;
         if( (l1 != NULL) && l1->head != NULL) {
            for(ptr = l1->head; ptr; ptr = ptr->next) {
               t1 = ur_type( ((Argument)(ptr->data))->type);
                          if(member_type_dependency(t1)) 
                   BUILD_DEP_ENT(dl, CatType, 0, t1, CatType, 0, t) ;
               else 
                   BUILD_DEP_ENT(dl, CatType, 1, t1, CatType, 0, t) ;
            }
         }  
         break;

   default: retval = 0;
 }

 return retval;
}
Ejemplo n.º 10
0
/*
    Returns zero if matching rule not found or exception occured.
*/
static const UCell* _parseBlock( UThread* ut, BlockParser* pe,
                                 const UCell* rit, const UCell* rend,
                                 UIndex* spos )
{
    const UCell* tval;
    int32_t repMin;
    int32_t repMax;
    UAtom atom;
    const UBuffer* iblk = pe->blk;
    UIndex pos = *spos;


match:

    while( rit != rend )
    {
        switch( ur_type(rit) )
        {
            case UT_WORD:
                atom = ur_atom(rit);

                if( atom < UT_BI_COUNT )
                {
                    // Datatype
                    if( pos >= pe->inputEnd )
                        goto failed;
                    tval = iblk->ptr.cell + pos;
                    if( ur_type(tval) != atom )
                    {
                        /*
                        if( atom == UT_NUMBER )
                        {
                            if( ur_is(tval,UT_INT) || ur_is(tval,UT_DECIMAL) )
                                goto type_matched;
                        }
                        */
                        goto failed;
                    }
//type_matched:
                    ++rit;
                    ++pos;
                }
                else switch( atom )
                {
                    case UR_ATOM_OPT:
                        ++rit;
                        repMin = 0;
                        repMax = 1;
                        goto repeat;

                    case UR_ATOM_ANY:
                        ++rit;
                        repMin = 0;
                        repMax = 0x7fffffff;
                        goto repeat;

                    case UR_ATOM_SOME:
                        ++rit;
                        repMin = 1;
                        repMax = 0x7fffffff;
                        goto repeat;

                    case UR_ATOM_BREAK:
                        pe->exception = PARSE_EX_BREAK;
                        *spos = pos;
                        return 0;

                    case UR_ATOM_BAR:
                        goto complete;

                    case UR_ATOM_TO:
                    case UR_ATOM_THRU:
                    {
                        const UCell* ci;
                        const UCell* ce;
                        UAtom ratom = ur_atom(rit);

                        ++rit;
                        if( rit == rend )
                            return 0;

                        ci = iblk->ptr.cell + pos;
                        ce = iblk->ptr.cell + pe->inputEnd;

                        if( ur_is(rit, UT_WORD) )
                        {
                            if( ur_atom(rit) < UT_BI_COUNT )
                            {
                                atom = ur_atom(rit);
                                while( ci != ce )
                                {
                                    if( ur_type(ci) == atom )
                                        break;
                                    ++ci;
                                }
                                if( ci == ce )
                                    goto failed;
                                pos = ci - iblk->ptr.cell;
                                if( ratom == UR_ATOM_THRU )
                                    ++pos;
                                ++rit;
                                break;
                            }
                            else
                            {
                                tval = ur_wordCell( ut, rit );
                                CHECK_WORD( tval )
                            }
                        }
                        else
                        {
                            tval = rit;
                        }


                        if( ur_is(tval, UT_BLOCK) )
                        {
                            // TODO: If block then all values must match.
                            BLK_RULE_ERROR( "to/thru block! not implemented" );
                        }
                        else
                        {
                            while( ci != ce )
                            {
                                if( ur_equal(ut, ci, tval) )
                                    break;
                                ++ci;
                            }
                            if( ci == ce )
                                goto failed;
                            pos = ci - iblk->ptr.cell;
                            if( ratom == UR_ATOM_THRU )
                                ++pos;
                        }
                        ++rit;
                    }
                        break;

                    case UR_ATOM_INTO:
                        ++rit;
                        if( rit == rend || ! ur_is(rit, UT_BLOCK) )
                        {
                            BLK_RULE_ERROR( "parse into expected block" );
                        }
                        tval = iblk->ptr.cell + pos;
                        if( ! ur_is(tval, UT_BLOCK) )
                            goto failed;
                        if( ur_isShared( tval->series.buf ) )
                            goto failed;
                    {
                        BlockParser ip;
                        UBlockIter bi;
                        UIndex parsePos = 0;

                        ip.eval = pe->eval;
                        ip.blk  = ur_bufferSer( tval );
                        ip.inputBuf  = tval->series.buf;
                        ip.inputEnd  = ip.blk->used;
                        ip.sliced    = 0;
                        ip.exception = PARSE_EX_NONE;

                        ur_blkSlice( ut, &bi, rit );

                        tval = _parseBlock( ut, &ip, bi.it, bi.end, &parsePos );
                        iblk = _acquireInput( ut, pe );
                        if( ! tval )
                        {
                            if( ip.exception == PARSE_EX_ERROR )
                            {
                                pe->exception = PARSE_EX_ERROR;
                                ur_appendTrace( ut, rit->series.buf, 0 );
                                return 0;
                            }
                            if( ip.exception != PARSE_EX_BREAK )
                                goto failed;
                        }
                    }
                        ++rit;
                        ++pos;
                        break;

                    case UR_ATOM_SKIP:
                        repMin = 1;
skip:
                        if( (pos + repMin) > pe->inputEnd )
                            goto failed;
                        pos += repMin;
                        ++rit;
                        break;

                    case UR_ATOM_SET:
                        ++rit;
                        if( rit == rend )
                            goto unexpected_end;
                        if( ! ur_is(rit, UT_WORD) )
                        {
                            BLK_RULE_ERROR( "parse set expected word" );
                        }
                        {
                        UCell* cell = ur_wordCellM( ut, rit );
                        CHECK_WORD( cell )
                        *cell = iblk->ptr.cell[ pos ];
                        }
                        ++rit;
                        break;

                    case UR_ATOM_PLACE:
                        ++rit;
                        if( (rit != rend) && ur_is(rit, UT_WORD) )
                        {
                            tval = ur_wordCell( ut, rit++ );
                            CHECK_WORD( tval )
                            if( ur_is(tval, UT_BLOCK) )
                            {
                                pos = tval->series.it;
                                break;
                            }
                        }
                        BLK_RULE_ERROR( "place expected series word" );

                    //case UR_ATOM_COPY:

                    default:
                    {
                        tval = ur_wordCell( ut, rit );
                        CHECK_WORD( tval )

                        if( ur_is(tval, UT_BLOCK) )
                        {
                            goto match_block;
                        }
                        else
                        {
                            BLK_RULE_ERROR( "parse expected block" );
                        }
                    }
                        break;
                }
                break;

            case UT_SETWORD:
            {
                UCell* cell = ur_wordCellM( ut, rit );
                CHECK_WORD( cell )
                ++rit;

                ur_setId( cell, UT_BLOCK );
                ur_setSlice( cell, pe->inputBuf, pos, pe->inputEnd );
            }
                break;

            case UT_GETWORD:
            {
                UCell* cell = ur_wordCellM( ut, rit );
                CHECK_WORD( cell )
                ++rit;

                if( ur_is(cell, UT_BLOCK) &&
                    (cell->series.buf == pe->inputBuf) )
                    cell->series.end = pos;
            }
                break;

            case UT_LITWORD:
                if( pos >= pe->inputEnd )
                    goto failed;
                tval = iblk->ptr.cell + pos;
                if( (ur_is(tval, UT_WORD) || ur_is(tval, UT_LITWORD))
                    && (ur_atom(tval) == ur_atom(rit)) )
                {
                    ++rit;
                    ++pos;
                }
                else
                    goto failed;
                break;

            case UT_INT:
                repMin = ur_int(rit);

                ++rit;
                if( rit == rend )
                    return 0;

                if( ur_is(rit, UT_INT) )
                {
                    repMax = ur_int(rit);
                    ++rit;
                }
                else if( ur_is(rit, UT_WORD) && ur_atom(rit) == UR_ATOM_SKIP )
                {
                    goto skip;
                }
                else
                {
                    repMax = repMin;
                }
                goto repeat;

            case UT_DATATYPE:
                if( pos >= pe->inputEnd )
                    goto failed;
                if( ! ur_isDatatype( iblk->ptr.cell + pos, rit ) )
                    goto failed;
                ++rit;
                ++pos;
                break;

            case UT_CHAR:
            case UT_BINARY:
            case UT_STRING:
            case UT_FILE:
                if( pos >= pe->inputEnd )
                    goto failed;
                if( ! ur_equal( ut, iblk->ptr.cell + pos, rit ) )
                    goto failed;
                ++rit;
                ++pos;
                break;

            case UT_BLOCK:
                tval = rit;
match_block:
                {
                UBlockIter bi;
                UIndex rblkN = tval->series.buf;
                ur_blkSlice( ut, &bi, tval );
                tval = _parseBlock( ut, pe, bi.it, bi.end, &pos );
                iblk = pe->blk;
                if( ! tval )
                {
                    if( pe->exception == PARSE_EX_ERROR )
                    {
                        ur_appendTrace( ut, rblkN, 0 );
                        return 0;
                    }
                    if( pe->exception == PARSE_EX_BREAK )
                        pe->exception = PARSE_EX_NONE;
                    else
                        goto failed;
                }
                }
                ++rit;
                break;

            case UT_PAREN:
                if( UR_OK != pe->eval( ut, rit ) )
                    goto parse_err;
                iblk = _acquireInput( ut, pe );
                ++rit;
                break;

            default:
                BLK_RULE_ERROR( "invalid parse value" );
        }
Ejemplo n.º 11
0
/*
  Recursively evaluate math expression.

  \param cell   Cell to evaluate.
  \param res    Result.

  \return UR_OK or UR_THROW.
*/
int calc_eval( UThread* ut, UCell* cell, double* res )
{
    switch( ur_type(cell) )
    {
    case UT_WORD:
    {
        const UCell* val = ur_wordCell( ut, cell );
        if( ! val )
            return UR_THROW;
        if( ur_is(val, UT_DECIMAL) )
            *res = ur_decimal(val);
        else if( ur_is(val, UT_INT) || ur_is(val, UT_CHAR) )
            *res = (double) ur_int(val);
        else
        {
            return ur_error( ut, UR_ERR_SCRIPT, "Invalid word '%s",
                             ur_wordCStr( cell ) );
        }
    }
    break;

    case UT_DECIMAL:
        *res = ur_decimal(cell);
        break;

    case UT_INT:
    case UT_CHAR:
        *res = (double) ur_int(cell);
        break;

    case UT_BLOCK:
    case UT_PAREN:
    {
        UBlockIterM bi;
        double num = 0.0;
        double right;

#define RIGHT_VAL \
if( ++bi.it == bi.end ) \
    return ur_error( ut, UR_ERR_SCRIPT, "Expected operator r-value" ); \
if( ! calc_eval( ut, bi.it, &right ) ) \
    return UR_THROW;

        if( ! ur_blkSliceM( ut, &bi, cell ) )
            return UR_THROW;
        ur_foreach( bi )
        {
            if( ur_is(bi.it, UT_WORD) )
            {
                switch( ur_atom(bi.it) )
                {
                case UR_ATOM_PLUS:
                    RIGHT_VAL
                    num += right;
                    break;

                case UR_ATOM_MINUS:
                    RIGHT_VAL
                    num -= right;
                    break;

                case UR_ATOM_ASTERISK:
                    RIGHT_VAL
                    num *= right;
                    break;

                case UR_ATOM_SLASH:
                    RIGHT_VAL
                    num /= right;
                    break;

                default:
                    if( ! calc_eval( ut, bi.it, &num ) )
                        return UR_THROW;
                }
            }
            else if( ur_is(bi.it, UT_SETWORD) )
            {
                cell = ur_wordCellM( ut, bi.it );
                if( ! cell )
                    return UR_THROW;
                ur_setId( cell, UT_DECIMAL );
                ur_decimal(cell) = num;
            }
            else
            {
                if( ! calc_eval( ut, bi.it, &num ) )
                    return UR_THROW;
            }
        }
        *res = num;
    }
    break;

    default:
        *res = 0.0;
        break;
    }
    return UR_OK;
}
Ejemplo n.º 12
0
/*
  Returns zero if matching rule not found or exception occured.
*/
static const UCell* _parseBin( UThread* ut, BinaryParser* pe,
                               const UCell* rit, const UCell* rend,
                               UIndex* spos )
{
    const UCell* set = 0;
    const UCell* tval;
    uint32_t bitCount;
    uint32_t field;
    UBuffer* ibin  = ur_buffer( pe->inputBufN );
    uint8_t* in    = ibin->ptr.b + *spos;
    uint8_t* inEnd = ibin->ptr.b + pe->inputEnd;


match:

    while( rit != rend )
    {
        switch( ur_type(rit) )
        {
            case UT_INT:
                bitCount = ur_int(rit);
                if( bitCount < 1 || bitCount > 32 )
                {
                    ur_error( PARSE_ERR, "bit-field size must be 1 to 32" );
                    goto parse_err;
                }
                if( bitCount > 24 )
                {
                    uint32_t high;
                    in = pullBits( pe, bitCount - 16, in, inEnd, &high );
                    if( ! in )
                        goto failed;
                    in = pullBits( pe, 16, in, inEnd, &field );
                    if( ! in )
                        goto failed;
                    field |= high << 16;
                }
                else
                {
                    in = pullBits( pe, bitCount, in, inEnd, &field );
                    if( ! in )
                        goto failed;
                }
                goto set_field;

            case UT_WORD:
                switch( ur_atom(rit) )
                {
                case UR_ATOM_U8:
                    if( in == inEnd )
                        goto failed;
                    field = *in++;
                    goto set_field;

                case UR_ATOM_U16:
                    if( (inEnd - in) < 2 )
                        goto failed;
                    if( pe->bigEndian )
                        field = (in[0] << 8) | in[1];
                    else
                        field = (in[1] << 8) | in[0];
                    in += 2;
                    goto set_field;

                case UR_ATOM_U32:
                    if( (inEnd - in) < 4 )
                        goto failed;
                    if( pe->bigEndian )
                        field = (in[0] << 24) | (in[1] << 16) |
                                (in[2] <<  8) |  in[3];
                    else
                        field = (in[3] << 24) | (in[2] << 16) |
                                (in[1] <<  8) |  in[0];
                    in += 4;
                    goto set_field;

                case UR_ATOM_SKIP:
                    ++rit;
                    ++in;
                    break;
#if 0
                case UR_ATOM_MARK:
                    break;

                case UR_ATOM_PLACE:
                    ++rit;
                    if( (rit != rend) && ur_is(rit, UT_WORD) )
                    {
                        tval = ur_wordCell( ut, rit++ );
                        CHECK_WORD(tval);
                        if( ur_is(tval, UT_BINARY) )
                        {
                            pos = tval->series.it;
                            break;
                        }
                    }
                    ur_error( PARSE_ERR, "place expected series word" );
                    goto parse_err;
#endif
                case UR_ATOM_COPY:      // copy  dest   size
                                        //       word!  int!/word!
                    ++rit;
                    if( (rit != rend) && ur_is(rit, UT_WORD) )
                    {
                        UCell* res = ur_wordCellM( ut, rit );
                        CHECK_WORD(res);
                        if( ++rit != rend )
                        {
                            tval = rit++;
                            if( ur_is(tval, UT_WORD) )
                            {
                                tval = ur_wordCell( ut, tval );
                                CHECK_WORD(tval);
                            }
                            if( ur_is(tval, UT_INT) )
                            {
                                UBuffer* cb;
                                int size = ur_int(tval);
                                cb = ur_makeBinaryCell( ut, size, res );
                                cb->used = size;
                                memCpy( cb->ptr.b, in, size );
                                in += size;
                                break;
                            }
                        }
                        ur_error( PARSE_ERR, "copy expected int! count" );
                        goto parse_err;
                    }
                    ur_error( PARSE_ERR, "copy expected word! destination" );
                    goto parse_err;

                case UR_ATOM_BIG_ENDIAN:
                    ++rit;
                    pe->bigEndian = 1;
                    break;

                case UR_ATOM_LITTLE_ENDIAN:
                    ++rit;
                    pe->bigEndian = 0;
                    break;

                default:
                    tval = ur_wordCell( ut, rit );
                    CHECK_WORD(tval);

                    if( ur_is(tval, UT_CHAR) )
                        goto match_char;
                    else if( ur_is(tval, UT_STRING) )
                        goto match_string;
                    else if( ur_is(tval, UT_BLOCK) )
                        goto match_block;
                    /*
                    else if( ur_is(tval, UT_BITSET) )
                        goto match_bitset;
                    */
                    else
                    {
                        ur_error( PARSE_ERR,
                                "parse expected char!/string!/block!" );
                        goto parse_err;
                    }
                    break;
                }
                break;

            case UT_SETWORD:
                set = rit++;
                while( (rit != rend) && ur_is(rit, UT_SETWORD) )
                    ++rit;
                break;
#if 0
            case UT_GETWORD:
                break;

            case UT_INT:
                repMin = ur_int(rit);

                ++rit;
                if( rit == rend )
                    return 0;

                if( ur_is(rit, UT_INT) )
                {
                    repMax = ur_int(rit);
                    ++rit;
                }
                else
                {
                    repMax = repMin;
                }
                goto repeat;
#endif
            case UT_CHAR:
match_char:
                if( *in != ur_int(rit) )
                    goto failed;
                ++in;
                ++rit;
                break;

            case UT_BLOCK:
                tval = rit;
match_block:
            {
                UBlockIter bi;
                UIndex pos = in - ibin->ptr.b;
                UIndex rblkN = tval->series.buf;
                ur_blkSlice( ut, &bi, tval );
                tval = _parseBin( ut, pe, bi.it, bi.end, &pos );
                ibin = ur_buffer( pe->inputBufN );
                if( ! tval )
                {
                    if( pe->exception == PARSE_EX_ERROR )
                    {
                        ur_appendTrace( ut, rblkN, 0 );
                        return 0;
                    }
                    if( pe->exception == PARSE_EX_BREAK )
                        pe->exception = PARSE_EX_NONE;
                    else
                        goto failed;
                }
                in    = ibin->ptr.b + pos;
                inEnd = ibin->ptr.b + pe->inputEnd;
                ++rit;
            }
                break;

            case UT_PAREN:
            {
                UIndex pos = in - ibin->ptr.b;

                if( UR_OK != pe->eval( ut, rit ) )
                    goto parse_err;

                /* Re-acquire pointer & check if input modified. */
                ibin = ur_buffer( pe->inputBufN );
                if( pe->sliced )
                {
                    // We have no way to track changes to the end of a slice,
                    // so just make sure we remain in valid memery.
                    if( ibin->used < pe->inputEnd )
                        pe->inputEnd = ibin->used;
                }
                else
                {
                    // Not sliced, track input end.
                    if( ibin->used != pe->inputEnd )
                        pe->inputEnd = ibin->used;
                }
                in    = ibin->ptr.b + pos;
                inEnd = ibin->ptr.b + pe->inputEnd;
                ++rit;
            }
                break;

            case UT_STRING:
                tval = rit;
match_string:
            {
                UBinaryIter bi;
                int size;

                ur_binSlice( ut, &bi, tval );
                if( ur_strIsUcs2(bi.buf) )
                    goto bad_enc;
                size = bi.end - bi.it;
                if( size > (inEnd - in) )
                    goto failed;
                if( match_pattern_8(in, inEnd, bi.it, bi.end) == bi.end )
                {
                    in += size;
                    ++rit;
                }
                else
                    goto failed;
            }
                break;
#if 0
            case UT_BITSET:
                tval = rit;
match_bitset:
            if( pos >= pe->inputEnd )
                goto failed;
            {
                const UBuffer* bin = ur_bufferSer( tval );
                int c = istr->ptr.c[ pos ];
                if( bitIsSet( bin->ptr.b, c ) )
                {
                    ++rit;
                    ++pos;
                }
                else
                    goto failed;
            }
                break;
#endif
            default:
                ur_error( PARSE_ERR, "invalid parse value" );
                             //orDatatypeName( ur_type(rit) ) );
                goto parse_err;
        }
    }

//complete:

    *spos = in - ibin->ptr.b;
    return rit;

set_field:

    if( set )
    {
        UCell* val;
        while( set != rit )
        {
            val = ur_wordCellM( ut, set++ );
            CHECK_WORD(val);
            ur_setId(val, UT_INT);
            ur_int(val) = field;
        }
        set = 0;
    }
    ++rit;
    goto match;

failed:

    *spos = in - ibin->ptr.b;
    return 0;

bad_enc:

    ur_error( ut, UR_ERR_INTERNAL,
              "parse binary does not handle UCS2 strings" );
    //goto parse_err;

parse_err:

    pe->exception = PARSE_EX_ERROR;
    return 0;
}
Ejemplo n.º 13
0
/**
  Returns rule number of matched rule or -1 if no match was found.
  cbp->values points to the current position in the input block, or is set
  to zero when the end of input is reached.
*/
int cbp_matchRule( CBParser* cbp )
{
    const UCell* rit;
    const UCell* rend;
    const UCell* sit  = cbp->_inputPos;
    const UCell* send = cbp->_inputEnd;
    int ruleN = 0;

    if( sit == send )
    {
        cbp->values = 0;
        return -1;
    }

    cbp->values = sit;

    if( ! cbp->_rules )
        return -1;

    rit  = cbp->_rules;
    rend = cbp->_rulesEnd;

next:

    if( ur_is(rit, UT_LITWORD) )
    {
        if( ur_is(sit, UT_WORD) && (ur_atom(rit) == ur_atom(sit)) )
            goto value_matched;
    }
    else if( ur_is(rit, UT_WORD) )
    {
        UAtom atom = ur_atom(rit);
        if( atom < UT_BI_COUNT )
        {
            if( atom == ur_type(sit) )
                goto value_matched;
        }
        else if( atom == UR_ATOM_BAR )
            goto rule_matched;
    }
    else if( ur_is(rit, UT_DATATYPE) )
    {
        if( ur_isDatatype( sit, rit ) )
            goto value_matched;
    }

next_rule:

    sit = cbp->_inputPos;
    do
    {
        if( ur_is(rit, UT_WORD) && (ur_atom(rit) == UR_ATOM_BAR) )
        {
            ++ruleN;
            if( ++rit == rend )
                goto fail;
            goto next;
        }
        ++rit;
    }
    while( rit != rend );

fail:

    cbp->_inputPos = send;
    return -1;

value_matched:

    ++rit;
    ++sit;
    if( rit == rend )
        goto rule_matched;
    if( sit == send )
    {
        if( ur_is(rit, UT_WORD) && (ur_atom(rit) == UR_ATOM_BAR) )
            goto rule_matched;
        goto next_rule;
    }
    goto next;

rule_matched:

    cbp->_inputPos = sit;
    return ruleN;
}