type_def variables and methods are not parsed in ast_transformation, and kind-of generated in c_generator, but access and whatnot not supported yet
This commit is contained in:
@@ -190,27 +190,35 @@ 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 self_type: *type
|
var self_type: *type
|
||||||
|
var variables: vector<*ast_node>
|
||||||
|
var methods: vector<*ast_node>
|
||||||
fun construct(nameIn: string): *type_def {
|
fun construct(nameIn: string): *type_def {
|
||||||
scope.construct()
|
scope.construct()
|
||||||
name.copy_construct(&nameIn)
|
name.copy_construct(&nameIn)
|
||||||
self_type = null<type>()
|
self_type = null<type>()
|
||||||
|
variables.construct()
|
||||||
|
methods.construct()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
fun copy_construct(old: *type_def) {
|
fun copy_construct(old: *type_def) {
|
||||||
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)
|
||||||
|
variables.copy_construct(&old->variables)
|
||||||
|
methods.copy_construct(&old->methods)
|
||||||
}
|
}
|
||||||
fun destruct() {
|
fun destruct() {
|
||||||
scope.destruct()
|
scope.destruct()
|
||||||
name.destruct()
|
name.destruct()
|
||||||
|
variables.destruct()
|
||||||
|
methods.destruct()
|
||||||
}
|
}
|
||||||
fun operator=(other: ref type_def) {
|
fun operator=(other: ref type_def) {
|
||||||
destruct()
|
destruct()
|
||||||
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
|
return name == other.name && 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 {
|
||||||
@@ -903,7 +911,7 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> {
|
|||||||
ast_node::translation_unit(backing) return backing.children
|
ast_node::translation_unit(backing) return backing.children
|
||||||
ast_node::import(backing) return vector<*ast_node>()
|
ast_node::import(backing) return vector<*ast_node>()
|
||||||
ast_node::identifier(backing) return vector<*ast_node>()
|
ast_node::identifier(backing) return vector<*ast_node>()
|
||||||
ast_node::type_def(backing) return vector<*ast_node>()
|
ast_node::type_def(backing) return backing.variables + backing.methods
|
||||||
ast_node::adt_def(backing) return vector<*ast_node>()
|
ast_node::adt_def(backing) return vector<*ast_node>()
|
||||||
ast_node::function(backing) return backing.parameters + backing.body_statement
|
ast_node::function(backing) return backing.parameters + backing.body_statement
|
||||||
ast_node::code_block(backing) return backing.children
|
ast_node::code_block(backing) return backing.children
|
||||||
|
|||||||
@@ -82,13 +82,9 @@ obj ast_transformation (Object) {
|
|||||||
// defines inside of objects + ADTs, outside declaration statements, and function prototypes
|
// defines inside of objects + ADTs, outside declaration statements, and function prototypes
|
||||||
fun second_pass(parse_tree: *tree<symbol>, translation_unit: *ast_node) {
|
fun second_pass(parse_tree: *tree<symbol>, translation_unit: *ast_node) {
|
||||||
println(string("Second Pass for ") + translation_unit->translation_unit.name)
|
println(string("Second Pass for ") + translation_unit->translation_unit.name)
|
||||||
|
// we go through the parse tree for getting functions, but we're going through the ast for the things we've already set up and using the ast_to_syntax map
|
||||||
parse_tree->children.for_each(fun(child: *tree<symbol>) {
|
parse_tree->children.for_each(fun(child: *tree<symbol>) {
|
||||||
if (child->data.name == "type_def") {
|
if (child->data.name == "function") {
|
||||||
// second pass class stuff
|
|
||||||
// class insides calls into second_pass_declaration and second_pass_function...
|
|
||||||
} else if (child->data.name == "adt_def") {
|
|
||||||
// set up options and all the generated functions (operator==, operator!=, copy_construct, operator=, destruct)
|
|
||||||
} else if (child->data.name == "function") {
|
|
||||||
var function_node = second_pass_function(child, translation_unit, map<string, *type>())
|
var function_node = second_pass_function(child, translation_unit, map<string, *type>())
|
||||||
translation_unit->translation_unit.children.add(function_node)
|
translation_unit->translation_unit.children.add(function_node)
|
||||||
ast_to_syntax.set(function_node, child)
|
ast_to_syntax.set(function_node, child)
|
||||||
@@ -97,6 +93,26 @@ obj ast_transformation (Object) {
|
|||||||
translation_unit->translation_unit.children.add(transform_declaration_statement(child, translation_unit))
|
translation_unit->translation_unit.children.add(transform_declaration_statement(child, translation_unit))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// work on the ones already started
|
||||||
|
translation_unit->translation_unit.children.for_each(fun(node: *ast_node) {
|
||||||
|
match(*node) {
|
||||||
|
ast_node::type_def(backing) {
|
||||||
|
var type_def_syntax = ast_to_syntax[node]
|
||||||
|
type_def_syntax->children.for_each(fun(child: *tree<symbol>) {
|
||||||
|
if (child->data.name == "declaration_statement") {
|
||||||
|
var declaration_node = transform_declaration_statement(child, node)
|
||||||
|
node->type_def.variables.add(declaration_node)
|
||||||
|
ast_to_syntax.set(declaration_node, child)
|
||||||
|
} else if (child->data.name == "function") {
|
||||||
|
var function_node = second_pass_function(child, node, map<string, *type>())
|
||||||
|
node->type_def.methods.add(function_node)
|
||||||
|
ast_to_syntax.set(function_node, child)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ast_node::adt_def(backing) do_nothing() // actually go through and do methods inside
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
fun second_pass_function(node: *tree<symbol>, translation_unit: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
fun second_pass_function(node: *tree<symbol>, translation_unit: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
||||||
var function_name = concat_symbol_tree(get_node("func_identifier", node))
|
var function_name = concat_symbol_tree(get_node("func_identifier", node))
|
||||||
@@ -126,7 +142,13 @@ obj ast_transformation (Object) {
|
|||||||
println(string("Third Pass for ") + translation_unit->translation_unit.name)
|
println(string("Third Pass for ") + translation_unit->translation_unit.name)
|
||||||
translation_unit->translation_unit.children.for_each(fun(node: *ast_node) {
|
translation_unit->translation_unit.children.for_each(fun(node: *ast_node) {
|
||||||
match(*node) {
|
match(*node) {
|
||||||
ast_node::type_def(backing) do_nothing() // actually go through and do methods inside
|
ast_node::type_def(backing) {
|
||||||
|
// make sure not a template? or the method not a template?
|
||||||
|
// also same body problem as below
|
||||||
|
node->type_def.methods.for_each(fun(method: *ast_node) {
|
||||||
|
method->function.body_statement = transform_statement(get_node("statement", ast_to_syntax[method]), node)
|
||||||
|
})
|
||||||
|
}
|
||||||
ast_node::function(backing) {
|
ast_node::function(backing) {
|
||||||
// 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.
|
||||||
|
|||||||
@@ -34,6 +34,27 @@ obj c_generator (Object) {
|
|||||||
var function_definitions: string = "\n/**Function Definitions**/\n"
|
var function_definitions: string = "\n/**Function Definitions**/\n"
|
||||||
var variable_declarations: string = "\n/**Variable Declarations**/\n"
|
var variable_declarations: string = "\n/**Variable Declarations**/\n"
|
||||||
|
|
||||||
|
// moved out from below so that it can be used for methods as well as regular functions (and eventually lambdas...)
|
||||||
|
var generate_function_definition = fun(child: *ast_node) {
|
||||||
|
var backing = child->function
|
||||||
|
|
||||||
|
var parameter_types = string()
|
||||||
|
var parameters = string()
|
||||||
|
var decorated_name = generate_function(child)
|
||||||
|
// also add in name decoration
|
||||||
|
backing.parameters.for_each(fun(parameter: *ast_node) {
|
||||||
|
if (parameter_types != "") { parameter_types += ", "; parameters += ", ";}
|
||||||
|
parameter_types += type_to_c(parameter->identifier.type)
|
||||||
|
parameters += type_to_c(parameter->identifier.type) + " " + parameter->identifier.name
|
||||||
|
})
|
||||||
|
function_prototypes += type_to_c(backing.type->return_type) + " " + decorated_name + "(" + parameter_types + ");\n"
|
||||||
|
|
||||||
|
// add parameters to destructor thingy (for returns)? Or should that be a different pass?
|
||||||
|
function_definitions += type_to_c(backing.type->return_type) + " " + decorated_name + "(" + parameters + ") {\n" + generate_statement(backing.body_statement)
|
||||||
|
// emit parameter destructors?
|
||||||
|
function_definitions += "}\n"
|
||||||
|
}
|
||||||
|
|
||||||
var type_poset = poset<*ast_node>()
|
var type_poset = poset<*ast_node>()
|
||||||
// iterate through asts
|
// iterate through asts
|
||||||
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>,*ast_node>) {
|
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>,*ast_node>) {
|
||||||
@@ -52,21 +73,7 @@ obj c_generator (Object) {
|
|||||||
// make sure not a template
|
// make sure not a template
|
||||||
// or a passthrough
|
// or a passthrough
|
||||||
// check for and add to parameters if a closure
|
// check for and add to parameters if a closure
|
||||||
var parameter_types = string()
|
generate_function_definition(child)
|
||||||
var parameters = string()
|
|
||||||
var decorated_name = generate_function(child)
|
|
||||||
// also add in name decoration
|
|
||||||
backing.parameters.for_each(fun(parameter: *ast_node) {
|
|
||||||
if (parameter_types != "") { parameter_types += ", "; parameters += ", ";}
|
|
||||||
parameter_types += type_to_c(parameter->identifier.type)
|
|
||||||
parameters += type_to_c(parameter->identifier.type) + " " + parameter->identifier.name
|
|
||||||
})
|
|
||||||
function_prototypes += type_to_c(backing.type->return_type) + " " + decorated_name + "(" + parameter_types + ");\n"
|
|
||||||
|
|
||||||
// add parameters to destructor thingy (for returns)? Or should that be a different pass?
|
|
||||||
function_definitions += type_to_c(backing.type->return_type) + " " + decorated_name + "(" + parameters + ") {\n" + generate_statement(backing.body_statement)
|
|
||||||
// emit parameter destructors?
|
|
||||||
function_definitions += "}\n"
|
|
||||||
}
|
}
|
||||||
ast_node::type_def(backing) {
|
ast_node::type_def(backing) {
|
||||||
type_poset.add_vertex(child)
|
type_poset.add_vertex(child)
|
||||||
@@ -76,7 +83,11 @@ obj c_generator (Object) {
|
|||||||
})
|
})
|
||||||
type_poset.get_sorted().for_each(fun(vert: *ast_node) {
|
type_poset.get_sorted().for_each(fun(vert: *ast_node) {
|
||||||
plain_typedefs += string("typedef struct ") + vert->type_def.name + "_dummy " + vert->type_def.name + ";\n"
|
plain_typedefs += string("typedef struct ") + vert->type_def.name + "_dummy " + vert->type_def.name + ";\n"
|
||||||
structs += string("struct ") + vert->type_def.name + "_dummy {};\n"
|
structs += string("struct ") + vert->type_def.name + "_dummy {\n"
|
||||||
|
vert->type_def.variables.for_each(fun(variable_declaration: *ast_node) structs += generate_declaration_statement(variable_declaration) + ";\n";)
|
||||||
|
structs += "};\n"
|
||||||
|
// generate the methods
|
||||||
|
vert->type_def.methods.for_each(fun(method: *ast_node) generate_function_definition(method);)
|
||||||
})
|
})
|
||||||
|
|
||||||
return make_pair(prequal+plain_typedefs+top_level_c_passthrough+variable_extern_declarations+structs+function_typedef_string_pre+function_typedef_string+function_prototypes+variable_declarations+function_definitions + "\n", linker_string)
|
return make_pair(prequal+plain_typedefs+top_level_c_passthrough+variable_extern_declarations+structs+function_typedef_string_pre+function_typedef_string+function_prototypes+variable_declarations+function_definitions + "\n", linker_string)
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ fun main(): int {
|
|||||||
/*for (var j = 0; j < 10; j++;)*/
|
/*for (var j = 0; j < 10; j++;)*/
|
||||||
/*simple_print(j)*/
|
/*simple_print(j)*/
|
||||||
var an_obj: Something
|
var an_obj: Something
|
||||||
|
/*an_obj.member = 20*/
|
||||||
|
/*simple_print(an_obj.member)*/
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user