Move collection types. Improve linked list interface. Update map.destroy => map.free

This commit is contained in:
Christoffer Lerno
2023-02-05 20:55:47 +01:00
parent 4a102698b2
commit 86e085e0c0
16 changed files with 626 additions and 270 deletions

View File

@@ -1,5 +1,5 @@
// TODO: ensure the type is an enum first.
module std::enumset<Enum>;
module std::collections::enumset<Enum>;
$assert(Enum.elements < 64, "Maximum number of elements for an enum used as enum set is 63");

View File

@@ -0,0 +1,312 @@
// Copyright (c) 2021 Christoffer Lerno. All rights reserved.
// Use of this source code is governed by the MIT license
// a copy of which can be found in the LICENSE_STDLIB file.
module std::collections::linkedlist<Type>;
private struct Node
{
Node *next;
Node *prev;
Type value;
}
struct LinkedList
{
Allocator *allocator;
usz size;
Node *_first;
Node *_last;
}
fn void LinkedList.push(LinkedList* list, Type value)
{
list.link_first(value);
}
fn void LinkedList.push_last(LinkedList* list, Type value)
{
list.link_last(value);
}
fn void LinkedList.init(LinkedList* list, Allocator* alloc = mem::current_allocator())
{
*list = { .allocator = alloc };
}
fn void LinkedList.tinit(LinkedList* list) => list.init(mem::temp_allocator()) @inline;
/**
* @require list.allocator
**/
private macro void LinkedList.@free_node(LinkedList &list, Node* node)
{
list.allocator.free(node)!!;
}
private macro Node* LinkedList.@alloc_node(LinkedList &list)
{
if (!list.allocator) list.allocator = mem::current_allocator();
return list.allocator.alloc(Node.sizeof)!!;
}
private fn void LinkedList.link_first(LinkedList* list, Type value)
{
Node *first = list._first;
Node *new_node = list.@alloc_node();
*new_node = { .next = first, .value = value };
list._first = new_node;
if (!first)
{
list._last = new_node;
}
else
{
first.prev = new_node;
}
list.size++;
}
private fn void LinkedList.link_last(LinkedList* list, Type value)
{
Node *last = list._last;
Node *new_node = list.@alloc_node();
*new_node = { .prev = last, .value = value };
list._last = new_node;
if (!last)
{
list._first = new_node;
}
else
{
last.next = new_node;
}
list.size++;
}
fn Type! peek(LinkedList* list) => list.first() @inline;
fn Type! peek_last(LinkedList* list) => list.last() @inline;
fn Type! LinkedList.first(LinkedList *list)
{
if (!list._first) return IteratorResult.NO_MORE_ELEMENT!;
return list._first.value;
}
fn Type! LinkedList.last(LinkedList* list)
{
if (!list._last) return IteratorResult.NO_MORE_ELEMENT!;
return list._last.value;
}
fn void LinkedList.free(LinkedList* list) => list.clear() @inline;
fn void LinkedList.clear(LinkedList* list)
{
for (Node* node = list._first; node != null;)
{
Node* next = node.next;
list.@free_node(node);
node = next;
}
list._first = null;
list._last = null;
list.size = 0;
}
fn usz LinkedList.len(LinkedList* list) @inline => list.size;
/**
* @require index < list.size
**/
macro Node* LinkedList.node_at_index(LinkedList* list, usz index)
{
if (index * 2 >= list.size)
{
Node* node = list._last;
index = list.size - index - 1;
while (index--) node = node.prev;
return node;
}
Node* node = list._first;
while (index--) node = node.next;
return node;
}
/**
* @require index < list.size
**/
fn Type LinkedList.get(LinkedList* list, usz index)
{
return list.node_at_index(index).value;
}
/**
* @require index < list.size
**/
fn void LinkedList.set(LinkedList* list, usz index, Type element)
{
list.node_at_index(index).value = element;
}
/**
* @require index < list.size
**/
fn void LinkedList.remove(LinkedList* list, usz index)
{
list.unlink(list.node_at_index(index));
}
/**
* @require index <= list.size
**/
fn void LinkedList.insert(LinkedList* list, usz index, Type element)
{
switch (index)
{
case 0:
list.push(element);
case list.size:
list.push_last(element);
default:
list.link_before(list.node_at_index(index), element);
}
}
/**
* @require succ != null
**/
private fn void LinkedList.link_before(LinkedList *list, Node *succ, Type value)
{
Node* pred = succ.prev;
Node* new_node = mem::alloc(Node);
*new_node = { .prev = pred, .next = succ, .value = value };
succ.prev = new_node;
if (!pred)
{
list._first = new_node;
}
else
{
pred.next = new_node;
}
list.size++;
}
/**
* @require list && list._first
**/
private fn void LinkedList.unlink_first(LinkedList* list)
{
Node* f = list._first;
Node* next = f.next;
list.@free_node(f);
list._first = next;
if (!next)
{
list._last = null;
}
else
{
next.prev = null;
}
list.size--;
}
fn bool LinkedList.remove_value(LinkedList* list, Type t)
{
for (Node* node = list._first; node != null; node = node.next)
{
if (node.value == t)
{
list.unlink(node);
return true;
}
}
return false;
}
fn bool LinkedList.remove_last_value(LinkedList* list, Type t)
{
for (Node* node = list._last; node != null; node = node.prev)
{
if (node.value == t)
{
list.unlink(node);
return true;
}
}
return false;
}
/**
* @param [&inout] list
**/
fn Type! LinkedList.pop(LinkedList* list)
{
if (!list._first) return IteratorResult.NO_MORE_ELEMENT!;
defer list.unlink_first();
return list._first.value;
}
/**
* @param [&inout] list
**/
fn void! LinkedList.remove_last(LinkedList* list)
{
if (!list._first) return IteratorResult.NO_MORE_ELEMENT!;
list.unlink_last();
}
/**
* @param [&inout] list
**/
fn void! LinkedList.remove_first(LinkedList* list)
{
if (!list._first) return IteratorResult.NO_MORE_ELEMENT!;
list.unlink_first();
}
/**
* @param [&inout] list
* @require list._last
**/
private fn void LinkedList.unlink_last(LinkedList *list) @inline
{
Node* l = list._last;
Node* prev = l.prev;
list._last = prev;
list.@free_node(l);
if (!prev)
{
list._first = null;
}
else
{
prev.next = null;
}
list.size--;
}
/**
* @require list != null, x != null
**/
private fn void LinkedList.unlink(LinkedList* list, Node* x)
{
Node* next = x.next;
Node* prev = x.prev;
if (!prev)
{
list._first = next;
}
else
{
prev.next = next;
}
if (!next)
{
list._last = prev;
}
else
{
next.prev = prev;
}
list.@free_node(x);
list.size--;
}

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2021 Christoffer Lerno. All rights reserved.
// Use of this source code is governed by the MIT license
// a copy of which can be found in the LICENSE_STDLIB file.
module std::array::list<Type>;
module std::collections::list<Type>;
import std::math;
struct List

View File

@@ -1,4 +1,4 @@
module std::map<Key, Value>;
module std::collections::map<Key, Value>;
import std::math;
const uint DEFAULT_INITIAL_CAPACITY = 16;
@@ -12,6 +12,7 @@ private struct Entry
Value value;
Entry* next;
}
struct HashMap
{
Entry*[] table;
@@ -140,17 +141,17 @@ fn void HashMap.clear(HashMap* map)
{
Entry* entry = *entry_ref;
if (!entry) continue;
map.free(entry);
map.free_internal(entry);
*entry_ref = null;
}
map.count = 0;
}
fn void HashMap.destroy(HashMap* map)
fn void HashMap.free(HashMap* map)
{
if (!map.allocator) return;
map.clear();
map.free(map.table.ptr);
map.free_internal(map.table.ptr);
map.table = Entry*[] {};
}
@@ -238,7 +239,7 @@ private fn void HashMap.resize(HashMap* map, uint new_capacity)
Entry*[] new_table = array::make(Entry*, new_capacity, map.allocator);
map.transfer(new_table);
map.table = new_table;
map.free(old_table.ptr);
map.free_internal(old_table.ptr);
map.threshold = (uint)(new_capacity * map.load_factor);
}
@@ -297,7 +298,7 @@ private fn void HashMap.put_for_create(HashMap* map, Key key, Value value)
map.create_entry(hash, key, value, i);
}
private fn void HashMap.free(HashMap* map, void* ptr)
private fn void HashMap.free_internal(HashMap* map, void* ptr) @inline
{
map.allocator.free(ptr)!!;
}
@@ -322,7 +323,7 @@ private fn bool HashMap.remove_entry_for_key(HashMap* map, Key key)
{
prev.next = next;
}
map.free(e);
map.free_internal(e);
return true;
}
prev = e;

View File

@@ -20,8 +20,8 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
module std::priorityqueue<Type>;
import std::array::list;
module std::collections::priorityqueue<Type>;
import std::collections::list;
define Heap = List<Type>;

View File

@@ -1,5 +1,5 @@
module std::io;
import std::map;
import std::collections::map;
import libc;
const int PRINTF_NTOA_BUFFER_SIZE = 256;
@@ -21,8 +21,8 @@ define ToStringFunction = fn String(void* value, Allocator *allocator);
define ToFormatFunction = fn void!(void* value, Formatter* formatter);
define FloatType = double;
private define StringFunctionMap = std::map::HashMap<typeid, ToStringFunction>;
private define FormatterFunctionMap = std::map::HashMap<typeid, ToFormatFunction>;
private define StringFunctionMap = HashMap<typeid, ToStringFunction>;
private define FormatterFunctionMap = HashMap<typeid, ToFormatFunction>;
private FormatterFunctionMap toformat_functions;
private StringFunctionMap tostring_functions;

View File

@@ -1,169 +0,0 @@
// Copyright (c) 2021 Christoffer Lerno. All rights reserved.
// Use of this source code is governed by the MIT license
// a copy of which can be found in the LICENSE_STDLIB file.
module std::array::linkedlist<Type>;
private struct Node
{
Node *next;
Node *prev;
Type value;
}
struct LinkedList
{
usz size;
Node *first;
Node *last;
}
fn void LinkedList.push(LinkedList *list, Type value)
{
list.linkLast(value);
}
private fn void LinkedList.linkFirst(LinkedList *list, Type value)
{
Node *first = list.first;
Node *new_node = mem::alloc(Node);
*new_node = { .next = first, .value = value };
list.first = new_node;
if (!first)
{
list.last = new_node;
}
else
{
first.prev = new_node;
}
list.size++;
}
private fn void LinkedList.linkLast(LinkedList *list, Type value)
{
Node *last = list.last;
Node *new_node = mem::alloc(Node);
*new_node = { .prev = last, .value = value };
list.last = new_node;
if (!last)
{
list.first = new_node;
}
else
{
last.next = new_node;
}
list.size++;
}
fn void LinkedList.free(LinkedList *list)
{
for (Node* node = list.first; node != null;)
{
Node* next = node.next;
free(node);
node = next;
}
list.first = null;
list.last = null;
list.size = 0;
}
fn usz LinkedList.len(LinkedList* list) @inline
{
return list.size;
}
fn Type LinkedList.get(LinkedList* list, usz index)
{
Node* node = list.first;
while (index--)
{
node = node.next;
}
return node.value;
}
/**
* @require succ != null
**/
private fn void LinkedList.linkBefore(LinkedList *list, Node *succ, Type value)
{
Node* pred = succ.prev;
Node* new_node = mem::alloc(Node);
*new_node = { .prev = pred, .next = succ, .value = value };
succ.prev = new_node;
if (!pred)
{
list.first = new_node;
}
else
{
pred.next = new_node;
}
list.size++;
}
/**
* @require f == list.first && f != null
**/
private fn void unlinkFirst(LinkedList* list, Node* f)
{
Node* next = f.next;
free(f);
list.first = next;
if (!next)
{
list.last = null;
}
else
{
next.prev = null;
}
list.size--;
}
/**
* @require l == list.last && l != null
**/
private fn void LinkedList.unlinkLast(LinkedList *list, Node* l)
{
Node* prev = l.prev;
list.last = prev;
free(l);
if (!prev)
{
list.first = null;
}
else
{
prev.next = null;
}
list.size--;
}
/**
* @require x != null
**/
private fn void LinkedList.unlink(LinkedList* list, Node* x)
{
Node* next = x.next;
Node* prev = x.prev;
if (!prev)
{
list.first = next;
}
else
{
prev.next = next;
}
if (!next)
{
list.last = prev;
}
else
{
next.prev = prev;
}
free(x);
list.size--;
}

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.45"
#define COMPILER_VERSION "0.4.46"

View File

@@ -2,8 +2,8 @@
module test;
import test2;
import std::array::list;
import std::array::linkedlist;
import std::collections::list;
import std::collections::linkedlist;
import hello_world;
@@ -239,7 +239,7 @@ fn Type getValue(Blob blob)
%Foo2 = type { i32 }
%Bobo = type { i16, float, i16, i16, float, i16 }
%"int[]" = type { ptr, i64 }
%LinkedList = type { i64, ptr, ptr }
%LinkedList = type { ptr, i64, ptr, ptr }
%List = type { i64, i64, ptr, ptr }
%Foo = type { i32, i32 }
@@ -430,16 +430,16 @@ entry:
%1 = call i32 @test_test_static()
%2 = call i32 @test_test_static()
call void @hello_world_hello()
call void @llvm.memset.p0.i64(ptr align 8 %list, i8 0, i64 24, i1 false)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 10)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 15)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 30)
call void @llvm.memset.p0.i64(ptr align 8 %list, i8 0, i64 32, i1 false)
call void @"std_collections_linkedlist$$int_LinkedList_push"(ptr %list, i32 10)
call void @"std_collections_linkedlist$$int_LinkedList_push"(ptr %list, i32 15)
call void @"std_collections_linkedlist$$int_LinkedList_push"(ptr %list, i32 30)
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%3 = load i32, ptr %i, align 4
%4 = call i64 @"std_array_linkedlist$$int_LinkedList_len"(ptr %list) #3
%4 = call i64 @"std_collections_linkedlist$$int_LinkedList_len"(ptr %list) #3
%uisitrunc = trunc i64 %4 to i32
%lt = icmp slt i32 %3, %uisitrunc
br i1 %lt, label %loop.body, label %loop.exit
@@ -448,7 +448,7 @@ loop.body: ; preds = %loop.cond
%5 = load i32, ptr %i, align 4
%6 = load i32, ptr %i, align 4
%siuiext = sext i32 %6 to i64
%7 = call i32 @"std_array_linkedlist$$int_LinkedList_get"(ptr %list, i64 %siuiext)
%7 = call i32 @"std_collections_linkedlist$$int_LinkedList_get"(ptr %list, i64 %siuiext)
%8 = call i32 (ptr, ...) @printf(ptr @.str.2, i32 %5, i32 %7)
%9 = load i32, ptr %i, align 4
%add = add i32 %9, 1
@@ -456,22 +456,22 @@ loop.body: ; preds = %loop.cond
br label %loop.cond
loop.exit: ; preds = %loop.cond
call void @"std_array_linkedlist$$int_LinkedList_free"(ptr %list)
call void @"std_collections_linkedlist$$int_LinkedList_free"(ptr %list)
%10 = call i32 (ptr, ...) @printf(ptr @.str.3, i32 3)
store i32 3, ptr %elements, align 4
%11 = call i32 (ptr, ...) @printf(ptr @.str.4)
call void @llvm.memset.p0.i64(ptr align 8 %array, i8 0, i64 32, i1 false)
call void @"std_array_list$$int_List_append"(ptr %array, i32 100)
call void @"std_array_list$$int_List_append"(ptr %array, i32 200)
call void @"std_array_list$$int_List_append"(ptr %array, i32 400)
call void @"std_array_list$$int_List_push"(ptr %array, i32 600) #3
call void @"std_array_list$$int_List_insert_at"(ptr %array, i64 2, i32 300)
call void @"std_collections_list$$int_List_append"(ptr %array, i32 100)
call void @"std_collections_list$$int_List_append"(ptr %array, i32 200)
call void @"std_collections_list$$int_List_append"(ptr %array, i32 400)
call void @"std_collections_list$$int_List_push"(ptr %array, i32 600) #3
call void @"std_collections_list$$int_List_insert_at"(ptr %array, i64 2, i32 300)
store i32 0, ptr %i1, align 4
br label %loop.cond2
loop.cond2: ; preds = %loop.body5, %loop.exit
%12 = load i32, ptr %i1, align 4
%13 = call i64 @"std_array_list$$int_List_len"(ptr %array)
%13 = call i64 @"std_collections_list$$int_List_len"(ptr %array)
%uisitrunc3 = trunc i64 %13 to i32
%lt4 = icmp slt i32 %12, %uisitrunc3
br i1 %lt4, label %loop.body5, label %loop.exit8
@@ -480,7 +480,7 @@ loop.body5: ; preds = %loop.cond2
%14 = load i32, ptr %i1, align 4
%15 = load i32, ptr %i1, align 4
%siuiext6 = sext i32 %15 to i64
%16 = call i32 @"std_array_list$$int_List_get"(ptr %array, i64 %siuiext6)
%16 = call i32 @"std_collections_list$$int_List_get"(ptr %array, i64 %siuiext6)
%17 = call i32 (ptr, ...) @printf(ptr @.str.5, i32 %14, i32 %16)
%18 = load i32, ptr %i1, align 4
%add7 = add i32 %18, 1
@@ -488,7 +488,7 @@ loop.body5: ; preds = %loop.cond2
br label %loop.cond2
loop.exit8: ; preds = %loop.cond2
call void @"std_array_list$$int_List_free"(ptr %array)
call void @"std_collections_list$$int_List_free"(ptr %array)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %a, ptr align 4 @.__const.6, i32 4, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %b, ptr align 8 @.__const.7, i32 8, i1 false)
%19 = load i32, ptr %a, align 4

View File

@@ -2,8 +2,8 @@
module test;
import test2;
import std::array::list;
import std::array::linkedlist;
import std::collections::list;
import std::collections::linkedlist;
import hello_world;
@@ -241,7 +241,7 @@ fn Type getValue(Blob blob)
%Foo2 = type { i32 }
%Bobo = type { i16, float, i16, i16, float, i16 }
%"int[]" = type { ptr, i64 }
%LinkedList = type { i64, ptr, ptr }
%LinkedList = type { ptr, i64, ptr, ptr }
%List = type { i64, i64, ptr, ptr }
%Foo = type { i32, i32 }
@@ -473,16 +473,16 @@ entry:
%1 = call i32 @test_test_static()
%2 = call i32 @test_test_static()
call void @hello_world_hello()
call void @llvm.memset.p0.i64(ptr align 8 %list, i8 0, i64 24, i1 false)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 10)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 15)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 30)
call void @llvm.memset.p0.i64(ptr align 8 %list, i8 0, i64 32, i1 false)
call void @"std_collections_linkedlist$$int_LinkedList_push"(ptr %list, i32 10)
call void @"std_collections_linkedlist$$int_LinkedList_push"(ptr %list, i32 15)
call void @"std_collections_linkedlist$$int_LinkedList_push"(ptr %list, i32 30)
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%3 = load i32, ptr %i, align 4
%4 = call i64 @"std_array_linkedlist$$int_LinkedList_len"(ptr %list) #3
%4 = call i64 @"std_collections_linkedlist$$int_LinkedList_len"(ptr %list) #3
%uisitrunc = trunc i64 %4 to i32
%lt = icmp slt i32 %3, %uisitrunc
br i1 %lt, label %loop.body, label %loop.exit
@@ -491,7 +491,7 @@ loop.body: ; preds = %loop.cond
%5 = load i32, ptr %i, align 4
%6 = load i32, ptr %i, align 4
%siuiext = sext i32 %6 to i64
%7 = call i32 @"std_array_linkedlist$$int_LinkedList_get"(ptr %list, i64 %siuiext)
%7 = call i32 @"std_collections_linkedlist$$int_LinkedList_get"(ptr %list, i64 %siuiext)
%8 = call i32 (ptr, ...) @printf(ptr @.str.2, i32 %5, i32 %7)
%9 = load i32, ptr %i, align 4
%add = add i32 %9, 1
@@ -499,22 +499,22 @@ loop.body: ; preds = %loop.cond
br label %loop.cond
loop.exit: ; preds = %loop.cond
call void @"std_array_linkedlist$$int_LinkedList_free"(ptr %list)
call void @"std_collections_linkedlist$$int_LinkedList_free"(ptr %list)
%10 = call i32 (ptr, ...) @printf(ptr @.str.3, i32 3)
store i32 3, ptr %elements, align 4
%11 = call i32 (ptr, ...) @printf(ptr @.str.4)
call void @llvm.memset.p0.i64(ptr align 8 %array, i8 0, i64 32, i1 false)
call void @"std_array_list$$int_List_append"(ptr %array, i32 100)
call void @"std_array_list$$int_List_append"(ptr %array, i32 200)
call void @"std_array_list$$int_List_append"(ptr %array, i32 400)
call void @"std_array_list$$int_List_push"(ptr %array, i32 600) #3
call void @"std_array_list$$int_List_insert_at"(ptr %array, i64 2, i32 300)
call void @"std_collections_list$$int_List_append"(ptr %array, i32 100)
call void @"std_collections_list$$int_List_append"(ptr %array, i32 200)
call void @"std_collections_list$$int_List_append"(ptr %array, i32 400)
call void @"std_collections_list$$int_List_push"(ptr %array, i32 600) #3
call void @"std_collections_list$$int_List_insert_at"(ptr %array, i64 2, i32 300)
store i32 0, ptr %i1, align 4
br label %loop.cond2
loop.cond2: ; preds = %loop.body5, %loop.exit
%12 = load i32, ptr %i1, align 4
%13 = call i64 @"std_array_list$$int_List_len"(ptr %array)
%13 = call i64 @"std_collections_list$$int_List_len"(ptr %array)
%uisitrunc3 = trunc i64 %13 to i32
%lt4 = icmp slt i32 %12, %uisitrunc3
br i1 %lt4, label %loop.body5, label %loop.exit8
@@ -523,7 +523,7 @@ loop.body5: ; preds = %loop.cond2
%14 = load i32, ptr %i1, align 4
%15 = load i32, ptr %i1, align 4
%siuiext6 = sext i32 %15 to i64
%16 = call i32 @"std_array_list$$int_List_get"(ptr %array, i64 %siuiext6)
%16 = call i32 @"std_collections_list$$int_List_get"(ptr %array, i64 %siuiext6)
%17 = call i32 (ptr, ...) @printf(ptr @.str.5, i32 %14, i32 %16)
%18 = load i32, ptr %i1, align 4
%add7 = add i32 %18, 1
@@ -531,7 +531,7 @@ loop.body5: ; preds = %loop.cond2
br label %loop.cond2
loop.exit8: ; preds = %loop.cond2
call void @"std_array_list$$int_List_free"(ptr %array)
call void @"std_collections_list$$int_List_free"(ptr %array)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %a, ptr align 4 @.__const.6, i32 4, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %b, ptr align 8 @.__const.7, i32 8, i1 false)
%19 = load i32, ptr %a, align 4
@@ -607,26 +607,25 @@ declare void @hello_world_hello()
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #2
declare void @"std_array_linkedlist$$int_LinkedList_push"(ptr, i32)
declare void @"std_collections_linkedlist$$int_LinkedList_push"(ptr, i32)
declare i64 @"std_array_linkedlist$$int_LinkedList_len"(ptr)
declare i64 @"std_collections_linkedlist$$int_LinkedList_len"(ptr)
declare i32 @"std_array_linkedlist$$int_LinkedList_get"(ptr, i64)
declare i32 @"std_collections_linkedlist$$int_LinkedList_get"(ptr, i64)
declare void @"std_array_linkedlist$$int_LinkedList_free"(ptr)
declare void @"std_collections_linkedlist$$int_LinkedList_free"(ptr)
declare void @"std_array_list$$int_List_append"(ptr, i32)
declare void @"std_collections_list$$int_List_append"(ptr, i32)
declare void @"std_array_list$$int_List_push"(ptr, i32)
declare void @"std_collections_list$$int_List_push"(ptr, i32)
declare void @"std_array_list$$int_List_insert_at"(ptr, i64, i32)
declare void @"std_collections_list$$int_List_insert_at"(ptr, i64, i32)
declare i64 @"std_array_list$$int_List_len"(ptr)
declare i64 @"std_collections_list$$int_List_len"(ptr)
declare i32 @"std_array_list$$int_List_get"(ptr, i64)
declare double @"test2$$double_getMult"(double)
declare i32 @"std_collections_list$$int_List_get"(ptr, i64)
declare void @"std_collections_list$$int_List_free"(ptr)
// #expect: hello_world.ll

View File

@@ -1,7 +1,7 @@
// #target: macos-x64
module test;
import std::io;
import std::enumset;
import std::collections::enumset;
define AbcEnumSet = EnumSet<Abc>;
@@ -47,23 +47,23 @@ entry:
%varargslots11 = alloca [1 x %variant], align 16
%taddr12 = alloca i8, align 1
store i32 0, ptr %set, align 4
%0 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
%0 = call i8 @"std_collections_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
store i8 %0, ptr %taddr, align 1
%1 = insertvalue %variant undef, ptr %taddr, 0
%2 = insertvalue %variant %1, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%3 = getelementptr inbounds [1 x %variant], ptr %varargslots, i64 0, i64 0
store %variant %2, ptr %3, align 16
%4 = call i64 @std_io_printf(ptr %retparam, ptr @.str, i64 14, ptr %varargslots, i64 1)
call void @"std_enumset$$test_Abc_EnumSet_add"(ptr %set, i32 0)
%5 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
call void @"std_collections_enumset$$test_Abc_EnumSet_add"(ptr %set, i32 0)
%5 = call i8 @"std_collections_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
store i8 %5, ptr %taddr3, align 1
%6 = insertvalue %variant undef, ptr %taddr3, 0
%7 = insertvalue %variant %6, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%8 = getelementptr inbounds [1 x %variant], ptr %varargslots2, i64 0, i64 0
store %variant %7, ptr %8, align 16
%9 = call i64 @std_io_printf(ptr %retparam1, ptr @.str.1, i64 14, ptr %varargslots2, i64 1)
call void @"std_enumset$$test_Abc_EnumSet_add"(ptr %set, i32 1)
%10 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
call void @"std_collections_enumset$$test_Abc_EnumSet_add"(ptr %set, i32 1)
%10 = call i8 @"std_collections_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
store i8 %10, ptr %taddr6, align 1
%11 = insertvalue %variant undef, ptr %taddr6, 0
%12 = insertvalue %variant %11, i64 ptrtoint (ptr @"ct$bool" to i64), 1
@@ -72,8 +72,8 @@ entry:
%14 = call i64 @std_io_printf(ptr %retparam4, ptr @.str.2, i64 14, ptr %varargslots5, i64 1)
store i32 0, ptr %set2, align 4
%15 = load i32, ptr %set, align 4
call void @"std_enumset$$test_Abc_EnumSet_add_all"(ptr %set2, i32 %15)
%16 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set2, i32 1)
call void @"std_collections_enumset$$test_Abc_EnumSet_add_all"(ptr %set2, i32 %15)
%16 = call i8 @"std_collections_enumset$$test_Abc_EnumSet_has"(ptr %set2, i32 1)
store i8 %16, ptr %taddr9, align 1
%17 = insertvalue %variant undef, ptr %taddr9, 0
%18 = insertvalue %variant %17, i64 ptrtoint (ptr @"ct$bool" to i64), 1
@@ -81,8 +81,8 @@ entry:
store %variant %18, ptr %19, align 16
%20 = call i64 @std_io_printf(ptr %retparam7, ptr @.str.3, i64 14, ptr %varargslots8, i64 1)
%21 = load i32, ptr %set2, align 4
call void @"std_enumset$$test_Abc_EnumSet_remove_all"(ptr %set, i32 %21)
%22 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
call void @"std_collections_enumset$$test_Abc_EnumSet_remove_all"(ptr %set, i32 %21)
%22 = call i8 @"std_collections_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
store i8 %22, ptr %taddr12, align 1
%23 = insertvalue %variant undef, ptr %taddr12, 0
%24 = insertvalue %variant %23, i64 ptrtoint (ptr @"ct$bool" to i64), 1

View File

@@ -1,5 +1,5 @@
module compiler_c3;
import std::array::list;
import std::collections::list;
define IntArray = List<int>;

View File

@@ -1,7 +1,7 @@
// #target: macos-x64
module test;
import std::map;
import std::collections::map;
define IntMap = HashMap<char[], int>;
@@ -18,7 +18,7 @@ define void @test_main() #0 {
entry:
%map = alloca %HashMap, align 8
call void @llvm.memset.p0.i64(ptr align 8 %map, i8 0, i64 40, i1 false)
%0 = call i8 @"std_map$$sa$char.int_HashMap_set"(ptr %map, ptr @.str, i64 5, i32 4)
%1 = call i8 @"std_map$$sa$char.int_HashMap_set"(ptr %map, ptr @.str.1, i64 3, i32 5)
%0 = call i8 @"std_collections_map$$sa$char.int_HashMap_set"(ptr %map, ptr @.str, i64 5, i32 4)
%1 = call i8 @"std_collections_map$$sa$char.int_HashMap_set"(ptr %map, ptr @.str.1, i64 3, i32 5)
ret void
}

View File

@@ -2,12 +2,12 @@
module test;
import std::io;
import std::map;
import std::collections::map;
struct Foo { int x; void* bar; }
define IntFooMap = std::map::HashMap<int, Foo>;
define IntDoubleMap = std::map::HashMap<int, double>;
define IntFooMap = HashMap<int, Foo>;
define IntDoubleMap = HashMap<int, double>;
fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator())
{
@@ -65,11 +65,11 @@ entry:
if.then: ; preds = %entry
%1 = load ptr, ptr @std_core_mem_thread_allocator, align 8
call void @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(ptr @std_io_tostring_functions, i32 64, float 7.500000e-01, ptr %1)
call void @"std_collections_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(ptr @std_io_tostring_functions, i32 64, float 7.500000e-01, ptr %1)
br label %if.exit
if.exit: ; preds = %if.then, %entry
%2 = call i8 @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_set"(ptr @std_io_tostring_functions, i64 ptrtoint (ptr @"ct$test_Foo" to i64), ptr @test_Foo_to_string)
%2 = call i8 @"std_collections_map$$typeid.p$std_io$ToStringFunction_HashMap_set"(ptr @std_io_tostring_functions, i64 ptrtoint (ptr @"ct$test_Foo" to i64), ptr @test_Foo_to_string)
ret void
}
@@ -147,7 +147,7 @@ entry:
%result54 = alloca %"int[]", align 8
call void @llvm.memset.p0.i64(ptr align 8 %map, i8 0, i64 40, i1 false)
%0 = load ptr, ptr @std_core_mem_thread_allocator, align 8
call void @"std_map$$int.test_Foo_HashMap_init"(ptr %map, i32 16, float 7.500000e-01, ptr %0)
call void @"std_collections_map$$int.test_Foo_HashMap_init"(ptr %map, i32 16, float 7.500000e-01, ptr %0)
%1 = getelementptr inbounds %HashMap.0, ptr %map, i32 0, i32 2
%2 = insertvalue %variant undef, ptr %1, 0
%3 = insertvalue %variant %2, i64 ptrtoint (ptr @"ct$uint" to i64), 1
@@ -162,7 +162,7 @@ entry:
%lo = load i64, ptr %8, align 8
%9 = getelementptr inbounds { i64, ptr }, ptr %literal, i32 0, i32 1
%hi = load ptr, ptr %9, align 8
%10 = call i8 @"std_map$$int.test_Foo_HashMap_set"(ptr %map, i32 1, i64 %lo, ptr %hi)
%10 = call i8 @"std_collections_map$$int.test_Foo_HashMap_set"(ptr %map, i32 1, i64 %lo, ptr %hi)
%11 = getelementptr inbounds %HashMap.0, ptr %map, i32 0, i32 2
%12 = insertvalue %variant undef, ptr %11, 0
%13 = insertvalue %variant %12, i64 ptrtoint (ptr @"ct$uint" to i64), 1
@@ -177,14 +177,14 @@ entry:
%lo4 = load i64, ptr %18, align 8
%19 = getelementptr inbounds { i64, ptr }, ptr %literal3, i32 0, i32 1
%hi5 = load ptr, ptr %19, align 8
%20 = call i8 @"std_map$$int.test_Foo_HashMap_set"(ptr %map, i32 1, i64 %lo4, ptr %hi5)
%20 = call i8 @"std_collections_map$$int.test_Foo_HashMap_set"(ptr %map, i32 1, i64 %lo4, ptr %hi5)
%21 = getelementptr inbounds %HashMap.0, ptr %map, i32 0, i32 2
%22 = insertvalue %variant undef, ptr %21, 0
%23 = insertvalue %variant %22, i64 ptrtoint (ptr @"ct$uint" to i64), 1
%24 = getelementptr inbounds [1 x %variant], ptr %varargslots7, i64 0, i64 0
store %variant %23, ptr %24, align 16
%25 = call i64 @std_io_printfn(ptr %retparam6, ptr @.str.2, i64 12, ptr %varargslots7, i64 1)
%26 = call i64 @"std_map$$int.test_Foo_HashMap_get"(ptr %retparam10, ptr %map, i32 1)
%26 = call i64 @"std_collections_map$$int.test_Foo_HashMap_get"(ptr %retparam10, ptr %map, i32 1)
%not_err = icmp eq i64 %26, 0
br i1 %not_err, label %after_check, label %after_check12
@@ -199,14 +199,14 @@ after_check: ; preds = %entry
br i1 %not_err11, label %after_check12, label %after_check12
after_check12: ; preds = %entry, %after_check, %after_check
%32 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(ptr %map, i32 1)
%32 = call i8 @"std_collections_map$$int.test_Foo_HashMap_has_key"(ptr %map, i32 1)
store i8 %32, ptr %taddr, align 1
%33 = insertvalue %variant undef, ptr %taddr, 0
%34 = insertvalue %variant %33, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%35 = getelementptr inbounds [1 x %variant], ptr %varargslots14, i64 0, i64 0
store %variant %34, ptr %35, align 16
%36 = call i64 @std_io_printfn(ptr %retparam13, ptr @.str.4, i64 9, ptr %varargslots14, i64 1)
%37 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(ptr %map, i32 2)
%37 = call i8 @"std_collections_map$$int.test_Foo_HashMap_has_key"(ptr %map, i32 2)
store i8 %37, ptr %taddr19, align 1
%38 = insertvalue %variant undef, ptr %taddr19, 0
%39 = insertvalue %variant %38, i64 ptrtoint (ptr @"ct$bool" to i64), 1
@@ -221,9 +221,9 @@ after_check12: ; preds = %entry, %after_check
%lo23 = load i64, ptr %44, align 8
%45 = getelementptr inbounds { i64, ptr }, ptr %literal22, i32 0, i32 1
%hi24 = load ptr, ptr %45, align 8
%46 = call i8 @"std_map$$int.test_Foo_HashMap_set"(ptr %map, i32 7, i64 %lo23, ptr %hi24)
%46 = call i8 @"std_collections_map$$int.test_Foo_HashMap_set"(ptr %map, i32 7, i64 %lo23, ptr %hi24)
%47 = load ptr, ptr @std_core_mem_thread_allocator, align 8
%48 = call { ptr, i64 } @"std_map$$int.test_Foo_HashMap_value_list"(ptr %map, ptr %47)
%48 = call { ptr, i64 } @"std_collections_map$$int.test_Foo_HashMap_value_list"(ptr %map, ptr %47)
store { ptr, i64 } %48, ptr %result, align 8
%49 = insertvalue %variant undef, ptr %result, 0
%50 = insertvalue %variant %49, i64 ptrtoint (ptr @"ct$sa$test_Foo" to i64), 1
@@ -232,25 +232,25 @@ after_check12: ; preds = %entry, %after_check
%52 = call i64 @std_io_printfn(ptr %retparam25, ptr @.str.6, i64 10, ptr %varargslots26, i64 1)
call void @llvm.memset.p0.i64(ptr align 8 %map2, i8 0, i64 40, i1 false)
%53 = load ptr, ptr @std_core_mem_thread_allocator, align 8
call void @"std_map$$int.double_HashMap_init"(ptr %map2, i32 16, float 7.500000e-01, ptr %53)
%54 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map2, i32 4, double 1.300000e+00)
%55 = call i8 @"std_map$$int.double_HashMap_has_value"(ptr %map2, double 1.300000e+00)
call void @"std_collections_map$$int.double_HashMap_init"(ptr %map2, i32 16, float 7.500000e-01, ptr %53)
%54 = call i8 @"std_collections_map$$int.double_HashMap_set"(ptr %map2, i32 4, double 1.300000e+00)
%55 = call i8 @"std_collections_map$$int.double_HashMap_has_value"(ptr %map2, double 1.300000e+00)
store i8 %55, ptr %taddr31, align 1
%56 = insertvalue %variant undef, ptr %taddr31, 0
%57 = insertvalue %variant %56, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%58 = getelementptr inbounds [1 x %variant], ptr %varargslots30, i64 0, i64 0
store %variant %57, ptr %58, align 16
%59 = call i64 @std_io_printfn(ptr %retparam29, ptr @.str.7, i64 12, ptr %varargslots30, i64 1)
%60 = call i8 @"std_map$$int.double_HashMap_has_value"(ptr %map2, double 1.200000e+00)
%60 = call i8 @"std_collections_map$$int.double_HashMap_has_value"(ptr %map2, double 1.200000e+00)
store i8 %60, ptr %taddr36, align 1
%61 = insertvalue %variant undef, ptr %taddr36, 0
%62 = insertvalue %variant %61, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%63 = getelementptr inbounds [1 x %variant], ptr %varargslots35, i64 0, i64 0
store %variant %62, ptr %63, align 16
%64 = call i64 @std_io_printfn(ptr %retparam34, ptr @.str.8, i64 12, ptr %varargslots35, i64 1)
%65 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map2, i32 100, double 3.400000e+00)
%65 = call i8 @"std_collections_map$$int.double_HashMap_set"(ptr %map2, i32 100, double 3.400000e+00)
%66 = load ptr, ptr @std_core_mem_thread_allocator, align 8
%67 = call { ptr, i64 } @"std_map$$int.double_HashMap_key_list"(ptr %map2, ptr %66)
%67 = call { ptr, i64 } @"std_collections_map$$int.double_HashMap_key_list"(ptr %map2, ptr %66)
store { ptr, i64 } %67, ptr %result41, align 8
%68 = insertvalue %variant undef, ptr %result41, 0
%69 = insertvalue %variant %68, i64 ptrtoint (ptr @"ct$sa$int" to i64), 1
@@ -258,7 +258,7 @@ after_check12: ; preds = %entry, %after_check
store %variant %69, ptr %70, align 16
%71 = call i64 @std_io_printfn(ptr %retparam39, ptr @.str.9, i64 2, ptr %varargslots40, i64 1)
%72 = load ptr, ptr @std_core_mem_thread_allocator, align 8
%73 = call { ptr, i64 } @"std_map$$int.double_HashMap_value_list"(ptr %map2, ptr %72)
%73 = call { ptr, i64 } @"std_collections_map$$int.double_HashMap_value_list"(ptr %map2, ptr %72)
store { ptr, i64 } %73, ptr %result46, align 8
%74 = insertvalue %variant undef, ptr %result46, 0
%75 = insertvalue %variant %74, i64 ptrtoint (ptr @"ct$sa$double" to i64), 1
@@ -301,11 +301,11 @@ if.exit: ; preds = %noerr_block, %after
store i64 %86, ptr %mark, align 8
call void @llvm.memset.p0.i64(ptr align 8 %map3, i8 0, i64 40, i1 false)
%87 = load ptr, ptr @std_core_mem_thread_allocator, align 8
call void @"std_map$$int.double_HashMap_init"(ptr %map3, i32 16, float 7.500000e-01, ptr %87)
%88 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map3, i32 5, double 3.200000e+00)
%89 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map3, i32 7, double 5.200000e+00)
call void @"std_collections_map$$int.double_HashMap_init"(ptr %map3, i32 16, float 7.500000e-01, ptr %87)
%88 = call i8 @"std_collections_map$$int.double_HashMap_set"(ptr %map3, i32 5, double 3.200000e+00)
%89 = call i8 @"std_collections_map$$int.double_HashMap_set"(ptr %map3, i32 7, double 5.200000e+00)
%90 = load ptr, ptr @std_core_mem_thread_allocator, align 8
%91 = call { ptr, i64 } @"std_map$$int.double_HashMap_key_list"(ptr %map3, ptr %90)
%91 = call { ptr, i64 } @"std_collections_map$$int.double_HashMap_key_list"(ptr %map3, ptr %90)
store { ptr, i64 } %91, ptr %result54, align 8
%92 = insertvalue %variant undef, ptr %result54, 0
%93 = insertvalue %variant %92, i64 ptrtoint (ptr @"ct$sa$int" to i64), 1

View File

@@ -2,7 +2,7 @@
module test;
import std::io;
import std::math;
import std::priorityqueue;
import std::collections::priorityqueue;
define FooPriorityQueue = PriorityQueue<Foo>;

View File

@@ -0,0 +1,213 @@
module linkedlist_test;
import std::collections::linkedlist;
define IntList = LinkedList<int>;
fn void! test_push() @test
{
IntList list;
list.push(23);
assert(list.len() == 1);
assert(list.first()? == 23);
assert(list.last()? == 23);
list.push(55);
assert(list.len() == 2);
assert(list.last()? == 23);
assert(list.first()? == 55);
}
fn void! test_push_last() @test
{
IntList list;
list.push_last(23);
assert(list.len() == 1);
assert(list.first()? == 23);
assert(list.last()? == 23);
list.push_last(55);
assert(list.len() == 2);
assert(list.last()? == 55);
assert(list.first()? == 23);
}
fn void! test_get() @test
{
IntList list;
list.push(23);
list.push(55);
list.push(-3);
assert(list.get(0) == -3);
assert(list.get(1) == 55);
assert(list.get(2) == 23);
}
fn void! test_insert() @test
{
IntList list;
list.push(23);
list.push(55);
list.push(-3);
list.insert(0, 1);
list.insert(2, 11);
list.insert(4, 111);
list.insert(6, 1111);
assert(list.get(0) == 1);
assert(list.get(1) == -3);
assert(list.get(2) == 11);
assert(list.get(3) == 55);
assert(list.get(4) == 111);
assert(list.get(5) == 23);
assert(list.get(6) == 1111);
}
fn void! test_set() @test
{
IntList list;
list.push(23);
list.push(55);
list.push(-3);
for (int i = 0; i < 3; i++) list.set(i, list.get(i) + 1);
assert(list.get(0) == -2);
assert(list.get(1) == 56);
assert(list.get(2) == 24);
}
fn void! test_remove() @test
{
IntList list;
for (int i = 0; i < 10; i++) list.push(i);
list.remove(0);
list.remove(1);
list.remove(7);
list.remove(5);
assert(list.get(0) == 8);
assert(list.get(1) == 6);
assert(list.get(5) == 1);
assert(list.get(4) == 3);
}
fn void! test_remove_value() @test
{
IntList list;
list.push(23);
list.push(55);
list.push(-3);
assert(list.remove_value(23));
assert(list.pop()? == -3);
assert(list.pop()? == 55);
assert(!list.len());
list.push(23);
list.push(55);
list.push(-3);
assert(list.remove_value(55));
assert(list.pop()? == -3);
assert(list.pop()? == 23);
assert(!list.len());
list.push(23);
list.push(55);
list.push(-3);
assert(list.remove_value(-3));
assert(list.pop()? == 55);
assert(list.pop()? == 23);
assert(!list.len());
}
fn void! test_remove_last_value() @test
{
IntList list;
list.push(23);
list.push(55);
list.push(-3);
assert(list.remove_last_value(23));
assert(list.pop()? == -3);
assert(list.pop()? == 55);
assert(!list.len());
list.push(23);
list.push(55);
list.push(-3);
assert(list.remove_last_value(55));
assert(list.pop()? == -3);
assert(list.pop()? == 23);
assert(!list.len());
list.push(23);
list.push(55);
list.push(-3);
assert(list.remove_last_value(-3));
assert(list.pop()? == 55);
assert(list.pop()? == 23);
assert(!list.len());
}
fn void! test_pop() @test
{
IntList list;
list.push(23);
list.push(55);
list.push(-3);
assert(list.len() == 3);
assert(list.last()? == 23);
assert(list.first()? == -3);
assert(list.pop()? == -3);
assert(list.len() == 2);
assert(list.last()? == 23);
assert(list.first()? == 55);
assert(list.pop()? == 55);
assert(list.last()? == 23);
assert(list.first()? == 23);
assert(list.pop()? == 23);
assert(list.len() == 0);
assert(catch(list.pop()));
assert(list.len() == 0);
list.push(55);
assert(list.len() == 1);
}
fn void! test_remove_first() @test
{
IntList list;
list.push(23);
list.push(55);
list.push(-3);
assert(list.len() == 3);
assert(list.last()? == 23);
assert(list.first()? == -3);
assert(try(list.remove_first()));
assert(list.len() == 2);
assert(list.last()? == 23);
assert(list.first()? == 55);
assert(try(list.remove_first()));
assert(list.last()? == 23);
assert(list.first()? == 23);
assert(try(list.remove_first()));
assert(list.len() == 0);
assert(catch(list.pop()));
assert(list.len() == 0);
list.push(55);
assert(list.len() == 1);
}
fn void! test_remove_last() @test
{
IntList list;
list.push(23);
list.push(55);
list.push(-3);
assert(list.len() == 3);
assert(list.last()? == 23);
assert(list.first()? == -3);
assert(try(list.remove_last()));
assert(list.len() == 2);
assert(list.first()? == -3);
assert(list.last()? == 55);
assert(try(list.remove_last()));
assert(list.first()? == -3);
assert(list.last()? == -3);
assert(try(list.remove_last()));
assert(list.len() == 0);
assert(catch(list.remove_last()));
assert(list.len() == 0);
list.push(55);
assert(list.len() == 1);
}