Compare commits
No commits in common. "35e5aa2ee58a2b4e46b27ca455dbb7bf718c88b1" and "294500fb70ca8ecda87f44c049fae5da46a14754" have entirely different histories.
35e5aa2ee5
...
294500fb70
@ -25,7 +25,6 @@ import hulk.serial;
|
|||||||
import hulk.usb;
|
import hulk.usb;
|
||||||
import hulk.pit;
|
import hulk.pit;
|
||||||
import hulk.time;
|
import hulk.time;
|
||||||
import hulk.test;
|
|
||||||
|
|
||||||
extern extern(C) __gshared ubyte _hulk_bss_size;
|
extern extern(C) __gshared ubyte _hulk_bss_size;
|
||||||
|
|
||||||
@ -98,9 +97,6 @@ void hulk_start()
|
|||||||
}
|
}
|
||||||
Klog.writefln("\a5HULK Initialization Complete!");
|
Klog.writefln("\a5HULK Initialization Complete!");
|
||||||
|
|
||||||
/* Run kernel tests. */
|
|
||||||
Test.run();
|
|
||||||
|
|
||||||
/* Idle loop. */
|
/* Idle loop. */
|
||||||
Time.msleep(1);
|
Time.msleep(1);
|
||||||
for (;;)
|
for (;;)
|
||||||
|
122
src/hulk/list.d
122
src/hulk/list.d
@ -10,119 +10,55 @@ import hulk.hurl.a1;
|
|||||||
*/
|
*/
|
||||||
struct List(T)
|
struct List(T)
|
||||||
{
|
{
|
||||||
struct Node
|
/**
|
||||||
{
|
* Linked list item.
|
||||||
/**
|
*/
|
||||||
* Linked list node.
|
T item;
|
||||||
*/
|
|
||||||
T item;
|
|
||||||
alias item this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Next node.
|
|
||||||
*/
|
|
||||||
Node * next;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Previous node.
|
|
||||||
*/
|
|
||||||
Node * prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Head node.
|
* Next list entry.
|
||||||
*/
|
*/
|
||||||
public Node * head;
|
List!T * next;
|
||||||
|
|
||||||
/**
|
|
||||||
* Tail node.
|
|
||||||
*/
|
|
||||||
public Node * tail;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an item to this linked list.
|
* Add an item to this linked list.
|
||||||
*/
|
*/
|
||||||
public void add(T)(auto ref T item)
|
public void add(T item)
|
||||||
{
|
{
|
||||||
Node * new_node = A1.allocate!Node();
|
List!T * last_entry = last_entry();
|
||||||
new_node.item = item;
|
List!T * new_entry = A1.allocate!(List!T)();
|
||||||
new_node.next = null;
|
last_entry.item = item;
|
||||||
new_node.prev = tail;
|
last_entry.next = new_entry;
|
||||||
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.
|
* Allow foreach iteration across a List.
|
||||||
*/
|
*/
|
||||||
public int opApply(scope int delegate(ref Node) dg)
|
public int opApply(scope int delegate(ref T) dg)
|
||||||
{
|
{
|
||||||
Node * node = head;
|
List!T * entry = &this;
|
||||||
while (node != null)
|
while (entry.next != null)
|
||||||
{
|
{
|
||||||
Node * current = node;
|
int result = dg(entry.item);
|
||||||
node = node.next;
|
|
||||||
int result = dg(*current);
|
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
entry = entry.next;
|
||||||
}
|
}
|
||||||
return 0;
|
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
131
src/hulk/test.d
@ -1,131 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user