Basic support for templates in ast, rest will come with types
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++;) {
|
||||
|
||||
Reference in New Issue
Block a user