Term* start_building_for_loop(Term* forTerm, const char* iteratorName, Type* iteratorType) { Branch* contents = nested_contents(forTerm); // Add input placeholder for the list input Term* listInput = apply(contents, FUNCS.input, TermList()); // Add loop_index() Term* index = apply(contents, FUNCS.loop_index, TermList(listInput)); hide_from_source(index); // Add get_index to fetch the list's current element. Term* iterator = apply(contents, FUNCS.get_index, TermList(listInput, index), name_from_string(iteratorName)); if (iteratorType == NULL) iteratorType = infer_type_of_get_index(forTerm->input(0)); change_declared_type(iterator, iteratorType); hide_from_source(iterator); // Add the zero branch create_branch_unevaluated(contents, "#zero"); // Add an loop output index Term* loopOutputIndex = apply(contents, FUNCS.loop_output_index, TermList()); return iterator; }
void modify_branch_so_that_state_access_is_indexed(Branch* branch, int index) { Term* stateInput = find_state_input(branch); if (stateInput == NULL) return; // If the state output is connected directly to state input, then do nothing. Term* stateOutput = find_state_output(branch); if (stateOutput->input(0) == stateInput) return; Term* unpackList = apply(branch, FUNCS.unpack_state_from_list, TermList(stateInput)); unpackList->setIntProp("index", index); move_after_inputs(unpackList); for (int i=0; i < stateInput->users.length(); i++) { Term* term = stateInput->users[i]; if (term == unpackList) continue; remap_pointers_quick(term, stateInput, unpackList); } Term* stateResult = stateOutput->input(0); ca_assert(stateResult != NULL); Term* packList = apply(branch, FUNCS.pack_state_to_list, TermList(stateInput, stateResult)); packList->setIntProp("index", index); packList->setBoolProp("final", true); set_input(stateOutput, 0, packList); move_after(packList, stateResult); }
// equality constructor // 09/05/2002 Manchester Atom::Data::Data (const Term& l, const Term& r) : _counter (1), _functor (sig->equality()), _args (TermList (l, TermList(r))) { } // Atom::Data::Data (const Term& l, const Term& r)
void finish_for_loop(Term* forTerm) { Branch* contents = nested_contents(forTerm); // Add a 'loop_output' term that will collect each iteration's output. Term* loopOutput = apply(contents, FUNCS.loop_output, TermList(loop_get_primary_result(contents))); // Add a primary output apply(contents, FUNCS.output, TermList(loopOutput)); // pack_any_open_state_vars(contents); for_loop_fix_state_input(contents); check_to_add_state_output_placeholder(contents); add_implicit_placeholders(forTerm); repoint_terms_to_use_input_placeholders(contents); check_to_insert_implicit_inputs(forTerm); update_extra_outputs(forTerm); loop_update_exit_points(contents); set_branch_in_progress(contents, false); }
Polynomial::Polynomial(double coef, unsigned exp) { if (coef == 0.0) { // the "zero polynomial"has degree -1 _terms = TermList(0); _degree = -1; } else { _terms = TermList(1, Term(coef, exp)); _degree = exp; } }
void for_loop_fix_state_input(Branch* contents) { // This function will look at the state access inside for-loop contents. // If there's state, the default building functions will have created // terms that look like this: // // input() :state -> unpack_state -> pack_state -> output() :state // // We want each loop iteration to have its own state container. So we'll // insert pack/unpack_state_list_n terms so that each iteration accesses // state from a list. The result will look like: // // input() :state -> unpack_state_list_n(index) -> unpack_state -> pack_state // -> pack_state_list_n(index) -> output() :state // First insert the unpack_state_list_n call Term* stateInput = find_state_input(contents); // Nothing to do if there's no state input if (stateInput == NULL) return; // Nothing to do if unpack_state_list_n term already exists if (find_user_with_function(stateInput, FUNCS.unpack_state_list_n) != NULL) return; Term* unpackState = find_user_with_function(stateInput, FUNCS.unpack_state); ca_assert(unpackState != NULL); Term* index = for_loop_find_index(contents); Term* unpackStateList = apply(contents, FUNCS.unpack_state_list_n, TermList(stateInput, index)); transfer_users(stateInput, unpackStateList); move_before(unpackStateList, unpackState); set_input(unpackState, 0, unpackStateList); // Now insert the pack_state_list_n call Term* stateResult = find_open_state_result(contents, contents->length()); Term* packStateList = apply(contents, FUNCS.pack_state_list_n, TermList(stateInput, stateResult, index)); packStateList->setBoolProp("final", true); move_after(packStateList, stateResult); // Make sure the state output uses this result Term* stateOutput = append_state_output(contents); set_input(stateOutput, 0, packStateList); }
void add_implicit_placeholders(Term* forTerm) { Branch* contents = nested_contents(forTerm); std::string listName = forTerm->input(0)->name; Term* iterator = for_loop_get_iterator(contents); std::string iteratorName = iterator->name; std::vector<std::string> reboundNames; list_names_that_this_branch_rebinds(contents, reboundNames); int inputIndex = 1; for (size_t i=0; i < reboundNames.size(); i++) { std::string const& name = reboundNames[i]; if (name == listName) continue; if (name == iteratorName) continue; Term* original = find_name_at(forTerm, name.c_str()); // The name might not be found, for certain parser errors. if (original == NULL) continue; Term* result = contents->get(name); // Create input_placeholder Term* input = apply(contents, FUNCS.input, TermList(), name_from_string(name)); Type* type = find_common_type(original->type, result->type); change_declared_type(input, type); contents->move(input, inputIndex); set_input(forTerm, inputIndex, original); // Repoint terms to use our new input_placeholder for (BranchIterator it(contents); it.unfinished(); it.advance()) remap_pointers_quick(*it, original, input); // Create output_placeholder Term* term = apply(contents, FUNCS.output, TermList(result), name_from_string(name)); // Move output into the correct output slot contents->move(term, contents->length() - 1 - inputIndex); inputIndex++; } }
void erase_term(Term* term) { pre_erase_term(term); set_null(term_value(term)); set_inputs(term, TermList()); change_function(term, NULL); term->type = NULL; remove_nested_contents(term); // for each user, clear that user's input list of this term remove_from_any_user_lists(term); clear_from_dependencies_of_users(term); if (term->owningBlock != NULL) { // remove name binding if necessary term->owningBlock->removeNameBinding(term); // index may be invalid if something bad has happened ca_assert(term->index < term->owningBlock->length()); term->owningBlock->_terms.setAt(term->index, NULL); term->owningBlock = NULL; term->index = -1; } dealloc_term(term); }
void load_script(Block* block, const char* filename) { // Store the filename set_string(block_insert_property(block, s_filename), filename); // Read the text file circa::Value contents; circa_read_file(block->world, filename, &contents); if (is_null(&contents)) { Value msg; set_string(&msg, "File not found: "); string_append(&msg, filename); Term* term = create_string(block, as_cstring(&msg)); apply(block, FUNCS.error, TermList(term)); return; } parse(block, parse_statement_list, &contents); // Make sure the block has a primary output. if (get_output_placeholder(block, 0) == NULL) append_output_placeholder(block, NULL); update_static_error_list(block); return; }
void insert_looped_placeholders(Block* contents) { Value names; list_names_that_must_be_looped(contents, &names); for (ListIterator it(&names); it; ++it) { Term* inputPlaceholder = append_input_placeholder(contents); Value* name = it.value(); rename(inputPlaceholder, name); Value owningTermVal; owningTermVal.set_term(contents->owningTerm); Term* outsideTerm = find_name_at(&owningTermVal, name); Term* innerResult = find_local_name(contents, name); Term* outputPlaceholder = append_output_placeholder(contents, innerResult); rename(outputPlaceholder, name); set_inputs(inputPlaceholder, TermList(outsideTerm, outputPlaceholder)); for (BlockInputIterator it(contents); it; ++it) { Term* term = it.currentTerm(); if (it.currentInput() == outsideTerm && term != inputPlaceholder) set_input(term, it.currentInputIndex(), inputPlaceholder); } } }
Block* load_script_term(Block* block, const char* filename) { ca_assert(block != NULL); Term* filenameTerm = create_string(block, filename); Term* includeFunc = apply(block, FUNCS.load_script, TermList(filenameTerm)); return nested_contents(includeFunc); }
Term* if_block_append_case(Term* ifBlock, Term* input) { Branch* contents = nested_contents(ifBlock); int insertPos = 0; for (int i=0; i < contents->length(); i++) { Term* term = contents->get(i); if (term->function == FUNCS.input) insertPos = term->index + 1; // Insert position is right after the last non-default case. if (term->function == FUNCS.case_func && term->input(0) != NULL) insertPos = term->index + 1; } Term* newCase = apply(contents, FUNCS.case_func, TermList(input)); contents->move(newCase, insertPos); // Add existing input placeholders to this case for (int i=0;; i++) { Term* placeholder = get_input_placeholder(contents, i); if (placeholder == NULL) break; Term* localPlaceholder = append_input_placeholder(nested_contents(newCase)); change_declared_type(localPlaceholder, placeholder->type); } return newCase; }
void finish_for_loop(Term* forTerm) { Branch* contents = nested_contents(forTerm); // Need to finish here to prevent error branch_finish_changes(contents); // Add a a primary output Term* primaryOutput = apply(contents, FUNCS.output, TermList(loop_get_primary_result(contents))); primaryOutput->setBoolProp("accumulatingOutput", true); respecialize_type(primaryOutput); // pack_any_open_state_vars(contents); for_loop_fix_state_input(contents); check_to_add_state_output_placeholder(contents); add_implicit_placeholders(forTerm); repoint_terms_to_use_input_placeholders(contents); check_to_insert_implicit_inputs(forTerm); update_extra_outputs(forTerm); branch_finish_changes(contents); }
void finish_while_loop(Term* whileTerm) { Branch* branch = nested_contents(whileTerm); // Append a call to unbounded_loop_finish() Term* term = apply(branch, FUNCS.unbounded_loop_finish, TermList()); move_before_outputs(term); }
Term* start_building_for_loop(Term* forTerm, const char* iteratorName) { Branch* contents = nested_contents(forTerm); // Add input placeholder for the list input Term* listInput = apply(contents, FUNCS.input, TermList()); // Add loop_index() Term* index = apply(contents, FUNCS.loop_index, TermList(listInput)); hide_from_source(index); // Add loop_iterator() Term* iterator = apply(contents, FUNCS.get_index, TermList(listInput, index), iteratorName); change_declared_type(iterator, infer_type_of_get_index(forTerm->input(0))); hide_from_source(iterator); return iterator; }
int main(void) { Menu menu; List list; InitList(&list); do { Data x; switch (menu = SelectMenu()) { case InsFront: x = Read("先頭に挿入", NO | NAME); InsertFront(&list, x); break; case InsRear: x = Read("末尾に挿入", NO | NAME); InsertRear(&list, x); break; case RmvFront: RemoveFront(&list); break; case RmvRear: RemoveRear(&list); break; case PrintCrnt: PrintCrntNode(&list); break; case RmvCrnt: RemoveCrnt(&list); break; case SrchNo: x = Read("探索", NO); if (SearchNode(&list, x, NoEqual) != NULL){ PrintCrntNode(&list); } break; case SrchName: x = Read("探索", NAME); if(SearchNode(&list, x, NameEqual) != NULL){ PrintCrntNode(&list); } break; case PrintAll: PrintList(&list); break; case Clear: ClearList(&list); break; } } while (menu != Term); TermList(&list); return (0); }
void if_block_finish_appended_case(Term* ifBlock, Term* caseTerm) { if_block_fix_outer_pointers(ifBlock, nested_contents(caseTerm)); // Add an output placeholder apply(nested_contents(caseTerm), FUNCS.output, TermList(find_last_non_comment_expression(nested_contents(caseTerm)))); //std::cout << "finished appended case.." << std::endl; }
void do_write_block(caValue* blockName, caValue* contents, caValue* reply) { Term* term = find_global(as_cstring(blockName)); // Create the block if needed if (term == NULL) term = apply(global_root_block(), FUNCS.section_block, TermList(), blockName); // Import the new block contents Block* block = nested_contents(term); rewrite_block(block, contents, reply); }
Term* statically_infer_length_func(Block* block, Term* term) { Term* input = term->input(0); if (input->function == FUNCS.copy) return statically_infer_length_func(block, input->input(0)); if (input->function == FUNCS.list) return create_int(block, input->numInputs()); if (input->function == FUNCS.list_append) { Term* leftLength = apply(block, FUNCS.length, TermList(input->input(0))); return apply(block, FUNCS.add, TermList( statically_infer_length_func(block, leftLength), create_int(block, 1))); } // Give up std::cout << "statically_infer_length_func didn't understand: " << input->function->name << std::endl; return create_string(block, "unknown"); }
Term* statically_infer_length_func(Branch* branch, Term* term) { Term* input = term->input(0); if (input->function == FUNCS.copy) return statically_infer_length_func(branch, input->input(0)); if (input->function == FUNCS.list) return create_int(branch, input->numInputs()); if (input->function == LIST_APPEND_FUNC) { Term* leftLength = apply(branch, FUNCS.length, TermList(input->input(0))); return apply(branch, FUNCS.add, TermList( statically_infer_length_func(branch, leftLength), create_int(branch, 1))); } // Give up std::cout << "statically_infer_length_func didn't understand: " << input->function->name << std::endl; return create_symbol_value(branch, name_Unknown); }
void start_building_for_loop(Block* contents, Term* listExpr, Value* indexName, Value* elementName, Type* iteratorType) { Term* iterator = apply(contents, FUNCS.loop_iterator, TermList(listExpr)); Term* done = apply_dynamic_method(contents, s_done, TermList(iterator)); hide_from_source(done); Term* getKey = apply_dynamic_method(contents, s_key, TermList(iterator)); hide_from_source(getKey); if (!is_null(indexName)) { Term* getIndex = apply_dynamic_method(contents, s_key, TermList(iterator), indexName); hide_from_source(getIndex); } Term* getCurrent = apply_dynamic_method(contents, s_current, TermList(iterator), elementName); getCurrent->setBoolProp(s_iterator_value, true); hide_from_source(getCurrent); if (iteratorType != NULL) { Term* castedValue = apply(contents, FUNCS.cast, TermList(getCurrent, iteratorType->declaringTerm), elementName); } }
Term* rebind_possible_accessor(Branch* branch, Term* accessor, Term* result) { // Check if this isn't a recognized accessor. if (!has_empty_name(accessor)) { // Just create a named copy of 'result'. return apply(branch, FUNCS.copy, TermList(result), accessor->nameSymbol); } TermList accessorChain; trace_accessor_chain(accessor, &accessorChain); Term* head = accessorChain[0]; // Create the selector Term* selector = write_selector_for_accessor_chain(branch, &accessorChain); Term* set = apply(branch, FUNCS.set_with_selector, TermList(head, selector, result), head->nameSymbol); change_declared_type(set, declared_type(head)); return set; }
void generate_source_for_function_calls() { Branch branch; Term* a = create_int(&branch, 5, "a"); Term* b = create_int(&branch, 9, "b"); Term* c = apply(&branch, "add", TermList(a,b)); test_assert(should_print_term_source_line(a)); test_assert(should_print_term_source_line(b)); test_assert(should_print_term_source_line(c)); test_equals(get_branch_source_text(&branch), "a = 5\nb = 9\nadd(a, b)"); // Same test with anonymous values branch.clear(); Term* d = create_int(&branch, 3); Term* e = create_int(&branch, 4); /*Term* f =*/ apply(&branch, "add", TermList(d,e)); /* TODO, fix this test_assert(!should_print_term_source_line(d)); test_assert(!should_print_term_source_line(e)); test_assert(should_print_term_source_line(f)); test_equals(get_branch_source_text(branch), "add(3, 4)"); // Do a test where some calls are parser-created, and then user-created calls // are added. branch.clear(); branch.compile("a = 1"); branch.compile("b = 2"); a = create_int(branch, 3, "c"); b = create_int(branch, 4, "d"); apply(branch, "add", TermList(a,b)); test_equals(get_branch_source_text(branch), "a = 1\nb = 2\nc = 3\nd = 4\nadd(c, d)"); */ }
void finish_while_loop(Block* block) { block_finish_changes(block); // Add a a primary output apply(block, FUNCS.output, TermList(NULL)); // Add looped_inputs insert_looped_placeholders(block); update_extra_outputs(block->owningTerm, block); update_for_control_flow(block); block_finish_changes(block); }
void finish_for_loop(Term* forTerm) { Block* block = nested_contents(forTerm); // Need to finish here to prevent error block_finish_changes(block); Term* primaryResult = loop_get_primary_result(block); Term* iterator = loop_find_iterator(block); Term* nextCall = apply_dynamic_method(block, s_advance, TermList(iterator)); hide_from_source(nextCall); // Add a a primary output Term* primaryOutput = apply(block, FUNCS.output, TermList(primaryResult)); primaryOutput->setBoolProp(s_AccumulatingOutput, true); // TODO: can delete? respecialize_type(primaryOutput); insert_looped_placeholders(block); update_extra_outputs(forTerm, block); block_finish_changes(block); }
void clear_block(Block* block) { block->names.clear(); block->inProgress = false; // Iterate through the block and tear down any term references, so that we // don't have to worry about stale pointers later. for (BlockIterator it(block); it; ++it) { if (*it == NULL) continue; pre_erase_term(*it); set_inputs(*it, TermList()); remove_from_any_user_lists(*it); change_function(*it, NULL); } for (int i= block->_terms.length() - 1; i >= 0; i--) { Term* term = block->get(i); if (term == NULL) continue; if (term->nestedContents) clear_block(term->nestedContents); } for (int i = block->_terms.length() - 1; i >= 0; i--) { Term* term = block->get(i); if (term == NULL) continue; // Delete any leftover users, mark them as repairable. for (int userIndex = 0; userIndex < term->users.length(); userIndex++) { Term* user = term->users[userIndex]; for (int depIndex = 0; depIndex < user->numDependencies(); depIndex++) { if (user->dependency(depIndex) == term) { // mark_repairable_link(user, term->name, depIndex); user->setDependency(depIndex, NULL); } } } erase_term(term); } block->_terms.clear(); }
// normalize the atom // 29/08/2002 Torrevieja, changed void Atom::normalize () { if ( ! isEquality() ) { return; } // equality TermList as (args()); Term l (as.head()); Term r (as.second()); if (l.compare(r) == LESS) { TermList newAs (r, TermList (l)); Atom newAtom (functor(), newAs); *this = newAtom; } } // Atom::normalize
void pack_any_open_state_vars(Branch* branch) { for (int i=0; i < branch->length(); i++) { Term* term = branch->get(i); if (term == NULL) continue; if (term->function == FUNCS.declared_state) { Term* result = branch->get(term->name); // If this result already has a pack_state() term then leave it alone. if (find_user_with_function(result, FUNCS.pack_state) != NULL) continue; Term* pack = apply(branch, FUNCS.pack_state, TermList( find_open_state_result(branch, branch->length()), result, term)); pack->setStringProp("field", unique_name(term)); branch->move(pack, result->index + 1); } } }
/*--- メイン ---*/ int main(void) { Menu menu; Node *list; InitList(&list); do { Node x; int n; char name[NAMELEN]; switch (menu = SelectMenu()) { case Insert: x = Read("挿入"); InsertNode(&list, x.no, x.name); break; case InsertNth: x = Read("挿入"); printf("何番目? "); scanf("%d", &n); InsertNodeNth(&list, n, x.no, x.name); break; case Append: x = Read("挿入"); AppendNode(&list, x.no, x.name); break; case Delete: DeleteNode(&list); break; case DeleteNth: printf("何番目? "); scanf("%d", &n); DeleteNodeNth(&list, n); break; case Clear: ClearList(&list); break; case Print: PrintList(&list); break; } } while (menu != Term); TermList(&list); return (0); }
void bootstrap_kernel() { // First, instanciate the types that are used by Type. TYPES.dict = create_type_uninitialized(); TYPES.null = create_type_uninitialized(); TYPES.string = create_type_uninitialized(); TYPES.type = create_type_uninitialized(); initialize_type(TYPES.dict); initialize_type(TYPES.null); initialize_type(TYPES.string); initialize_type(TYPES.type); string_setup_type(TYPES.string); // Initialize remaining global types. TYPES.any = create_type(); TYPES.block = create_type(); TYPES.bool_type = create_type(); TYPES.error = create_type(); TYPES.eval_context = create_type(); TYPES.float_type = create_type(); TYPES.function = create_type(); TYPES.int_type = create_type(); TYPES.list = create_type(); TYPES.map = create_type(); TYPES.opaque_pointer = create_type(); TYPES.symbol = create_type(); TYPES.term = create_type(); TYPES.void_type = create_type(); any_t::setup_type(TYPES.any); block_setup_type(TYPES.block); bool_t::setup_type(TYPES.bool_type); dict_t::setup_type(TYPES.dict); eval_context_t::setup_type(TYPES.eval_context); function_t::setup_type(TYPES.function); hashtable_setup_type(TYPES.map); int_t::setup_type(TYPES.int_type); list_t::setup_type(TYPES.list); symbol_setup_type(TYPES.symbol); null_t::setup_type(TYPES.null); number_t::setup_type(TYPES.float_type); opaque_pointer_t::setup_type(TYPES.opaque_pointer); term_setup_type(TYPES.term); string_setup_type(TYPES.error); // errors are just stored as strings for now type_t::setup_type(TYPES.type); void_t::setup_type(TYPES.void_type); // Start building World g_world = alloc_world(); g_world->bootstrapStatus = sym_Bootstrapping; // Create root Block. g_world->root = new Block(); Block* kernel = g_world->root; // Create value function Term* valueFunc = kernel->appendNew(); rename(valueFunc, "value"); FUNCS.value = valueFunc; // Create Type type Term* typeType = kernel->appendNew(); typeType->function = FUNCS.value; typeType->type = TYPES.type; term_value(typeType)->value_type = TYPES.type; term_value(typeType)->value_data.ptr = TYPES.type; TYPES.type->declaringTerm = typeType; rename(typeType, "Type"); // Create Any type Term* anyType = kernel->appendNew(); anyType->function = valueFunc; anyType->type = TYPES.type; term_value(anyType)->value_type = TYPES.type; term_value(anyType)->value_data.ptr = TYPES.any; TYPES.any->declaringTerm = anyType; rename(anyType, "any"); // Create Function type Term* functionType = kernel->appendNew(); functionType->function = valueFunc; functionType->type = TYPES.type; TYPES.function->declaringTerm = functionType; term_value(functionType)->value_type = TYPES.type; term_value(functionType)->value_data.ptr = TYPES.function; rename(functionType, "Function"); // Initialize value() func valueFunc->type = TYPES.function; valueFunc->function = valueFunc; make(TYPES.function, term_value(valueFunc)); function_t::initialize(TYPES.function, term_value(valueFunc)); initialize_function(valueFunc); as_function(valueFunc)->name = "value"; block_set_evaluation_empty(function_contents(valueFunc), true); // Initialize primitive types (this requires value() function) create_type_value(kernel, TYPES.bool_type, "bool"); create_type_value(kernel, TYPES.block, "Block"); create_type_value(kernel, TYPES.dict, "Dict"); create_type_value(kernel, TYPES.float_type, "number"); create_type_value(kernel, TYPES.int_type, "int"); create_type_value(kernel, TYPES.list, "List"); create_type_value(kernel, TYPES.opaque_pointer, "opaque_pointer"); create_type_value(kernel, TYPES.string, "String"); create_type_value(kernel, TYPES.symbol, "Symbol"); create_type_value(kernel, TYPES.term, "Term"); create_type_value(kernel, TYPES.void_type, "void"); create_type_value(kernel, TYPES.map, "Map"); // Finish initializing World (this requires List and Hashtable types) world_initialize(g_world); // Create global symbol table (requires Hashtable type) symbol_initialize_global_table(); // Setup output_placeholder() function, needed to declare functions properly. FUNCS.output = create_value(kernel, TYPES.function, "output_placeholder"); function_t::initialize(TYPES.function, term_value(FUNCS.output)); initialize_function(FUNCS.output); as_function(FUNCS.output)->name = "output_placeholder"; as_function(FUNCS.output)->evaluate = NULL; as_function(FUNCS.output)->specializeType = output_placeholder_specializeType; ca_assert(function_get_output_type(FUNCS.output, 0) == TYPES.any); // Fix some holes in value() function { Function* attrs = as_function(valueFunc); Term* output = append_output_placeholder(function_contents(attrs), NULL); change_declared_type(output, TYPES.any); finish_building_function(function_contents(attrs)); } ca_assert(function_get_output_type(valueFunc, 0) == TYPES.any); // input_placeholder() is needed before we can declare a function with inputs FUNCS.input = import_function(kernel, NULL, "input_placeholder() -> any"); block_set_evaluation_empty(function_contents(FUNCS.input), true); // Now that we have input_placeholder() let's declare one input on output_placeholder() apply(function_contents(as_function(FUNCS.output)), FUNCS.input, TermList())->setBoolProp("optional", true); namespace_function::early_setup(kernel); // Setup declare_field() function, needed to represent compound types. FUNCS.declare_field = import_function(kernel, NULL, "declare_field() -> any"); // Initialize a few more types Term* set_type = create_value(kernel, TYPES.type, "Set"); set_t::setup_type(unbox_type(set_type)); Term* indexableType = create_value(kernel, TYPES.type, "Indexable"); indexable_t::setup_type(unbox_type(indexableType)); TYPES.selector = unbox_type(create_value(kernel, TYPES.type, "Selector")); list_t::setup_type(TYPES.selector); control_flow_setup_funcs(kernel); selector_setup_funcs(kernel); loop_setup_functions(kernel); // Setup all the builtin functions defined in src/functions setup_builtin_functions(kernel); FUNCS.section_block = import_function(kernel, NULL, "def section_block() -> any"); as_function(FUNCS.section_block)->formatSource = section_block_formatSource; // Create IMPLICIT_TYPES (deprecated) type_initialize_kernel(kernel); // Now we can build derived functions // Create overloaded functions FUNCS.add = create_overloaded_function(kernel, "add(any a,any b) -> any"); append_to_overloaded_function(FUNCS.add, FUNCS.add_i); append_to_overloaded_function(FUNCS.add, FUNCS.add_f); Term* less_than = create_overloaded_function(kernel, "less_than(any a,any b) -> bool"); append_to_overloaded_function(less_than, kernel->get("less_than_i")); append_to_overloaded_function(less_than, kernel->get("less_than_f")); Term* less_than_eq = create_overloaded_function(kernel, "less_than_eq(any a,any b) -> bool"); append_to_overloaded_function(less_than_eq, kernel->get("less_than_eq_i")); append_to_overloaded_function(less_than_eq, kernel->get("less_than_eq_f")); Term* greater_than = create_overloaded_function(kernel, "greater_than(any a,any b) -> bool"); append_to_overloaded_function(greater_than, kernel->get("greater_than_i")); append_to_overloaded_function(greater_than, kernel->get("greater_than_f")); Term* greater_than_eq = create_overloaded_function(kernel, "greater_than_eq(any a,any b) -> bool"); append_to_overloaded_function(greater_than_eq, kernel->get("greater_than_eq_i")); append_to_overloaded_function(greater_than_eq, kernel->get("greater_than_eq_f")); Term* max_func = create_overloaded_function(kernel, "max(any a,any b) -> any"); append_to_overloaded_function(max_func, kernel->get("max_i")); append_to_overloaded_function(max_func, kernel->get("max_f")); Term* min_func = create_overloaded_function(kernel, "min(any a,any b) -> any"); append_to_overloaded_function(min_func, kernel->get("min_i")); append_to_overloaded_function(min_func, kernel->get("min_f")); Term* remainder_func = create_overloaded_function(kernel, "remainder(any a,any b) -> any"); append_to_overloaded_function(remainder_func, kernel->get("remainder_i")); append_to_overloaded_function(remainder_func, kernel->get("remainder_f")); Term* mod_func = create_overloaded_function(kernel, "mod(any a,any b) -> any"); append_to_overloaded_function(mod_func, kernel->get("mod_i")); append_to_overloaded_function(mod_func, kernel->get("mod_f")); FUNCS.mult = create_overloaded_function(kernel, "mult(any a,any b) -> any"); append_to_overloaded_function(FUNCS.mult, kernel->get("mult_i")); append_to_overloaded_function(FUNCS.mult, kernel->get("mult_f")); FUNCS.neg = create_overloaded_function(kernel, "neg(any n) -> any"); append_to_overloaded_function(FUNCS.neg, kernel->get("neg_i")); append_to_overloaded_function(FUNCS.neg, kernel->get("neg_f")); as_function(FUNCS.neg)->formatSource = neg_function::formatSource; FUNCS.sub = create_overloaded_function(kernel, "sub(any a,any b) -> any"); append_to_overloaded_function(FUNCS.sub, kernel->get("sub_i")); append_to_overloaded_function(FUNCS.sub, kernel->get("sub_f")); // Create vectorized functions Term* add_v = create_function(kernel, "add_v"); create_function_vectorized_vv(function_contents(add_v), FUNCS.add, TYPES.list, TYPES.list); Term* add_s = create_function(kernel, "add_s"); create_function_vectorized_vs(function_contents(add_s), FUNCS.add, TYPES.list, TYPES.any); append_to_overloaded_function(FUNCS.add, add_v); append_to_overloaded_function(FUNCS.add, add_s); Term* sub_v = create_function(kernel, "sub_v"); create_function_vectorized_vv(function_contents(sub_v), FUNCS.sub, TYPES.list, TYPES.list); Term* sub_s = create_function(kernel, "sub_s"); create_function_vectorized_vs(function_contents(sub_s), FUNCS.sub, TYPES.list, TYPES.any); append_to_overloaded_function(FUNCS.sub, sub_v); append_to_overloaded_function(FUNCS.sub, sub_s); // Create vectorized mult() functions Term* mult_v = create_function(kernel, "mult_v"); create_function_vectorized_vv(function_contents(mult_v), FUNCS.mult, TYPES.list, TYPES.list); Term* mult_s = create_function(kernel, "mult_s"); create_function_vectorized_vs(function_contents(mult_s), FUNCS.mult, TYPES.list, TYPES.any); append_to_overloaded_function(FUNCS.mult, mult_v); append_to_overloaded_function(FUNCS.mult, mult_s); Term* div_s = create_function(kernel, "div_s"); create_function_vectorized_vs(function_contents(div_s), FUNCS.div, TYPES.list, TYPES.any); // Need dynamic_method before any hosted functions FUNCS.dynamic_method = import_function(kernel, dynamic_method_call, "def dynamic_method(any inputs :multiple) -> any"); // Load the standard library from stdlib.ca parser::compile(kernel, parser::statement_list, STDLIB_CA_TEXT); // Install C functions static const ImportRecord records[] = { {"assert", hosted_assert}, {"cppbuild:build_module", cppbuild_function::build_module}, {"file:version", file__version}, {"file:exists", file__exists}, {"file:read_text", file__read_text}, {"length", length}, {"from_string", from_string}, {"to_string_repr", to_string_repr}, {"call_actor", call_actor_func}, {"send", send_func}, {"test_spy", test_spy}, {"test_oracle", test_oracle}, {"refactor:rename", refactor__rename}, {"refactor:change_function", refactor__change_function}, {"reflect:this_block", reflect__this_block}, {"reflect:kernel", reflect__kernel}, {"sys:module_search_paths", sys__module_search_paths}, {"sys:perf_stats_reset", sys__perf_stats_reset}, {"sys:perf_stats_dump", sys__perf_stats_dump}, {"Dict.count", Dict__count}, {"Dict.get", Dict__get}, {"Dict.set", Dict__set}, {"Function.block", Function__block}, {"empty_list", empty_list}, {"List.append", List__append}, {"List.concat", List__concat}, {"List.resize", List__resize}, {"List.count", List__count}, {"List.insert", List__insert}, {"List.length", List__length}, {"List.join", List__join}, {"List.slice", List__slice}, {"List.get", List__get}, {"List.set", List__set}, {"Map.contains", Map__contains}, {"Map.remove", Map__remove}, {"Map.get", Map__get}, {"Map.set", Map__set}, {"Map.insertPairs", Map__insertPairs}, {"Mutable.get", Mutable__get}, {"Mutable.set", Mutable__set}, {"String.char_at", String__char_at}, {"String.ends_with", String__ends_with}, {"String.length", String__length}, {"String.substr", String__substr}, {"String.slice", String__slice}, {"String.starts_with", String__starts_with}, {"String.split", String__split}, {"String.to_camel_case", String__to_camel_case}, {"String.to_upper", String__to_upper}, {"String.to_lower", String__to_lower}, {"Type.name", Type__name}, {"Type.property", Type__property}, {"Type.declaringTerm", Type__declaringTerm}, {"type", typeof_func}, {"static_type", static_type_func}, {NULL, NULL} }; install_function_list(kernel, records); closures_install_functions(kernel); modules_install_functions(kernel); reflection_install_functions(kernel); interpreter_install_functions(kernel); // Fetch refereneces to certain builtin funcs. FUNCS.block_dynamic_call = kernel->get("Block.call"); FUNCS.dll_patch = kernel->get("sys:dll_patch"); FUNCS.dynamic_call = kernel->get("dynamic_call"); FUNCS.has_effects = kernel->get("has_effects"); FUNCS.length = kernel->get("length"); FUNCS.list_append = kernel->get("List.append"); FUNCS.native_patch = kernel->get("native_patch"); FUNCS.not_func = kernel->get("not"); FUNCS.output_explicit = kernel->get("output"); FUNCS.type = kernel->get("type"); block_set_has_effects(nested_contents(FUNCS.has_effects), true); // Finish setting up some hosted types TYPES.actor = as_type(kernel->get("Actor")); TYPES.color = as_type(kernel->get("Color")); TYPES.closure = as_type(kernel->get("Closure")); callable_t::setup_type(as_type(kernel->get("Callable"))); TYPES.frame = as_type(kernel->get("Frame")); TYPES.point = as_type(kernel->get("Point")); TYPES.file_signature = as_type(kernel->get("FileSignature")); Type* mutableType = as_type(kernel->get("Mutable")); circa_setup_object_type(mutableType, sizeof(Value), MutableRelease); mutableType->initialize = MutableInitialize; color_t::setup_type(TYPES.color); as_function(FUNCS.list_append)->specializeType = List__append_specializeType; }