Compare commits

...

2 Commits

3 changed files with 228 additions and 29 deletions

View File

@ -25,6 +25,7 @@ import hulk.serial;
import hulk.usb;
import hulk.pit;
import hulk.time;
import hulk.test;
extern extern(C) __gshared ubyte _hulk_bss_size;
@ -97,6 +98,9 @@ void hulk_start()
}
Klog.writefln("\a5HULK Initialization Complete!");
/* Run kernel tests. */
Test.run();
/* Idle loop. */
Time.msleep(1);
for (;;)

View File

@ -10,55 +10,119 @@ import hulk.hurl.a1;
*/
struct List(T)
{
/**
* Linked list item.
*/
T item;
struct Node
{
/**
* Linked list node.
*/
T item;
alias item this;
/**
* Next node.
*/
Node * next;
/**
* Previous node.
*/
Node * prev;
}
/**
* Next list entry.
* Head node.
*/
List!T * next;
public Node * head;
/**
* Tail node.
*/
public Node * tail;
/**
* Add an item to this linked list.
*/
public void add(T item)
public void add(T)(auto ref T item)
{
List!T * last_entry = last_entry();
List!T * new_entry = A1.allocate!(List!T)();
last_entry.item = item;
last_entry.next = new_entry;
Node * new_node = A1.allocate!Node();
new_node.item = item;
new_node.next = null;
new_node.prev = tail;
if (tail != null)
{
tail.next = new_node;
}
tail = new_node;
if (head == null)
{
head = new_node;
}
}
/**
* Remove an item from this linked list.
*/
public void remove(ref Node node)
{
if (node.prev != null)
{
node.prev.next = node.next;
}
else
{
/* Removing the first list node. */
head = node.next;
}
if (node.next != null)
{
node.next.prev = node.prev;
}
else
{
/* Removing the last list node. */
tail = node.prev;
}
}
/**
* Remove an item from this linked list.
*/
public void remove(Node * node)
{
remove(*node);
}
/**
* Get the number of nodes in this list.
*/
public @property size_t count() const
{
size_t count;
const(Node) * node = head;
while (node != null)
{
count++;
node = node.next;
}
return count;
}
/**
* Allow foreach iteration across a List.
*/
public int opApply(scope int delegate(ref T) dg)
public int opApply(scope int delegate(ref Node) dg)
{
List!T * entry = &this;
while (entry.next != null)
Node * node = head;
while (node != null)
{
int result = dg(entry.item);
Node * current = node;
node = node.next;
int result = dg(*current);
if (result != 0)
{
return result;
}
entry = entry.next;
}
return 0;
}
/**
* Get the last linked list entry.
*/
private @property List!T * last_entry()
{
List!T * result = &this;
while (result.next != null)
{
result = result.next;
}
return result;
}
}

131
src/hulk/test.d Normal file
View File

@ -0,0 +1,131 @@
/**
* Kernel tests.
*/
module hulk.test;
import hulk.klog;
import hulk.list;
struct Test
{
/**
* Run tests.
*/
public static void run()
{
Klog.writefln("\a3Running kernel tests");
test_list();
Klog.writefln("\a3Kernel tests complete");
}
private static void test_list()
{
Klog.writefln("Testing list...");
List!ulong list;
assert_eq(null, list.head);
assert_eq(null, list.tail);
ulong v = 33;
list.add(42);
assert_neq(null, list.head);
assert_neq(null, list.tail);
list.add(v);
list.add(0xFFFF);
v = 55;
size_t count;
assert_eq(3, list.count);
foreach (entry; list)
{
switch (count)
{
case 0:
assert_eq(42, entry);
break;
case 1:
assert_eq(33, entry);
break;
case 2:
assert_eq(0xFFFF, entry);
break;
case 3:
assert_eq(0, 1);
break;
default:
break;
}
count++;
}
foreach (entry; list)
{
if (entry == 33)
{
list.remove(entry);
}
}
assert_eq(2, list.count);
count = 0;
foreach (entry; list)
{
switch (count)
{
case 0:
assert_eq(42, entry);
break;
case 1:
assert_eq(0xFFFF, entry);
break;
case 2:
assert_eq(0, 1);
break;
default:
break;
}
count++;
}
foreach (entry; list)
{
if (entry == 42)
{
list.remove(entry);
}
}
assert_eq(1, list.count);
count = 0;
foreach (entry; list)
{
switch (count)
{
case 0:
assert_eq(0xFFFF, entry);
break;
case 1:
assert_eq(0, 1);
break;
default:
break;
}
count++;
}
assert_neq(null, list.head);
assert_neq(null, list.tail);
list.remove(list.head);
assert_eq(0, list.count);
assert_eq(null, list.head);
assert_eq(null, list.tail);
}
private static void assert_eq(T)(T first, T second)
{
if (first != second)
{
Klog.fatal_error("Assertion failed! %x != %x", first, second);
}
}
private static void assert_neq(T)(T first, T second)
{
if (first == second)
{
Klog.fatal_error("Assertion failed! %x == %x", first, second);
}
}
}