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 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 Term__asint(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) { circa_output_error(stack, "NULL reference"); return; } if (!is_int(term_value(t))) { circa_output_error(stack, "Not an int"); return; } set_int(circa_output(stack, 0), as_int(term_value(t))); }
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 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__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 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()); }
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__global_id(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) return circa_output_error(stack, "NULL reference"); set_int(circa_output(stack, 0), t->id); }
void Term__location_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_short_location(t).c_str()); }
void Branch__get_term(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); if (branch == NULL) return circa_output_error(stack, "NULL branch"); int index = circa_int_input(stack, 1); set_term_ref(circa_output(stack, 0), branch->get(index)); }
void Term__num_inputs(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) { circa_output_error(stack, "NULL reference"); return; } set_int(circa_output(stack, 0), t->numInputs()); }
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 Term__contents(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) { circa_output_error(stack, "NULL reference"); return; } set_branch(circa_output(stack, 0), t->nestedContents); }
void Term__parent(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) { circa_output_error(stack, "NULL reference"); return; } set_branch(circa_output(stack, 0), t->owningBranch); }
void Branch__find_term(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); if (branch == NULL) return circa_output_error(stack, "NULL branch"); Term* term = branch->get(circa_string_input(stack, 1)); set_term_ref(circa_output(stack, 0), term); }
void Term__value(caStack* stack) { Term* target = as_term_ref(circa_input(stack, 0)); if (target == NULL) { circa_output_error(stack, "NULL reference"); return; } copy(term_value(target), circa_output(stack, 0)); }
void Term__asfloat(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) { circa_output_error(stack, "NULL reference"); return; } set_float(circa_output(stack, 0), to_float(term_value(t))); }
void Term__source_location(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) return circa_output_error(stack, "NULL reference"); circa_set_vec4(circa_output(stack, 0), t->sourceLoc.col, t->sourceLoc.line, t->sourceLoc.colEnd, t->sourceLoc.lineEnd); }
void hosted_get_index(caStack* stack) { caValue* list = circa_input(stack, 0); int index = circa_int_input(stack, 1); if (index < 0) { char indexStr[40]; sprintf(indexStr, "Negative index: %d", index); return circa_output_error(stack, indexStr); } else if (index >= list_length(list)) { char indexStr[40]; sprintf(indexStr, "Index out of range: %d", index); return circa_output_error(stack, indexStr); } caValue* result = get_index(list, index); copy(result, circa_output(stack, 0)); cast(circa_output(stack, 0), declared_type((Term*) circa_caller_term(stack))); }
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 Term__inputs(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) return circa_output_error(stack, "NULL reference"); caValue* output = circa_output(stack, 0); circa_set_list(output, t->numInputs()); for (int i=0; i < t->numInputs(); i++) set_term_ref(circa_index(output, i), t->input(i)); }
void Branch__terms(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); if (branch == NULL) return circa_output_error(stack, "NULL branch"); caValue* out = circa_output(stack, 0); set_list(out, branch->length()); for (int i=0; i < branch->length(); i++) set_term_ref(circa_index(out, i), branch->get(i)); }
void String__substr(caStack* stack) { int start = circa_int_input(stack, 1); int end = circa_int_input(stack, 2); std::string const& s = as_string(circa_input(stack, 0)); if (start < 0) return circa_output_error(stack, "Negative index"); if (end < 0) return circa_output_error(stack, "Negative index"); if ((unsigned) start > s.length()) { std::stringstream msg; msg << "Start index is too high: " << start; return circa_output_error(stack, msg.str().c_str()); } if ((unsigned) (start+end) > s.length()) { std::stringstream msg; msg << "End index is too high: " << start; return circa_output_error(stack, msg.str().c_str()); } set_string(circa_output(stack, 0), s.substr(start, end)); }
void Term__input(caStack* stack) { Term* t = as_term_ref(circa_input(stack, 0)); if (t == NULL) { circa_output_error(stack, "NULL reference"); return; } int index = circa_int_input(stack, 1); if (index >= t->numInputs()) set_term_ref(circa_output(stack, 0), NULL); else set_term_ref(circa_output(stack, 0), t->input(index)); }
void send_func(caStack* stack) { #if 0 // actorList disabled const char* actorSymbol = circa_string_input(stack, 0); caValue* msg = circa_input(stack, 1); if (stack->world == NULL) { circa_output_error(stack, "Stack was not created with World"); return; } ListData* actor = find_actor(stack->world, actorName); if (actor == NULL) { std::string msg = "Actor not found: "; msg += actorName; circa_output_error(stack, msg.c_str()); return; } actor_send_message(actor, msg); #endif }
void call_actor_func(caStack* stack) { #if 0 // actorList disabled const char* actorSymbol = circa_string_input(stack, 0); caValue* msg = circa_input(stack, 1); if (stack->world == NULL) { circa_output_error(stack, "Stack was not created with World"); return; } circa_actor_run_message(stack->world, actorName, msg); #endif }
void evaluate_f_range(caStack* stack) { seed_if_needed(); float r = (float) rand() / RAND_MAX; float min = circa_float_input(stack, 0); float max = circa_float_input(stack, 1); if (min >= max) { circa_output_error(stack, "min is >= max"); return; } set_float(circa_output(stack, 0), min + r * (max - min)); }