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 }
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); }
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; }
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); } }
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; }
/** * 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 (); }
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); }
/** * 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; } }
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}]"); }
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); }
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); }
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; }
int main() { run_interpreter(); return 0; }