C extern implemented
This commit is contained in:
@@ -72,7 +72,7 @@ func_identifier = identifier | identifier overloadable_operator ;
|
|||||||
|
|
||||||
# HACKY - typed_return has it's own internal whitespace as to not make WS typed_return-reduces to null WS ambigious
|
# HACKY - typed_return has it's own internal whitespace as to not make WS typed_return-reduces to null WS ambigious
|
||||||
typed_return = WS dec_type | ;
|
typed_return = WS dec_type | ;
|
||||||
function = "fun" WS func_identifier WS template_dec WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement | "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement ;
|
function = "ext" WS "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" typed_return | "fun" WS func_identifier WS template_dec WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement | "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement ;
|
||||||
lambda = "fun" WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement ;
|
lambda = "fun" WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement ;
|
||||||
|
|
||||||
opt_typed_parameter_list = typed_parameter_list | ;
|
opt_typed_parameter_list = typed_parameter_list | ;
|
||||||
|
|||||||
@@ -285,8 +285,8 @@ obj adt_def (Object) {
|
|||||||
return name == other.name && self_type == other.self_type && options == other.options && option_funcs == other.option_funcs && regular_funcs == other.regular_funcs
|
return name == other.name && self_type == other.self_type && options == other.options && option_funcs == other.option_funcs && regular_funcs == other.regular_funcs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun ast_function_ptr(name: string, type: *type, parameters: vector<*ast_node>): *ast_node {
|
fun ast_function_ptr(name: string, type: *type, parameters: vector<*ast_node>, is_extern: bool): *ast_node {
|
||||||
var to_ret.construct(name, type, parameters): function
|
var to_ret.construct(name, type, parameters, is_extern): function
|
||||||
var ptr = new<ast_node>()
|
var ptr = new<ast_node>()
|
||||||
ptr->copy_construct(&ast_node::function(to_ret))
|
ptr->copy_construct(&ast_node::function(to_ret))
|
||||||
return ptr
|
return ptr
|
||||||
@@ -304,13 +304,15 @@ obj function (Object) {
|
|||||||
var closed_variables: set<*ast_node>
|
var closed_variables: set<*ast_node>
|
||||||
var body_statement: *ast_node
|
var body_statement: *ast_node
|
||||||
var scope: map<string, vector<*ast_node>>
|
var scope: map<string, vector<*ast_node>>
|
||||||
fun construct(name_in: string, type_in: *type, parameters_in: vector<*ast_node>): *function {
|
var is_extern: bool
|
||||||
|
fun construct(name_in: string, type_in: *type, parameters_in: vector<*ast_node>, is_extern_in: bool): *function {
|
||||||
name.copy_construct(&name_in)
|
name.copy_construct(&name_in)
|
||||||
parameters.copy_construct(¶meters_in)
|
parameters.copy_construct(¶meters_in)
|
||||||
closed_variables.construct()
|
closed_variables.construct()
|
||||||
scope.construct()
|
scope.construct()
|
||||||
type = type_in
|
type = type_in
|
||||||
body_statement = null<ast_node>()
|
body_statement = null<ast_node>()
|
||||||
|
is_extern = is_extern_in
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
fun copy_construct(old: *function) {
|
fun copy_construct(old: *function) {
|
||||||
@@ -320,6 +322,7 @@ obj function (Object) {
|
|||||||
parameters.copy_construct(&old->parameters)
|
parameters.copy_construct(&old->parameters)
|
||||||
closed_variables.copy_construct(&old->closed_variables)
|
closed_variables.copy_construct(&old->closed_variables)
|
||||||
scope.copy_construct(&old->scope)
|
scope.copy_construct(&old->scope)
|
||||||
|
is_extern = old->is_extern
|
||||||
}
|
}
|
||||||
fun destruct() {
|
fun destruct() {
|
||||||
name.destruct()
|
name.destruct()
|
||||||
@@ -332,7 +335,7 @@ obj function (Object) {
|
|||||||
copy_construct(&other)
|
copy_construct(&other)
|
||||||
}
|
}
|
||||||
fun operator==(other: ref function): bool {
|
fun operator==(other: ref function): bool {
|
||||||
return name == name && type == other.type && parameters == other.parameters && body_statement == other.body_statement && closed_variables == other.closed_variables
|
return name == name && type == other.type && parameters == other.parameters && body_statement == other.body_statement && closed_variables == other.closed_variables && is_extern == other.is_extern
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun ast_template_ptr(name: string, syntax_node: *tree<symbol>, template_types: vector<string>, template_type_replacements: map<string, *type>, is_function: bool): *ast_node {
|
fun ast_template_ptr(name: string, syntax_node: *tree<symbol>, template_types: vector<string>, template_type_replacements: map<string, *type>, is_function: bool): *ast_node {
|
||||||
@@ -1116,7 +1119,12 @@ fun get_ast_name(node: *ast_node): string {
|
|||||||
ast_node::identifier(backing) return string("identifier: ") + backing.name + ": " + backing.type->to_string()
|
ast_node::identifier(backing) return string("identifier: ") + backing.name + ": " + backing.type->to_string()
|
||||||
ast_node::type_def(backing) return string("type_def: ") + backing.name
|
ast_node::type_def(backing) return string("type_def: ") + backing.name
|
||||||
ast_node::adt_def(backing) return string("adt_def: ") + backing.name
|
ast_node::adt_def(backing) return string("adt_def: ") + backing.name
|
||||||
ast_node::function(backing) return string("function: ") + backing.name + ": " + backing.type->to_string()
|
ast_node::function(backing) {
|
||||||
|
if (backing.is_extern)
|
||||||
|
return string("extern function: ") + backing.name + ": " + backing.type->to_string()
|
||||||
|
else
|
||||||
|
return string("function: ") + backing.name + ": " + backing.type->to_string()
|
||||||
|
}
|
||||||
ast_node::template(backing) return string("template: ") + backing.name
|
ast_node::template(backing) return string("template: ") + backing.name
|
||||||
ast_node::code_block(backing) return string("code_block")
|
ast_node::code_block(backing) return string("code_block")
|
||||||
ast_node::statement(backing) return string("statement")
|
ast_node::statement(backing) return string("statement")
|
||||||
|
|||||||
@@ -167,9 +167,9 @@ obj ast_transformation (Object) {
|
|||||||
var function_node = null<ast_node>()
|
var function_node = null<ast_node>()
|
||||||
if (type_syntax) {
|
if (type_syntax) {
|
||||||
var identifier_param = ast_identifier_ptr(option_name, ident_type, node)
|
var identifier_param = ast_identifier_ptr(option_name, ident_type, node)
|
||||||
function_node = ast_function_ptr(option_name, type_ptr(vector(get_ast_type(identifier_param)), node->adt_def.self_type), vector(identifier_param))
|
function_node = ast_function_ptr(option_name, type_ptr(vector(get_ast_type(identifier_param)), node->adt_def.self_type), vector(identifier_param), false)
|
||||||
} else {
|
} else {
|
||||||
function_node = ast_function_ptr(option_name, type_ptr(vector<*type>(), node->adt_def.self_type), vector<*ast_node>())
|
function_node = ast_function_ptr(option_name, type_ptr(vector<*type>(), node->adt_def.self_type), vector<*ast_node>(), false)
|
||||||
}
|
}
|
||||||
add_to_scope(option_name, function_node, node)
|
add_to_scope(option_name, function_node, node)
|
||||||
add_to_scope("~enclosing_scope", node, function_node)
|
add_to_scope("~enclosing_scope", node, function_node)
|
||||||
@@ -184,11 +184,11 @@ obj ast_transformation (Object) {
|
|||||||
var copy_construct_param = ast_identifier_ptr(string("in"), node->adt_def.self_type->clone_with_indirection(1,false), node)
|
var copy_construct_param = ast_identifier_ptr(string("in"), node->adt_def.self_type->clone_with_indirection(1,false), node)
|
||||||
var assign_param = ast_identifier_ptr(string("in"), node->adt_def.self_type->clone_with_indirection(0,true), node)
|
var assign_param = ast_identifier_ptr(string("in"), node->adt_def.self_type->clone_with_indirection(0,true), node)
|
||||||
vector(
|
vector(
|
||||||
make_pair("operator==", ast_function_ptr(string("operator=="), type_ptr(vector(equals_param->identifier.type), type_ptr(base_type::boolean())), vector(equals_param))),
|
make_pair("operator==", ast_function_ptr(string("operator=="), type_ptr(vector(equals_param->identifier.type), type_ptr(base_type::boolean())), vector(equals_param), false)),
|
||||||
make_pair("operator!=", ast_function_ptr(string("operator!="), type_ptr(vector(nequals_param->identifier.type), type_ptr(base_type::boolean())), vector(nequals_param))),
|
make_pair("operator!=", ast_function_ptr(string("operator!="), type_ptr(vector(nequals_param->identifier.type), type_ptr(base_type::boolean())), vector(nequals_param), false)),
|
||||||
make_pair("copy_construct", ast_function_ptr(string("copy_construct"), type_ptr(vector(copy_construct_param->identifier.type), type_ptr(base_type::void_return())), vector(copy_construct_param))),
|
make_pair("copy_construct", ast_function_ptr(string("copy_construct"), type_ptr(vector(copy_construct_param->identifier.type), type_ptr(base_type::void_return())), vector(copy_construct_param), false)),
|
||||||
make_pair("operator=", ast_function_ptr(string("operator="), type_ptr(vector(assign_param->identifier.type), type_ptr(base_type::void_return())), vector(assign_param))),
|
make_pair("operator=", ast_function_ptr(string("operator="), type_ptr(vector(assign_param->identifier.type), type_ptr(base_type::void_return())), vector(assign_param), false)),
|
||||||
make_pair("destruct", ast_function_ptr(string("destruct"), type_ptr(vector<*type>(), type_ptr(base_type::void_return())), vector<*ast_node>()))
|
make_pair("destruct", ast_function_ptr(string("destruct"), type_ptr(vector<*type>(), type_ptr(base_type::void_return())), vector<*ast_node>(), false))
|
||||||
).for_each(fun(func_pair: pair<*char, *ast_node>) {
|
).for_each(fun(func_pair: pair<*char, *ast_node>) {
|
||||||
node->adt_def.regular_funcs.add(func_pair.second)
|
node->adt_def.regular_funcs.add(func_pair.second)
|
||||||
add_to_scope(string(func_pair.first), func_pair.second, node)
|
add_to_scope(string(func_pair.first), func_pair.second, node)
|
||||||
@@ -234,7 +234,7 @@ obj ast_transformation (Object) {
|
|||||||
parameters.add(ast_identifier_ptr(concat_symbol_tree(get_node("identifier", child)), param_type, null<ast_node>()))
|
parameters.add(ast_identifier_ptr(concat_symbol_tree(get_node("identifier", child)), param_type, null<ast_node>()))
|
||||||
})
|
})
|
||||||
// figure out function type and make function_node
|
// figure out function type and make function_node
|
||||||
var function_node = ast_function_ptr(function_name, type_ptr(parameters.map(fun(parameter: *ast_node): *type return parameter->identifier.type;), return_type), parameters)
|
var function_node = ast_function_ptr(function_name, type_ptr(parameters.map(fun(parameter: *ast_node): *type return parameter->identifier.type;), return_type), parameters, get_node("\"ext\"", node) && true)
|
||||||
// fix up the enclosing_scope's
|
// fix up the enclosing_scope's
|
||||||
parameters.for_each(fun(n: *ast_node) n->identifier.enclosing_scope = function_node;)
|
parameters.for_each(fun(n: *ast_node) n->identifier.enclosing_scope = function_node;)
|
||||||
// add to scope
|
// add to scope
|
||||||
@@ -263,7 +263,8 @@ obj ast_transformation (Object) {
|
|||||||
// make sure not a template
|
// make sure not a template
|
||||||
// huh, I guess I can't actually assign to the backing.
|
// huh, I guess I can't actually assign to the backing.
|
||||||
// This is actually a little bit of a problem, maybe these should be pointers also. All the pointers!
|
// This is actually a little bit of a problem, maybe these should be pointers also. All the pointers!
|
||||||
node->function.body_statement = transform_statement(get_node("statement", ast_to_syntax[node]), node, map<string, *type>())
|
if (!node->function.is_extern)
|
||||||
|
node->function.body_statement = transform_statement(get_node("statement", ast_to_syntax[node]), node, map<string, *type>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1109,18 +1110,18 @@ fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node {
|
|||||||
// none of the builtin functions should take in references
|
// none of the builtin functions should take in references
|
||||||
param_types = param_types.map(fun(t: *type): *type return t->clone_without_ref();)
|
param_types = param_types.map(fun(t: *type): *type return t->clone_without_ref();)
|
||||||
if (name == "==" || name == "!=" || name == ">" || name == "<" || name == "<=" || name == ">" || name == ">=" || name == "&&" || name == "||" || name == "!")
|
if (name == "==" || name == "!=" || name == ">" || name == "<" || name == "<=" || name == ">" || name == ">=" || name == "&&" || name == "||" || name == "!")
|
||||||
return ast_function_ptr(name, type_ptr(param_types, type_ptr(base_type::boolean())), vector<*ast_node>())
|
return ast_function_ptr(name, type_ptr(param_types, type_ptr(base_type::boolean())), vector<*ast_node>(), false)
|
||||||
if (name == "." || name == "->")
|
if (name == "." || name == "->")
|
||||||
return ast_function_ptr(name, type_ptr(param_types, param_types[1]), vector<*ast_node>())
|
return ast_function_ptr(name, type_ptr(param_types, param_types[1]), vector<*ast_node>(), false)
|
||||||
if (name == "[]")
|
if (name == "[]")
|
||||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_decreased_indirection()), vector<*ast_node>())
|
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_decreased_indirection()), vector<*ast_node>(), false)
|
||||||
if (name == "&" && param_types.size == 1)
|
if (name == "&" && param_types.size == 1)
|
||||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_increased_indirection()), vector<*ast_node>())
|
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_increased_indirection()), vector<*ast_node>(), false)
|
||||||
if (name == "\*" && param_types.size == 1)
|
if (name == "\*" && param_types.size == 1)
|
||||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_decreased_indirection()), vector<*ast_node>())
|
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_decreased_indirection()), vector<*ast_node>(), false)
|
||||||
if (param_types.size > 1 && param_types[1]->rank() > param_types[0]->rank())
|
if (param_types.size > 1 && param_types[1]->rank() > param_types[0]->rank())
|
||||||
return ast_function_ptr(name, type_ptr(param_types, param_types[1]), vector<*ast_node>())
|
return ast_function_ptr(name, type_ptr(param_types, param_types[1]), vector<*ast_node>(), false)
|
||||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]), vector<*ast_node>())
|
return ast_function_ptr(name, type_ptr(param_types, param_types[0]), vector<*ast_node>(), false)
|
||||||
}
|
}
|
||||||
fun unify_type(template_type: *tree<symbol>, param_type: *type, new_map: *map<string, *type>, template_replacements: map<string, *type>) {
|
fun unify_type(template_type: *tree<symbol>, param_type: *type, new_map: *map<string, *type>, template_replacements: map<string, *type>) {
|
||||||
/*println(string("Unifying type: ") + concat_symbol_tree(template_type))*/
|
/*println(string("Unifying type: ") + concat_symbol_tree(template_type))*/
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ obj c_generator (Object) {
|
|||||||
var function_type_map: map<type, string>
|
var function_type_map: map<type, string>
|
||||||
var function_typedef_string: string
|
var function_typedef_string: string
|
||||||
var closure_struct_definitions: string
|
var closure_struct_definitions: string
|
||||||
|
var c_keyword_avoid: set<string>
|
||||||
var replacement_map: map<string, string>
|
var replacement_map: map<string, string>
|
||||||
var longest_replacement: int
|
var longest_replacement: int
|
||||||
var linker_string: string
|
var linker_string: string
|
||||||
@@ -91,6 +92,8 @@ obj c_generator (Object) {
|
|||||||
function_typedef_string.construct()
|
function_typedef_string.construct()
|
||||||
closure_struct_definitions.construct()
|
closure_struct_definitions.construct()
|
||||||
linker_string.construct()
|
linker_string.construct()
|
||||||
|
c_keyword_avoid.construct()
|
||||||
|
c_keyword_avoid.add(string("extern"))
|
||||||
replacement_map.construct()
|
replacement_map.construct()
|
||||||
// IMPORTANT
|
// IMPORTANT
|
||||||
longest_replacement = 3
|
longest_replacement = 3
|
||||||
@@ -146,6 +149,7 @@ obj c_generator (Object) {
|
|||||||
function_type_map.copy_construct(&old->function_type_map)
|
function_type_map.copy_construct(&old->function_type_map)
|
||||||
function_typedef_string.copy_construct(&old->function_typedef_string)
|
function_typedef_string.copy_construct(&old->function_typedef_string)
|
||||||
closure_struct_definitions.copy_construct(&old->closure_struct_definitions)
|
closure_struct_definitions.copy_construct(&old->closure_struct_definitions)
|
||||||
|
c_keyword_avoid.copy_construct(&old->c_keyword_avoid)
|
||||||
replacement_map.copy_construct(&old->replacement_map)
|
replacement_map.copy_construct(&old->replacement_map)
|
||||||
longest_replacement = old->longest_replacement
|
longest_replacement = old->longest_replacement
|
||||||
linker_string.copy_construct(&old->linker_string)
|
linker_string.copy_construct(&old->linker_string)
|
||||||
@@ -160,6 +164,7 @@ obj c_generator (Object) {
|
|||||||
function_type_map.destruct()
|
function_type_map.destruct()
|
||||||
function_typedef_string.destruct()
|
function_typedef_string.destruct()
|
||||||
closure_struct_definitions.destruct()
|
closure_struct_definitions.destruct()
|
||||||
|
c_keyword_avoid.destruct()
|
||||||
replacement_map.destruct()
|
replacement_map.destruct()
|
||||||
linker_string.destruct()
|
linker_string.destruct()
|
||||||
}
|
}
|
||||||
@@ -182,7 +187,11 @@ obj c_generator (Object) {
|
|||||||
parameters += closed_type_name + "* closure_data"
|
parameters += closed_type_name + "* closure_data"
|
||||||
}
|
}
|
||||||
|
|
||||||
var decorated_name = generate_function(child, enclosing_object, null<ast_node>(), false, false).one_string()
|
var decorated_name = string()
|
||||||
|
if (backing.is_extern)
|
||||||
|
decorated_name = backing.name
|
||||||
|
else
|
||||||
|
decorated_name = generate_function(child, enclosing_object, null<ast_node>(), false, false).one_string()
|
||||||
backing.parameters.for_each(fun(parameter: *ast_node) {
|
backing.parameters.for_each(fun(parameter: *ast_node) {
|
||||||
if (parameter_types != "") { parameter_types += ", "; parameters += ", ";}
|
if (parameter_types != "") { parameter_types += ", "; parameters += ", ";}
|
||||||
parameter_types += type_to_c(parameter->identifier.type)
|
parameter_types += type_to_c(parameter->identifier.type)
|
||||||
@@ -216,13 +225,14 @@ obj c_generator (Object) {
|
|||||||
var defer_stack = stack<pair<bool,stack<*ast_node>>>(make_pair(false, stack<*ast_node>()))
|
var defer_stack = stack<pair<bool,stack<*ast_node>>>(make_pair(false, stack<*ast_node>()))
|
||||||
var prototype_and_header = generate_function_prototype_and_header(child, enclosing_object, is_lambda, &defer_stack)
|
var prototype_and_header = generate_function_prototype_and_header(child, enclosing_object, is_lambda, &defer_stack)
|
||||||
function_prototypes += prototype_and_header.first
|
function_prototypes += prototype_and_header.first
|
||||||
function_definitions += prototype_and_header.second
|
if (!backing.is_extern)
|
||||||
|
function_definitions += prototype_and_header.second
|
||||||
if (backing.body_statement) {
|
if (backing.body_statement) {
|
||||||
function_definitions += string(" {\n") + generate_statement(backing.body_statement, enclosing_object, child, &defer_stack).one_string()
|
function_definitions += string(" {\n") + generate_statement(backing.body_statement, enclosing_object, child, &defer_stack).one_string()
|
||||||
function_definitions += generate_from_defer_stack(&defer_stack, -1, enclosing_object, child).one_string()
|
function_definitions += generate_from_defer_stack(&defer_stack, -1, enclosing_object, child).one_string()
|
||||||
function_definitions += "}\n"
|
function_definitions += "}\n"
|
||||||
} else {
|
} else if (!backing.is_extern) {
|
||||||
// adt constructor
|
// adt constructor if no body and not extern
|
||||||
// wow. no pass in for no this
|
// wow. no pass in for no this
|
||||||
enclosing_object = get_ast_scope(child)->get(string("~enclosing_scope"))[0]
|
enclosing_object = get_ast_scope(child)->get(string("~enclosing_scope"))[0]
|
||||||
// if this is an option constructor
|
// if this is an option constructor
|
||||||
@@ -361,7 +371,8 @@ obj c_generator (Object) {
|
|||||||
ast_node::declaration_statement(backing) variable_declarations += generate_declaration_statement(child, null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n" // false - don't do defer
|
ast_node::declaration_statement(backing) variable_declarations += generate_declaration_statement(child, null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n" // false - don't do defer
|
||||||
ast_node::function(backing) {
|
ast_node::function(backing) {
|
||||||
// check for and add to parameters if a closure
|
// check for and add to parameters if a closure
|
||||||
generate_function_definition(child, null<ast_node>(), false)
|
if (!backing.is_extern)
|
||||||
|
generate_function_definition(child, null<ast_node>(), false)
|
||||||
}
|
}
|
||||||
ast_node::template(backing) {
|
ast_node::template(backing) {
|
||||||
backing.instantiated.for_each(fun(node: *ast_node) {
|
backing.instantiated.for_each(fun(node: *ast_node) {
|
||||||
@@ -1027,6 +1038,8 @@ obj c_generator (Object) {
|
|||||||
return backing.name
|
return backing.name
|
||||||
if (backing.name == "main")
|
if (backing.name == "main")
|
||||||
return backing.name
|
return backing.name
|
||||||
|
if (backing.is_extern)
|
||||||
|
return backing.name
|
||||||
result = "fun_"
|
result = "fun_"
|
||||||
var upper = backing.scope.get_with_default(string("~enclosing_scope"), vector(null<ast_node>()))[0]
|
var upper = backing.scope.get_with_default(string("~enclosing_scope"), vector(null<ast_node>()))[0]
|
||||||
if (upper && is_type_def(upper))
|
if (upper && is_type_def(upper))
|
||||||
@@ -1042,8 +1055,10 @@ obj c_generator (Object) {
|
|||||||
}
|
}
|
||||||
if (result == "impossible name")
|
if (result == "impossible name")
|
||||||
error("HUGE PROBLEMS")
|
error("HUGE PROBLEMS")
|
||||||
if (ast_name_map.contains_value(result))
|
// TODO keyword avoid seems not to work
|
||||||
|
if (ast_name_map.contains_value(result) || c_keyword_avoid.contains(result))
|
||||||
result += get_id()
|
result += get_id()
|
||||||
|
println("HERE: " + result)
|
||||||
ast_name_map.set(node, result)
|
ast_name_map.set(node, result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
1
tests/test_extern.expected_results
Normal file
1
tests/test_extern.expected_results
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Hello extern!
|
||||||
8
tests/test_extern.krak
Normal file
8
tests/test_extern.krak
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
ext fun printf(format_str: *char, actual_str: *char): int
|
||||||
|
|
||||||
|
fun main():int {
|
||||||
|
printf("%s", "Hello extern!\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user