Added in the beginnings of pass three which can parse and emit statements and code blocks
This commit is contained in:
@@ -258,17 +258,20 @@ obj function (Object) {
|
|||||||
var name: string
|
var name: string
|
||||||
var type: *type
|
var type: *type
|
||||||
var parameters: vector<*ast_node>
|
var parameters: vector<*ast_node>
|
||||||
|
var body_statement: *ast_node
|
||||||
var scope: map<string, vector<*ast_node>>
|
var scope: map<string, vector<*ast_node>>
|
||||||
fun construct(name_in: string, type_in: *type, parameters_in: vector<*ast_node>): *function {
|
fun construct(name_in: string, type_in: *type, parameters_in: vector<*ast_node>): *function {
|
||||||
name.copy_construct(&name_in)
|
name.copy_construct(&name_in)
|
||||||
parameters.copy_construct(¶meters_in)
|
parameters.copy_construct(¶meters_in)
|
||||||
scope.construct()
|
scope.construct()
|
||||||
type = type_in
|
type = type_in
|
||||||
|
body_statement = null<ast_node>()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
fun copy_construct(old: *function) {
|
fun copy_construct(old: *function) {
|
||||||
name.copy_construct(&old->name)
|
name.copy_construct(&old->name)
|
||||||
type = old->type
|
type = old->type
|
||||||
|
body_statement = old->body_statement
|
||||||
parameters.copy_construct(&old->parameters)
|
parameters.copy_construct(&old->parameters)
|
||||||
scope.copy_construct(&old->scope)
|
scope.copy_construct(&old->scope)
|
||||||
}
|
}
|
||||||
@@ -282,7 +285,7 @@ obj function (Object) {
|
|||||||
copy_construct(&other)
|
copy_construct(&other)
|
||||||
}
|
}
|
||||||
fun operator==(other: ref function): bool {
|
fun operator==(other: ref function): bool {
|
||||||
return name == name && type == other.type && parameters == other.parameters
|
return name == name && type == other.type && parameters == other.parameters && body_statement == other.body_statement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun ast_code_block_ptr(): *ast_node {
|
fun ast_code_block_ptr(): *ast_node {
|
||||||
@@ -337,6 +340,7 @@ obj statement (Object) {
|
|||||||
var scope: map<string, vector<*ast_node>>
|
var scope: map<string, vector<*ast_node>>
|
||||||
var child: *ast_node
|
var child: *ast_node
|
||||||
fun construct(): *statement {
|
fun construct(): *statement {
|
||||||
|
child = null<ast_node>()
|
||||||
scope.construct()
|
scope.construct()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -849,7 +853,7 @@ fun get_ast_children(node: *ast_node): 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 vector<*ast_node>()
|
||||||
ast_node::adt_def(backing) return vector<*ast_node>()
|
ast_node::adt_def(backing) return vector<*ast_node>()
|
||||||
ast_node::function(backing) return vector<*ast_node>()
|
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
|
||||||
ast_node::statement(backing) return vector<*ast_node>(backing.child)
|
ast_node::statement(backing) return vector<*ast_node>(backing.child)
|
||||||
ast_node::if_statement(backing) return vector<*ast_node>()
|
ast_node::if_statement(backing) return vector<*ast_node>()
|
||||||
|
|||||||
@@ -19,16 +19,20 @@ import type:*
|
|||||||
/*NodeTree<ASTData>* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated*/
|
/*NodeTree<ASTData>* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated*/
|
||||||
/*int lambdaID = 0;*/
|
/*int lambdaID = 0;*/
|
||||||
obj ast_transformation (Object) {
|
obj ast_transformation (Object) {
|
||||||
|
var ast_to_syntax: map<*ast_node, *tree<symbol>>
|
||||||
fun construct(): *ast_transformation {
|
fun construct(): *ast_transformation {
|
||||||
|
ast_to_syntax.construct()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
fun copy_construct(old: *ast_transformation) {
|
fun copy_construct(old: *ast_transformation) {
|
||||||
|
ast_to_syntax.copy_construct(&old->ast_to_syntax)
|
||||||
}
|
}
|
||||||
fun operator=(old: ref ast_transformation) {
|
fun operator=(old: ref ast_transformation) {
|
||||||
destruct()
|
destruct()
|
||||||
copy_construct(&old)
|
copy_construct(&old)
|
||||||
}
|
}
|
||||||
fun destruct() {
|
fun destruct() {
|
||||||
|
ast_to_syntax.destruct()
|
||||||
}
|
}
|
||||||
// first pass defines all type_defs (objects and aliases), ADTs, and top-level if-comps/passthroughs
|
// first pass defines all type_defs (objects and aliases), ADTs, and top-level if-comps/passthroughs
|
||||||
fun first_pass(file_name: string, parse_tree: *tree<symbol>, importer: *importer): *ast_node {
|
fun first_pass(file_name: string, parse_tree: *tree<symbol>, importer: *importer): *ast_node {
|
||||||
@@ -39,6 +43,7 @@ obj ast_transformation (Object) {
|
|||||||
var name = concat_symbol_tree(get_node("identifier", child))
|
var name = concat_symbol_tree(get_node("identifier", child))
|
||||||
var type_def_node = ast_type_def_ptr(name)
|
var type_def_node = ast_type_def_ptr(name)
|
||||||
translation_unit->translation_unit.children.add(type_def_node)
|
translation_unit->translation_unit.children.add(type_def_node)
|
||||||
|
ast_to_syntax.set(type_def_node, child)
|
||||||
add_to_scope("~enclosing_scope", translation_unit, type_def_node)
|
add_to_scope("~enclosing_scope", translation_unit, type_def_node)
|
||||||
add_to_scope(name, type_def_node, translation_unit)
|
add_to_scope(name, type_def_node, translation_unit)
|
||||||
// set up type - self-referential, traits, template, etc
|
// set up type - self-referential, traits, template, etc
|
||||||
@@ -46,11 +51,13 @@ obj ast_transformation (Object) {
|
|||||||
var name = concat_symbol_tree(get_node("identifier", child))
|
var name = concat_symbol_tree(get_node("identifier", child))
|
||||||
var adt_def_node = ast_adt_def_ptr(name)
|
var adt_def_node = ast_adt_def_ptr(name)
|
||||||
translation_unit->translation_unit.children.add(adt_def_node)
|
translation_unit->translation_unit.children.add(adt_def_node)
|
||||||
|
ast_to_syntax.set(adt_def_node, child)
|
||||||
add_to_scope("~enclosing_scope", translation_unit, adt_def_node)
|
add_to_scope("~enclosing_scope", translation_unit, adt_def_node)
|
||||||
add_to_scope(name, adt_def_node, translation_unit)
|
add_to_scope(name, adt_def_node, translation_unit)
|
||||||
} else if (child->data.name == "if_comp") {
|
} else if (child->data.name == "if_comp") {
|
||||||
var if_comp_node = transform_if_comp(child, translation_unit)
|
var if_comp_node = transform_if_comp(child, translation_unit)
|
||||||
translation_unit->translation_unit.children.add(if_comp_node)
|
translation_unit->translation_unit.children.add(if_comp_node)
|
||||||
|
ast_to_syntax.set(if_comp_node, child)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -62,6 +69,7 @@ obj ast_transformation (Object) {
|
|||||||
var name = concat_symbol_tree(import_identifier_children[0])
|
var name = concat_symbol_tree(import_identifier_children[0])
|
||||||
var import_node = ast_import_ptr(name)
|
var import_node = ast_import_ptr(name)
|
||||||
translation_unit->translation_unit.children.add(import_node)
|
translation_unit->translation_unit.children.add(import_node)
|
||||||
|
ast_to_syntax.set(import_node, child)
|
||||||
add_to_scope("~enclosing_scope", translation_unit, import_node)
|
add_to_scope("~enclosing_scope", translation_unit, import_node)
|
||||||
var outside_translation_unit = importer->import_first_pass(name + ".krak")
|
var outside_translation_unit = importer->import_first_pass(name + ".krak")
|
||||||
add_to_scope(name, outside_translation_unit, translation_unit)
|
add_to_scope(name, outside_translation_unit, translation_unit)
|
||||||
@@ -80,7 +88,9 @@ obj ast_transformation (Object) {
|
|||||||
} else if (child->data.name == "adt_def") {
|
} else if (child->data.name == "adt_def") {
|
||||||
// set up options and all the generated functions (operator==, operator!=, copy_construct, operator=, destruct)
|
// set up options and all the generated functions (operator==, operator!=, copy_construct, operator=, destruct)
|
||||||
} else if (child->data.name == "function") {
|
} else if (child->data.name == "function") {
|
||||||
translation_unit->translation_unit.children.add(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)
|
||||||
|
ast_to_syntax.set(function_node, child)
|
||||||
} else if (child->data.name == "declaration_statement") {
|
} else if (child->data.name == "declaration_statement") {
|
||||||
// second pass declaration can actually just call a normal transform (but maybe should be it's own method to do so because typedef has to do it too?)...
|
// second pass declaration can actually just call a normal transform (but maybe should be it's own method to do so because typedef has to do it too?)...
|
||||||
}
|
}
|
||||||
@@ -109,9 +119,22 @@ obj ast_transformation (Object) {
|
|||||||
parameters.for_each(fun(parameter: *ast_node) add_to_scope(parameter->identifier.name, parameter, function_node);)
|
parameters.for_each(fun(parameter: *ast_node) add_to_scope(parameter->identifier.name, parameter, function_node);)
|
||||||
return function_node
|
return function_node
|
||||||
}
|
}
|
||||||
|
// The third pass finishes up by doing all function bodies (top level and methods in objects)
|
||||||
fun third_pass(parse_tree: *tree<symbol>, translation_unit: *ast_node) {
|
fun third_pass(parse_tree: *tree<symbol>, translation_unit: *ast_node) {
|
||||||
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) {
|
||||||
|
match(*node) {
|
||||||
|
ast_node::type_def(backing) do_nothing() // actually go through and do methods inside
|
||||||
|
ast_node::function(backing) {
|
||||||
|
// make sure not a template
|
||||||
|
// huh, I guess I can't actually assign to the backing.
|
||||||
|
// This is actually a little bit of a problem, maybe these should be pointers also. All the pointers!
|
||||||
|
node->function.body_statement = transform_statement(get_node("statement", ast_to_syntax[node]), translation_unit)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// The fourth pass generates the class templates that have not yet been generated in a "chaotic iteration" loop
|
||||||
fun fourth_pass(parse_tree: *tree<symbol>, translation_unit: *ast_node) {
|
fun fourth_pass(parse_tree: *tree<symbol>, translation_unit: *ast_node) {
|
||||||
println(string("Fourth Pass for ") + translation_unit->translation_unit.name)
|
println(string("Fourth Pass for ") + translation_unit->translation_unit.name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ obj c_generator (Object) {
|
|||||||
function_prototypes += type_to_c(backing.type->return_type) + " " + backing.name + "(" + parameter_types + ");\n"
|
function_prototypes += type_to_c(backing.type->return_type) + " " + backing.name + "(" + parameter_types + ");\n"
|
||||||
|
|
||||||
// add parameters to destructor thingy (for returns)? Or should that be a different pass?
|
// add parameters to destructor thingy (for returns)? Or should that be a different pass?
|
||||||
function_definitions += type_to_c(backing.type->return_type) + " " + backing.name + "(" + parameters + ") { " + " /* body here */ "
|
function_definitions += type_to_c(backing.type->return_type) + " " + backing.name + "(" + parameters + ") {\n" + generate_statement(backing.body_statement)
|
||||||
// emit parameter destructors?
|
// emit parameter destructors?
|
||||||
function_definitions += "}\n"
|
function_definitions += "}\n"
|
||||||
}
|
}
|
||||||
@@ -76,11 +76,22 @@ obj c_generator (Object) {
|
|||||||
// deal with all the passthrough params
|
// deal with all the passthrough params
|
||||||
return node->simple_passthrough.passthrough_str
|
return node->simple_passthrough.passthrough_str
|
||||||
}
|
}
|
||||||
|
fun generate_statement(node: *ast_node): string return generate(node->statement.child) + ";\n";
|
||||||
|
fun generate_code_block(node: *ast_node): string {
|
||||||
|
var to_ret = string("{\n")
|
||||||
|
node->code_block.children.for_each(fun(child: *ast_node) to_ret += generate(child);)
|
||||||
|
return to_ret + "}\n"
|
||||||
|
}
|
||||||
|
|
||||||
// for now, anyway
|
// for now, anyway
|
||||||
fun generate(node: *ast_node): string {
|
fun generate(node: *ast_node): string {
|
||||||
|
if (!node) return string("/*NULL*/")
|
||||||
match (*node) {
|
match (*node) {
|
||||||
ast_node::simple_passthrough(backing) return generate_simple_passthrough(node)
|
ast_node::simple_passthrough(backing) return generate_simple_passthrough(node)
|
||||||
|
ast_node::statement(backing) return generate_statement(node)
|
||||||
|
ast_node::code_block(backing) return generate_code_block(node)
|
||||||
}
|
}
|
||||||
|
return string("/* COULD NOT GENERATE */")
|
||||||
}
|
}
|
||||||
fun type_to_c(type: *type): string {
|
fun type_to_c(type: *type): string {
|
||||||
match (type->base) {
|
match (type->base) {
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import mem
|
|||||||
import vector
|
import vector
|
||||||
import serialize
|
import serialize
|
||||||
|
|
||||||
|
// maybe my favorite function
|
||||||
|
fun do_nothing() {}
|
||||||
|
|
||||||
fun max<T>(a: T, b: T): T {
|
fun max<T>(a: T, b: T): T {
|
||||||
if (a > b)
|
if (a > b)
|
||||||
return a;
|
return a;
|
||||||
|
|||||||
@@ -71,13 +71,19 @@ obj vector<T> (Object, Serializable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun operator+(other:vector<T>):vector<T> {
|
fun operator+(other:vector<T>):vector<T> {
|
||||||
var newVec.construct():vector<T>
|
// lets be at least a little bit smarter by copy_constructing our copy.
|
||||||
for (var i = 0; i < size; i++;)
|
// We could get a lot better than this by initially creating enough space
|
||||||
newVec.addEnd(get(i))
|
// for both and copy_constructing all of them, but this is just a quick fix
|
||||||
|
var newVec.copy_construct(this):vector<T>
|
||||||
for (var i = 0; i < other.size; i++;)
|
for (var i = 0; i < other.size; i++;)
|
||||||
newVec.addEnd(other.get(i))
|
newVec.addEnd(other.get(i))
|
||||||
return newVec
|
return newVec
|
||||||
}
|
}
|
||||||
|
fun operator+(other: T):vector<T> {
|
||||||
|
var newVec.copy_construct(this):vector<T>
|
||||||
|
newVec.addEnd(other)
|
||||||
|
return newVec
|
||||||
|
}
|
||||||
|
|
||||||
fun operator+=(other: T):void {
|
fun operator+=(other: T):void {
|
||||||
addEnd(other)
|
addEnd(other)
|
||||||
|
|||||||
@@ -7,10 +7,8 @@ obj Something (ObjectTrait) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun some_function(): float {
|
fun some_function(): int return 0;
|
||||||
return 0
|
fun some_other_function(in: bool): float {
|
||||||
}
|
return 0.0
|
||||||
fun some_other_function(in: bool): int {
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user