void Map__remove(caStack* stack) { caValue* out = circa_output(stack, 0); copy(circa_input(stack, 0), out); hashtable_remove(out, circa_input(stack, 1)); }
void List__insert(caStack* stack) { caValue* out = circa_output(stack, 0); copy(circa_input(stack, 0), out); copy(circa_input(stack, 1), list_insert(out, circa_int_input(stack, 2))); }
void Term__tweak(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) return circa_output_error(stack, "NULL reference"); int steps = tweak_round(to_float(circa_input(stack, 1))); caValue* val = term_value(t); if (steps == 0) return; if (is_float(val)) { float step = get_step(t); // Do the math like this so that rounding errors are not accumulated float new_value = (tweak_round(as_float(val) / step) + steps) * step; set_float(val, new_value); } else if (is_int(val)) set_int(val, as_int(val) + steps); else circa_output_error(stack, "Ref is not an int or number"); }
void Branch__link(caStack* stack) { Branch* self = (Branch*) circa_branch(circa_input(stack, 0)); Branch* source = (Branch*) circa_branch(circa_input(stack, 1)); branch_link_missing_functions(self, source); }
void make_client(Stack* stack) { printf("make_client\n"); Connection* connection = new Connection(); ca_assert(stack->world->libuvWorld->uv_loop != NULL); uv_tcp_init(stack->world->libuvWorld->uv_loop, &connection->uv_tcp); connection->uv_tcp.data = connection; Value* ip = circa_input(stack, 0); Value* port = circa_input(stack, 1); sockaddr_in bind_addr = uv_ip4_addr(circa_string(ip), circa_int(port)); #if 0 if (uv_ip4_addr(circa_string(ip), circa_int(port), &bind_addr)) { printf("error from uv_ip4_addr\n"); return; } #endif uv_connect_t* uv_connect = (uv_connect_t*) malloc(sizeof(*uv_connect)); uv_connect->data = connection; if (uv_tcp_connect(uv_connect, &connection->uv_tcp, bind_addr, client_on_connect)) { printf("uv_tcp_connect error\n"); } Value* out = circa_set_default_output(stack, 0); circa_set_native_ptr(circa_index(out, 0), connection, ConnectionRelease); printf("make_client fin\n"); }
void Connection__send(Stack* stack) { Connection* connection = (Connection*) circa_native_ptr(circa_index(circa_input(stack, 0), 0)); Value* asStr = circa_alloc_value(); circa_to_string(circa_input(stack, 1), asStr); circa_uv_write((uv_stream_t*) &connection->uv_tcp, asStr, true); }
void Branch__call(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); if (branch == NULL) return circa_output_error(stack, "NULL branch"); caValue* inputs = circa_input(stack, 1); push_frame_with_inputs(stack, branch, inputs); }
void Map__set(caStack* stack) { caValue* out = circa_output(stack, 0); copy(circa_input(stack, 0), out); caValue* key = circa_input(stack, 1); caValue* value = circa_input(stack, 2); copy(value, hashtable_insert(out, key, false)); }
void Type__property(caStack* stack) { Type* type = as_type(circa_input(stack, 0)); const char* str = as_cstring(circa_input(stack, 1)); caValue* prop = get_type_property(type, str); if (prop == NULL) set_null(circa_output(stack, 0)); else copy(prop, circa_output(stack, 0)); }
void Dict__set(caStack* stack) { caValue* dict = circa_output(stack, 0); copy(circa_input(stack, 0), dict); const char* key = circa_string_input(stack, 1); caValue* value = circa_input(stack, 2); copy(value, dict_insert(dict, key)); }
void List__set(caStack* stack) { caValue* self = circa_output(stack, 0); copy(circa_input(stack, 0), self); int index = circa_int_input(stack, 1); caValue* value = circa_input(stack, 2); touch(self); copy(value, list_get(self, index)); }
void Map__get(caStack* stack) { caValue* table = circa_input(stack, 0); caValue* key = circa_input(stack, 1); caValue* value = hashtable_get(table, key); if (value == NULL) { std::string msg = "Key not found: " + to_string(key); return circa_output_error(stack, msg.c_str()); } copy(value, circa_output(stack, 0)); }
void Map__insertPairs(caStack* stack) { caValue* out = circa_output(stack, 0); copy(circa_input(stack, 0), out); caValue* pairs = circa_input(stack, 1); for (int i=0; i < list_length(pairs); i++) { caValue* pair = list_get(pairs, i); copy(list_get(pair, 1), hashtable_insert(out, list_get(pair, 0), false)); } }
int main(int argc, char** argv) { caWorld* world = circa_initialize(); circa_load_module_from_file(world, "ClassA", "ClassA.ca"); // circa_dump_b(circa_kernel(world)); caStack* stack = circa_alloc_stack(world); circa_push_function_by_name(stack, "create_ClassA"); circa_run(stack); if (circa_has_error(stack)) circa_print_error_to_stdout(stack); caValue* classA = circa_alloc_value(); circa_move(circa_output(stack, 0), classA); circa_pop(stack); // Dump to stdout circa_push_function_by_name(stack, "ClassA.dump"); circa_copy(classA, circa_input(stack, 0)); circa_run(stack); if (circa_has_error(stack)) circa_print_error_to_stdout(stack); circa_pop(stack); for (int i=0; i < 5; i++) { // Increment circa_push_function_by_name(stack, "ClassA.increment"); circa_copy(classA, circa_input(stack, 0)); circa_run(stack); if (circa_has_error(stack)) circa_print_error_to_stdout(stack); // Using index #1 not 0: circa_move(circa_output(stack, 1), classA); circa_pop(stack); // And dump circa_push_function_by_name(stack, "ClassA.dump"); circa_copy(classA, circa_input(stack, 0)); circa_run(stack); if (circa_has_error(stack)) circa_print_error_to_stdout(stack); circa_pop(stack); } circa_dealloc_value(classA); circa_dealloc_stack(stack); circa_shutdown(world); }
void make_server(Stack* stack) { Value* ip = circa_input(stack, 0); Value* port = circa_input(stack, 1); Value* type = circa_input(stack, 2); Server* server = new Server(); if (circa_string_equals(type, ":tcp")) { server->serverType = TCP; } else if (circa_string_equals(type, ":websock")) { server->serverType = WEBSOCK; memset(&server->parser_settings, 0, sizeof(server->parser_settings)); server->parser_settings.on_message_begin = http_on_message_begin; server->parser_settings.on_url = http_on_url; server->parser_settings.on_status = http_on_status; server->parser_settings.on_header_field = http_on_header_field; server->parser_settings.on_header_value = http_on_header_value; server->parser_settings.on_headers_complete = http_on_headers_complete; server->parser_settings.on_body = http_on_body; server->parser_settings.on_message_complete = http_on_message_complete; } else { Value msg; circa_set_string(&msg, "Unrecognized server type: "); circa_string_append_val(&msg, type); circa_output_error_val(stack, &msg); delete server; return; } uv_loop_t* loop = get_uv_loop(stack->world); circa_set_list(&server->connections, 0); uv_tcp_init(stack->world->libuvWorld->uv_loop, &server->uv_tcp); struct sockaddr_in bind_addr = uv_ip4_addr(circa_string(ip), circa_int(port)); uv_tcp_bind(&server->uv_tcp, bind_addr); int err = uv_listen((uv_stream_t*) &server->uv_tcp, 128, server_on_connect); server->uv_tcp.data = server; if (err) { Value msg; circa_set_string(&msg, "Listen error: "); circa_string_append(&msg, uv_err_name(uv_last_error(loop))); circa_output_error_val(stack, &msg); return; } Value* out = circa_set_default_output(stack, 0); circa_set_native_ptr(circa_index(out, 0), server, ServerRelease); }
void List__extend(caStack* stack) { caValue* out = circa_output(stack, 1); copy(circa_input(stack, 0), out); caValue* additions = circa_input(stack, 1); int oldLength = list_length(out); int additionsLength = list_length(additions); list_resize(out, oldLength + additionsLength); for (int i = 0; i < additionsLength; i++) copy(list_get(additions, i), list_get(out, oldLength + i)); }
void Term__assign(caStack* stack) { Term* target = as_term_ref(circa_input(stack, 0)); if (target == NULL) { circa_output_error(stack, "NULL reference"); return; } caValue* source = circa_input(stack, 1); circa::copy(source, term_value(target)); // Probably should update term->type at this point. }
void List__join(caStack* stack) { caValue* input = circa_input(stack, 0); caValue* joiner = circa_input(stack, 1); caValue* out = circa_output(stack, 0); set_string(out, ""); for (int i=0; i < list_length(input); i++) { if (i != 0) string_append(out, joiner); string_append(out, list_get(input, i)); } }
void Dict__get(caStack* stack) { caValue* dict = circa_input(stack, 0); const char* key = circa_string_input(stack, 1); copy(dict_get(dict, key), circa_output(stack, 0)); }
void Branch__version(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); if (branch == NULL) return circa_output_error(stack, "NULL branch"); set_int(circa_output(stack, 0), branch->version); }
void Term__to_string(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) return circa_output_error(stack, "NULL reference"); set_string(circa_output(stack, 0), circa::to_string(term_value(t))); }
void Term__to_source_string(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) return circa_output_error(stack, "NULL reference"); set_string(circa_output(stack, 0), get_term_source_text(t)); }
void Term__function(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) return circa_output_error(stack, "NULL reference"); set_branch(circa_output(stack, 0), function_contents(as_function(t->function))); }
void Term__type(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) return circa_output_error(stack, "NULL reference"); set_type(circa_output(stack, 0), t->type); }
void Term__properties(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) return circa_output_error(stack, "NULL reference"); circa::copy(&t->properties, circa_output(stack, 0)); }
void List__slice(caStack* stack) { caValue* input = circa_input(stack, 0); int start = circa_int_input(stack, 1); int end = circa_int_input(stack, 2); caValue* output = circa_output(stack, 0); if (start < 0) start = 0; else if (start > list_length(input)) start = list_length(input); if (end > list_length(input)) end = list_length(input); else if (end < 0) end = list_length(input) + end; if (end < start) { set_list(output, 0); return; } int length = end - start; set_list(output, length); for (int i=0; i < length; i++) copy(list_get(input, start + i), list_get(output, i)); }
void load_font(caStack* stack) { caValue* filename = circa_input(stack, 0); FontFace* font = new FontFace(); circa_read_file_with_stack(stack, circa_string(filename), &font->rawData); if (circa_is_null(&font->rawData)) return circa_output_error(stack, "Failed to load file"); if (!g_ftLibraryInitialized) { FT_Init_FreeType(&g_ftLibrary); g_ftLibraryInitialized = true; } int error = FT_New_Memory_Face(g_ftLibrary, (FT_Byte*) circa_blob(&font->rawData), circa_blob_size(&font->rawData), 0, &font->ftFace); if (error) return circa_output_error(stack, "FT_New_Memory_Face failed"); font->cairoFace = cairo_ft_font_face_create_for_ft_face(font->ftFace, 0); caValue* out = circa_set_default_output(stack, 0); circa_set_native_ptr(circa_index(out, 0), font, FontFaceRelease); }
void List__resize(caStack* stack) { caValue* out = circa_output(stack, 0); copy(circa_input(stack, 0), out); int count = circa_int_input(stack, 1); circa_resize(out, count); }
void Branch__format_function_heading(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); caValue* output = circa_output(stack, 0); circa_set_list(output, 0); function_format_header_source(output, branch); }
void dynamic_method_call(caStack* stack) { INCREMENT_STAT(DynamicMethodCall); caValue* args = circa_input(stack, 0); caValue* object = circa_index(args, 0); // Lookup method Term* term = (Term*) circa_caller_term(stack); std::string functionName = term->stringProp("syntax:functionName", ""); // Find and dispatch method Term* method = find_method((Block*) circa_caller_block(stack), (Type*) circa_type_of(object), functionName.c_str()); // copy(object, circa_output(stack, 1)); if (method != NULL) { // Grab inputs before pop Value inputs; swap(args, &inputs); pop_frame(stack); push_frame_with_inputs(stack, function_contents(method), &inputs); return; } // Method not found. Raise error. std::string msg; msg += "Method "; msg += functionName; msg += " not found on type "; msg += as_cstring(&circa_type_of(object)->name); circa_output_error(stack, msg.c_str()); }