inline optional get_sym(table *t, char *id) { if (*id == '$') { return arr_get(t->tmps, (unsigned) atoi(&id[1])); } else if (isdigit(*id) || *id == '.') { unsigned idx; optional opt; for (idx = 0; idx < arr_size(t->lits); idx++) { if (strcmp(((sym *) (opt = arr_get(t->lits, idx)).val)->id, id) == 0) { return opt; } } opt.e = false; opt.err = element_not_found; return opt; } else { unsigned idx; optional opt; for (idx = 0; idx < arr_size(t->syms); idx++) { if (cmp((opt = arr_get(t->syms, idx)).val, id)) { return opt; } } opt.e = false; opt.err = element_not_found; return opt; } }
static void new_void__arr_add(void **state) { arr_t * arr = arr_new(5); assert_int_equal(arr_add(arr, 3, 10), 0); assert_int_equal(arr_add(arr, 6, 10), 1); int elem = 0; assert_int_equal(arr_get(arr, 3, &elem), 1); assert_int_equal(elem, 10); assert_int_equal(arr_get(arr, 37, &elem), 0); arr_remove(&arr); }
char is_close(compiler_wrapper *cw, int idx) { lky_object *o = arr_get(&cw->rops, idx); lky_instruction istr = OBJ_NUM_UNWRAP(o); return istr == LI_LOAD_CLOSE || istr == LI_SAVE_CLOSE; }
char switch_to_close(compiler_wrapper *cw, char *sid, int idx) { lky_object *o = arr_get(&cw->rops, idx); lky_instruction istr = OBJ_NUM_UNWRAP(o); if(istr == LI_LOAD_CLOSE || istr == LI_SAVE_CLOSE) return 0; istr = istr == LI_LOAD_LOCAL ? LI_LOAD_CLOSE : LI_SAVE_CLOSE; cw->rops.items[idx] = lobjb_build_int(istr); char *nsid = malloc(strlen(sid) + 1); strcpy(nsid, sid); int i = find_prev_name(cw, nsid); if(i < 0) { i = (int)cw->rnames.count; arr_append(&cw->rnames, nsid); } unsigned char buf[4]; int_to_byte_array(buf, i); cw->rops.items[idx + 1] = lobjb_build_int(buf[0]); cw->rops.items[idx + 2] = lobjb_build_int(buf[1]); cw->rops.items[idx + 3] = lobjb_build_int(buf[2]); cw->rops.items[idx + 4] = lobjb_build_int(buf[3]); return 1; }
int ty_class_implements_interface(EagleComplexType *type, EagleComplexType *interface) { while(type->type == ETPointer) type = ET_POINTEE(type); while(interface->type == ETPointer) interface = ET_POINTEE(interface); EagleStructType *st = (EagleStructType *)type; Arraylist *ifcs = &st->interfaces; EagleInterfaceType *ie = (EagleInterfaceType *)interface; int j; for(j = 0; j < ie->names.count; j++) { int good = 0; char *name = arr_get(&ie->names, j); int i; for(i = 0; i < ifcs->count; i++) { if(strcmp(ifcs->items[i], name) == 0) good = 1; } if(!good) return 0; } return 1; }
inline optional create_sym(table *t, char *id, value val) { optional opt; if (isdigit(*id) || *id == '.') { sym *s = malloc(sizeof(sym)); memset(s, 0, sizeof(sym)); strcpy(s->id, id); s->val = val; opt.e = true; opt.val = s; unsigned idx; unsigned n = arr_size(t->lits); for (idx = 0; idx < n; idx++) { if (strcmp(((sym *) arr_get(t->lits, idx).val)->id, id) == 0) { break; } } if (idx >= n) { arr_push(t->lits, s); } } else { unsigned idx; opt.e = true; for (idx = 0; idx < arr_size(t->syms); idx++) { if (strcmp(((sym *) (opt = arr_get(t->syms, idx)).val)->id, id) == 0) { opt.e = false; opt.err = element_not_found; } } if (opt.e) { sym *s = malloc(sizeof(sym)); memset(s, 0, sizeof(sym)); strcpy(s->id, id); s->val = val; opt.val = s; arr_push(t->syms, s); } } return opt; }
void compile_class_decl(compiler_wrapper *cw, ast_node *root) { ast_class_decl_node *node = (ast_class_decl_node *)root; arraylist list = arr_create(10); ast_node *member = node->members->next; for(; member; member = member->next) { ast_class_member_node *m = (ast_class_member_node *)member; //append_op(cw, m->prefix); compile(cw, m->payload); arr_append(&list, member); } int init_flag = 0; if(node->super) { compile(cw, node->super); init_flag |= 2; } if(node->init) { compile(cw, ((ast_class_member_node *)node->init)->payload); init_flag |= 1; } append_op(cw, LI_MAKE_CLASS, node->lineno); append_op(cw, list.count, node->lineno); append_op(cw, init_flag, node->lineno); int i; for(i = list.count - 1; i >= 0; i--) { ast_class_member_node *m = (ast_class_member_node *)arr_get(&list, i); append_op(cw, m->prefix, node->lineno); long idx = find_prev_name(cw, m->name); if(idx < 0) { idx = cw->rnames.count; char *nid = malloc(strlen(m->name) + 1); strcpy(nid, m->name); arr_append(&cw->rnames, nid); } unsigned char buf[4]; int_to_byte_array(buf, idx); append_op(cw, buf[0], node->lineno); append_op(cw, buf[1], node->lineno); append_op(cw, buf[2], node->lineno); append_op(cw, buf[3], node->lineno); } }
// Generic break/continue compilation void compile_one_off(compiler_wrapper *cw, ast_node *root) { ast_one_off_node *node = (ast_one_off_node *)root; long jix = -1; switch(node->opt) { case 'c': jix = OBJ_NUM_UNWRAP(arr_get(&cw->loop_start_stack, cw->loop_start_stack.count - 1)); break; case 'b': jix = OBJ_NUM_UNWRAP(arr_get(&cw->loop_end_stack, cw->loop_end_stack.count - 1)); break; } append_op(cw, LI_JUMP, node->lineno); append_op(cw, jix, node->lineno); append_op(cw, -1, node->lineno); append_op(cw, -1, node->lineno); append_op(cw, -1, node->lineno); }
// Used to find and reuse previous constants. long find_prev_const(compiler_wrapper *cw, lky_object *obj) { long i; for(i = 0; i < cw->rcon.count; i++) { lky_object *o = arr_get(&cw->rcon, i); if(lobjb_quick_compare(obj, o)) return i; } return -1; }
// Used to lookup and reuse previous names/identifiers int find_prev_name(compiler_wrapper *cw, char *name) { long i; for(i = 0; i < cw->rnames.count; i++) { char *n = arr_get(&cw->rnames, i); if(strcmp(name, n) == 0) return (int)i; } return -1; }
long *finalize_indices(compiler_wrapper *cw) { long *idcs = malloc(cw->rindices.count * sizeof(long)); long i; for(i = 0; i < cw->rindices.count; i++) { lky_object_builtin *obj = arr_get(&cw->rindices, i); idcs[i] = (long)(OBJ_NUM_UNWRAP(obj)); } return idcs; }
// Converts the arraylist 'rops' referenced in 'cw' // into an unsigned char array. Note that we are // downcasting from a long to an unsigned char. // We need to make sure everything makes sense // *before* this step. unsigned char *finalize_ops(compiler_wrapper *cw) { unsigned char *ops = malloc(cw->rops.count); long i; for(i = 0; i < cw->rops.count; i++) { lky_object_builtin *obj = arr_get(&cw->rops, i); ops[i] = (unsigned char)(OBJ_NUM_UNWRAP(obj)); } return ops; }
void compile_object_simple(compiler_wrapper *cw, ast_object_decl_node *node) { int ct = 0; ast_node *list = node->payload; arraylist names = arr_create(20); for(; list; list = list->next) { arr_append(&names, ((ast_value_node *)list)->value.s); list = list->next; compile(cw, list); ct++; } if(node->obj) compile(cw, node->obj); else append_op(cw, LI_PUSH_NEW_OBJECT, node->lineno); unsigned char buf[4]; int_to_byte_array(buf, ct); append_op(cw, LI_MAKE_OBJECT, node->lineno); append_op(cw, buf[0], node->lineno); append_op(cw, buf[1], node->lineno); append_op(cw, buf[2], node->lineno); append_op(cw, buf[3], node->lineno); int i; for(i = ct - 1; i >= 0; i--) { char *sid = arr_get(&names, i); char *nsid = malloc(strlen(sid) + 1); strcpy(nsid, sid); int i = find_prev_name(cw, nsid); if(i < 0) { i = (int)cw->rnames.count; arr_append(&cw->rnames, nsid); } unsigned char buf[4]; int_to_byte_array(buf, i); append_op(cw, buf[0], node->lineno); append_op(cw, buf[1], node->lineno); append_op(cw, buf[2], node->lineno); append_op(cw, buf[3], node->lineno); } arr_free(&names); }
char *ty_interface_for_method(EagleComplexType *ett, char *method) { EagleInterfaceType *it = (EagleInterfaceType *)ett; Arraylist *names = &it->names; int i; for(i = 0; i < names->count; i++) { char *name = arr_get(names, i); if(ty_method_lookup(name, method)) return name; } return NULL; }
static void avl_clear_intern (avl_t avl, int free_data) { arr_t arr; avl_entry_t curr; size_t size; /* Create a new array to be used as a stack */ arr = arr_init (); /* Iterate over every node */ arr_insert_back (arr, avl->root); while ((size = arr_size (arr)) > 0) { /* Get the current element from the stack */ curr = (avl_entry_t) arr_get (arr, size-1); arr_remove (arr, size-1); /* Check for invalid nodes */ if (curr == NULL) continue; /* Push children onto the stack */ arr_insert_back (arr, curr->left); arr_insert_back (arr, curr->right); /* Free parent */ if (free_data && curr->data != NULL) free (curr->data); avl->free (curr->key); free (curr); } /* Cleanup the array */ arr_destroy (arr); /* Update AVL Struct */ avl->size = 0; avl->root = NULL; return; }
void append_var_info(compiler_wrapper *cw, char *ch, char load, int lineno) { char needs_close = cw->repl; char already_defined = 0; arraylist list = cw->used_names; int i; for(i = 0; i < list.count; i++) { name_wrapper *w = arr_get(&cw->used_names, i); if(strcmp(w->name, ch)) continue; if(w->owner != cw) { switch_to_close(w->owner, ch, w->idx); needs_close = 1; } else { needs_close = is_close(cw, w->idx); already_defined = 1; } } if(!needs_close && !already_defined && load) needs_close = 1; if(needs_close) { lky_instruction istr = load ? LI_LOAD_CLOSE : LI_SAVE_CLOSE; char *nsid = malloc(strlen(ch) + 1); strcpy(nsid, ch); int i = find_prev_name(cw, nsid); if(i < 0) { i = (int)cw->rnames.count; arr_append(&cw->rnames, nsid); } append_op(cw, istr, lineno); unsigned char buf[4]; int_to_byte_array(buf, i); append_op(cw, buf[0], lineno); append_op(cw, buf[1], lineno); append_op(cw, buf[2], lineno); append_op(cw, buf[3], lineno); return; } lky_instruction istr = load ? LI_LOAD_LOCAL : LI_SAVE_LOCAL; hm_error_t err; int idx = 0; lky_object_builtin *o = hm_get(&cw->saved_locals, ch, &err); if(err == HM_KEY_NOT_FOUND) { idx = get_next_local(cw); lky_object *obj = lobjb_build_int(idx); pool_add(&ast_memory_pool, obj); hm_put(&cw->saved_locals, ch, obj); } else idx = OBJ_NUM_UNWRAP(o); append_op(cw, istr, lineno); unsigned char buf[4]; int_to_byte_array(buf, idx); append_op(cw, buf[0], lineno); append_op(cw, buf[1], lineno); append_op(cw, buf[2], lineno); append_op(cw, buf[3], lineno); name_wrapper *wrap = malloc(sizeof(name_wrapper)); pool_add(&ast_memory_pool, wrap); wrap->idx = cw->rops.count - 5; wrap->name = ch; wrap->owner = cw; arr_append(&cw->used_names, wrap); }
void compile_object(compiler_wrapper *cw, ast_node *n) { ast_object_decl_node *node = (ast_object_decl_node *)n; if(!node->refname) return compile_object_simple(cw, node); arraylist name_list = cw->used_names; int i; for(i = 0; i < name_list.count; i++) { name_wrapper *w = arr_get(&cw->used_names, i); if(strcmp(w->name, node->refname)) continue; switch_to_close(cw, node->refname, w->idx); } int ct = 0; ast_node *list = node->payload; arraylist names = arr_create(20); for(; list; list = list->next) { arr_append(&names, ((ast_value_node *)list)->value.s); list = list->next; compile(cw, list); ct++; } char *nsid = malloc(strlen(node->refname) + 1); strcpy(nsid, node->refname); i = find_prev_name(cw, nsid); if(i < 0) { i = (int)cw->rnames.count; arr_append(&cw->rnames, nsid); } append_op(cw, LI_LOAD_CLOSE, node->lineno); unsigned char buf[4]; int_to_byte_array(buf, i); append_op(cw, buf[0], node->lineno); append_op(cw, buf[1], node->lineno); append_op(cw, buf[2], node->lineno); append_op(cw, buf[3], node->lineno); int_to_byte_array(buf, ct); append_op(cw, LI_MAKE_OBJECT, node->lineno); append_op(cw, buf[0], node->lineno); append_op(cw, buf[1], node->lineno); append_op(cw, buf[2], node->lineno); append_op(cw, buf[3], node->lineno); for(i = ct - 1; i >= 0; i--) { char *sid = arr_get(&names, i); char *nsid = malloc(strlen(sid) + 1); strcpy(nsid, sid); int i = find_prev_name(cw, nsid); if(i < 0) { i = (int)cw->rnames.count; arr_append(&cw->rnames, nsid); } unsigned char buf[4]; int_to_byte_array(buf, i); append_op(cw, buf[0], node->lineno); append_op(cw, buf[1], node->lineno); append_op(cw, buf[2], node->lineno); append_op(cw, buf[3], node->lineno); } arr_free(&names); }