// NIY: // Because this can filter the results the vector that gets returned must be freeable - so for now // make a copy of the translation->attributes vector if returning unfiltered so behaviour is // consistent. Long term probably want reference count incremented Vector *Translation_getAllAttributes(Translation *translation, char *attribCode) { if (translation->attributes == NULL) { TranslationAdaptor *tlna = (TranslationAdaptor *)Translation_getAdaptor(translation); if (tlna == NULL) { // No adaptor // Perl comments out the warning, I'll put it back for now, just in case //fprintf(stderr,"Warning: Cannot get attributes without an adaptor.\n"); return Vector_new(); } AttributeAdaptor *ata = DBAdaptor_getAttributeAdaptor(tlna->dba); translation->attributes = AttributeAdaptor_fetchAllByTranslation(ata, translation, NULL); } if (attribCode != NULL) { Vector *results = Vector_new(); int i; for (i=0; i<Vector_getNumElement(translation->attributes); i++) { Attribute *attrib = Vector_getElementAt(translation->attributes, i); if (!strcasecmp(attrib->code, attribCode)) { Vector_addElement(results, attrib); } } return results; } else { // See NIY note above for why I'm making a copy return Vector_copy(translation->attributes); } }
Value* Value_copy(const Value* val) { Value* ret; switch(val->type) { case VAL_INT: ret = ValInt(val->ival); break; case VAL_REAL: ret = ValReal(val->rval); break; case VAL_FRAC: ret = ValFrac(Fraction_copy(val->frac)); break; case VAL_EXPR: ret = ValExpr(BinOp_copy(val->expr)); break; case VAL_CALL: ret = ValCall(FuncCall_copy(val->call)); break; case VAL_UNARY: ret = ValUnary(UnOp_copy(val->term)); break; case VAL_VAR: ret = ValVar(val->name); break; case VAL_VEC: ret = ValVec(Vector_copy(val->vec)); break; case VAL_NEG: /* Shouldn't be reached, but so easy to code */ ret = ValNeg(); break; case VAL_ERR: ret = ValErr(Error_copy(val->err)); break; default: typeError("Unknown value type: %d.", val->type); ret = NULL; break; } return ret; }
Node Node_new(Node node, mint label) { //构造函数 Node n; NEW(n); assert(n); if (node) { n->m_edges = Vector_copy(node->m_edges); n->m_label = node->m_label; } else { n->m_edges = Vector_new(0); n->m_label = label; } return n; }
void vm_exec(VM *vm, bool trace) { int a = 0; int i = 0; bool b1, b2; float f,g; char* c; PVector_ptr vptr,r,l; int x, y; Activation_Record *frame; Function_metadata *const main = vm_function(vm, "main"); vm_call(vm, main); // Define VM registers (C compiler probably ignores 'register' nowadays // but it's good documentation in this case. Keep as locals for // convenience but write them back to the vm object after each decode/execute. register addr32 ip = vm->ip; register int sp = vm->sp; register int fp = vm->fp; const byte *code = vm->code; element *stack = vm->stack; int opcode = code[ip]; while (opcode != HALT && ip < vm->code_size ) { if (trace) vm_print_instr(vm, ip); ip++; switch (opcode) { case IADD: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].i = x + y; break; case ISUB: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].i = x - y; break; case IMUL: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].i = x * y; break; case IDIV: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; if (y ==0 ) { zero_division_error(); break; } stack[sp].i = x / y; break; case FADD: validate_stack_address(sp-1); f = stack[sp--].f; g = stack[sp].f; stack[sp].f = g + f; break; case FSUB: validate_stack_address(sp-1); f = stack[sp--].f; g = stack[sp].f; stack[sp].f = g - f; break; case FMUL: validate_stack_address(sp-1); f = stack[sp--].f; g = stack[sp].f; stack[sp].f = g * f; break; case FDIV: validate_stack_address(sp-1); f = stack[sp--].f; g = stack[sp].f; if (f == 0) { zero_division_error(); break; } stack[sp].f = g / f; break; case VADD: validate_stack_address(sp-1); r = stack[sp--].vptr; l = stack[sp].vptr; vptr = Vector_add(l,r); stack[sp].vptr = vptr; break; case VADDI: validate_stack_address(sp-1); i = stack[sp--].i; vptr = stack[sp].vptr; vptr = Vector_add(vptr,Vector_from_int(i,vptr.vector->length)); stack[sp].vptr = vptr; break; case VADDF: validate_stack_address(sp-1); f = stack[sp--].f; vptr = stack[sp].vptr; vptr = Vector_add(vptr,Vector_from_float(f,vptr.vector->length)); stack[sp].vptr = vptr; break; case VSUB: validate_stack_address(sp-1); r = stack[sp--].vptr; l = stack[sp].vptr; vptr = Vector_sub(l,r); stack[sp].vptr = vptr; break; case VSUBI: validate_stack_address(sp-1); i = stack[sp--].i; vptr = stack[sp].vptr; vptr = Vector_sub(vptr,Vector_from_int(i,vptr.vector->length)); stack[sp].vptr = vptr; break; case VSUBF: validate_stack_address(sp-1); f = stack[sp--].f; vptr = stack[sp].vptr; vptr = Vector_sub(vptr,Vector_from_float(f,vptr.vector->length)); stack[sp].vptr = vptr; break; case VMUL: validate_stack_address(sp-1); r = stack[sp--].vptr; l = stack[sp].vptr; vptr = Vector_mul(l,r); stack[sp].vptr = vptr; break; case VMULI: validate_stack_address(sp-1); i = stack[sp--].i; vptr = stack[sp].vptr; vptr = Vector_mul(vptr,Vector_from_int(i,vptr.vector->length)); stack[sp].vptr = vptr; break; case VMULF: validate_stack_address(sp-1); f = stack[sp--].f; vptr = stack[sp].vptr; vptr = Vector_mul(vptr,Vector_from_float(f,vptr.vector->length)); stack[sp].vptr = vptr; break; case VDIV: validate_stack_address(sp-1); r = stack[sp--].vptr; l = stack[sp].vptr; vptr = Vector_div(l,r); stack[sp].vptr = vptr; break; case VDIVI: validate_stack_address(sp-1); i = stack[sp--].i; if (i == 0) { zero_division_error(); break; } vptr = stack[sp].vptr; vptr = Vector_div(vptr,Vector_from_int(i,vptr.vector->length)); stack[sp].vptr = vptr; break; case VDIVF: validate_stack_address(sp-1); f = stack[sp--].f; if (f == 0) { zero_division_error(); break; } vptr = stack[sp].vptr; vptr = Vector_div(vptr,Vector_from_float(f,vptr.vector->length)); stack[sp].vptr = vptr; break; case SADD: validate_stack_address(sp-1); char * right = stack[sp--].s; stack[sp].s = String_add(String_new(stack[sp].s),String_new(right))->str; break; case OR : validate_stack_address(sp-1); b2 = stack[sp--].b; b1 = stack[sp].b; stack[sp].b = b1 || b2; break; case AND : validate_stack_address(sp-1); b2 = stack[sp--].b; b1 = stack[sp].b; stack[sp].b = b1 && b2; break; case INEG: validate_stack_address(sp); stack[sp].i = -stack[sp].i; break; case FNEG: validate_stack_address(sp); stack[sp].f = -stack[sp].f; break; case NOT: validate_stack_address(sp); stack[sp].b = !stack[sp].b; break; case I2F: validate_stack_address(sp); stack[sp].f = stack[sp].i; break; case I2S: validate_stack_address(sp); stack[sp].s = String_from_int(stack[sp].i)->str; break; case F2I: validate_stack_address(sp); stack[sp].i = (int)stack[sp].f; break; case F2S: validate_stack_address(sp); stack[sp].s = String_from_float((float)stack[sp].f)->str; break; case V2S: validate_stack_address(sp); vptr = stack[sp].vptr; stack[sp].s = String_from_vector(vptr)->str; break; case IEQ: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x == y; break; case INEQ: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x != y; break; case ILT: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x < y; break; case ILE: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x <= y; break; case IGT: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x > y; break; case IGE: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x >= y; break; case FEQ: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f == g; break; case FNEQ: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f != g; break; case FLT: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f < g; break; case FLE: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f <= g; break; case FGT: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f > g; break; case FGE: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f >= g; break; case SEQ: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_eq(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SNEQ: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_neq(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SGT: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_gt(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SGE: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_ge(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SLT: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_lt(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SLE: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_le(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case VEQ: validate_stack_address(sp-1); l = stack[sp--].vptr; r = stack[sp--].vptr; b1 = Vector_eq(l,r); stack[++sp].b = b1; break; case VNEQ: validate_stack_address(sp-1); l = stack[sp--].vptr; r = stack[sp--].vptr; b1 = Vector_neq(l,r); stack[++sp].b = b1; break; case BR: ip += int16(code,ip) - 1; break; case BRF: validate_stack_address(sp); if ( !stack[sp--].b ) { int offset = int16(code,ip); ip += offset - 1; } else { ip += 2; } break; case ICONST: stack[++sp].i = int32(code,ip); ip += 4; break; case FCONST: stack[++sp].f = float32(code,ip); ip += 4; break; case SCONST : i = int16(code,ip); ip += 2; stack[++sp].s = vm->strings[i]; break; case ILOAD: i = int16(code,ip); ip += 2; stack[++sp].i = vm->call_stack[vm->callsp].locals[i].i; break; case FLOAD: i = int16(code,ip); ip += 2; stack[++sp].f = vm->call_stack[vm->callsp].locals[i].f; break; case VLOAD: i = int16(code,ip); ip += 2; stack[++sp].vptr = vm->call_stack[vm->callsp].locals[i].vptr; break; case SLOAD: i = int16(code,ip); ip += 2; stack[++sp].s = vm->call_stack[vm->callsp].locals[i].s; break; case STORE: i = int16(code,ip); ip += 2; vm->call_stack[vm->callsp].locals[i] = stack[sp--]; // untyped store; it'll just copy all bits break; case VECTOR: i = stack[sp--].i; validate_stack_address(sp-i+1); double *data = (double*)malloc(i*sizeof(double)); for (int j = i-1; j >= 0;j--) { data[j] = stack[sp--].f; } vptr = Vector_new(data,i); stack[++sp].vptr = vptr; break; case VLOAD_INDEX: i = stack[sp--].i; vptr = stack[sp--].vptr; vm->stack[++sp].f = ith(vptr, i-1); break; case STORE_INDEX: f = stack[sp--].f; i = stack[sp--].i; vptr = stack[sp--].vptr; set_ith(vptr, i-1, f); break; case SLOAD_INDEX: i = stack[sp--].i; if (i-1 >= strlen(stack[sp].s)) { fprintf(stderr, "StringIndexOutOfRange: %d\n",(int)strlen(stack[sp].s)); break; } c = String_from_char(stack[sp--].s[i-1])->str; stack[++sp].s = c; break; case PUSH_DFLT_RETV: i = *&vm->call_stack[vm->callsp].func->return_type; sp = push_default_value(i, sp, stack); break; case POP: sp--; break; case CALL: a = int16(code,ip); // load index of function from code memory WRITE_BACK_REGISTERS(vm); // (ip has been updated) vm_call(vm, &vm->functions[a]); LOAD_REGISTERS(vm); break; case RET: frame = &vm->call_stack[vm->callsp--]; ip = frame->retaddr; break; case IPRINT: validate_stack_address(sp); printf("%d\n", stack[sp--].i); break; case FPRINT: validate_stack_address(sp); printf("%1.2f\n", stack[sp--].f); break; case BPRINT: validate_stack_address(sp); printf("%d\n", stack[sp--].b); break; case SPRINT: validate_stack_address(sp); printf("%s\n", stack[sp--].s); break; case VPRINT: validate_stack_address(sp); print_vector(stack[sp--].vptr); break; case VLEN: vptr = stack[sp--].vptr; i = Vector_len(vptr); stack[++sp].i = i; break; case SLEN: c = stack[sp--].s; i = String_len(String_new(c)); stack[++sp].i = i; break; case GC_START: vm->call_stack[vm->callsp].save_gc_roots = gc_num_roots(); break; case GC_END: gc_set_num_roots(vm->call_stack[vm->callsp].save_gc_roots); break; case SROOT: gc_add_root((void **)&stack[sp].s); break; case VROOT: gc_add_root((void **)&stack[sp].vptr); break; case COPY_VECTOR: if (vm->call_stack[vm->callsp].locals[i].vptr.vector != NULL) { stack[sp].vptr = Vector_copy(vm->call_stack[vm->callsp].locals[i].vptr); } else if (stack[sp].vptr.vector != NULL) { stack[sp].vptr = Vector_copy(stack[sp].vptr); } else { fprintf(stderr, "Vector reference cannot be found\n"); } break; case NOP : break; default: printf("invalid opcode: %d at ip=%d\n", opcode, (ip - 1)); exit(1); } WRITE_BACK_REGISTERS(vm); if (trace) vm_print_stack(vm); opcode = code[ip]; } if (trace) vm_print_instr(vm, ip); if (trace) vm_print_stack(vm); gc_check(); }
// Also added a flag to indicate we actually want the gaps vector returned - quite often its not used in the caller and so would leak // memory Vector *RangeRegistry_checkAndRegister(RangeRegistry *registry, IDType id, long start, long end, long rStart, long rEnd, int wantGaps) { // The following was commented out due to Ensembl Genomes requirements // for bacterial genomes. // The following was uncommented because I'm not caring about those requirements if ( start > end ) { fprintf(stderr, "start argument [%ld] must be less than (or equal to) end argument [%ld]\n", start, end); exit(1); } if ( rStart > rEnd ) { fprintf(stderr, "rStart argument [%ld] must be less than (or equal to) rEnd argument [%ld]\n", rStart, rEnd); exit(1); } if ( rStart > start ) { fprintf(stderr, "rStart argument [%ld] must be less than (or equal to) start [%ld]\n", rStart, start); exit(1); } if ( rEnd < end ) { fprintf(stderr, "rEnd argument [%ld] must be greater than (or equal to) end [%ld]\n", rEnd, end); exit(1); } IDHash *regReg = RangeRegistry_getRegistry(registry); Vector *list; if (IDHash_contains(regReg, id)) { list = IDHash_getValue(regReg, id); } else { list = Vector_new(); IDHash_add(regReg, id, list); } Vector *gapPairs = NULL; if (wantGaps) { gapPairs = Vector_new(); } int len = Vector_getNumElement(list); if (len == 0) { //this is the first request for this id, return a gap pair for the // entire range and register it as seen CoordPair *cp = CoordPair_new(rStart, rEnd); Vector_addElement(list, cp); return Vector_copy(list); } //#### // loop through the list of existing ranges recording any "gaps" where // the existing range does not cover part of the requested range // int startIdx = 0; int endIdx = Vector_getNumElement(list)-1; int midIdx; CoordPair *range; // binary search the relevant pairs // helps if the list is big while ( ( endIdx - startIdx ) > 1 ) { midIdx = ( startIdx + endIdx ) >> 1; range = Vector_getElementAt(list, midIdx); if ( CoordPair_getEnd(range) < rStart ) { startIdx = midIdx; } else { endIdx = midIdx; } } long gapStart; long gapEnd; int rIdx = -1; int rStartIdx = -1; int rEndIdx; gapStart = rStart; int i; for (i=startIdx; i < len ; i++ ) { CoordPair *pRange = Vector_getElementAt(list, i); long pStart = CoordPair_getStart(pRange); long pEnd = CoordPair_getEnd(pRange); // no work needs to be done at all if we find a range pair that // entirely overlaps the requested region if ( pStart <= start && pEnd >= end ) { return Vector_new(); // perl returns undef, but that causes me problems } // find adjacent or overlapping regions already registered if ( pEnd >= ( rStart - 1 ) && pStart <= ( rEnd + 1 ) ) { if ( rStartIdx < 0 ) { // Not yet been set rStartIdx = i; } rEndIdx = i; } if ( pStart > rStart ) { gapEnd = ( rEnd < pStart ) ? rEnd : pStart - 1; if (wantGaps) { CoordPair *cp = CoordPair_new(gapStart, gapEnd); Vector_addElement(gapPairs, cp); } } gapStart = ( rStart > pEnd ) ? rStart : pEnd + 1; if ( pEnd >= rEnd && rIdx < 0 ) { rIdx = i; break; } } // do we have to make another gap? if ( gapStart <= rEnd ) { if (wantGaps) { CoordPair *cp = CoordPair_new(gapStart, rEnd); Vector_addElement(gapPairs, cp); } } // // Merge the new range into the registered list // if (rStartIdx >= 0 ) { // rStartIdx has been set to something long newStart; long newEnd; CoordPair *rStartIdxRange = Vector_getElementAt(list, rStartIdx); CoordPair *rEndIdxRange = Vector_getElementAt(list, rEndIdx); if ( rStart < CoordPair_getStart(rStartIdxRange)) { newStart = rStart; } else { newStart = CoordPair_getStart(rStartIdxRange); } if ( rEnd > CoordPair_getEnd(rEndIdxRange)) { newEnd = rEnd; } else { newEnd = CoordPair_getEnd(rEndIdxRange); } CoordPair *cp = CoordPair_new(newStart, newEnd); // Think its <= for (i=rStartIdx; i<=rEndIdx; i++) { Vector_removeElementAt(list, rStartIdx); // Always remove from rStartIdx as array is shrinking by one each time called } Vector_insertElementAt(list, rStartIdx, cp); //splice( @$list, $rstart_idx, // $rend_idx - $rstart_idx + 1, // [ $new_start, $new_end ] ); } else if (rIdx >= 0) { CoordPair *cp = CoordPair_new(rStart, rEnd); Vector_insertElementAt(list, rIdx, cp); //splice( @$list, $r_idx, 0, [ $rstart, $rend ] ); } else { CoordPair *cp = CoordPair_new(rStart, rEnd); Vector_addElement(list, cp); } // Note if wantGaps is not set then gapPairs will be NULL - but you said you didn't want it so that should be OK return gapPairs; }
List doPathfinding(Map map, Car cars[3]) { Heap openSet = Heap_new(State_compare); List closedSet = List_new(); List finalPath = List_new(); List neighbors; Position neighbor; State state, newState; Vector newSpeed, acceleration; int end = 0, i, j, useBoost, positionTaken, distance; float cost; LOGINFO("A* doin' da werk!"); state = State_new(Car_getPosition(cars[0]), Car_getSpeed(cars[0]), Car_getBoosts(cars[0]), map); Heap_insert(openSet, state); while(!Heap_isEmpty(openSet) && !end) { state = Heap_extractMin(openSet); if(Map_getTile(map, State_getPosition(state)->x, State_getPosition(state)->y) == ARRIVAL) { end = 1; break; } distance = Map_getDistance(map, State_getPosition(state)->x, State_getPosition(state)->y); neighbors = Map_getReachablePositions(map, State_getPosition(state), State_getSpeed(state), State_getBoosts(state)); List_foreach(neighbors, neighbor, i) { if(Map_getDistance(map, neighbor->x, neighbor->y) > distance) { Position_delete(neighbor); continue; } cost = State_getRealCost(state) + 1; newSpeed = Position_findOffset(State_getPosition(state), neighbor); acceleration = Vector_copy(newSpeed); Vector_substract(acceleration, State_getSpeed(state)); useBoost = 0; positionTaken = 0; if(Vector_squaredLength(acceleration) > 2) { useBoost = 1; } for(j = 1; j < 3; j++) { if(Position_equal(neighbor, Car_getPosition(cars[j]))) { positionTaken = 1; } } if(!positionTaken) { newState = State_new(neighbor, newSpeed, State_getBoosts(state) - useBoost, map); State_setRealCost(newState, cost); State_setParent(newState, state); Heap_insert(openSet, newState); } Vector_delete(newSpeed); Vector_delete(acceleration); Position_delete(neighbor); } List_insert(closedSet, state); List_empty(neighbors); List_delete(neighbors); } while(state != NULL) { List_insert(finalPath, Position_copy(State_getPosition(state))); state = State_getParent(state); } List_head(closedSet); while(!List_isEmpty(closedSet)) { state = List_getCurrent(closedSet); List_remove(closedSet); State_delete(state); } List_delete(closedSet); while((state = Heap_extractMin(openSet)) != NULL) { State_delete(state); } Heap_delete(openSet); LOGINFO("A* is done mate"); return finalPath; }
Value* Vector_magnitude(const Vector* vec, const Context* ctx) { TP(tp); return TP_EVAL(tp, ctx, "sqrt(dot(@1v,@1v))", Vector_copy(vec)); }