Added in sizeof intrinsic + piping for more in the future. Inbetween commit before removing sizeof function

This commit is contained in:
Nathan Braswell
2016-04-28 18:47:53 -04:00
parent b52d38f648
commit 2051f54b55
7 changed files with 98 additions and 1 deletions

View File

@@ -117,6 +117,10 @@ continue_statement = "continue" ;
defer_statement = "defer" WS statement ;
function_call = unarad WS "\(" WS opt_parameter_list WS "\)" ;
compiler_intrinsic = "#" identifier WS "\(" WS intrinsic_parameter_list WS "\)" | "#" identifier WS "<" WS type_list WS ">" ;
intrinsic_parameter_list = intrinsic_parameter_list WS "," WS intrinsic_parameter | intrinsic_parameter ;
intrinsic_parameter = identifier ;
boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ;
and_boolean_expression = and_boolean_expression WS "&&" WS bitwise_or | bitwise_or ;
bitwise_or = bitwise_or WS "\|" WS bitwise_xor | bitwise_xor ;
@@ -129,7 +133,7 @@ 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 | cast_expression ;
unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | compiler_intrinsic | 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 ;

View File

@@ -35,6 +35,7 @@ adt ast_node {
if_comp: if_comp,
simple_passthrough: simple_passthrough,
function_call: function_call,
compiler_intrinsic: compiler_intrinsic,
cast: cast,
value: value
}
@@ -961,6 +962,50 @@ obj function_call (Object) {
return func == func && parameters == other.parameters
}
}
fun ast_compiler_intrinsic_ptr(intrinsic: string, parameters: vector<string>, type_parameters: vector<*type>, return_type: *type): *ast_node {
var to_ret.construct(intrinsic, parameters, type_parameters, return_type): compiler_intrinsic
var ptr = new<ast_node>()
ptr->copy_construct(&ast_node::compiler_intrinsic(to_ret))
return ptr
}
fun is_compiler_intrinsic(node: *ast_node): bool {
match(*node) {
ast_node::compiler_intrinsic(backing) return true
}
return false
}
obj compiler_intrinsic (Object) {
var intrinsic: string
var parameters: vector<string>
var type_parameters: vector<*type>
var return_type: *type
fun construct(intrinsic_in: string, parameters_in: vector<string>, type_parameters_in: vector<*type>, return_type_in: *type): *compiler_intrinsic {
intrinsic.copy_construct(&intrinsic_in)
parameters.copy_construct(&parameters_in)
type_parameters.copy_construct(&type_parameters_in)
return_type = return_type_in
return this
}
/*fun copy_construct(old: *function_call) {*/
fun copy_construct(old: *compiler_intrinsic) {
intrinsic.copy_construct(&old->intrinsic)
parameters.copy_construct(&old->parameters)
type_parameters.copy_construct(&old->type_parameters)
return_type = old->return_type
}
fun destruct() {
intrinsic.destruct()
parameters.destruct()
type_parameters.destruct()
}
fun operator=(other: ref compiler_intrinsic) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref compiler_intrinsic): bool {
return intrinsic == intrinsic && parameters == other.parameters && type_parameters == other.type_parameters && return_type == other.return_type
}
}
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>()
@@ -1059,6 +1104,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::compiler_intrinsic(backing) return vector<*ast_node>()
ast_node::cast(backing) return vector<*ast_node>(backing.value)
ast_node::value(backing) return vector<*ast_node>()
}
@@ -1087,6 +1133,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::compiler_intrinsic(backing) return string("compiler_intrinsic:") + backing.intrinsic + "(" + backing.parameters.size + "," + backing.type_parameters.size + "):" + backing.return_type->to_string()
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()
}
@@ -1119,6 +1166,7 @@ fun get_ast_type(node: *ast_node): *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::compiler_intrinsic(backing) return backing.return_type
ast_node::cast(backing) return backing.to_type
ast_node::value(backing) return backing.value_type
}

View File

@@ -454,6 +454,8 @@ obj ast_transformation (Object) {
return transform_match_statement(node, scope, template_replacements)
} else if (name == "function_call") {
return transform_function_call(node, scope, template_replacements)
} else if (name == "compiler_intrinsic") {
return transform_compiler_intrinsic(node, scope, template_replacements)
} else if (name == "lambda") {
return transform_lambda(node, scope, template_replacements)
} else if (name == "boolean_expression" || name == "and_boolean_expression"
@@ -755,6 +757,16 @@ obj ast_transformation (Object) {
/*f->function_call.parameters.for_each(fun(param: *ast_node) print(param);)*/
return f
}
fun transform_compiler_intrinsic(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
// don't bother with a full transform for parameters with their own function, just get the boolean expression and transform it
var parameters = vector<string>()
var type_parameters = vector<*type>()
if (get_nodes("intrinsic_parameter", node).size)
parameters = get_nodes("intrinsic_parameter", node).map(fun(child: *tree<symbol>): string return concat_symbol_tree(child);)
if (get_nodes("type", node).size)
type_parameters = get_nodes("type", node).map(fun(child: *tree<symbol>): *type return transform_type(child, scope, template_replacements);)
return ast_compiler_intrinsic_ptr(concat_symbol_tree(get_node("identifier", node)), parameters, type_parameters, type_ptr(base_type::integer()))
}
fun transform_lambda(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
var function_node = second_pass_function(node, scope, template_replacements, false)
function_node->function.body_statement = transform_statement(get_node("statement", node), function_node, template_replacements)
@@ -918,6 +930,11 @@ obj ast_transformation (Object) {
}
}
}
// this is the case where it's null but not a method call. Should add default to case above and move there
if (!second_param) {
error(node, "Could not find member " + concat_symbol_tree(node->children[2]) + " on the right side of (. or ->) " + concat_symbol_tree(node->children[0]) +
", whole string: " + concat_symbol_tree(node) + ", left type: " + get_ast_type(first_param)->to_string())
}
} else {
second_param = transform(node->children[2], scope, template_replacements)
}

View File

@@ -911,6 +911,15 @@ obj c_generator (Object) {
call_string.value = ref_pre + call_string.value + ref_post
return call_string
}
fun generate_compiler_intrinsic(node: *ast_node): code_triple {
if (node->compiler_intrinsic.intrinsic == "sizeof") {
if (node->compiler_intrinsic.parameters.size || node->compiler_intrinsic.type_parameters.size != 1)
error("wrong parameters to sizeof compiler intrinsic")
return code_triple("sizeof(") + type_to_c(node->compiler_intrinsic.type_parameters[0]) + ")"
}
error(node->compiler_intrinsic.intrinsic + ": unknown intrinsic")
return code_triple("ERROR")
}
// for now, anyway
fun generate(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>, need_variable: bool): code_triple {
@@ -926,6 +935,7 @@ obj c_generator (Object) {
ast_node::for_loop(backing) return generate_for_loop(node, enclosing_object, enclosing_func, defer_stack)
ast_node::function(backing) return generate_function(node, enclosing_object, enclosing_func, true, need_variable)
ast_node::function_call(backing) return generate_function_call(node, enclosing_object, enclosing_func, need_variable)
ast_node::compiler_intrinsic(backing) return generate_compiler_intrinsic(node)
ast_node::code_block(backing) return generate_code_block(node, enclosing_object, enclosing_func, defer_stack)
ast_node::return_statement(backing) return generate_return_statement(node, enclosing_object, enclosing_func, defer_stack)
ast_node::branching_statement(backing) return generate_branching_statement(node, enclosing_object, enclosing_func, defer_stack)

View File

@@ -123,6 +123,7 @@ obj importer (Object) {
collapse_node(symbol("param_assign_list", false), parse_tree)
collapse_node(symbol("opt_typed_parameter_list", false), parse_tree)
collapse_node(symbol("opt_parameter_list", false), parse_tree)
collapse_node(symbol("intrinsic_parameter_list", false), parse_tree)
collapse_node(symbol("identifier_list", false), parse_tree)
collapse_node(symbol("adt_option_list", false), parse_tree)
collapse_node(symbol("statement_list", false), parse_tree)

View File

@@ -0,0 +1,5 @@
1
4
4
8
8

View File

@@ -0,0 +1,12 @@
import simple_print:*
fun main(): int {
println(#sizeof<char>)
println(#sizeof<int>)
println(#sizeof<float>)
println(#sizeof<double>)
println(#sizeof<*void>)
return 0
}