Example #1
0
void file_source_read_file(Value* file_source, Value* name, Value* contents)
{
    if (file_source_is_map(file_source)) {
        Value* entry = hashtable_get(file_source, name);
        if (entry == NULL)
            set_null(contents);
        else
            copy(list_get(entry, 1), contents);
        return;
    }

    else if (file_source_is_filesystem_backed(file_source)) {
        Value fullPath;
        Value* rootDir = list_get(file_source, 1);
        copy(rootDir, &fullPath);
        join_path(&fullPath, name);
        read_text_file(as_cstring(&fullPath), contents);
        return;
    }

    else if (file_source_is_tarball_backed(file_source)) {
        Value* tarball = list_get(file_source, 1);
        tar_read_file(tarball, as_cstring(name), contents);
        return;
    }
    internal_error("file_source_read_file: file_source type not recognized");
}
Example #2
0
static bool find_module_file(const char* module_name, caValue* filenameOut)
{
    Value module;
    set_string(&module, module_name);

    int count = list_length(&g_moduleSearchPaths);
    for (int i=0; i < count; i++) {

        // For each search path we'll check two places.

        // Look under searchPath/moduleName.ca
        Value searchPath;
        copy(g_moduleSearchPaths[i], &searchPath);
        circa_join_path(&searchPath, &module);
        string_append(&searchPath, ".ca");

        if (circa_file_exists(as_cstring(&searchPath))) {
            swap(&searchPath, filenameOut);
            return true;
        }

        // Look under searchPath/moduleName/moduleName.ca
        copy(g_moduleSearchPaths[i], &searchPath);

        circa_join_path(&searchPath, &module);
        circa_join_path(&searchPath, &module);
        string_append(&searchPath, ".ca");

        if (circa_file_exists(as_cstring(&searchPath))) {
            swap(&searchPath, filenameOut);
            return true;
        }
    }
    return false;
}
Example #3
0
void join_path(Value* left, Value* right)
{
    const char* leftStr = as_cstring(left);
    const char* rightStr = as_cstring(right);
    int left_len = (int) strlen(leftStr);
    int right_len = (int) strlen(leftStr);

    if (string_equals(left, "") || string_equals(left, ".")) {
        copy(right, left);
        return;
    }

    if (string_equals(right, ""))
        return;

    int seperatorCount = 0;
    if (left_len > 0 && is_path_seperator(leftStr[left_len-1]))
        seperatorCount++;

    if (right_len > 0 && is_path_seperator(rightStr[0]))
        seperatorCount++;

    if (seperatorCount == 2)
        string_resize(left, left_len - 1);
    else if (seperatorCount == 0)
        string_append(left, "/");

    string_append(left, right);
}
Example #4
0
void file_watch_trigger_actions(World* world, FileWatch* watch)
{
    // Walk through each action and execute it.
    for (int i = 0; i < list_length(&watch->onChangeActions); i++) {
        caValue* action = list_get(&watch->onChangeActions, i);

        Name label = as_int(list_get(action, 0));
        ca_assert(label != name_None);

        switch (label) {
        case name_NativePatch: {
            caValue* moduleName = list_get(action, 1);

            NativePatch* nativeModule = add_native_patch(world, as_cstring(moduleName));
            native_patch_load_from_file(nativeModule, as_cstring(&watch->filename));
            native_patch_finish_change(nativeModule);
            break;
        }
        case name_PatchBlock: {
            // Reload this code block.
            caValue* moduleName = list_get(action, 1);
            load_module_file(world, as_cstring(moduleName), as_cstring(&watch->filename));
            break;
        }
        default:
            internal_error("unrecognized file watch action");
        }
    }
}
Example #5
0
void write_term_value(SourceWriter* writer, Term* term)
{
    caValue* val = term_value(term);
    if (is_int(val)) {
        writer->write(as_cstring(val));
    } else if (is_float(val)) {
        writer->write(as_cstring(val));
    } else if (is_string(val)) {
        writer->write("\"");
        writer->write(as_cstring(val));
        writer->write("\"");
    }
}
Example #6
0
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());
}
Example #7
0
bool block_check_invariants_print_result(Block* block, Value* out)
{
    circa::Value result;
    block_check_invariants(&result, block);

    if (list_length(&result) == 0)
        return true;

    string_append(out, list_length(&result));
    string_append(out, " errors found in block ");
    string_append_ptr(out, block);
    string_append(out, "\n");

    for (int i=0; i < list_length(&result); i++) {
        Value* error = list_get(&result,i);
        string_append(out, "[");
        string_append(out, as_int(list_get(error, 1)));
        string_append(out, "]");
        string_append(out, as_cstring(list_get(error, 2)));
        string_append(out, "\n");
    }

    string_append(out, "contents:\n");
    print_block(block, out);

    return false;
}
Example #8
0
const char* term_get_string_input_prop(Term* term, int inputIndex, Symbol key, const char* defaultValue)
{
    Value* value = term_get_input_property(term, inputIndex, key);
    if (value == NULL)
        return defaultValue;
    return as_cstring(value);
}
Example #9
0
void TokenStream::reset(Value* inputString)
{
    _position = 0;
    tokens.clear();
    set_value(&_sourceText, inputString);
    tokenize(as_cstring(&_sourceText), string_length(&_sourceText), &tokens);
}
Example #10
0
const char*
Term::name()
{
    if (!is_string(&nameValue))
        return "";
    return as_cstring(&nameValue);
}
Example #11
0
caValue* selector_advance(caValue* value, caValue* selectorElement, caValue* error)
{
    if (is_int(selectorElement)) {
        int selectorIndex = as_int(selectorElement);

        if (!is_list(value)) {
            set_error_string(error, "Value is not indexable: ");
            string_append_quoted(error, value);
            return NULL;
        }

        if (selectorIndex >= list_length(value)) {
            set_error_string(error, "Index ");
            string_append(error, selectorIndex);
            string_append(error, " is out of range");
            return NULL;
        }

        return get_index(value, selectorIndex);
    }
    else if (is_string(selectorElement)) {
        caValue* field = get_field(value, as_cstring(selectorElement));
        if (field == NULL) {
            set_error_string(error, "Field not found: ");
            string_append(error, selectorElement);
            return NULL;
        }
        return field;
    } else {
        set_error_string(error, "Unrecognized selector element: ");
        string_append_quoted(error, selectorElement);
        return NULL;
    }
}
Example #12
0
Branch* load_module(const char* module_name, Term* loadCall)
{
    Branch* existing = find_loaded_module(module_name);
    if (existing != NULL)
        return existing;
    
    Value filename;
    bool found = find_module_file(module_name, &filename);

    if (!found)
        return NULL;

    Term* import = load_module_from_file(module_name, as_cstring(&filename))->owningTerm;

    // If a loadCall is provided, possibly move the new import to be before the loadCall.
    if (loadCall != NULL) {
        Term* callersModule = find_parent_term_in_branch(loadCall, import->owningBranch);

        if (callersModule != NULL && (import->index > callersModule->index))
            move_before(import, callersModule);
    }

    // If the module has static errors, print them now.
    print_static_errors_formatted(nested_contents(import));

    return nested_contents(import);
}
Example #13
0
void parse_string_as_argument_list(caValue* str, List* output)
{
    // Read the tokens as a space-seperated list of strings.
    // TODO is to be more smart about word boundaries: spaces inside
    // quotes or parentheses shouldn't break apart items.

    TokenStream tokens;
    tokens.reset(as_cstring(str));
    
    Value itemInProgress;
    set_string(&itemInProgress, "");

    while (!tokens.finished()) {

        if (tokens.nextIs(tok_Whitespace)) {
            if (!equals_string(&itemInProgress, "")) {
                copy(&itemInProgress, list_append(output));
                set_string(&itemInProgress, "");
            }

        } else {
            string_append(&itemInProgress, tokens.nextStr().c_str());
        }

        tokens.consume();
    }

    if (!equals_string(&itemInProgress, "")) {
        copy(&itemInProgress, list_append(output));
        set_string(&itemInProgress, "");
    }
}
Example #14
0
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;
}
Example #15
0
void set_symbol_from_string(caValue* val, caValue* str)
{
    // Find this name as an existing builtin symbol.
    int foundBuiltin = builtin_symbol_from_string(as_cstring(str));
    if (foundBuiltin != -1) {
        set_symbol(val, foundBuiltin);
        return;
    }

    // Find this name as an existing runtime symbol.
    caValue* foundRuntime = hashtable_get(g_runtimeSymbolMap, str);
    if (foundRuntime != NULL) {
        copy(foundRuntime, val);
        return;
    }

    // Create a new runtime symbol.
    caValue* newRuntime = hashtable_insert(g_runtimeSymbolMap, str);
    int index = g_nextRuntimeSymbol++;
    set_symbol(newRuntime, index);
    set_symbol(val, index);

    list_resize(g_runtimeSymbolTable, index+1);
    set_value(list_get(g_runtimeSymbolTable, index), str);
}
Example #16
0
void dll_loading_check_for_patches_on_loaded_branch(Branch* branch)
{
    for (BranchIteratorFlat it(branch); it.unfinished(); it.advance()) {
        if (it.current()->function == FUNCS.dll_patch) {
            Term* caller = it.current();

            // Find the DLL.
            String filename;
            find_dll_for_script(branch, &filename);

            if (!is_string(&filename)) {
                mark_static_error(caller, "Couldn't find DLL");
                continue;
            }

            Value error;
            patch_with_dll(as_cstring(&filename), branch, &error);

            if (!is_null(&error)) {
                std::cout << as_string(&error) << std::endl;

                mark_static_error(caller, &error);
                continue;
            }
        }
    }
}
Example #17
0
void block_update_state_type(Block* block)
{
    if (!block_state_type_is_out_of_date(block))
        return;

    // Recreate the state type
    Type* type = create_compound_type();

    // TODO: give this new type a nice name

    for (int i=0; i < block->length(); i++) {
        Term* term = block->get(i);
        if (term == NULL)
            continue;

        if (term->function != FUNCS.unpack_state || FUNCS.unpack_state == NULL)
            continue;

        Term* identifyingTerm = term->input(1);

        caValue* fieldName = get_unique_name(identifyingTerm);
        ca_assert(is_string(fieldName));
        ca_assert(!string_eq(fieldName, ""));

        compound_type_append_field(type, declared_type(term), as_cstring(fieldName));
    }

    block->stateType = type;
    block_remove_property(block, sym_DirtyStateType);

    // Might need to update any existing pack_state calls.
    block_update_pack_state_calls(block);
}
Example #18
0
void run_repl_stdin(World* world)
{
    Stack* stack = alloc_stack(world);
    repl_start(stack);

    printf("Started REPL, type /help for reference.\n");

    while (true) {
        Value input;

        // Get next line
        if (!circa_get_line(&input))
            break;

        // Before doing any work, process any pending file changes.
        file_watch_check_all(world);

        Value output;
        repl_run_line(stack, &input, &output);

        for (int i=0; i < list_length(&output); i++)
            std::cout << as_cstring(list_get(&output, i)) << std::endl;

        // Check if we've finished.
        if (top_frame(stack) == NULL)
            return;

    }
}
Example #19
0
void run_generate_cpp(caValue* args)
{
    if (list_length(args) < 2) {
        std::cout << "Expected 2 arguments";
        return;
    }

    const char* source_file = as_cstring(list_get(args, 0));
    const char* output_file = as_cstring(list_get(args, 1));

    std::cout << "Loading source from: " << source_file << std::endl;
    std::cout << "Will write to: " << output_file << std::endl;

    Block block;
    load_script(&block, source_file);
    write_program_to_file(&block, output_file);
}
Example #20
0
int string_find_char(caValue* s, int start, char c)
{
    const char* cstr = as_cstring(s);

    for (int i=start; cstr[i] != 0; i++)
        if (cstr[i] == c)
            return i;
    return -1;
}
Example #21
0
Type* create_typed_unsized_list_type(Type* elementType)
{
    Type* type = create_type();
    list_t::setup_type(type);
    set_type(&type->parameter, elementType);
    std::string name = std::string("List<") + as_cstring(&elementType->name) + ">";
    set_string(&type->name, name.c_str());
    return type;
}
Example #22
0
int string_find_char_from_end(caValue* s, char c)
{
    const char* cstr = as_cstring(s);

    for (int i= (int) strlen(cstr) - 1; i >= 0; i--)
        if (cstr[i] == c)
            return i;
    return -1;
}
Example #23
0
std::string
TokenStream::consumeStr(int match)
{
    Value next;
    getNextStr(&next);
    std::string out = as_cstring(&next);
    consume(match);
    return out;
}
Example #24
0
void test_assert_function(Block* block, int line, const char* file)
{
    Value str;
    if (!block_check_invariants_print_result(block, &str)) {
        std::cout << as_cstring(&str) << std::endl;
        std::cout << "Block failed invariant check in " << file << ", line " << line << std::endl;
        declare_current_test_failed();
    }

    Value errors;
    check_for_static_errors(&errors, block);
    if (!errors.isEmpty()) {
        std::cout << "Block has static errors at " << file << ", line " << line << std::endl;
        print_static_errors_formatted(&errors, &str);
        std::cout << as_cstring(&str) << std::endl;
        declare_current_test_failed();
    }
}
Example #25
0
void module_possibly_patch_new_function(World* world, Block* function)
{
    NativePatchWorld* moduleWorld = world->nativePatchWorld;

    Value globalName;
    get_global_name(function, &globalName);

    // No global name: no patch.
    if (!is_string(&globalName))
        return;

    // Lookup in the global table.
    caValue* patchEntry = hashtable_get(&moduleWorld->everyPatchedFunction, &globalName);

    if (patchEntry == NULL) {
        // No patch for this function.
        return;
    }

    caValue* nativeModuleName = list_get(patchEntry, 0);
    caValue* functionName = list_get(patchEntry, 1);

    // Found a patch; apply it.
    NativePatch* module = get_existing_native_patch(world, as_cstring(nativeModuleName));

    if (module == NULL) {
        std::cout << "in module_possibly_patch_new_function, couldn't find module: "
            << as_cstring(nativeModuleName) << std::endl;
        return;
    }

    std::map<std::string, EvaluateFunc>::const_iterator it;
    it = module->patches.find(as_cstring(functionName));

    if (it == module->patches.end()) {
        std::cout << "in module_possibly_patch_new_function, couldn't find function: "
            << as_cstring(functionName) << std::endl;
        return;
    }
    
    EvaluateFunc evaluateFunc = it->second;

    install_function(function->owningTerm, evaluateFunc);
}
Example #26
0
int get_hash_value(caValue* value)
{
    Type::HashFunc f = value->value_type->hashFunc;
    if (f == NULL) {
        std::string msg;
        msg += std::string("No hash function for type ") + as_cstring(&value->value_type->name);
        internal_error(msg);
    }
    return f(value);
}
Example #27
0
bool string_starts_with(caValue* s, const char* beginning)
{
    const char* left = as_cstring(s);
    for (int i=0;; i++) {
        if (beginning[i] == 0)
            return true;
        if (left[i] != beginning[i])
            return false;
    }
}
Example #28
0
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));
}
Example #29
0
bool file_source_does_file_exist(Value* file_source, Value* name)
{
    if (file_source_is_map(file_source)) {
        return hashtable_get(file_source, name) != NULL;
    }
    else if (file_source_is_filesystem_backed(file_source)) {
        Value fullPath;
        Value* rootDir = list_get(file_source, 1);
        copy(rootDir, &fullPath);
        join_path(&fullPath, name);
        return file_exists(as_cstring(&fullPath));
    }
    else if (file_source_is_tarball_backed(file_source)) {
        Value* tarball = list_get(file_source, 1);
        return tar_file_exists(tarball, as_cstring(name));
    }
    internal_error("file_source_does_file_exist: file_source type not recognized");
    return false;
}
Example #30
0
static bool file_watch_check_for_update(FileWatch* watch)
{
    int latestMtime = file_get_mtime(as_cstring(&watch->filename));
    if (latestMtime != watch->lastObservedMtime) {
        watch->lastObservedMtime = latestMtime;
        return true;
    }

    return false;
}