Init globals before lowering CTCE, allows CTCE to use imported functions, etc.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,6 +14,7 @@ kraklist.txt
|
|||||||
papers
|
papers
|
||||||
callgrind*
|
callgrind*
|
||||||
*.comp_new
|
*.comp_new
|
||||||
|
*.comp_new.expr
|
||||||
*.comp_bac
|
*.comp_bac
|
||||||
bintest.bin
|
bintest.bin
|
||||||
*.dot
|
*.dot
|
||||||
|
|||||||
25
kraken.krak
25
kraken.krak
@@ -35,6 +35,13 @@ fun main(argc: int, argv: **char):int {
|
|||||||
doing_repl = true
|
doing_repl = true
|
||||||
} else if (string(argv[1]) == "-v" || string(argv[1]) == "--version") {
|
} else if (string(argv[1]) == "-v" || string(argv[1]) == "--version") {
|
||||||
println(compiler_version::version_string)
|
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)
|
exit(0)
|
||||||
}
|
}
|
||||||
var input_file_offset = 1
|
var input_file_offset = 1
|
||||||
@@ -100,13 +107,17 @@ fun main(argc: int, argv: **char):int {
|
|||||||
|
|
||||||
// This is our REPL loop
|
// This is our REPL loop
|
||||||
var scope = ast_translation_unit_ptr(string("stdin"))
|
var scope = ast_translation_unit_ptr(string("stdin"))
|
||||||
while (doing_repl) {
|
if (doing_repl) {
|
||||||
var line = get_line(string("> "), 100)
|
/*var globals = setup_globals(importer.name_ast_map)*/
|
||||||
if (line == "end")
|
while (doing_repl) {
|
||||||
return 0
|
var line = get_line(string("> "), 100)
|
||||||
var trimmed_parse = trim(parse1.parse_input(line, string("stdin")))
|
if (line == "end")
|
||||||
var ast_expression = ast_pass.transform_expression(trimmed_parse, scope, map<string, *type>())
|
return 0
|
||||||
print_value(evaluate_constant_expression(ast_expression))
|
var trimmed_parse = trim(parse1.parse_input(line, string("stdin")))
|
||||||
|
var ast_expression = ast_pass.transform_expression(trimmed_parse, scope, map<string, *type>())
|
||||||
|
print_value(evaluate_constant_expression(ast_expression))
|
||||||
|
/*print_value(evaluate_with_globals(ast_expression, &globals))*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var kraken_file_name = string(argv[input_file_offset])
|
var kraken_file_name = string(argv[input_file_offset])
|
||||||
|
|||||||
@@ -13,12 +13,13 @@ import interpreter:*
|
|||||||
import pass_common:*
|
import pass_common:*
|
||||||
|
|
||||||
fun ctce_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
fun ctce_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||||
|
var globals = setup_globals(*name_ast_map)
|
||||||
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
|
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
|
||||||
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
match(*node) {
|
match(*node) {
|
||||||
ast_node::compiler_intrinsic(backing) {
|
ast_node::compiler_intrinsic(backing) {
|
||||||
if (backing.intrinsic == "ctce") {
|
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)
|
*node = *unwrap_value(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -553,9 +553,10 @@ fun call_main(name_ast_map: ref map<string, pair<*tree<symbol>,*ast_node>>) {
|
|||||||
var result = call_function(results[0], vector<value>(), vector<*ast_node>(), &var_stack, map<*ast_node,value>(), value::void_nothing(), value::void_nothing(), null<ast_node>(), &globals)
|
var result = call_function(results[0], vector<value>(), vector<*ast_node>(), &var_stack, map<*ast_node,value>(), value::void_nothing(), value::void_nothing(), null<ast_node>(), &globals)
|
||||||
pop_and_free(&var_stack)
|
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<stack<map<*ast_node, value>>>(), value::void_nothing(), null<ast_node>(), null<map<*ast_node, value>>()).first
|
return interpret(node, null<stack<map<*ast_node, value>>>(), value::void_nothing(), null<ast_node>(), null<map<*ast_node, value>>()).first
|
||||||
}
|
fun evaluate_with_globals(node: *ast_node, globals: *map<*ast_node, value>): value
|
||||||
|
return interpret(node, null<stack<map<*ast_node, value>>>(), value::void_nothing(), null<ast_node>(), globals).first
|
||||||
fun setup_globals(name_ast_map: ref map<string, pair<*tree<symbol>,*ast_node>>): map<*ast_node, value> {
|
fun setup_globals(name_ast_map: ref map<string, pair<*tree<symbol>,*ast_node>>): map<*ast_node, value> {
|
||||||
var globals = map<*ast_node, value>()
|
var globals = map<*ast_node, value>()
|
||||||
name_ast_map.for_each(fun(key: string, value: pair<*tree<symbol>,*ast_node>) {
|
name_ast_map.for_each(fun(key: string, value: pair<*tree<symbol>,*ast_node>) {
|
||||||
@@ -679,7 +680,7 @@ fun interpret_function_call(func_call: *ast_node, var_stack: *stack<map<*ast_nod
|
|||||||
return make_pair(dereference_pointer_into_variable(dereference_val), control_flow::nor())
|
return make_pair(dereference_pointer_into_variable(dereference_val), control_flow::nor())
|
||||||
}
|
}
|
||||||
// check for built-in-ish externs (everything the standard library needs)
|
// check for built-in-ish externs (everything the standard library needs)
|
||||||
if (func_name == "printf" || func_name == "malloc" || func_name == "free" || func_name == "memmove" || func_name == "fflush" || func_name == "snprintf" || func_name == "fopen" || func_name == "fclose" || func_name == "ftell" || func_name == "fseek" || func_name == "fread" || func_name == "fwrite" || func_name == "atan" || func_name == "atan2" || func_name == "acos" || func_name == "asin" || func_name == "tan" || func_name == "cos" || func_name == "sin")
|
if (func_name == "printf" || func_name == "malloc" || func_name == "free" || func_name == "memmove" || func_name == "fflush" || func_name == "snprintf" || func_name == "fopen" || func_name == "fclose" || func_name == "ftell" || func_name == "fseek" || func_name == "fread" || func_name == "fwrite" || func_name == "atan" || func_name == "atan2" || func_name == "acos" || func_name == "asin" || func_name == "tan" || func_name == "cos" || func_name == "sin" || func_name == "fgets" || func_name == "popen" || func_name == "pclose")
|
||||||
return make_pair(call_built_in_extern(func_name, parameters), control_flow::nor())
|
return make_pair(call_built_in_extern(func_name, parameters), control_flow::nor())
|
||||||
if (!func_call_func->function.body_statement)
|
if (!func_call_func->function.body_statement)
|
||||||
error(string("trying to call unsupported extern function: ") + func_name)
|
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>): value {
|
|||||||
} else if (func_name == "sin") {
|
} else if (func_name == "sin") {
|
||||||
assert(parameters.size == 1 && is_double_precision(parameters[0]), "Calling sin with wrong params")
|
assert(parameters.size == 1 && is_double_precision(parameters[0]), "Calling sin with wrong params")
|
||||||
return value::double_precision(sin(parameters[0].double_precision))
|
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 {
|
} else {
|
||||||
error(string("trying to call invalid func: ") + func_name)
|
error(string("trying to call invalid func: ") + func_name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ fun get_line(prompt: string::string, line_size: int): string::string {
|
|||||||
print(prompt)
|
print(prompt)
|
||||||
return get_line(line_size)
|
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<char>(line_size)
|
var buff = new<char>(line_size)
|
||||||
fgets(buff, line_size, stdin)
|
fgets(buff, line_size, file)
|
||||||
var to_ret = string::string(buff)
|
var to_ret = string::string(buff)
|
||||||
delete(buff)
|
delete(buff)
|
||||||
return to_ret.slice(0,-2) // remove '\n'
|
return to_ret.slice(0,-2) // remove '\n'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import string:*
|
import string:*
|
||||||
import mem:*
|
import mem:*
|
||||||
|
import io:*
|
||||||
|
|
||||||
fun system(call_string: string):int {
|
fun system(call_string: string):int {
|
||||||
var c_call_string = call_string.toCharArray()
|
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 system(call_string: *char): int
|
||||||
ext fun exit(code: int):void
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -180,6 +180,7 @@ obj string (Object, Serializable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun operator+(integer: int): string return *this + to_string(integer);
|
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+(b: bool): string return *this + to_string(b);*/
|
||||||
|
|
||||||
fun operator+(str: *char): string {
|
fun operator+(str: *char): string {
|
||||||
@@ -194,6 +195,7 @@ obj string (Object, Serializable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun operator+=(integer: int) *this += to_string(integer);
|
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+=(b: bool) *this += to_string(b);*/
|
||||||
|
|
||||||
fun operator+=(character: char): void {
|
fun operator+=(character: char): void {
|
||||||
|
|||||||
@@ -1,2 +1,14 @@
|
|||||||
3
|
3
|
||||||
hello, world
|
hello, world
|
||||||
|
From Shell
|
||||||
|
From Shell
|
||||||
|
From Shell
|
||||||
|
From Shell
|
||||||
|
From Shell
|
||||||
|
From Shell
|
||||||
|
From Shell
|
||||||
|
From Shell
|
||||||
|
From Shell
|
||||||
|
From Shell
|
||||||
|
true
|
||||||
|
true
|
||||||
|
|||||||
@@ -1,8 +1,28 @@
|
|||||||
import io: *
|
import io: *
|
||||||
|
import os: *
|
||||||
|
import string: *
|
||||||
|
import ast_nodes: *
|
||||||
|
|
||||||
|
fun compare_sizes<T>() {
|
||||||
|
var a = #sizeof<T>
|
||||||
|
var b = #ctce(#sizeof<T>)
|
||||||
|
println(a == b)
|
||||||
|
if (a != b)
|
||||||
|
println(string() + a + " is not the same size as " + b)
|
||||||
|
}
|
||||||
|
|
||||||
fun main(): int {
|
fun main(): int {
|
||||||
var a = #ctce(1+2)
|
var a = #ctce(1+2)
|
||||||
println(a)
|
println(a)
|
||||||
println(#ctce("junkhello, world"+4))
|
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<string>()
|
||||||
|
compare_sizes<ast_node>()
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user