Basic support for templates in ast, rest will come with types

This commit is contained in:
Nathan Braswell
2018-06-22 09:02:30 -04:00
parent a8d4b4eb7f
commit 6ffe7aee46
5 changed files with 130 additions and 20 deletions

View File

@@ -10,7 +10,7 @@ adt ast {
_translation_unit: str,
_import: set<str>,
_identifier: pair<str, *type>,
_binding: pair<str, *tree<ast>>,
_binding: triple<str, vec<*type>, *tree<ast>>,
_type_def: str,
_adt_def: str,
_function: pair<str, *type>,
@@ -41,7 +41,7 @@ fun to_string(a: ref ast): str {
ast::_type_def(b) return str("_type_def(") + b + ")"
ast::_adt_def(b) return str("_adt_def(") + b + ")"
ast::_function(b) return str("_function(") + b.first + ")"
ast::_template(b) return str("_template(") + b.first + ")"
ast::_template(b) return str("_template(") + b.first + "[" + str(",").join(b.second.data) + "])"
ast::_declaration() return str("_declaration")
ast::_assignment() return str("_assignment")
ast::_block() return str("_block")
@@ -78,8 +78,11 @@ fun _cast(p: *type): *tree<ast> {
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 _binding(p1: str, p3: *tree<ast>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_binding(make_triple(p1, vec<*type>(), p3)))
}
fun _binding(p1: str, p2: vec<*type>, p3: *tree<ast>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_binding(make_triple(p1, p2, p3)))
}
fun _function(p1: str, p2: *type): *tree<ast> {
return new<tree<ast>>()->construct(ast::_function(make_pair(p1, p2)))
@@ -153,8 +156,11 @@ fun _cast(p: *type, c: ref vec<*tree<ast>>): *tree<ast> {
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 _binding(p1: str, p3: *tree<ast>, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_binding(make_triple(p1, vec<*type>(), p3)), c)
}
fun _binding(p1: str, p2: vec<*type>, p3: *tree<ast>, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_binding(make_triple(p1, p2, p3)), 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)

View File

@@ -70,13 +70,13 @@ fun make_pair<T,U>(first: T, second: U): pair<T,U> {
}
// little ugly, but it works
fun unpack<T,U>(first: ref T, second: ref U): unpack_dummy<T,U> {
var toRet: unpack_dummy<T,U>
fun unpack<T,U>(first: ref T, second: ref U): unpack_dummy_pair<T,U> {
var toRet: unpack_dummy_pair<T,U>
toRet.first = &first
toRet.second = &second
return toRet
}
obj unpack_dummy<T,U> {
obj unpack_dummy_pair<T,U> {
var first: *T
var second: *U
fun operator=(p: ref pair<T,U>) {
@@ -131,6 +131,83 @@ obj pair<T,U> (Object, Serializable, Hashable) {
}
}
fun make_triple<T,U,V>(first: T, second: U, third: V): triple<T,U,V> {
var it.construct(first, second, third): triple<T,U,V>
return it
}
// little ugly, but it works
fun unpack<T,U,V>(first: ref T, second: ref U, third: ref V): unpack_dummy_triple<T,U,V> {
var toRet: unpack_dummy_triple<T,U>
toRet.first = &first
toRet.second = &second
toRet.third = &third
return toRet
}
obj unpack_dummy_triple<T,U,V> {
var first: *T
var second: *U
var third: *V
fun operator=(p: ref triple<T,U,V>) {
*first = p.first
*second = p.second
*third = p.third
}
}
obj triple<T,U,V> (Object, Serializable, Hashable) {
var first: T
var second: U
var third: V
fun construct(firstIn: ref T, secondIn: ref U, thirdIn: ref V): *triple<T,U,V> {
mem::maybe_copy_construct(&first, &firstIn)
mem::maybe_copy_construct(&second, &secondIn)
mem::maybe_copy_construct(&third, &thirdIn)
return this
}
fun construct(): *triple<T,U,V> {
mem::maybe_construct(&first)
mem::maybe_construct(&second)
mem::maybe_construct(&third)
return this
}
fun copy_construct(old: *triple<T,U,V>):void {
mem::maybe_copy_construct(&first, &old->first)
mem::maybe_copy_construct(&second, &old->second)
mem::maybe_copy_construct(&third, &old->third)
}
fun destruct():void {
mem::maybe_destruct(&first)
mem::maybe_destruct(&second)
mem::maybe_destruct(&third)
}
fun serialize(): vec::vec<char> {
return serialize::serialize(first) + serialize::serialize(second) + serialize::serialize(third)
}
fun unserialize(it: ref vec::vec<char>, pos: int): int {
// can't use unpack :( (b/c we can't make an already constructed empty one)
var first_pair = serialize::unserialize<T>(it, pos)
var second_pair = serialize::unserialize<U>(it, first_pair.second)
var third_pair = serialize::unserialize<V>(it, second_pair.second)
mem::maybe_copy_construct(&first, &first_pair.first)
mem::maybe_copy_construct(&second, &second_pair.first)
mem::maybe_copy_construct(&third, &third_pair.first)
return third_pair.second
}
fun hash():ulong return hash(first) ^ hash(second) ^ hash(third)
// the old unnecessary template to prevent generation
// if not used trick (in this case, changing out V with X)
fun operator==<X>(other: ref triple<T,U,X>): bool {
return first == other.first && second == other.second && third == other.third
}
}
fun range(end:int): range {
var toRet.construct(0, end, 1): range
return toRet

View File

@@ -289,12 +289,24 @@ obj vec<T> (Object, Serializable) {
newVec.addEnd(func(data[i]))
return newVec
}
fun map<U>(func: run(ref T):U):vec<U> {
var newVec.construct(size): vec<U>
for (var i = 0; i < size; i++;)
newVec.addEnd(func(data[i]))
return newVec
}
fun map<U>(func: fun(T):U):vec<U> {
var newVec.construct(size): vec<U>
for (var i = 0; i < size; i++;)
newVec.addEnd(func(data[i]))
return newVec
}
fun map<U>(func: run(T):U):vec<U> {
var newVec.construct(size): vec<U>
for (var i = 0; i < size; i++;)
newVec.addEnd(func(data[i]))
return newVec
}
fun flatten_map<U>(func: fun(T):vec<U>):vec<U> {
var newVec.construct(size): vec<U>
for (var i = 0; i < size; i++;) {