Пример #1
0
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;
}
Пример #2
0
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));
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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);
}
Пример #6
0
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));
}
Пример #7
0
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);
}
Пример #8
0
    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();
    }
Пример #9
0
void if_block_turn_common_rebinds_into_outputs(Term* ifCall)
{
    // Find names which are bound in every branch (and not already outputs)
    Branch* contents = nested_contents(ifCall);

    bool firstBranch = true;
    List names;

    for (CaseIterator it(contents); it.unfinished(); it.advance()) {
        Branch* caseBranch = nested_contents(it.current());

        if (firstBranch) {
            firstBranch = false;
            write_all_names_to_list(caseBranch, &names);

            // remove names that are already outputs
            for (int i=0; i < names.length(); i++) {
                Term* existing = contents->get(as_cstring(names[i]));
                if (existing != NULL && existing->function == FUNCS.output)
                    set_null(names[i]);
            }

            continue;
        }

        // search through 'names' and remove any not in this branch.
        for (int i=0; i < names.length(); i++) {
            if (is_null(names[i]))
                continue;
            if (caseBranch->get(as_cstring(names[i])) == NULL)
                set_null(names[i]);
        }
    }

    names.removeNulls();
    // std::cout << names.toString() << std::endl;

    for (int i=0; i < names.length(); i++) {
        if_block_add_output_for_name(ifCall, as_cstring(names[i]));
    }
}
Пример #10
0
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));
}
Пример #11
0
    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;
    }
Пример #12
0
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);
    }
}
Пример #13
0
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++;
    }
}
Пример #14
0
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"));
    }
}
Пример #15
0
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));
    }
}