void test_assert_function(Stack& context, int line, const char* file) { if (context.errorOccurred) { std::cout << "Runtime error at " << file << ", line " << line << std::endl; print_error_stack(&context, std::cout); declare_current_test_failed(); } }
bool test_fail_on_runtime_error(Stack& context) { if (context.errorOccurred) { std::cout << "Runtime error in " << get_current_test_name() << std::endl; print_error_stack(&context, std::cout); std::cout << std::endl; declare_current_test_failed(); return true; } return false; }
void test_block_as_assertions_list(Block* block, std::string const& contextStr) { if (has_static_errors(block)) { std::cout << "Static error " << contextStr << ":" << std::endl; print_static_errors_formatted(block, std::cout); declare_current_test_failed(); return; } std::stringstream checkInvariantsOutput; if (!block_check_invariants_print_result(block, checkInvariantsOutput)) { std::cout << "Failed invariant " << contextStr << std::endl; std::cout << checkInvariantsOutput.str() << std::endl; declare_current_test_failed(); return; } Stack context; evaluate_block(&context, block); if (context.errorOccurred) { std::cout << "Runtime error " << contextStr << std::endl; print_error_stack(&context, std::cout); declare_current_test_failed(); return; } int boolean_statements_found = 0; for (int i=0; i < block->length(); i++) { Term* term = block->get(i); if (!is_statement(term)) continue; if (!is_bool(term_value(term))) continue; boolean_statements_found++; if (!as_bool(term_value(term))) { std::cout << "Assertion failed " << contextStr << std::endl; std::cout << "failed: " << get_term_source_text(term) << std::endl; declare_current_test_failed(); return; } } if (boolean_statements_found == 0) { std::cout << "No boolean statements found " << contextStr << std::endl; declare_current_test_failed(); return; } }
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 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; }
void do_file_command(List* args, caValue* reply) { RawOutputPrefs rawOutputPrefs; bool printRaw = false; bool printSource = false; bool printState = false; bool dontRunScript = false; int argIndex = 1; while (true) { if (argIndex >= args->length()) { set_string(reply, "No filename found"); return; } if (string_eq(args->get(argIndex), "-p")) { printRaw = true; argIndex++; continue; } if (string_eq(args->get(argIndex), "-pp")) { printRaw = true; rawOutputPrefs.showProperties = true; argIndex++; continue; } if (string_eq(args->get(argIndex), "-b") || string_eq(args->get(argIndex), "-pb")) { printRaw = true; rawOutputPrefs.showBytecode = true; argIndex++; continue; } if (string_eq(args->get(argIndex), "-s")) { printSource = true; argIndex++; continue; } if (string_eq(args->get(argIndex), "-print-state")) { printState = true; argIndex++; continue; } if (string_eq(args->get(argIndex), "-n")) { dontRunScript = true; argIndex++; continue; } break; } Block block; load_script(&block, as_cstring(args->get(argIndex))); if (printSource) std::cout << get_block_source_text(&block); if (dontRunScript) return; Stack stack; evaluate_block(&stack, &block); 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; return; } }