blob: 1de185dfdc1759275e5c10d104b3a48ffa6498d1 (
plain) (
tree)
|
|
implementation module Heap;
import StdOverloaded,StdMisc;
:: Heap v = {heap::!.(HeapN v)};
:: HeapN v = Heap !Int;
:: Ptr v = {pointer::!.(PtrN v)};
:: PtrN v = Ptr !v !(HeapN v);
newHeap :: .Heap v;
newHeap = {heap=Heap 0};
newPtr :: !v !*(Heap v) -> (!.Ptr v,!.Heap v);
newPtr v h = code {
build_r e_Heap_kPtr 2 0 0 0
update_a 0 1
pop_a 1
};
nilPtr :: Ptr v;
nilPtr =: make_nilPtr;
make_nilPtr :: Ptr v;
make_nilPtr = code {
build _Nil 0 _hnf
push_a 0
build_r e_Heap_kPtr 2 0 0 0
update_a 0 2
pop_a 2
};
isNilPtr :: !(Ptr v) -> Bool;
isNilPtr p = code {
repl_args 2 2
pop_a 1
eq_desc _Nil 0 0
pop_a 1
};
allocPtr :: Ptr v;
allocPtr = code {
build _Cons 0 _hnf
push_a 0
build_r e_Heap_kPtr 2 0 0 0
update_a 0 2
pop_a 2
};
initPtr :: !(Ptr v) !v !*(Heap v) !*World -> (!.Heap v,!*World);
initPtr p v h w
= code {
push_args 0 2 2
pop_a 1
eq_desc _Cons 0 0
pop_a 1
jmp_false init_pointer_error
push_a 2
push_a 2
fill1_r e_Heap_kPtr 2 0 2 011
.keep 0 2
pop_a 2
.d 2 0
rtn
:init_pointer_error
pop_a 3
print "initPtr: Pointer already initialized"
halt
};
/*
initPtr :: !(Ptr v) !v !*(Heap v) -> .Heap v;
initPtr p v h
= code {
push_args 0 2 2
pop_a 1
eq_desc _Cons 0 0
pop_a 1
jmp_false init_pointer_error
push_a 2
push_a 2
fill1_r e_Heap_kPtr 2 0 2 011
.keep 0 2
pop_a 2
.d 1 0
rtn
:init_pointer_error
pop_a 2
print "initPtr: Pointer already initialized"
halt
};
*/
readPtr :: !(Ptr v) !u:(Heap v) -> (!v,!u:Heap v);
readPtr p h = code {
push_a_b 1
push_r_args_b 0 1 1 1 1
eqI
jmp_false read_heap_error
repl_r_args_a 2 0 1 1
.d 2 0
rtn
:read_heap_error
pop_a 1
print "readPtr: Not a pointer of this heap"
halt
};
sreadPtr :: !(Ptr v) !(Heap v) -> v;
sreadPtr p h = code {
push_a_b 1
push_r_args_b 0 1 1 1 1
eqI
jmp_false sread_heap_error
repl_r_args_a 2 0 1 1
update_a 0 1
pop_a 1
.d 1 0
rtn
:sread_heap_error
pop_a 1
print "sreadPtr: Not a pointer of this heap"
halt
};
writePtr :: !(Ptr v) !v !*(Heap v) -> .Heap v;
writePtr p v h
/*
| isNilPtr p
= abort "writePtr: Nil pointer encountered\n";
= writePtr2 p v h;
writePtr2 :: !(Ptr v) !v !*(Heap v) -> .Heap v;
writePtr2 p v h
*/
= code {
push_a_b 2
push_r_args_b 0 1 1 1 1
eqI
jmp_false write_heap_error
push_a 1
fill1_r e_Heap_kPtr 2 0 1 010
.keep 0 2
pop_a 2
.d 1 0
rtn
:write_heap_error
pop_a 2
print "writePtr: Not a pointer of this heap"
halt
};
(<:=) infixl;
(<:=) heap ptr_and_val :== writePtr ptr val heap ;
{
(ptr, val) = ptr_and_val;
}
ptrToInt :: !(Ptr v) -> Int;
ptrToInt p
| isNilPtr p
= 0;
= ptrToInt2 p;
ptrToInt2 :: !(Ptr v) -> Int;
ptrToInt2 p = code {
push_a_b 0
pop_a 1
build _Nil 0 _hnf
push_a_b 0
pop_a 1
push_b 1
eqI
jmp_false not_nil
pop_b 1
pushI 0
.d 0 1 b
rtn
:not_nil
.d 0 1 b
rtn
};
instance == (Ptr a)
where
{ (==) p1 p2 = code {
push_r_args_b 1 1 1 1 1
push_r_args_b 0 1 1 1 1
eqI
jmp_false equal_pointer_error
push_a_b 1
push_a_b 0
pop_a 2
eqI
.d 0 1 b
rtn
:equal_pointer_error
pop_a 1
print "equal_pointer: Pointers to different heaps or a nilPtr"
halt
}
};
|