static ChimpRef * _chimp_os_dirname (ChimpRef *self, ChimpRef *args) { ChimpRef *path = CHIMP_ARRAY_ITEM(args, 0); size_t i; const char *begin = CHIMP_STR_DATA(path); const char *end = begin + CHIMP_STR_SIZE(path); for (i = 0; i < CHIMP_STR_SIZE(path); i++) { end--; if (*end == '/') { return chimp_str_new (begin, (size_t) (end - begin)); } } return CHIMP_STR_NEW (""); }
static ChimpRef * _chimp_os_basename (ChimpRef *self, ChimpRef *args) { ChimpRef *path = CHIMP_ARRAY_ITEM(args, 0); size_t len = CHIMP_STR_SIZE(path); const char *s = CHIMP_STR_DATA(path) + len; if (len > 0) len--; while (len > 0) { if (*s == '/') { s++; break; } s--; len--; } return chimp_str_new (s, CHIMP_STR_SIZE(path) - len); }
static ChimpRef * assemble_module (const char *filename) { char buf[8192]; ChimpRef *code; ChimpRef *mod; ChimpRef *method; FILE *stream = fopen (filename, "r"); if (stream == NULL) { fprintf (stderr, "error: failed to open %s\n", filename); return NULL; } code = chimp_code_new (); if (code == NULL) { fprintf (stderr, "error: failed to allocate code object\n"); return NULL; } while (!feof (stream)) { const char *ptr; ChimpRef *opname; ChimpOpcode opcode; if (fgets (buf, sizeof(buf)-1, stream) == NULL) { break; } ptr = buf; _skip_whitespace (&ptr); if (!*ptr) continue; if (*ptr == '#') continue; if (!_parse_name (&ptr, &opname)) { fprintf (stderr, "error: expected name\n"); goto error; } opcode = _str_to_opcode (CHIMP_STR_DATA (opname)); switch (opcode) { case CHIMP_OPCODE_PUSHNIL: { if (!chimp_code_pushnil (code)) { goto error; } break; } case CHIMP_OPCODE_DUP: { if (!chimp_code_dup (code)) { goto error; } break; } case CHIMP_OPCODE_NOT: { if (!chimp_code_not (code)) { goto error; } break; } case CHIMP_OPCODE_RET: { if (!chimp_code_ret (code)) { goto error; } break; } case CHIMP_OPCODE_SPAWN: { if (!chimp_code_spawn (code)) { goto error; } break; } case CHIMP_OPCODE_MAKEARRAY: { ChimpRef *nargs; if (!_parse_const_int (&ptr, &nargs)) { goto error; } if (!chimp_code_makearray ( code, CHIMP_INT(nargs)->value)) { goto error; } break; } case CHIMP_OPCODE_MAKECLOSURE: { if (!chimp_code_makeclosure (code)) { goto error; } break; } case CHIMP_OPCODE_POP: { if (!chimp_code_pop (code)) { goto error; } break; } case CHIMP_OPCODE_PUSHNAME: { ChimpRef *name; if (!_parse_name (&ptr, &name)) { goto error; } if (!chimp_code_pushname (code, name)) { goto error; } break; } case CHIMP_OPCODE_STORENAME: { ChimpRef *name; if (!_parse_name (&ptr, &name)) { goto error; } if (!chimp_code_storename (code, name)) { goto error; } break; } case CHIMP_OPCODE_GETATTR: { ChimpRef *name; if (!_parse_name (&ptr, &name)) { goto error; } if (!chimp_code_getattr (code, name)) { goto error; } break; } case CHIMP_OPCODE_GETITEM: { if (!chimp_code_getitem (code)) { goto error; } break; } case CHIMP_OPCODE_PUSHCONST: { ChimpRef *value; if (!_parse_const (&ptr, &value)) { goto error; } if (!chimp_code_pushconst (code, value)) { goto error; } break; } case CHIMP_OPCODE_ADD: { if (!chimp_code_add (code)) { goto error; } break; } case CHIMP_OPCODE_SUB: { if (!chimp_code_sub (code)) { goto error; } break; } case CHIMP_OPCODE_MUL: { if (!chimp_code_mul (code)) { goto error; } break; } case CHIMP_OPCODE_DIV: { if (!chimp_code_div (code)) { goto error; } break; } case CHIMP_OPCODE_GETCLASS: { if (!chimp_code_getclass (code)) { goto error; } break; } case CHIMP_OPCODE_CALL: { ChimpRef *nargs; if (!_parse_const_int (&ptr, &nargs)) { goto error; } if (!chimp_code_call ( code, (uint8_t) CHIMP_INT(nargs)->value)) { goto error; } break; } default: fprintf (stderr, "error: unknown or unsupported opname: %s\n", CHIMP_STR_DATA (opname)); goto error; }; _skip_whitespace (&ptr); if (*ptr) { fprintf (stderr, "error: too many arguments for op: %s\n", CHIMP_STR_DATA(opname)); goto error; } } fclose (stream); /* printf ("%s\n", CHIMP_STR_DATA (chimp_code_dump (code))); */ mod = chimp_module_new_str ("main", NULL); if (mod == NULL) { return NULL; } method = chimp_method_new_bytecode (mod, code); if (method == NULL) { return NULL; } if (!chimp_module_add_local (mod, CHIMP_STR_NEW("main"), method)) { return NULL; } return mod; error: fclose (stream); return NULL; }
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); }