int main () { carp_bool status; carp_ht h; carp_ht_entry *res; const char *key = "mykey"; const char *badkey = "badkey"; carp_value value = 17; plan(NO_PLAN); carp_ht_init(&h, 10); status = carp_ht_del(&h, key); ok(status == 1, "Delete fails with empty table."); status = carp_ht_set(&h, key, value); ok(status == 0, "Set returns successfully."); res = carp_ht_get(&h, key); ok(res->value == value && !strcmp(key, res->key), \ "Gets correct struct back."); res = carp_ht_get(&h, badkey); ok(res == NULL, "Bad key gives null response."); carp_ht_cleanup(&h); done_testing(); }
/* VM initialization for parsed code (since the labels will have already been generated). Would like to rename this at some point. */ void carp_vm_make (carp_machine_state *m) { assert(m != NULL); assert(&m->labels != NULL); carp_reg_init(m->regs); carp_ht_entry *res = carp_ht_get(&m->labels, "main"); if (res == NULL) carp_vm_err(m, CARP_VM_NO_MAIN); carp_reg_set(m->regs, CARP_IP, res->value - 1); m->regs[CARP_RUN] = 1; int status = carp_stack_init(&m->stack, &m->regs[CARP_SP], 1); if (status == 1) carp_vm_err(m, CARP_STACK_NO_MEM); }
/* Assigns values to a series of tokens. NUM is obvious. REG is obvious. LBL is NOP instr. FUNC is label lookup value. INSTR is obvious. */ void carp_lex_lex (carp_machine_state *m, carp_tok *tokens) { assert(m != NULL); assert(tokens != NULL); long long length = -1; carp_tok *tmp = tokens; carp_ht_init(&m->labels, 10); while (tmp != NULL) { switch (tmp->type) { case CARP_TOK_UNDEF: { fprintf(stderr, "Unknown token <%s>\n", tmp->lexeme); carp_lex_exit(tokens, &m->labels, EXIT_FAILURE); break; } case CARP_TOK_NUM: { long long num = atoi(tmp->lexeme); tmp->value = num; break; } case CARP_TOK_REG: { carp_reg reg = carp_reg_lookup(tmp->lexeme); tmp->value = reg; break; } case CARP_TOK_LBL: { carp_bool status = carp_ht_set(&m->labels, tmp->lexeme, tmp->pos); if (status != 0) { fprintf(stderr, "Could not make label <%s>\n", tmp->lexeme); carp_lex_exit(tokens, &m->labels, 1); } carp_value instr = CARP_INSTR_NOP; tmp->value = instr; break; } case CARP_TOK_FUNC: { carp_ht_entry *res = carp_ht_get(&m->labels, tmp->lexeme); if (res == NULL) { fprintf(stderr, "Unknown label <%s>\n", tmp->lexeme); carp_lex_exit(tokens, &m->labels, EXIT_FAILURE); } tmp->value = res->value; break; } case CARP_TOK_VAR: { break; } case CARP_TOK_INSTR: { carp_value instr = carp_instr_lookup(tmp->lexeme); tmp->value = instr; break; } } #ifdef CDEBUG printf("[%04ld] %5s (%5s) = %4ld\n", tmp->pos, tmp->lexeme, carp_reverse_type[tmp->type], tmp->value); #endif tmp = tmp->next; length++; } carp_value code[length]; tmp = tokens; while (tmp != NULL) { code[tmp->pos] = tmp->value; tmp = tmp->next; } carp_lex_cleanup(tokens); carp_vm_make(m); carp_vm_load(m, code, length); }