Added support for unions as a step towards lowering ADTs in the next pass to be written.
This commit is contained in:
@@ -83,9 +83,8 @@ opt_parameter_list = parameter_list | ;
|
|||||||
parameter_list = parameter_list WS "," WS parameter | parameter ;
|
parameter_list = parameter_list WS "," WS parameter | parameter ;
|
||||||
parameter = boolean_expression ;
|
parameter = boolean_expression ;
|
||||||
|
|
||||||
def_nonterm = "def" ;
|
obj_nonterm = "obj" | "uni" ;
|
||||||
obj_nonterm = "obj" ;
|
type_def = obj_nonterm WS identifier WS template_dec WS "{" WS declaration_block WS "}" | obj_nonterm WS identifier WS "{" WS declaration_block WS "}" | obj_nonterm WS identifier WS template_dec WS traits WS "{" WS declaration_block WS "}" | obj_nonterm WS identifier WS traits WS "{" WS declaration_block WS "}" ;
|
||||||
type_def = def_nonterm WS identifier WS type | obj_nonterm WS identifier WS template_dec WS "{" WS declaration_block WS "}" | obj_nonterm WS identifier WS "{" WS declaration_block WS "}" | obj_nonterm WS identifier WS template_dec WS traits WS "{" WS declaration_block WS "}" | obj_nonterm WS identifier WS traits WS "{" WS declaration_block WS "}" ;
|
|
||||||
|
|
||||||
declaration_block = declaration_statement line_end WS declaration_block | function WS declaration_block | declaration_statement line_end | function | ;
|
declaration_block = declaration_statement line_end WS declaration_block | function WS declaration_block | declaration_statement line_end | function | ;
|
||||||
traits = "\(" WS trait_list WS "\)" ;
|
traits = "\(" WS trait_list WS "\)" ;
|
||||||
|
|||||||
@@ -190,8 +190,10 @@ obj identifier (Object) {
|
|||||||
return name == other.name && type == other.type && enclosing_scope == other.enclosing_scope
|
return name == other.name && type == other.type && enclosing_scope == other.enclosing_scope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun ast_type_def_ptr(name: string): *ast_node {
|
fun ast_type_def_ptr(name: ref string): *ast_node
|
||||||
var to_ret.construct(name): type_def
|
return ast_type_def_ptr(name, false)
|
||||||
|
fun ast_type_def_ptr(name: ref string, is_union: bool): *ast_node {
|
||||||
|
var to_ret.construct(name, is_union): type_def
|
||||||
var ptr = new<ast_node>()
|
var ptr = new<ast_node>()
|
||||||
ptr->copy_construct(&ast_node::type_def(to_ret))
|
ptr->copy_construct(&ast_node::type_def(to_ret))
|
||||||
return ptr
|
return ptr
|
||||||
@@ -205,12 +207,14 @@ fun is_type_def(node: *ast_node): bool {
|
|||||||
obj type_def (Object) {
|
obj type_def (Object) {
|
||||||
var scope: map<string, vector<*ast_node>>
|
var scope: map<string, vector<*ast_node>>
|
||||||
var name: string
|
var name: string
|
||||||
|
var is_union: bool
|
||||||
var self_type: *type
|
var self_type: *type
|
||||||
var variables: vector<*ast_node>
|
var variables: vector<*ast_node>
|
||||||
var methods: vector<*ast_node>
|
var methods: vector<*ast_node>
|
||||||
fun construct(nameIn: string): *type_def {
|
fun construct(nameIn: ref string, is_unionIn: bool): *type_def {
|
||||||
scope.construct()
|
scope.construct()
|
||||||
name.copy_construct(&nameIn)
|
name.copy_construct(&nameIn)
|
||||||
|
is_union = is_unionIn
|
||||||
self_type = null<type>()
|
self_type = null<type>()
|
||||||
variables.construct()
|
variables.construct()
|
||||||
methods.construct()
|
methods.construct()
|
||||||
@@ -220,6 +224,7 @@ obj type_def (Object) {
|
|||||||
self_type = old->self_type
|
self_type = old->self_type
|
||||||
scope.copy_construct(&old->scope)
|
scope.copy_construct(&old->scope)
|
||||||
name.copy_construct(&old->name)
|
name.copy_construct(&old->name)
|
||||||
|
is_union = old->is_union
|
||||||
variables.copy_construct(&old->variables)
|
variables.copy_construct(&old->variables)
|
||||||
methods.copy_construct(&old->methods)
|
methods.copy_construct(&old->methods)
|
||||||
}
|
}
|
||||||
@@ -234,7 +239,7 @@ obj type_def (Object) {
|
|||||||
copy_construct(&other)
|
copy_construct(&other)
|
||||||
}
|
}
|
||||||
fun operator==(other: ref type_def): bool {
|
fun operator==(other: ref type_def): bool {
|
||||||
return name == other.name && self_type == other.self_type && variables == other.variables && methods == other.methods
|
return name == other.name && is_union == other.is_union && self_type == other.self_type && variables == other.variables && methods == other.methods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun ast_adt_def_ptr(name: string): *ast_node {
|
fun ast_adt_def_ptr(name: string): *ast_node {
|
||||||
@@ -1128,7 +1133,7 @@ fun get_ast_name(node: *ast_node): string {
|
|||||||
ast_node::translation_unit(backing) return string("translation_unit: ") + backing.name
|
ast_node::translation_unit(backing) return string("translation_unit: ") + backing.name
|
||||||
ast_node::import(backing) return string("import: ") + backing.name + "; [" + backing.imported.reduce(fun(name: string, acc: string): string return acc + " " + name;, string()) + " ]"
|
ast_node::import(backing) return string("import: ") + backing.name + "; [" + backing.imported.reduce(fun(name: string, acc: string): string return acc + " " + name;, 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 + " union?:" + backing.is_union
|
||||||
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) {
|
ast_node::function(backing) {
|
||||||
if (backing.is_extern)
|
if (backing.is_extern)
|
||||||
|
|||||||
@@ -103,7 +103,8 @@ obj ast_transformation (Object) {
|
|||||||
add_to_scope(name, template, scope)
|
add_to_scope(name, template, scope)
|
||||||
return template
|
return template
|
||||||
} else {
|
} else {
|
||||||
var type_def_node = ast_type_def_ptr(name)
|
// pass in whether or not this is a union
|
||||||
|
var type_def_node = ast_type_def_ptr(name, concat_symbol_tree(get_node("obj_nonterm", child)) == "uni")
|
||||||
type_def_node->type_def.self_type = type_ptr(type_def_node, transform_traits(get_node("traits", child)))
|
type_def_node->type_def.self_type = type_ptr(type_def_node, transform_traits(get_node("traits", child)))
|
||||||
ast_to_syntax.set(type_def_node, child)
|
ast_to_syntax.set(type_def_node, child)
|
||||||
add_to_scope("~enclosing_scope", scope, type_def_node)
|
add_to_scope("~enclosing_scope", scope, type_def_node)
|
||||||
|
|||||||
@@ -445,8 +445,16 @@ obj c_generator (Object) {
|
|||||||
type_poset.get_sorted().for_each(fun(vert: *ast_node) {
|
type_poset.get_sorted().for_each(fun(vert: *ast_node) {
|
||||||
/*var base_name = vert->type_def.name*/
|
/*var base_name = vert->type_def.name*/
|
||||||
var base_name = get_name(vert)
|
var base_name = get_name(vert)
|
||||||
plain_typedefs += string("typedef struct ") + base_name + "_dummy " + base_name + ";\n"
|
plain_typedefs += string("typedef ")
|
||||||
structs += string("struct ") + base_name + "_dummy {\n"
|
if (vert->type_def.is_union) {
|
||||||
|
plain_typedefs += "union "
|
||||||
|
structs += "union "
|
||||||
|
} else {
|
||||||
|
plain_typedefs += "struct "
|
||||||
|
structs += "struct "
|
||||||
|
}
|
||||||
|
plain_typedefs += base_name + "_dummy " + base_name + ";\n"
|
||||||
|
structs += base_name + "_dummy {\n"
|
||||||
if (is_type_def(vert)) {
|
if (is_type_def(vert)) {
|
||||||
vert->type_def.variables.for_each(fun(variable_declaration: *ast_node) structs += generate_declaration_statement(variable_declaration, null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n";) // also no defer stack
|
vert->type_def.variables.for_each(fun(variable_declaration: *ast_node) structs += generate_declaration_statement(variable_declaration, null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n";) // also no defer stack
|
||||||
// generate the methods (note some of these may be templates)
|
// generate the methods (note some of these may be templates)
|
||||||
|
|||||||
@@ -123,8 +123,7 @@ obj importer (Object) {
|
|||||||
remove_node(symbol("\"while\"", true), parse_tree)
|
remove_node(symbol("\"while\"", true), parse_tree)
|
||||||
remove_node(symbol("\"__if_comp__\"", true), parse_tree)
|
remove_node(symbol("\"__if_comp__\"", true), parse_tree)
|
||||||
remove_node(symbol("\"comp_simple_passthrough\"", true), parse_tree)
|
remove_node(symbol("\"comp_simple_passthrough\"", true), parse_tree)
|
||||||
remove_node(symbol("def_nonterm", false), parse_tree)
|
/*remove_node(symbol("obj_nonterm", false), parse_tree)*/
|
||||||
remove_node(symbol("obj_nonterm", false), parse_tree)
|
|
||||||
remove_node(symbol("adt_nonterm", false), parse_tree)
|
remove_node(symbol("adt_nonterm", false), parse_tree)
|
||||||
|
|
||||||
collapse_node(symbol("case_statement_list", false), parse_tree)
|
collapse_node(symbol("case_statement_list", false), parse_tree)
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import mem
|
|||||||
import serialize
|
import serialize
|
||||||
import io
|
import io
|
||||||
|
|
||||||
|
fun to_string(in: bool): string
|
||||||
|
if (in) return string("true")
|
||||||
|
else return string("false")
|
||||||
fun to_string(in: uchar): string
|
fun to_string(in: uchar): string
|
||||||
return to_string_num(in)
|
return to_string_num(in)
|
||||||
fun to_string(in: short): string
|
fun to_string(in: short): string
|
||||||
@@ -168,6 +171,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+(b: bool): string return *this + to_string(b);
|
||||||
|
|
||||||
fun operator+(str: *char): string {
|
fun operator+(str: *char): string {
|
||||||
var newStr.construct(str):string
|
var newStr.construct(str):string
|
||||||
@@ -181,6 +185,7 @@ obj string (Object, Serializable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun operator+=(integer: int) *this += to_string(integer);
|
fun operator+=(integer: int) *this += to_string(integer);
|
||||||
|
fun operator+=(b: bool) *this += to_string(b);
|
||||||
|
|
||||||
fun operator+=(character: char): void {
|
fun operator+=(character: char): void {
|
||||||
data += character
|
data += character
|
||||||
|
|||||||
3
tests/test_union.expected_results
Normal file
3
tests/test_union.expected_results
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
true
|
||||||
|
4
|
||||||
|
4.400000
|
||||||
22
tests/test_union.krak
Normal file
22
tests/test_union.krak
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import io:*
|
||||||
|
|
||||||
|
uni packed {
|
||||||
|
var a: int
|
||||||
|
var b: double
|
||||||
|
}
|
||||||
|
|
||||||
|
obj loose {
|
||||||
|
var a: int
|
||||||
|
var b: double
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main():int {
|
||||||
|
var a: packed
|
||||||
|
var b: loose
|
||||||
|
println(#sizeof<packed> < #sizeof<loose>)
|
||||||
|
a.a = 4
|
||||||
|
println(a.a)
|
||||||
|
a.b = 4.4
|
||||||
|
println(a.b)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user