static ChimpRef * _chimp_symtable_init (ChimpRef *self, ChimpRef *args) { ChimpRef *filename; ChimpRef *ast; if (!chimp_method_parse_args (args, "oo", &filename, &ast)) { return NULL; } CHIMP_ANY(self)->klass = chimp_symtable_class; CHIMP_SYMTABLE(self)->filename = filename; CHIMP_SYMTABLE(self)->ste = chimp_nil; CHIMP_SYMTABLE(self)->lookup = chimp_hash_new (); if (CHIMP_SYMTABLE(self)->lookup == NULL) { return NULL; } CHIMP_SYMTABLE(self)->stack = chimp_array_new (); if (CHIMP_SYMTABLE(self)->stack == NULL) { return NULL; } if (CHIMP_ANY_CLASS(ast) == chimp_ast_mod_class) { if (!chimp_symtable_visit_mod (self, ast)) return NULL; } else { CHIMP_BUG ("unknown top-level AST node type: %s", CHIMP_STR_DATA(CHIMP_CLASS(CHIMP_ANY_CLASS(ast))->name)); return NULL; } return self; }
static ChimpCmpResult _chimp_task_cmp (ChimpRef *self, ChimpRef *other) { if (CHIMP_ANY_CLASS(self) == CHIMP_ANY_CLASS(other)) { if (CHIMP_TASK(self)->priv == CHIMP_TASK(other)->priv) { return CHIMP_CMP_EQ; } else if (CHIMP_TASK(self)->priv < CHIMP_TASK(other)->priv) { return CHIMP_CMP_LT; } else /* if (CHIMP_TASK(self)->priv > CHIMP_TASK(other)->priv) */ { return CHIMP_CMP_GT; } } else { return CHIMP_CMP_NOT_IMPL; } }
static chimp_bool_t chimp_symtable_visit_stmts_or_decls (ChimpRef *self, ChimpRef *arr) { size_t i; for (i = 0; i < CHIMP_ARRAY_SIZE(arr); i++) { ChimpRef *item = CHIMP_ARRAY_ITEM(arr, i); if (CHIMP_ANY_CLASS(item) == chimp_ast_stmt_class) { if (!chimp_symtable_visit_stmt (self, item)) { return CHIMP_FALSE; } } else if (CHIMP_ANY_CLASS(item) == chimp_ast_decl_class) { if (!chimp_symtable_visit_decl (self, item)) { return CHIMP_FALSE; } } else { CHIMP_BUG ("dude"); return CHIMP_FALSE; } } return CHIMP_TRUE; }
static ChimpRef * chimp_hash_str (ChimpRef *self) { size_t size = CHIMP_HASH_SIZE(self); /* '{' + '}' + (': ' x size) + (', ' x (size-1)) + '\0' */ size_t total_len = 2 + (size * 2) + (size > 0 ? ((size-1) * 2) : 0) + 1; ChimpRef *ref; ChimpRef *strs; char *data; size_t i, k; strs = chimp_array_new_with_capacity (size); if (strs == NULL) { return NULL; } for (i = 0; i < size; i++) { size_t j; ChimpRef *item[2]; item[0] = CHIMP_HASH(self)->keys[i]; item[1] = CHIMP_HASH(self)->values[i]; for (j = 0; j < 2; j++) { ref = item[j]; /* XXX what we really want is something like Python's repr() */ if (CHIMP_ANY_CLASS(ref) == chimp_str_class) { /* for surrounding quotes */ total_len += 2; } ref = chimp_object_str (ref); if (ref == NULL) { return NULL; } chimp_array_push (strs, ref); total_len += CHIMP_STR_SIZE(ref); } } data = CHIMP_MALLOC(char, total_len); if (data == NULL) { return NULL; } k = 0; data[k++] = '{'; for (i = 0; i < size; i++) { size_t j; ChimpRef *item[2]; item[0] = CHIMP_HASH(self)->keys[i]; item[1] = CHIMP_HASH(self)->values[i]; for (j = 0; j < 2; j++) { ref = CHIMP_ARRAY_ITEM(strs, (i * 2) + j); /* XXX what we really want is something like Python's repr() */ /* TODO instanceof */ if (CHIMP_ANY_CLASS(item[j]) == chimp_str_class) { data[k++] = '"'; } memcpy (data + k, CHIMP_STR_DATA(ref), CHIMP_STR_SIZE(ref)); k += CHIMP_STR_SIZE(ref); if (CHIMP_ANY_CLASS(item[j]) == chimp_str_class) { data[k++] = '"'; } if (j == 0) { data[k++] = ':'; data[k++] = ' '; } } if (i < (size-1)) { data[k++] = ','; data[k++] = ' '; } } data[k++] = '}'; data[k] = '\0'; return chimp_str_new_take (data, total_len-1); }