/* 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); }
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; }
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; } }
/* 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; }
/* 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; }
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" ); }
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; }
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; } }
/* 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; }
/* 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" ); }
/* 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; }
/* 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; }
/** 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; }