Add casting as a language feature. Have not removed the function yet as we need an inbetween version for the bootstrap
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
Goal = translation_unit ;
|
||||
cast_expression = "\(" WS boolean_expression WS "\)" WS "cast" WS type ;
|
||||
translation_unit = WS unorderd_list_part WS ;
|
||||
unorderd_list_part = import WS unorderd_list_part | function WS unorderd_list_part | type_def line_end WS unorderd_list_part | adt_def line_end WS unorderd_list_part | if_comp WS unorderd_list_part | simple_passthrough WS unorderd_list_part | declaration_statement line_end WS unorderd_list_part | import | function | type_def line_end | adt_def line_end | if_comp | simple_passthrough | declaration_statement line_end ;
|
||||
|
||||
@@ -125,7 +126,8 @@ expression = expression WS "<<" WS term | expression WS right_shift WS shiftand
|
||||
shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ;
|
||||
term = term WS "/" WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ;
|
||||
factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ;
|
||||
unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | unarad WS "[" WS expression WS "]" | lambda ;
|
||||
unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | unarad WS "[" WS expression WS "]" | lambda | cast_expression ;
|
||||
cast_expression = "\(" WS boolean_expression WS "\)" WS "cast" WS type ;
|
||||
number = integer | floating_literal ;
|
||||
access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier | unarad WS "." WS identifier WS template_inst | unarad WS "->" WS identifier WS template_inst ;
|
||||
|
||||
@@ -139,7 +141,7 @@ float_end = "(0|1|2|3|4|5|6|7|8|9)+" | "(0|1|2|3|4|5|6|7|8|9)+f" | "(0|1|2|3|4|5
|
||||
bool = "true" | "false" ;
|
||||
character = "'(`|1|2|3|4|5|6|7|8|9|0|-|=|(\\t)|q|w|e|r|t|y|u|i|o|p|[|]|(\\\\)|a|s|d|f|g|h|j|k|l|;|(\\')|(\\n)|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|\"|Z|X|C|V|B|N|M|<|>|\?| |(\\0))'" ;
|
||||
|
||||
keywords_also_identifiers = "obj" | "def" | "fun" | "var" | "ref" | "adt" | "import" | "simple_passthrough" ;
|
||||
keywords_also_identifiers = "obj" | "def" | "fun" | "var" | "ref" | "adt" | "cast" | "import" | "simple_passthrough" ;
|
||||
alpha_alphanumeric = "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|_)(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|_|0|1|2|3|4|5|6|7|8|9)*" ;
|
||||
augmented_alpha_alphanumeric = alpha_alphanumeric augmented_alpha_alphanumeric | keywords_also_identifiers augmented_alpha_alphanumeric | alpha_alphanumeric | keywords_also_identifiers ;
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ adt ast_node {
|
||||
if_comp: if_comp,
|
||||
simple_passthrough: simple_passthrough,
|
||||
function_call: function_call,
|
||||
cast: cast,
|
||||
value: value
|
||||
}
|
||||
/*
|
||||
@@ -960,6 +961,40 @@ obj function_call (Object) {
|
||||
return func == func && parameters == other.parameters
|
||||
}
|
||||
}
|
||||
fun ast_cast_ptr(value: *ast_node, to_type: *type): *ast_node {
|
||||
var to_ret.construct(value, to_type): cast
|
||||
var ptr = new<ast_node>()
|
||||
ptr->copy_construct(&ast_node::cast(to_ret))
|
||||
return ptr
|
||||
}
|
||||
fun is_cast(node: *ast_node): bool {
|
||||
match(*node) {
|
||||
ast_node::cast(backing) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
obj cast (Object) {
|
||||
var value: *ast_node
|
||||
var to_type: *type
|
||||
fun construct(value_in: *ast_node, to_type_in: *type): *cast {
|
||||
value = value_in
|
||||
to_type = to_type_in
|
||||
return this
|
||||
}
|
||||
fun copy_construct(old: *cast) {
|
||||
value = old->value
|
||||
to_type = old->to_type
|
||||
}
|
||||
fun destruct() {
|
||||
}
|
||||
fun operator=(other: cast) {
|
||||
destruct()
|
||||
copy_construct(&other)
|
||||
}
|
||||
fun operator==(other: cast): bool {
|
||||
return value == other.value && to_type == other.to_type
|
||||
}
|
||||
}
|
||||
fun ast_value_ptr(string_value: string, value_type: *type): *ast_node {
|
||||
var to_ret.construct(string_value, value_type): value
|
||||
var ptr = new<ast_node>()
|
||||
@@ -1024,6 +1059,7 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> {
|
||||
ast_node::if_comp(backing) return vector<*ast_node>(backing.statement)
|
||||
ast_node::simple_passthrough(backing) return vector<*ast_node>()
|
||||
ast_node::function_call(backing) return vector(backing.func) + backing.parameters
|
||||
ast_node::cast(backing) return vector<*ast_node>(backing.value)
|
||||
ast_node::value(backing) return vector<*ast_node>()
|
||||
}
|
||||
}
|
||||
@@ -1051,6 +1087,7 @@ fun get_ast_name(node: *ast_node): string {
|
||||
ast_node::if_comp(backing) return string("if_comp: ") + backing.wanted_generator
|
||||
ast_node::simple_passthrough(backing) return string("simple_passthrough: , string:") + backing.passthrough_str
|
||||
ast_node::function_call(backing) return string("function_call:") + get_ast_name(backing.func) + "(" + backing.parameters.size + ")"
|
||||
ast_node::cast(backing) return string("cast: ") + get_ast_name(backing.value) + ": " + backing.to_type->to_string()
|
||||
ast_node::value(backing) return string("value: ") + backing.string_value + ": " + backing.value_type->to_string()
|
||||
}
|
||||
return string("impossible adt type")
|
||||
@@ -1079,10 +1116,11 @@ fun get_ast_scope(node: *ast_node): *map<string,vector<*ast_node>> {
|
||||
}
|
||||
fun get_ast_type(node: *ast_node): *type {
|
||||
match (*node) {
|
||||
ast_node::identifier() return node->identifier.type
|
||||
ast_node::function() return node->function.type
|
||||
ast_node::function_call() return get_ast_type(node->function_call.func)->return_type
|
||||
ast_node::value() return node->value.value_type
|
||||
ast_node::identifier(backing) return backing.type
|
||||
ast_node::function(backing) return backing.type
|
||||
ast_node::function_call(backing) return get_ast_type(backing.func)->return_type
|
||||
ast_node::cast(backing) return backing.to_type
|
||||
ast_node::value(backing) return backing.value_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -460,7 +460,7 @@ obj ast_transformation (Object) {
|
||||
|| name == "bool_exp" || name == "expression"
|
||||
|| name == "shiftand" || name == "term"
|
||||
|| name == "factor" || name == "unarad"
|
||||
|| name == "access_operation"
|
||||
|| name == "access_operation" || name == "cast_expression"
|
||||
) {
|
||||
// for now, assume passthrough and just transform underneath
|
||||
return transform_expression(node, scope, searching_for, template_replacements)
|
||||
@@ -605,6 +605,8 @@ obj ast_transformation (Object) {
|
||||
if (identifiers.size == 2) {
|
||||
var parameters = get_nodes("parameter", node).map(fun(child: *tree<symbol>): *ast_node return transform(get_node("boolean_expression", child), scope, template_replacements);)
|
||||
var method = transform(identifiers[1], identifier->identifier.type->type_def, search_type::function(parameters.map(fun(i:*ast_node):*type return get_ast_type(i);)), template_replacements)
|
||||
if (!method)
|
||||
error(identifiers[1], "Cannot find method for declaration site method call")
|
||||
declaration->declaration_statement.init_method_call = make_method_call(identifier, method, parameters)
|
||||
}
|
||||
return declaration
|
||||
@@ -885,6 +887,8 @@ obj ast_transformation (Object) {
|
||||
func_name = concat_symbol_tree(node->children[1])
|
||||
if (func_name == "[")
|
||||
func_name += "]"
|
||||
if (func_name == "cast")
|
||||
return ast_cast_ptr(transform(get_node("boolean_expression", node), scope, template_replacements), transform_type(get_node("type", node), scope, template_replacements))
|
||||
var first_param = transform(node->children[0], scope, template_replacements)
|
||||
var second_param = null<ast_node>()
|
||||
if (func_name == "." || func_name == "->") {
|
||||
|
||||
@@ -586,6 +586,11 @@ obj c_generator (Object) {
|
||||
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
|
||||
// have to pass false to the declaration generator, so can't do it through generate_statement
|
||||
to_ret.pre = generate_declaration_statement(declaration, enclosing_object, enclosing_func, defer_stack, false).one_string() + ";\n"
|
||||
if ((function_return_type->is_object() || temp_ident_type->is_object()) &&
|
||||
( (!function_return_type->is_ref && !function_return_type->equality(temp_ident_type, false)) ||
|
||||
(function_return_type->is_ref && !function_return_type->equality(temp_ident_type->clone_with_decreased_indirection(), false)) ) )
|
||||
// note the clone with decreased indirection because of the clone with increased indirection above
|
||||
error(string("return type does not match: ") + function_return_type->to_string() + ", " + temp_ident_type->to_string());
|
||||
if (!function_return_type->is_ref && return_value_type->indirection == 0 && (return_value_type->is_adt() || (return_value_type->is_object() && has_method(return_value_type->type_def, "copy_construct", vector(return_value_type->clone_with_indirection(1)))))) {
|
||||
to_ret.pre += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(return_value))))), enclosing_object, enclosing_func, defer_stack).one_string()
|
||||
} else {
|
||||
@@ -658,6 +663,9 @@ obj c_generator (Object) {
|
||||
})
|
||||
return to_ret
|
||||
}
|
||||
fun generate_cast(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>, need_variable: bool): code_triple {
|
||||
return code_triple("(") + type_to_c(node->cast.to_type) + ")(" + generate(node->cast.value, enclosing_object, enclosing_func, defer_stack, false) + ")"
|
||||
}
|
||||
fun generate_value(node: *ast_node, need_variable: bool): code_triple {
|
||||
var value = node->value.string_value
|
||||
var to_ret = string()
|
||||
@@ -924,6 +932,7 @@ obj c_generator (Object) {
|
||||
ast_node::branching_statement(backing) return generate_branching_statement(node, enclosing_object, enclosing_func, defer_stack)
|
||||
ast_node::defer_statement(backing) return generate_defer_statement(node, enclosing_object, enclosing_func, defer_stack)
|
||||
ast_node::match_statement(backing) return generate_match_statement(node, enclosing_object, enclosing_func, defer_stack)
|
||||
ast_node::cast(backing) return generate_cast(node, enclosing_object, enclosing_func, defer_stack, need_variable)
|
||||
ast_node::value(backing) return generate_value(node, need_variable)
|
||||
ast_node::identifier(backing) return generate_identifier(node, enclosing_object, enclosing_func)
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ fun print<T>(toPrint: *T) : void{
|
||||
__if_comp__ __C__ {
|
||||
simple_passthrough(toPrint = toPrint::) """
|
||||
printf("%p", (void*)toPrint);
|
||||
fflush(0);
|
||||
"""
|
||||
}
|
||||
return;
|
||||
@@ -28,6 +29,7 @@ fun print(toPrint: *char) : void {
|
||||
__if_comp__ __C__ {
|
||||
simple_passthrough(toPrint = toPrint::) """
|
||||
printf("%s", toPrint);
|
||||
fflush(0);
|
||||
"""
|
||||
}
|
||||
return;
|
||||
@@ -37,6 +39,7 @@ fun print(toPrint: char) : void {
|
||||
__if_comp__ __C__ {
|
||||
simple_passthrough(toPrint = toPrint::) """
|
||||
printf("%c", toPrint);
|
||||
fflush(0);
|
||||
"""
|
||||
}
|
||||
return;
|
||||
@@ -60,6 +63,7 @@ fun print(toPrint: int): void {
|
||||
__if_comp__ __C__ {
|
||||
simple_passthrough(toPrint = toPrint::) """
|
||||
printf("%d", toPrint);
|
||||
fflush(0);
|
||||
"""
|
||||
}
|
||||
return;
|
||||
@@ -69,6 +73,7 @@ fun print(toPrint: float): void {
|
||||
__if_comp__ __C__ {
|
||||
simple_passthrough(toPrint = toPrint::) """
|
||||
printf("%f", toPrint);
|
||||
fflush(0);
|
||||
"""
|
||||
}
|
||||
return;
|
||||
@@ -78,6 +83,7 @@ fun print(toPrint: double) : void{
|
||||
__if_comp__ __C__ {
|
||||
simple_passthrough(toPrint = toPrint::) """
|
||||
printf("%f", toPrint);
|
||||
fflush(0);
|
||||
"""
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -185,6 +185,7 @@ obj type (Object) {
|
||||
}
|
||||
fun clone(): *type return clone_with_indirection(indirection, is_ref);
|
||||
fun clone_without_ref(): *type return clone_with_indirection(indirection, false);
|
||||
fun clone_with_ref(): *type return clone_with_indirection(indirection, true);
|
||||
fun clone_with_increased_indirection(): *type return clone_with_indirection(indirection+1);
|
||||
fun clone_with_increased_indirection(more: int, is_ref_in: bool): *type return clone_with_indirection(indirection+more, is_ref_in);
|
||||
fun clone_with_decreased_indirection(): *type return clone_with_indirection(indirection-1);
|
||||
|
||||
@@ -6,8 +6,10 @@ fun main():int {
|
||||
println(to_int('B'))
|
||||
|
||||
var a = 1337
|
||||
var b = &a
|
||||
var c = cast_ptr<*int, *char>(b)
|
||||
var b = &a;
|
||||
var c = (b) cast *char
|
||||
|
||||
/*var c = cast_ptr<*int, *char>(b)*/
|
||||
//var d = c + 1
|
||||
//var e = 1 + c
|
||||
println(to_int(*(c+0)))
|
||||
|
||||
Reference in New Issue
Block a user