/* this reads a whole file into a vector */ Vector* read_file(char* filename) { char line[MAX_LINE_LENGTH]; char* str; FILE* fp; Vector* lines = Vector_new(sizeof(char**), string_dispose); fp = fopen(filename, "r"); if (fp == NULL) { /* the file probably doesn't exist which could be the case for */ /* the log and times files, let's create them with a call to fopen */ fp = fopen(filename, "a+"); if (fp == NULL) { /* bad times */ printf("Error opening %s\n", filename); exit(1); } fclose(fp); fp = fopen(filename, "r"); } while (fgets(line, MAX_LINE_LENGTH, fp) != NULL) { strtok(line, "\n"); /* strip newline */ str = strdup(line); /* make a new pointer */ Vector_add(lines, &str); /* pass it to the vector */ } fclose(fp); return lines; }
void Vector_sublist(const struct Vector *src, struct Vector *dst, const char *tag) { int i; int len; Vector_clear(dst, src->size); len = strlen(tag); for (i=0; i<src->length; i++) if (len==0 || strncasecmp(src->base + src->size * i, tag, len)==0) Vector_add(dst, src->base + src->size * i); }
/* Push elt, and optimize: elt can be removed if is starts with an already present string sequence. If another element starts with elt, that one can be removed. */ static void StackVectorString_push_optimize (StackVectorString* v, const VectorString* elt) { uintL n = StackVectorString_length(v); uintL i; for (i = 0; i < n; i++) if (VectorString_startsWith(elt,StackVectorString_element(v,i))) return; for (i = 0; i < n; ) if (VectorString_startsWith(StackVectorString_element(v,i),elt)) { Vector_remove_element(&v->rep,i); n--; } else i++; Vector_add(&v->rep,elt); }
/* somehow get scores for user and put them in stats */ void readdatafile(Vector stats, char *user) { FILE *dfile; char *line,*userstr,*moviestr,*scorestr,*found; double score, *scorep; dfile=fopen(DATAFILE,"r"); if (dfile==NULL) return; while ((line=freadln(dfile))!=NULL) { userstr=line; found=strchr(userstr,':'); if (found==NULL) continue; moviestr=&found[1]; found[0]='\0'; found=strchr(moviestr,':'); if (found==NULL) continue; scorestr=&found[1]; found[0]='\0'; if (!strcmp(userstr,user)) { score=safeatof(scorestr); if (score>=0) { scorep=malloc(sizeof(double)); *scorep=score; Vector_add(stats,scorep); } } free(line); } fclose(dfile); }
int Vector_match(const struct Vector *src, struct Vector *dst, const int key, const int pos) { int uckey, lckey; int i; Vector_clear(dst, src->size); uckey = chartoupper(key); if (key >= 'A' && key <= 'Z') lckey = key | 0x20; else lckey = key; for (i=0; i<src->length; i++) { int ch = src->base[src->size * i + pos]; if (ch == lckey || ch == uckey) Vector_add(dst, src->base + src->size * i); } return dst->length; }
void NBody_tick(NBody* self, uint32_t dt) { self->player->acceleration = Vector_init(0.0f, 0.0f, 0.0f); Vector accelerations[NUM_STARS] = {{0.0f, 0.0f, 0.0f}}; // Update player for (size_t i = 0; i < NUM_STARS; ++i) { Star* star = &self->stars[i]; Vector delta = Vector_subtract(star->position, self->player->position); float distance = Vector_mag(delta) + 0.00001f; // Add small amount to avoid collision Vector force = Vector_scale(delta, 0.001f / (distance * distance * distance)); self->player->acceleration = Vector_add(self->player->acceleration, Vector_scale(force, star->mass)); } self->player->velocity = Vector_add(self->player->velocity, Vector_scale(self->player->acceleration, 0.001f * dt)); self->player->position = Vector_add(self->player->position, Vector_scale(self->player->velocity, 0.001f * dt)); // Update stars for (size_t i = 0; i < NUM_STARS; ++i) { Star* star_i = &self->stars[i]; for (size_t j = i + 1; j < NUM_STARS; ++j) { Star* star_j = &self->stars[j]; Vector delta = Vector_subtract(star_j->position, star_i->position); float distance = Vector_mag(delta) + 0.00001f; // Add small amount to avoid collision Vector force = Vector_scale(delta, 0.001f / (distance * distance * distance)); accelerations[i] = Vector_add(accelerations[i], Vector_scale(force, star_j->mass)); accelerations[j] = Vector_add(accelerations[j], Vector_scale(force, -star_i->mass)); } star_i->velocity = Vector_add(star_i->velocity, Vector_scale(accelerations[i], 0.001f * dt)); star_i->position = Vector_add(star_i->position, Vector_scale(star_i->velocity, 0.001f * dt)); } }
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(); }
#include <stdio.h> #include "wich.h" #include "gc.h" int main(int ____c, char *____v[]) { setup_error_handlers(); gc_begin_func(); VECTOR(v); VECTOR(w); v = Vector_new((double[]) { 1.0, 2.0, 3.0}, 3); v = Vector_add(v, Vector_from_int(4, (v).vector->length)); w = Vector_add(Vector_from_int(100, (v).vector->length), v); print_vector(v); print_vector(w); gc_end_func(); gc(); Heap_Info info = get_heap_info(); if (info.live != 0) fprintf(stderr, "%d objects remain after collection\n", info.live); gc_shutdown(); return 0; }
static inline void addLine(const char* line, Vector* lines, Panel* panel, const char* incFilter) { Vector_add(lines, (Object*) ListItem_new(line, 0)); if (!incFilter || String_contains_i(line, incFilter)) Panel_add(panel, (Object*)Vector_get(lines, Vector_size(lines)-1)); }
static inline void StackVectorString_push (StackVectorString* v, const VectorString* elt) { Vector_add(&v->rep,elt); }
static inline void VectorVectorString_add (VectorVectorString* v, const VectorString* elt) { Vector_add(&v->rep,elt); }