static term nif_erlang_concat_2(Context *ctx, int argc, term argv[]) { if (UNLIKELY(argc != 2)) { fprintf(stderr, "++: wrong args count\n"); abort(); } term prepend_list = argv[0]; if (UNLIKELY(!term_is_nonempty_list(prepend_list))) { if (term_is_nil(prepend_list)) { return argv[1]; } else { fprintf(stderr, "Argument error\n"); abort(); } } int len = term_list_length(prepend_list); memory_ensure_free(ctx, len * 2); // GC might have changed all pointers prepend_list = argv[0]; term append_list = argv[1]; term t = prepend_list; term list_begin = term_nil(); term *prev_term = NULL; // TODO: handle impropers list while (!term_is_nil(t)) { term head = term_get_list_head(t); term *new_list_item = term_list_alloc(ctx); if (prev_term) { prev_term[0] = term_list_from_list_ptr(new_list_item); } else { list_begin = term_list_from_list_ptr(new_list_item); } prev_term = new_list_item; new_list_item[1] = head; t = term_get_list_tail(t); } if (prev_term) { prev_term[0] = append_list; } return list_begin; }
/* * Initialise the parser. */ extern void parse_init(void) { name_t entry; entry = name_lookup("false"); entry->val = term_boolean(make_boolean(false)); entry = name_lookup("inf"); entry->val = term_num(make_num(1.0/0.0)); entry = name_lookup("nil"); entry->val = term_nil(make_nil()); entry = name_lookup("true"); entry->val = term_boolean(make_boolean(true)); }
static term nif_erlang_display_1(Context *ctx, int argc, term argv[]) { UNUSED(ctx); if (argc != 1) { fprintf(stderr, "display: wrong args count\n"); abort(); } display_term(argv[0], ctx); printf("\n"); return term_nil(); }
static term nif_erlang_register_2(Context *ctx, int argc, term argv[]) { if (UNLIKELY((argc != 2) || !term_is_atom(argv[0]) || !term_is_pid(argv[1]))) { fprintf(stderr, "bad match\n"); abort(); } int atom_index = term_to_atom_index(argv[0]); int pid = term_to_local_process_id(argv[1]); globalcontext_register_process(ctx->global, atom_index, pid); return term_nil(); }
static term binary_to_atom(Context *ctx, int argc, term argv[], int create_new) { if (argc != 2) { fprintf(stderr, "binary_to_atom: wrong args count\n"); abort(); } if (UNLIKELY(argv[1] != term_from_atom_string(ctx->global, latin1_atom))) { fprintf(stderr, "binary_to_atom: only latin1 is supported.\n"); abort(); } char *atom_string = interop_binary_to_string(argv[0]); if (IS_NULL_PTR(atom_string)) { fprintf(stderr, "Failed to alloc temporary string\n"); abort(); } int atom_string_len = strlen(atom_string); if (UNLIKELY(atom_string_len > 255)) { fprintf(stderr, "Too long atom.\n"); free(atom_string); abort(); } AtomString atom = malloc(atom_string_len + 1); ((uint8_t *) atom)[0] = atom_string_len; memcpy(((char *) atom) + 1, atom_string, atom_string_len); unsigned long global_atom_index = atomshashtable_get_value(ctx->global->atoms_table, atom, ULONG_MAX); int has_atom = (global_atom_index != ULONG_MAX); if (create_new || has_atom) { if (!has_atom) { global_atom_index = globalcontext_insert_atom(ctx->global, atom); } else { free((void *) atom); } return term_from_atom_index(global_atom_index); } else { free((void *) atom); //TODO: error here return term_nil(); } }
static term nif_erlang_tuple_to_list_1(Context *ctx, int argc, term argv[]) { if (argc != 1) { fprintf(stderr, "tuple_to_list: wrong args count\n"); abort(); } int tuple_size = term_get_tuple_arity(argv[0]); memory_ensure_free(ctx, tuple_size * 2); term tuple = argv[0]; term prev = term_nil(); for (int i = tuple_size - 1; i >= 0; i--) { prev = term_list_prepend(term_get_tuple_element(tuple, i), prev, ctx); } return prev; }
static term nif_erlang_integer_to_list_1(Context *ctx, int argc, term argv[]) { if (argc != 1) { fprintf(stderr, "integer_to_list: wrong args count\n"); abort(); } int32_t int_value = term_to_int32(argv[0]); char integer_string[24]; snprintf(integer_string, 24, "%i", int_value); int integer_string_len = strlen(integer_string); memory_ensure_free(ctx, integer_string_len * 2); term prev = term_nil(); for (int i = integer_string_len - 1; i >= 0; i--) { prev = term_list_prepend(term_from_int11(integer_string[i]), prev, ctx); } return prev; }
static term nif_erlang_atom_to_list_1(Context *ctx, int argc, term argv[]) { if (argc != 1) { fprintf(stderr, "list_to_atom: wrong args count\n"); abort(); } int atom_index = term_to_atom_index(argv[0]); AtomString atom_string = (AtomString) valueshashtable_get_value(ctx->global->atoms_ids_table, atom_index, (unsigned long) NULL); int atom_len = atom_string_len(atom_string); memory_ensure_free(ctx, atom_len * 2); term prev = term_nil(); for (int i = atom_len - 1; i >= 0; i--) { char c = ((const char *) atom_string_data(atom_string))[i]; prev = term_list_prepend(term_from_int11(c), prev, ctx); } return prev; }