void test_lazy()
{
#ifdef DEFERRED_CALLS_FIRST_DRAFT
    Branch branch;

    Term* a = branch.compile("a = add(1 2)");
    set_lazy_call(a, true);

    Stack context;
    push_frame(&context, &branch);
    run_interpreter(&context);

    test_equals(get_register(&context, a), ":Unevaluated");

    Frame* frame = push_frame(&context, &branch);
    frame->pc = a->index;
    frame->startPc = frame->pc;
    frame->endPc = frame->pc + 1;
    frame->strategy = ByDemand;
    run_interpreter(&context);

    test_equals(get_register(&context, a), "3");

    reset_stack(&context);
    Term* b = branch.compile("b = add(a a)");
    push_frame(&context, &branch);
    run_interpreter(&context);

    test_equals(get_register(&context, a), "3");
    test_equals(get_register(&context, b), "6");
#endif
}
Exemple #2
0
void test_custom_object()
{
    g_currentlyAllocated = 0;
    g_totalAllocated = 0;

    Block block;
    block.compile(
        "type MyType; \n"
        "def create_object() -> MyType\n"
        "def check_object(MyType t)\n"
        "s = create_object()\n"
        "check_object(s)\n"
            );

    circa_install_function(&block, "create_object", create_object);
    circa_install_function(&block, "check_object", check_object);

    circa_setup_object_type(circa_find_type_local(&block, "MyType"),
            sizeof(CustomObject), CustomObjectRelease);

    // Shouldn't allocate any objects before running.
    test_equals(g_currentlyAllocated, 0);
    test_equals(g_totalAllocated, 0);

    Stack stack;
    push_frame(&stack, &block);
    run_interpreter(&stack);
    test_assert(&stack);
    circa_clear_stack(&stack);

    // Running the script should only cause 1 object allocation.
    test_equals(g_currentlyAllocated, 0);
    test_equals(g_totalAllocated, 1);
}
Exemple #3
0
int main(int argc, const char *argv[])
{
	init_tools();
	init_values();
	init_evaluator();
	init_interpreter();
	init_tests();
	init_sexp_to_c();
	
	// TO TRY: Add an -O3 flag to Xcode's compile. Then compile and profile, and see if it runs faster.
	
//	run_tests();
//	run_benchmarks();
		
	if (argc > 1) {
		if (streq(argv[1], "test")) {
			run_tests();
		} else if (streq(argv[1], "benchmark")) {
			run_benchmarks();
		} else {
			value str = value_set_str(argv[1]);
			value_import(str);
			value_clear(&str);
		}
	} else {
		run_interpreter();
	}
	
	return 0;
}
Exemple #4
0
void handle_release(caValue* value)
{
    HandleData* container = as_handle(value);
    ca_assert(container != NULL);

    container->refcount--;

    // Release data, if this is the last reference.
    if (container->refcount <= 0) {

        // Find the type's release function (if any), and call it.
        Term* releaseMethod = find_method(NULL, value->value_type, "release");
        if (releaseMethod != NULL) {
            Stack stack;
            push_frame(&stack, function_contents(releaseMethod));
            caValue* inputSlot = get_input(&stack, 0);

            // Don't copy this value, otherwise we'll get in trouble when the copy
            // needs to be released.
            swap(value, inputSlot);

            run_interpreter(&stack);

            swap(value, inputSlot);
        }

        free(container);
    }
}
Exemple #5
0
int main(int argc, char** argv)
{
	bf_state* state = NULL;
	bf_error status;
	
	if (2 != argc)
	{
		usage();
		return 0;
	}
	
	status = new_interpreter(argv[1], &state);
	if (ERR_SUCCESS != status)
	{
		print_error(state, status);
		free_interpreter(state);
		return status;
	}
	
	status = run_interpreter(state);
	if (ERR_SUCCESS != status)
		print_error(state, status);
	
	free_interpreter(state);
	return status;
}
Exemple #6
0
/**
 * Function called with reservation result.
 *
 * @param cls closure with the reservation command (`struct Command`)
 * @param peer identifies the peer
 * @param amount set to the amount that was actually reserved or unreserved;
 *               either the full requested amount or zero (no partial reservations)
 * @param res_delay if the reservation could not be satisfied (amount was 0), how
 *        long should the client wait until re-trying?
 */
static void
reservation_cb (void *cls,
                const struct GNUNET_PeerIdentity *peer,
                int32_t amount,
                struct GNUNET_TIME_Relative res_delay)
{
  struct Command *cmd = cls;
  struct GNUNET_PeerIdentity pid;

  cmd->details.reserve_bandwidth.rc = NULL;
  make_peer (cmd->details.reserve_bandwidth.pid,
             &pid);
  GNUNET_assert (0 == memcmp (peer,
                              &pid,
                              sizeof (struct GNUNET_PeerIdentity)));
  switch (cmd->details.reserve_bandwidth.expected_result)
  {
  case GNUNET_OK:
    if (amount != cmd->details.reserve_bandwidth.amount)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "Unexpectedly failed to reserve %d/%d bytes with delay %s!\n",
                  (int) amount,
                  (int) cmd->details.reserve_bandwidth.amount,
                  GNUNET_STRINGS_relative_time_to_string (res_delay,
                                                          GNUNET_YES));
      GNUNET_break (0);
      GNUNET_SCHEDULER_shutdown ();
      return;
    }
    break;
  case GNUNET_NO:
    GNUNET_break ( (0 != amount) ||
                   (0 != res_delay.rel_value_us) );
    break;
  case GNUNET_SYSERR:
    if ( (amount != 0) ||
         (0 == res_delay.rel_value_us) )
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "Unexpectedly reserved %d bytes with delay %s!\n",
                  (int) amount,
                  GNUNET_STRINGS_relative_time_to_string (res_delay,
                                                          GNUNET_YES));
      GNUNET_break (0);
      GNUNET_SCHEDULER_shutdown ();
      return;
    }
    break;
  }
  off++;
  run_interpreter ();
}
Exemple #7
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);
}
Exemple #8
0
/**
 * Function called from #GNUNET_ATS_performance_list_addresses when
 * we process a #CMD_LIST_ADDRESSES command.
 *
 * @param cls the `struct Command` that caused the call
 * @param address the address, NULL if ATS service was disconnected
 * @param address_active #GNUNET_YES if this address is actively used
 *        to maintain a connection to a peer;
 *        #GNUNET_NO if the address is not actively used;
 *        #GNUNET_SYSERR if this address is no longer available for ATS
 * @param bandwidth_out assigned outbound bandwidth for the connection
 * @param bandwidth_in assigned inbound bandwidth for the connection
 * @param prop performance data for the address
 */
static void
info_cb (void *cls,
         const struct GNUNET_HELLO_Address *address,
         int address_active,
         struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
         struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
         const struct GNUNET_ATS_Properties *prop)
{
  struct Command *c = cls;
  struct CommandListAddresses *cmd = &c->details.list_addresses;

  if (NULL == address)
  {
    cmd->alh = NULL;
    /* we are done with the iteration, continue to execute */
    if ( (cmd->calls < cmd->min_calls) &&
         (cmd->active_calls < cmd->min_active_calls) )
    {
      GNUNET_SCHEDULER_shutdown ();
      return;
    }
    off++;
    run_interpreter ();
    return;
  }
  switch (address_active)
  {
  case GNUNET_YES:
    cmd->active_calls++;
    cmd->calls++;
    break;
  case GNUNET_NO:
    cmd->calls++;
    break;
  case GNUNET_SYSERR:
    return;
  }
  if ( (cmd->calls > cmd->max_calls) &&
       (cmd->active_calls < cmd->max_active_calls) )
  {
    GNUNET_break (0);
    GNUNET_ATS_performance_list_addresses_cancel (cmd->alh);
    cmd->alh = NULL;
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
}
Exemple #9
0
void type_name_visible_from_module()
{
    FakeFilesystem fs;
    fs.set("a", "type A { int i }");
    load_module_file(global_world(), "a", "a");

    fs.set("b", "require a\ntest_spy(make(A))");
    Block* b = load_module_file(global_world(), "b", "b");

    Stack stack;
    push_frame(&stack, b);
    test_spy_clear();
    run_interpreter(&stack);
    test_assert(&stack);

    test_equals(test_spy_get_results(), "[{i: 0}]");
}
Exemple #10
0
void test_cast_first_inputs()
{
    // Pass an input of [1] to a branch that expects a compound type.
    // The function will need to cast the [1] to T in order for it to work.

    Branch branch;
    branch.compile("type T { int i }");
    Term* f = branch.compile("def f(T t) -> int { return t.i }");

    Stack context;
    push_frame(&context, function_contents(f));

    caValue* in = circa_input((caStack*) &context, 0);
    circa_set_list(in, 1);
    circa_set_int(circa_index(in, 0), 5);

    run_interpreter(&context);

    test_assert(circa_int(circa_output((caStack*) &context, 0)) == 5);
}
Exemple #11
0
static void *
service_thread(struct workorder *work)
{
	FILE *input, *output;

	fprintf(stderr, "Start thread for connection %d.\n", work->conn);

	ps();

	input = fdopen(work->conn, "r");
	if (input == NULL) {
		oprogname();
		perror("can't create input stream");
		goto done;
	}

	output = fdopen(work->conn, "w");
	if (output == NULL) {
		oprogname();
		perror("can't create output stream");
		fclose(input);
		goto done;
	}

	setvbuf(input, NULL, _IONBF, 0);
	setvbuf(output, NULL, _IONBF, 0);

	run_interpreter(input, output);

	fclose(input);
	fclose(output);

  done:
	fprintf(stderr, "End thread for connection %d.\n", work->conn);
	close(work->conn);
	free(work);
}
Exemple #12
0
int run_command_line(caWorld* world, caValue* args)
{
    RawOutputPrefs rawOutputPrefs;
    bool printRaw = false;
    bool printState = false;
    bool dontRunScript = false;
    bool printTrace = false;

    // Prepended options
    while (true) {

        if (list_length(args) == 0)
            break;

        if (string_eq(list_get(args, 0), "-break-on")) {
            DEBUG_BREAK_ON_TERM = atoi(as_cstring(list_get(args, 1)));

            list_remove_index(args, 0);
            list_remove_index(args, 0);
            std::cout << "breaking on creation of term: " << DEBUG_BREAK_ON_TERM << std::endl;
            continue;
        }

        if (string_eq(list_get(args, 0), "-path")) {
            // Add a module path
            module_add_search_path(world, as_cstring(list_get(args, 1)));
            list_remove_index(args, 0);
            list_remove_index(args, 0);
            continue;
        }

        if (string_eq(list_get(args, 0), "-p")) {
            printRaw = true;
            list_remove_index(args, 0);
            continue;
        }

        if (string_eq(list_get(args, 0), "-pp")) {
            printRaw = true;
            rawOutputPrefs.showProperties = true;
            list_remove_index(args, 0);
            continue;
        }

        if (string_eq(list_get(args, 0), "-b") || string_eq(list_get(args, 0), "-pb")) {
            printRaw = true;
            rawOutputPrefs.showBytecode = true;
            list_remove_index(args, 0);
            continue;
        }

        if (string_eq(list_get(args, 0), "-n")) {
            dontRunScript = true;
            list_remove_index(args, 0);
            continue;
        }
        if (string_eq(list_get(args, 0), "-print-state")) {
            printState = true;
            list_remove_index(args, 0);
            continue;
        }
        if (string_eq(list_get(args, 0), "-t")) {
            printTrace = true;
            list_remove_index(args, 0);
            continue;
        }

        if (string_eq(list_get(args, 0), "-load")) {
            caValue* filename = list_get(args, 1);

            Value moduleName;
            module_get_default_name_from_filename(filename, &moduleName);

            list_remove_index(args, 0);
            list_remove_index(args, 0);
            continue;
        }

        break;
    }

    // No arguments remaining
    if (list_length(args) == 0) {
        print_usage();
        return 0;
    }
    
    Block* mainBlock = fetch_module(world, "main");

    // Check to handle args[0] as a dash-command.

    // Print help
    if (string_eq(list_get(args, 0), "-help")) {
        print_usage();
        return 0;
    }

    // Eval mode
    if (string_eq(list_get(args, 0), "-e")) {
        list_remove_index(args, 0);

        Value command;
        set_string(&command, "");

        bool firstArg = true;
        while (!list_empty(args)) {
            if (!firstArg)
                string_append(&command, " ");
            string_append(&command, list_get(args, 0));
            list_remove_index(args, 0);
            firstArg = false;
        }

        caValue* result = term_value(mainBlock->eval(as_cstring(&command)));
        std::cout << to_string(result) << std::endl;
        return 0;
    }

    // Start repl
    if (string_eq(list_get(args, 0), "-repl")) {
        run_repl_stdin(world);
        return 0;
    }

    if (string_eq(list_get(args, 0), "-call")) {
        Symbol loadResult = load_script(mainBlock, as_cstring(list_get(args, 1)));

        if (loadResult == sym_Failure) {
            std::cout << "Failed to load file: " <<  as_cstring(list_get(args, 1)) << std::endl;
            return -1;
        }

        block_finish_changes(mainBlock);

        caStack* stack = circa_alloc_stack(world);

        // Push function
        caBlock* func = circa_find_function_local(mainBlock, as_cstring(list_get(args, 2)));
        circa_push_function(stack, func);

        // Push inputs
        for (int i=3, inputIndex = 0; i < circa_count(args); i++) {
            caValue* val = circa_input(stack, inputIndex++);
            circa_parse_string(as_cstring(list_get(args, i)), val);
        }

        circa_run(stack);

        if (circa_has_error(stack)) {
            circa_print_error_to_stdout(stack);
        }

        // Print outputs
        for (int i=0;; i++) {
            caValue* out = circa_output(stack, i);
            if (out == NULL)
                break;

            std::cout << to_string(circa_output(stack, i)) << std::endl;
        }
        
        circa_dealloc_stack(stack);
    }

    // Start debugger repl
    if (string_eq(list_get(args, 0), "-d"))
        return run_debugger_repl(as_cstring(list_get(args, 1)));

    // Generate cpp headers
    if (string_eq(list_get(args, 0), "-gh")) {
        load_script(mainBlock, as_cstring(list_get(args, 1)));
        std::cout << generate_cpp_headers(mainBlock);
        return 0;
    }

    // Run file checker
    if (string_eq(list_get(args, 0), "-check"))
        return run_file_checker(as_cstring(list_get(args, 1)));

    // Export parsed information
    if (string_eq(list_get(args, 0), "-export")) {
        const char* filename = "";
        const char* format = "";
        if (list_length(args) >= 2)
            format = as_cstring(list_get(args, 1));
        if (list_length(args) >= 3)
            filename = as_cstring(list_get(args, 2));
        return run_exporting_parser(format, filename);
    }

    // Build tool
    if (string_eq(list_get(args, 0), "-build")) {
        return run_build_tool(args);
    }

    // C++ gen
    if (string_eq(list_get(args, 0), "-cppgen")) {
        Value remainingArgs;
        list_slice(args, 1, -1, &remainingArgs);
        run_generate_cpp(&remainingArgs);
        return 0;
    }

    // Command reader (from stdin)
    if (string_eq(list_get(args, 0), "-run-stdin")) {
        run_commands_from_stdin();
        return 0;
    }

    // Reproduce source text
    if (string_eq(list_get(args, 0), "-source-repro")) {
        load_script(mainBlock, as_cstring(list_get(args, 1)));
        std::cout << get_block_source_text(mainBlock);
        return 0;
    }

    // Rewrite source, this is useful for upgrading old source
    if (string_eq(list_get(args, 0), "-rewrite-source")) {
        load_script(mainBlock, as_cstring(list_get(args, 1)));
        std::string contents = get_block_source_text(mainBlock);
        write_text_file(as_cstring(list_get(args, 1)), contents.c_str());
        return 0;
    }

    // Default behavior with no flags: run args[0] as a script filename.

    // Add the script's folder to module search paths.
    caValue* filename = list_get(args, 0);
    Value directory;
    get_directory_for_filename(filename, &directory);
    module_add_search_path(world, as_cstring(&directory));

    load_script(mainBlock, as_cstring(filename));
    block_finish_changes(mainBlock);
    refresh_bytecode(mainBlock);

    if (printRaw)
        print_block(mainBlock, &rawOutputPrefs, std::cout);

    if (dontRunScript)
        return 0;

    Stack* stack = alloc_stack(world);

    push_frame(stack, mainBlock);

    run_interpreter(stack);

    if (printState)
        std::cout << to_string(&stack->state) << std::endl;

    if (error_occurred(stack)) {
        std::cout << "Error occurred:\n";
        print_error_stack(stack, std::cout);
        std::cout << std::endl;
        std::cout << "Stack:\n";
        dump(stack);
        return 1;
    }

    return 0;
}
Exemple #13
0
int main()
{
	run_interpreter();
	return 0;
}