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:
Nathan Braswell
2016-04-18 22:56:29 -04:00
parent d5b930739f
commit cf46fb13af
7 changed files with 71 additions and 9 deletions

View File

@@ -1,4 +1,5 @@
Goal = translation_unit ; Goal = translation_unit ;
cast_expression = "\(" WS boolean_expression WS "\)" WS "cast" WS type ;
translation_unit = WS unorderd_list_part WS ; 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 ; 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 ; shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ;
term = term WS "/" WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ; 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 ; 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 ; 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 ; 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" ; 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))'" ; 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)*" ; 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 ; augmented_alpha_alphanumeric = alpha_alphanumeric augmented_alpha_alphanumeric | keywords_also_identifiers augmented_alpha_alphanumeric | alpha_alphanumeric | keywords_also_identifiers ;

View File

@@ -35,6 +35,7 @@ adt ast_node {
if_comp: if_comp, if_comp: if_comp,
simple_passthrough: simple_passthrough, simple_passthrough: simple_passthrough,
function_call: function_call, function_call: function_call,
cast: cast,
value: value value: value
} }
/* /*
@@ -960,6 +961,40 @@ obj function_call (Object) {
return func == func && parameters == other.parameters 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 { fun ast_value_ptr(string_value: string, value_type: *type): *ast_node {
var to_ret.construct(string_value, value_type): value var to_ret.construct(string_value, value_type): value
var ptr = new<ast_node>() 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::if_comp(backing) return vector<*ast_node>(backing.statement)
ast_node::simple_passthrough(backing) return vector<*ast_node>() ast_node::simple_passthrough(backing) return vector<*ast_node>()
ast_node::function_call(backing) return vector(backing.func) + backing.parameters 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>() 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::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::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::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() ast_node::value(backing) return string("value: ") + backing.string_value + ": " + backing.value_type->to_string()
} }
return string("impossible adt type") 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 { fun get_ast_type(node: *ast_node): *type {
match (*node) { match (*node) {
ast_node::identifier() return node->identifier.type ast_node::identifier(backing) return backing.type
ast_node::function() return node->function.type ast_node::function(backing) return backing.type
ast_node::function_call() return get_ast_type(node->function_call.func)->return_type ast_node::function_call(backing) return get_ast_type(backing.func)->return_type
ast_node::value() return node->value.value_type ast_node::cast(backing) return backing.to_type
ast_node::value(backing) return backing.value_type
} }
} }

View File

@@ -460,7 +460,7 @@ obj ast_transformation (Object) {
|| name == "bool_exp" || name == "expression" || name == "bool_exp" || name == "expression"
|| name == "shiftand" || name == "term" || name == "shiftand" || name == "term"
|| name == "factor" || name == "unarad" || name == "factor" || name == "unarad"
|| name == "access_operation" || name == "access_operation" || name == "cast_expression"
) { ) {
// for now, assume passthrough and just transform underneath // for now, assume passthrough and just transform underneath
return transform_expression(node, scope, searching_for, template_replacements) return transform_expression(node, scope, searching_for, template_replacements)
@@ -605,6 +605,8 @@ obj ast_transformation (Object) {
if (identifiers.size == 2) { 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 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) 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) declaration->declaration_statement.init_method_call = make_method_call(identifier, method, parameters)
} }
return declaration return declaration
@@ -885,6 +887,8 @@ obj ast_transformation (Object) {
func_name = concat_symbol_tree(node->children[1]) func_name = concat_symbol_tree(node->children[1])
if (func_name == "[") if (func_name == "[")
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 first_param = transform(node->children[0], scope, template_replacements)
var second_param = null<ast_node>() var second_param = null<ast_node>()
if (func_name == "." || func_name == "->") { if (func_name == "." || func_name == "->") {

View File

@@ -586,6 +586,11 @@ obj c_generator (Object) {
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>()) 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 // 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" 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)))))) { 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() 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 { } else {
@@ -658,6 +663,9 @@ obj c_generator (Object) {
}) })
return to_ret 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 { fun generate_value(node: *ast_node, need_variable: bool): code_triple {
var value = node->value.string_value var value = node->value.string_value
var to_ret = string() 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::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::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::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::value(backing) return generate_value(node, need_variable)
ast_node::identifier(backing) return generate_identifier(node, enclosing_object, enclosing_func) ast_node::identifier(backing) return generate_identifier(node, enclosing_object, enclosing_func)
} }

View File

@@ -19,6 +19,7 @@ fun print<T>(toPrint: *T) : void{
__if_comp__ __C__ { __if_comp__ __C__ {
simple_passthrough(toPrint = toPrint::) """ simple_passthrough(toPrint = toPrint::) """
printf("%p", (void*)toPrint); printf("%p", (void*)toPrint);
fflush(0);
""" """
} }
return; return;
@@ -28,6 +29,7 @@ fun print(toPrint: *char) : void {
__if_comp__ __C__ { __if_comp__ __C__ {
simple_passthrough(toPrint = toPrint::) """ simple_passthrough(toPrint = toPrint::) """
printf("%s", toPrint); printf("%s", toPrint);
fflush(0);
""" """
} }
return; return;
@@ -37,6 +39,7 @@ fun print(toPrint: char) : void {
__if_comp__ __C__ { __if_comp__ __C__ {
simple_passthrough(toPrint = toPrint::) """ simple_passthrough(toPrint = toPrint::) """
printf("%c", toPrint); printf("%c", toPrint);
fflush(0);
""" """
} }
return; return;
@@ -60,6 +63,7 @@ fun print(toPrint: int): void {
__if_comp__ __C__ { __if_comp__ __C__ {
simple_passthrough(toPrint = toPrint::) """ simple_passthrough(toPrint = toPrint::) """
printf("%d", toPrint); printf("%d", toPrint);
fflush(0);
""" """
} }
return; return;
@@ -69,6 +73,7 @@ fun print(toPrint: float): void {
__if_comp__ __C__ { __if_comp__ __C__ {
simple_passthrough(toPrint = toPrint::) """ simple_passthrough(toPrint = toPrint::) """
printf("%f", toPrint); printf("%f", toPrint);
fflush(0);
""" """
} }
return; return;
@@ -78,6 +83,7 @@ fun print(toPrint: double) : void{
__if_comp__ __C__ { __if_comp__ __C__ {
simple_passthrough(toPrint = toPrint::) """ simple_passthrough(toPrint = toPrint::) """
printf("%f", toPrint); printf("%f", toPrint);
fflush(0);
""" """
} }
return; return;

View File

@@ -185,6 +185,7 @@ obj type (Object) {
} }
fun clone(): *type return clone_with_indirection(indirection, is_ref); fun clone(): *type return clone_with_indirection(indirection, is_ref);
fun clone_without_ref(): *type return clone_with_indirection(indirection, false); 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(): *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_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); fun clone_with_decreased_indirection(): *type return clone_with_indirection(indirection-1);

View File

@@ -6,8 +6,10 @@ fun main():int {
println(to_int('B')) println(to_int('B'))
var a = 1337 var a = 1337
var b = &a var b = &a;
var c = cast_ptr<*int, *char>(b) var c = (b) cast *char
/*var c = cast_ptr<*int, *char>(b)*/
//var d = c + 1 //var d = c + 1
//var e = 1 + c //var e = 1 + c
println(to_int(*(c+0))) println(to_int(*(c+0)))