Basic AST

This commit is contained in:
Nathan Braswell
2018-06-18 19:04:24 -04:00
parent e898e7b285
commit b5ce776726
6 changed files with 274 additions and 9 deletions

47
k.krak
View File

@@ -10,8 +10,11 @@ import vec:*
import vec_literals:* import vec_literals:*
import poset:* import poset:*
import util:* import util:*
import ast:*
import tree:*
import symbol:*
fun main(argc: int, argv: **char):int { fun main(argc: int, argv: **char): int {
// delay construction until we either load it or copy construct it // delay construction until we either load it or copy construct it
var gram: grammer var gram: grammer
var base_dir = str("/").join(str(argv[0]).split('/').slice(0,-2)) var base_dir = str("/").join(str(argv[0]).split('/').slice(0,-2))
@@ -79,11 +82,10 @@ fun main(argc: int, argv: **char):int {
executable_name = positional_args[1] executable_name = positional_args[1]
var pass_poset = poset<pair<str, int>>() var pass_poset = poset<pair<str, int>>()
var name_ast_map = map<str, *node>() var name_ast_map = map<str, *tree<ast>>()
var import_paths = vec(str(), base_dir + "/stdlib/") var import_paths = vec(str(), base_dir + "/stdlib/")
var passes = vec( var passes = vec(
fun(file_name: str): *node { fun(file_name: str): *tree<ast> {
println("Doing thing 1 to " + file_name)
var file = str() var file = str()
for (var i = 0; i < import_paths.size; i++;) { for (var i = 0; i < import_paths.size; i++;) {
if (file_exists(import_paths[i] + file_name)) { if (file_exists(import_paths[i] + file_name)) {
@@ -96,11 +98,13 @@ fun main(argc: int, argv: **char):int {
error("File: " + file_name + ", not found in any import path - none of [" + str(",").join(import_paths) + "]") error("File: " + file_name + ", not found in any import path - none of [" + str(",").join(import_paths) + "]")
printerr(file_name + ", ") printerr(file_name + ", ")
var parse_tree = parse.parse_input(file, file_name) var parse_tree = parse.parse_input(file, file_name)
return new<node>()->copy_construct(&node::placeholder()) return syntax_to_ast(file_name, parse_tree)
}, },
fun(file_name: str): *node { fun(file_name: str): *tree<ast> {
println("Doing thing 2 to " + file_name) println("Doing thing 2 to " + file_name)
return new<node>()->copy_construct(&node::placeholder()) printlnerr("just gonna ret")
print_tree(name_ast_map[file_name], 1)
return name_ast_map[file_name]
} }
) )
for (var i = 0; i < passes.size; i++;) { for (var i = 0; i < passes.size; i++;) {
@@ -111,9 +115,19 @@ fun main(argc: int, argv: **char):int {
} }
while (pass_poset.size() != 0) { while (pass_poset.size() != 0) {
var file_pass = pass_poset.pop() var file_pass = pass_poset.pop()
printlnerr("doing pass " + to_string(file_pass.second) + " on " + file_pass.first)
name_ast_map[file_pass.first] = passes[file_pass.second](file_pass.first) name_ast_map[file_pass.first] = passes[file_pass.second](file_pass.first)
} }
println()
println()
println("Finished with trees:")
name_ast_map.for_each(fun(key: str, value: *tree<ast>) {
printlnerr(key + ":")
print_tree(value, 1)
printlnerr("done")
})
var kraken_c_output_name = kraken_file_name + ".c" var kraken_c_output_name = kraken_file_name + ".c"
var c_code = str("//don't you wish this was real kraken\n") var c_code = str("//don't you wish this was real kraken\n")
var c_flags = str("") var c_flags = str("")
@@ -127,6 +141,21 @@ fun main(argc: int, argv: **char):int {
return 0 return 0
} }
adt node {
placeholder fun syntax_to_ast(file_name: str, syntax: *tree<symbol>): *tree<ast> {
/*return _translation_unit(file_name)*/
var result = _translation_unit(file_name)
printlnerr("made")
print_tree(result, 1)
printlnerr("from")
print_tree(syntax, 1)
return result
}
fun print_tree<T>(t: *tree<T>, level: int) {
printlnerr("\t" * level + to_string(t->data))
for (var i = 0; i < t->children.size; i++;)
if (t->children[i])
print_tree(t->children[i], level+1)
else
printlnerr("\t" * level + "null!")
} }

209
stdlib/ast.krak Normal file
View File

@@ -0,0 +1,209 @@
import tree:*
import type:*
import vec:*
import set:*
import util:*
import str:*
import mem:*
adt ast {
_translation_unit: str,
_import: set<str>,
_identifier: pair<str, *type>,
_binding: pair<str, *tree<ast>>,
_type_def: str,
_adt_def: str,
_function: pair<str, *type>,
_template: pair<str, set<str>>,
_declaration,
_assignment,
_block,
_if,
_match,
_case,
_while,
_for,
_return,
_break,
_continue,
_defer,
_call,
_compiler_intrinsic: pair<str, vec<*type>>,
_cast: *type,
_value: pair<str, *type>
}
fun to_string(a: ref ast): str {
match(a) {
ast::_translation_unit() return str("_translation_unit")
ast::_import() return str("_import")
ast::_identifier() return str("_identifier")
ast::_binding() return str("_binding")
ast::_type_def() return str("_type_def")
ast::_adt_def() return str("_adt_def")
ast::_function() return str("_function")
ast::_template() return str("_template")
ast::_declaration() return str("_declaration")
ast::_assignment() return str("_assignment")
ast::_block() return str("_block")
ast::_if() return str("_if")
ast::_match() return str("_match")
ast::_case() return str("_case")
ast::_while() return str("_while")
ast::_for() return str("_for")
ast::_return() return str("_return")
ast::_break() return str("_break")
ast::_continue() return str("_continue")
ast::_defer() return str("_defer")
ast::_call() return str("_call")
ast::_compiler_intrinsic() return str("_compiler_intrinsic")
ast::_cast() return str("_cast")
ast::_value() return str("_value")
}
}
fun _translation_unit(p: str): *tree<ast> {
return new<tree<ast>>()->construct(ast::_translation_unit(p))
}
fun _import(p: set<str>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_import(p))
}
fun _type_def(p: str): *tree<ast> {
return new<tree<ast>>()->construct(ast::_type_def(p))
}
fun _adt_def(p: str): *tree<ast> {
return new<tree<ast>>()->construct(ast::_adt_def(p))
}
fun _cast(p: *type): *tree<ast> {
return new<tree<ast>>()->construct(ast::_cast(p))
}
fun _identifier(p1: str, p2: *type): *tree<ast> {
return new<tree<ast>>()->construct(ast::_identifier(make_pair(p1, p2)))
}
fun _binding(p1: str, p2: *tree<ast>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_binding(make_pair(p1, p2)))
}
fun _function(p1: str, p2: *type): *tree<ast> {
return new<tree<ast>>()->construct(ast::_function(make_pair(p1, p2)))
}
fun _template(p1: str, p2: set<str>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_template(make_pair(p1, p2)))
}
fun _compiler_intrinsic(p1: str, p2: vec<*type>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)))
}
fun _value(p1: str, p2: *type): *tree<ast> {
return new<tree<ast>>()->construct(ast::_value(make_pair(p1, p2)))
}
fun _declaration(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_declaration())
}
fun _assignment(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_assignment())
}
fun _block(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_block())
}
fun _if(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_if())
}
fun _match(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_match())
}
fun _case(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_case())
}
fun _while(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_while())
}
fun _for(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_for())
}
fun _return(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_return())
}
fun _break(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_break())
}
fun _continue(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_continue())
}
fun _defer(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_defer())
}
fun _call(): *tree<ast> {
return new<tree<ast>>()->construct(ast::_call())
}
fun _translation_unit(p: str, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_translation_unit(p), c)
}
fun _import(p: set<str>, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_import(p), c)
}
fun _type_def(p: str, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_type_def(p), c)
}
fun _adt_def(p: str, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_adt_def(p), c)
}
fun _cast(p: *type, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_cast(p), c)
}
fun _identifier(p1: str, p2: *type, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_identifier(make_pair(p1, p2)), c)
}
fun _binding(p1: str, p2: *tree<ast>, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_binding(make_pair(p1, p2)), c)
}
fun _function(p1: str, p2: *type, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_function(make_pair(p1, p2)), c)
}
fun _template(p1: str, p2: set<str>, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_template(make_pair(p1, p2)), c)
}
fun _compiler_intrinsic(p1: str, p2: vec<*type>, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)), c)
}
fun _value(p1: str, p2: *type, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_value(make_pair(p1, p2)), c)
}
fun _declaration(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_declaration(), c)
}
fun _assignment(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_assignment(), c)
}
fun _block(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_block(), c)
}
fun _if(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_if(), c)
}
fun _match(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_match(), c)
}
fun _case(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_case(), c)
}
fun _while(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_while(), c)
}
fun _for(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_for(), c)
}
fun _return(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_return(), c)
}
fun _break(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_break(), c)
}
fun _continue(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_continue(), c)
}
fun _defer(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_defer(), c)
}
fun _call(c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_call(), c)
}

3
stdlib/simple.krak Normal file
View File

@@ -0,0 +1,3 @@
fun main(argc: int, argv: **char): int {
return 0
}

View File

@@ -88,6 +88,15 @@ fun operator+(first: *char, second: ref str): str {
fun operator+(first: int, second: ref str): str { fun operator+(first: int, second: ref str): str {
return to_string(first) + second return to_string(first) + second
} }
fun operator*(first: *char, second: int): str {
return str(first) * second
}
fun operator*(first: int, second: *char): str {
return str(second) * first
}
fun operator*(first: int, second: ref str): str {
return second * first
}
fun str(in:*char):str { fun str(in:*char):str {
var out.construct(in):str var out.construct(in):str
@@ -191,6 +200,13 @@ obj str (Object, Serializable, Hashable) {
return *this == str return *this == str
} }
fun operator*(n: int): str {
var to_ret.construct(): str
while (n-- > 0)
to_ret += *this
return to_ret
}
fun operator+(c: char): str { fun operator+(c: char): str {
var to_ret = *this var to_ret = *this
to_ret += c to_ret += c

View File

@@ -39,6 +39,9 @@ fun symbol(nameIn: ref str::str, terminalIn: bool, dataIn: ref str::str, positio
return toRet return toRet
} }
fun to_string(s: ref symbol): str::str {
return s.to_string()
}
obj symbol (Object, Serializable) { obj symbol (Object, Serializable) {
var data: str::str var data: str::str
var name: str::str var name: str::str

View File

@@ -9,6 +9,11 @@ obj tree<T> (Object) {
children.construct() children.construct()
return this return this
} }
fun construct(dataIn: T, c: ref vec::vec<*tree<T>>): *tree<T> {
mem::maybe_copy_construct(&data, &dataIn)
children.copy_construct(&c)
return this
}
// Some of these don't really make much sense considering this tree is all about // Some of these don't really make much sense considering this tree is all about
// heap allocated pointers. Best to have it for saftey, though // heap allocated pointers. Best to have it for saftey, though
fun copy_construct(old: *tree<T>) { fun copy_construct(old: *tree<T>) {