int run_repl() { Stack context; Branch branch; bool displayRaw = false; push_frame(&context, &branch); while (true) { std::cout << "> "; std::string input; if (!std::getline(std::cin, input)) break; if (input == "exit" || input == "/exit") break; if (input == "") continue; if (input == "/raw") { displayRaw = !displayRaw; if (displayRaw) std::cout << "Displaying raw output" << std::endl; else std::cout << "Not displaying raw output" << std::endl; continue; } if (input == "/clear") { clear_branch(&branch); std::cout << "Cleared working area" << std::endl; continue; } if (input == "/dump") { dump(&branch); continue; } if (input == "/help") { std::cout << "Special commands: /raw, /help, /clear, /dump, /exit" << std::endl; continue; } int previousHead = branch.length(); repl_evaluate_line(&context, input, std::cout); if (displayRaw) { for (int i=previousHead; i < branch.length(); i++) { std::cout << get_term_to_string_extended(branch[i]) << std::endl; if (nested_contents(branch[i])->length() > 0) print_branch(std::cout, nested_contents(branch[i])); } } } return 0; }
int switch_getOutputCount(Term* term) { Branch* contents = nested_contents(term); // check if term is still being initialized: if (contents->length() == 0) return 1; Branch* outerRebinds = contents->getFromEnd(0)->contents(); return outerRebinds->length() + 1; }
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)); }
std::string cpp_accessor_for_type(Type* type) { #if 0 std::stringstream out; std::string indent = " "; out << "struct " << get_cpp_type_name(type) << "\n"; out << "{\n"; out << indent << "Term* _term\n"; out << "\n"; out << indent << get_cpp_type_name(type) << "(Term* term) : _term(term) {}\n"; out << "\n"; Branch* prototype = type->prototype; for (int i=0; i < prototype.length(); i++) { Term* field = prototype[i]; out << indent << get_cpp_type_name(field->type) << "& " << field->name << "() "; out << "{ return " << get_cpp_type_accessor(field->type) << "(_term->field(" << i << ")); }\n"; } out << "};\n"; return out.str(); #endif return ""; }
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 repl_evaluate_line(Stack* context, std::string const& input, std::ostream& output) { Branch* branch = top_branch(context); int previousHead = branch->length(); parser::compile(branch, parser::statement_list, input); int newHead = branch->length(); bool anyErrors = false; int resultIndex = -1; for (int i=previousHead; i < newHead; i++) { Term* result = branch->get(i); if (has_static_error(result)) { output << "error: "; print_static_error(result, output); output << std::endl; anyErrors = true; break; } Frame* frame = top_frame(context); frame->pc = i; frame->endPc = i + 1; run_interpreter(context); if (error_occurred(context)) { output << "error: "; print_error_stack(context, std::cout); anyErrors = true; break; } resultIndex = i; } // Print results of the last expression if (!anyErrors && resultIndex != -1) { Term* result = branch->get(resultIndex); if (result->type != as_type(VOID_TYPE)) { output << find_stack_value_for_term(context, result, 0)->toString() << std::endl; } } clear_error(context); }
int if_block_count_cases(Term* term) { Branch* contents = nested_contents(term); int result = 0; for (int i=0; i < contents->length(); i++) if (contents->get(i) != NULL && contents->get(i)->function == FUNCS.case_func) result++; return result; }
const char* switch_getOutputName(Term* term, int outputIndex) { Branch* contents = nested_contents(term); // check if term is still being initialized: if (contents->length() == 0) return ""; Branch* outerRebinds = contents->getFromEnd(0)->contents(); return outerRebinds->get(outputIndex - 1)->name.c_str(); }
Type* switch_getOutputType(Term* term, int outputIndex) { if (outputIndex == 0) return &VOID_T; Branch* contents = nested_contents(term); // check if term is still being initialized: if (contents->length() == 0) return &ANY_T; Branch* outerRebinds = contents->getFromEnd(0)->contents(); return outerRebinds->get(outputIndex - 1)->type; }
void Branch__statements(caStack* stack) { Branch* branch = (Branch*) circa_branch(circa_input(stack, 0)); if (branch == NULL) return circa_output_error(stack, "NULL branch"); caValue* out = circa_output(stack, 0); circa_set_list(out, 0); for (int i=0; i < branch->length(); i++) if (is_statement(branch->get(i))) circa_set_term(circa_append(out), (caTerm*) branch->get(i)); }
void Branch__list_configs(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); if (branch == NULL) return circa_output_error(stack, "NULL branch"); caValue* output = circa_output(stack, 0); for (int i=0; i < branch->length(); i++) { Term* term = branch->get(i); if (is_considered_config(term)) set_term_ref(circa_append(output), term); } }
Term* if_block_get_case(Term* term, int index) { Branch* contents = nested_contents(term); for (int i=0; i < contents->length(); i++) { if (contents->get(i) == NULL || contents->get(i)->function != FUNCS.case_func) continue; if (index == 0) return contents->get(i); index--; } return NULL; }
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 Branch__get_documentation(caStack* stack) { Branch* branch = as_branch(circa_input(stack, 0)); caValue* out = circa_output(stack, 0); set_list(out, 0); for (int i=0; i < branch->length(); i++) { Term* term = branch->get(i); if (is_input_placeholder(term)) continue; if (is_comment(term)) set_string(list_append(out), term->stringProp("comment")); } }
void if_block_update_output_placeholder_types_from_cases(Term* ifBlock) { Branch* masterContents = nested_contents(ifBlock); for (int outputIndex=0;; outputIndex++) { Term* masterPlaceholder = get_output_placeholder(masterContents, outputIndex); if (masterPlaceholder == NULL) return; List types; // Iterate through each case, and collect the output types for (int i=0; i < masterContents->length(); i++) { Term* term = masterContents->get(i); if (term->function != FUNCS.case_func) continue; Term* placeholder = get_output_placeholder(nested_contents(term), outputIndex); set_type(types.append(), placeholder->type); } change_declared_type(masterPlaceholder, find_common_type(&types)); } }