diff --git a/.gitignore b/.gitignore index 5f63ff6..a541ab2 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ kraklist.txt papers callgrind* *.comp_new +*.comp_new.expr *.comp_bac bintest.bin *.dot diff --git a/kraken.krak b/kraken.krak index c4f10de..44dd164 100644 --- a/kraken.krak +++ b/kraken.krak @@ -35,6 +35,13 @@ fun main(argc: int, argv: **char):int { doing_repl = true } else if (string(argv[1]) == "-v" || string(argv[1]) == "--version") { println(compiler_version::version_string) + /*var version_c_string = #ctce(fun(): *char {*/ + /*var version_string = string("Self-hosted Kraken compiler \"Kalypso\" - revision ") + from_system_command(string("git rev-list HEAD | wc -l"), 100) +*/ + /*", commit: " + from_system_command(string("git rev-parse HEAD"), 100) +*/ + /*", compile date: " + from_system_command(string("date"), 100) */ + /*return version_string.toCharArray()*/ + /*}())*/ + /*println(version_c_string)*/ exit(0) } var input_file_offset = 1 @@ -100,13 +107,17 @@ fun main(argc: int, argv: **char):int { // This is our REPL loop var scope = ast_translation_unit_ptr(string("stdin")) - while (doing_repl) { - var line = get_line(string("> "), 100) - if (line == "end") - return 0 - var trimmed_parse = trim(parse1.parse_input(line, string("stdin"))) - var ast_expression = ast_pass.transform_expression(trimmed_parse, scope, map()) - print_value(evaluate_constant_expression(ast_expression)) + if (doing_repl) { + /*var globals = setup_globals(importer.name_ast_map)*/ + while (doing_repl) { + var line = get_line(string("> "), 100) + if (line == "end") + return 0 + var trimmed_parse = trim(parse1.parse_input(line, string("stdin"))) + var ast_expression = ast_pass.transform_expression(trimmed_parse, scope, map()) + print_value(evaluate_constant_expression(ast_expression)) + /*print_value(evaluate_with_globals(ast_expression, &globals))*/ + } } var kraken_file_name = string(argv[input_file_offset]) diff --git a/stdlib/ctce_lower.krak b/stdlib/ctce_lower.krak index 821c498..02bb831 100644 --- a/stdlib/ctce_lower.krak +++ b/stdlib/ctce_lower.krak @@ -13,12 +13,13 @@ import interpreter:* import pass_common:* fun ctce_lower(name_ast_map: *map,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree>) { + var globals = setup_globals(*name_ast_map) name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree,*ast_node>) { var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) { match(*node) { ast_node::compiler_intrinsic(backing) { if (backing.intrinsic == "ctce") { - var result = evaluate_constant_expression(backing.parameters[0]) + var result = evaluate_with_globals(backing.parameters[0], &globals) *node = *unwrap_value(result) } } diff --git a/stdlib/interpreter.krak b/stdlib/interpreter.krak index 267a73a..06c5641 100644 --- a/stdlib/interpreter.krak +++ b/stdlib/interpreter.krak @@ -553,9 +553,10 @@ fun call_main(name_ast_map: ref map,*ast_node>>) { var result = call_function(results[0], vector(), vector<*ast_node>(), &var_stack, map<*ast_node,value>(), value::void_nothing(), value::void_nothing(), null(), &globals) pop_and_free(&var_stack) } -fun evaluate_constant_expression(node: *ast_node): value { +fun evaluate_constant_expression(node: *ast_node): value return interpret(node, null>>(), value::void_nothing(), null(), null>()).first -} +fun evaluate_with_globals(node: *ast_node, globals: *map<*ast_node, value>): value + return interpret(node, null>>(), value::void_nothing(), null(), globals).first fun setup_globals(name_ast_map: ref map,*ast_node>>): map<*ast_node, value> { var globals = map<*ast_node, value>() name_ast_map.for_each(fun(key: string, value: pair<*tree,*ast_node>) { @@ -679,7 +680,7 @@ fun interpret_function_call(func_call: *ast_node, var_stack: *stackfunction.body_statement) error(string("trying to call unsupported extern function: ") + func_name) @@ -814,6 +815,17 @@ fun call_built_in_extern(func_name: string, parameters: vector): value { } else if (func_name == "sin") { assert(parameters.size == 1 && is_double_precision(parameters[0]), "Calling sin with wrong params") return value::double_precision(sin(parameters[0].double_precision)) + } else if (func_name == "fgets") { + assert(parameters.size == 3 && is_pointer(parameters[0]) && is_integer(parameters[1]) && is_pointer(parameters[2]), "Calling fgets with wrong params") + // first param is *char, so reuse for return + return value::pointer(make_pair((fgets((parameters[0].pointer.first) cast *char, parameters[1].integer, parameters[2].pointer.first)) cast *void, parameters[0].pointer.second)) + } else if (func_name == "popen") { + assert(parameters.size == 2 && is_pointer(parameters[0]) && is_pointer(parameters[1]), "Calling popen with wrong params") + return value::pointer( + make_pair(popen((parameters[0].pointer.first) cast *char, (parameters[1].pointer.first) cast *char), type_ptr(base_type::void_return(), 1))) + } else if (func_name == "pclose") { + assert(parameters.size == 1 && is_pointer(parameters[0]), "Calling pclose with wrong params") + return value::integer(pclose(parameters[0].pointer.first)) } else { error(string("trying to call invalid func: ") + func_name) } diff --git a/stdlib/io.krak b/stdlib/io.krak index 4ac83f8..2da1cbc 100644 --- a/stdlib/io.krak +++ b/stdlib/io.krak @@ -14,9 +14,11 @@ fun get_line(prompt: string::string, line_size: int): string::string { print(prompt) return get_line(line_size) } -fun get_line(line_size: int): string::string { +fun get_line(line_size: int): string::string + return get_line(line_size, stdin) +fun get_line(line_size: int, file: *void): string::string { var buff = new(line_size) - fgets(buff, line_size, stdin) + fgets(buff, line_size, file) var to_ret = string::string(buff) delete(buff) return to_ret.slice(0,-2) // remove '\n' diff --git a/stdlib/os.krak b/stdlib/os.krak index 33f934b..fc36f55 100644 --- a/stdlib/os.krak +++ b/stdlib/os.krak @@ -1,5 +1,6 @@ import string:* import mem:* +import io:* fun system(call_string: string):int { var c_call_string = call_string.toCharArray() @@ -9,5 +10,15 @@ fun system(call_string: string):int { } ext fun system(call_string: *char): int ext fun exit(code: int):void -fun exit() exit(0); +fun exit() exit(0) +ext fun popen(command: *char, mode: *char): *void +ext fun pclose(file: *void): int +fun from_system_command(command: string, line_size: int): string { + var command_string = command.toCharArray() + defer delete(command_string) + var p = popen(command_string, "r") + var to_ret = get_line(line_size, p) + pclose(p) + return to_ret +} diff --git a/stdlib/string.krak b/stdlib/string.krak index 2a160ef..65f7b30 100644 --- a/stdlib/string.krak +++ b/stdlib/string.krak @@ -180,6 +180,7 @@ obj string (Object, Serializable) { } fun operator+(integer: int): string return *this + to_string(integer); + fun operator+(integer: ulong): string return *this + to_string(integer); /*fun operator+(b: bool): string return *this + to_string(b);*/ fun operator+(str: *char): string { @@ -194,6 +195,7 @@ obj string (Object, Serializable) { } fun operator+=(integer: int) *this += to_string(integer); + fun operator+=(integer: ulong) *this += to_string(integer); /*fun operator+=(b: bool) *this += to_string(b);*/ fun operator+=(character: char): void { diff --git a/tests/test_ctce.expected_results b/tests/test_ctce.expected_results index f7cf94f..db9a4b3 100644 --- a/tests/test_ctce.expected_results +++ b/tests/test_ctce.expected_results @@ -1,2 +1,14 @@ 3 hello, world +From Shell +From Shell +From Shell +From Shell +From Shell +From Shell +From Shell +From Shell +From Shell +From Shell +true +true diff --git a/tests/test_ctce.krak b/tests/test_ctce.krak index eb415f3..4b1e30c 100644 --- a/tests/test_ctce.krak +++ b/tests/test_ctce.krak @@ -1,8 +1,28 @@ import io: * +import os: * +import string: * +import ast_nodes: * + +fun compare_sizes() { + var a = #sizeof + var b = #ctce(#sizeof) + println(a == b) + if (a != b) + println(string() + a + " is not the same size as " + b) +} fun main(): int { var a = #ctce(1+2) println(a) println(#ctce("junkhello, world"+4)) + for (var i = 0; i < 10; i++;) { + println(#ctce(fun(): *char { + println("\n\n=====During CTCE!=====\n\n") + var it = from_system_command(string("echo From Shell"), 100) + return it.toCharArray() + }())) + } + compare_sizes() + compare_sizes() return 0 }