alisp.org: rework TODOs, setup one for allocators.
This commit is contained in:
169
alisp.org
169
alisp.org
@@ -4,6 +4,15 @@
|
|||||||
#+filetags: :alisp:
|
#+filetags: :alisp:
|
||||||
|
|
||||||
* Tasks
|
* Tasks
|
||||||
|
** String views :strings:
|
||||||
|
[[file:include/alisp/sv.h::/// String Views]]
|
||||||
|
*** DONE sv_substr
|
||||||
|
Takes an index and a size, returns a string view to that substring.
|
||||||
|
*** DONE sv_chop_left and sv_chop_right
|
||||||
|
Super obvious.
|
||||||
|
*** TODO Design Strings for the Lisp :api:
|
||||||
|
We have ~sv_t~ so our basic C API is done. We just need pluggable
|
||||||
|
functions to construct and deconstruct strings as lisps.
|
||||||
** Reader system :reader:
|
** Reader system :reader:
|
||||||
We need to design a reader system. The big idea: given a "stream" of
|
We need to design a reader system. The big idea: given a "stream" of
|
||||||
data, we can break out expressions from it. An expression could be
|
data, we can break out expressions from it. An expression could be
|
||||||
@@ -52,85 +61,50 @@ other state do we need to encode?
|
|||||||
*** TODO Write a parser for strings
|
*** TODO Write a parser for strings
|
||||||
Requires [[*Design Strings for the Lisp]] to be complete first.
|
Requires [[*Design Strings for the Lisp]] to be complete first.
|
||||||
*** TODO Write the general parser
|
*** TODO Write the general parser
|
||||||
** Unit tests :tests:
|
|
||||||
*** TODO Test streams :streams:
|
|
||||||
**** DONE Test file init
|
|
||||||
[[file:test/test_stream.c::void stream_test_file(void)]]
|
|
||||||
***** DONE Test successful init from real files
|
|
||||||
Ensure stream_size is 0 i.e. we don't read anything on creation.
|
|
||||||
Also ensure stream_eoc is false.
|
|
||||||
***** DONE Test failed init from fake files
|
|
||||||
**** DONE Test peeking and next
|
|
||||||
[[file:test/test_stream.c::void stream_test_peek_next(void)]]
|
|
||||||
- Peeking with bad streams ('\0' return)
|
|
||||||
- Peeking with good streams (no effect on position)
|
|
||||||
- Next with bad streams ('\0' return, no effect on position)
|
|
||||||
- Next with good streams (effects position)
|
|
||||||
- Peeking after next (should just work)
|
|
||||||
**** DONE Test seeking
|
|
||||||
[[file:test/test_stream.c::void stream_test_seek(void)]]
|
|
||||||
- Seeking forward/backward on a bad stream (should stop at 0)
|
|
||||||
- Seeking forward/backward too far (should clamp)
|
|
||||||
- Seeking forward/backward zero sum via relative index (stream_seek)
|
|
||||||
**** DONE Test substring
|
|
||||||
[[file:test/test_stream.c::void stream_test_substr(void)]]
|
|
||||||
- Substr on bad stream (NULL sv)
|
|
||||||
- Substr on bad position/size (NULL sv)
|
|
||||||
- Substr relative/absolute (good SV)
|
|
||||||
**** TODO Test till
|
|
||||||
[[file:test/test_stream.c::void stream_test_till(void)]]
|
|
||||||
- till on a bad stream (NULL SV)
|
|
||||||
- till on an ended stream (NULL SV)
|
|
||||||
- till on a stream with no items in search string (eoc)
|
|
||||||
- till on a stream with all items in search string (no effect)
|
|
||||||
- till on a stream with prefix being all search string (no effect)
|
|
||||||
- till on a stream with suffix being all search string (stops at
|
|
||||||
suffix)
|
|
||||||
**** TODO Test while
|
|
||||||
[[file:test/test_stream.c::void stream_test_while(void)]]
|
|
||||||
- while on a bad stream (NULL SV)
|
|
||||||
- while on an ended stream (NULL SV)
|
|
||||||
- while on a stream with no items in search string (no effect)
|
|
||||||
- while on a stream with all items in search string (eoc)
|
|
||||||
- while on a stream with prefix being all search string (effect)
|
|
||||||
- while on a stream with suffix being all search string (no effect)
|
|
||||||
**** TODO Test line_col
|
|
||||||
[[file:test/test_stream.c::void stream_test_line_col(void)]]
|
|
||||||
- line_col on bad stream (no effect on args)
|
|
||||||
- line_col on eoc stream (should go right to the end)
|
|
||||||
- line_col on random points in a stream
|
|
||||||
*** TODO Test reader :reader:
|
|
||||||
*** DONE Test system registration of allocated units
|
|
||||||
In particular, does clean up work as we expect? Do we have situations
|
|
||||||
where we may double free or not clean up something we should've?
|
|
||||||
** String views :strings:
|
|
||||||
[[file:include/alisp/sv.h::/// String Views]]
|
|
||||||
*** DONE sv_substr
|
|
||||||
Takes an index and a size, returns a string view to that substring.
|
|
||||||
*** DONE sv_chop_left and sv_chop_right
|
|
||||||
Super obvious.
|
|
||||||
*** TODO Design Strings for the Lisp :api:
|
|
||||||
We have ~sv_t~ so our basic C API is done. We just need pluggable
|
|
||||||
functions to construct and deconstruct strings as lisps.
|
|
||||||
** Design :design:
|
** Design :design:
|
||||||
*** TODO Design Big Integers :api:
|
*** TODO Design Big Integers :api:
|
||||||
We currently have 62 bit integers implemented via immediate values
|
We currently have 62 bit integers implemented via immediate values
|
||||||
embedded in a pointer. We need to be able to support even _bigger_
|
embedded in a pointer. We need to be able to support even _bigger_
|
||||||
integers. How do we do this?
|
integers. How do we do this?
|
||||||
*** TODO Design garbage collection scheme :gc:
|
*** TODO Capitalise symbols (TBD) :optimisation:
|
||||||
Really, regardless of what I do, we need to have some kind of garbage
|
Should we capitalise symbols? This way, we limit the symbol table's
|
||||||
collection header on whatever managed objects we allocate.
|
possible options a bit (potentially we could design a better hashing
|
||||||
|
algorithm?) and it would be kinda like an actual Lisp.
|
||||||
|
*** TODO Consider reader macros :reader:
|
||||||
|
Common Lisp has so-called "reader macros" which allows users to write
|
||||||
|
Lisp code that affects further Lisp code reading. It's quite
|
||||||
|
powerful.
|
||||||
|
|
||||||
Firstly, the distinction between managed and unmanaged objects:
|
Scheme doesn't have it. Should we implement this?
|
||||||
|
** Allocator :allocator:
|
||||||
|
*** Some definitions
|
||||||
- Managed objects are allocations that are generated as part of
|
- Managed objects are allocations that are generated as part of
|
||||||
evaluating user code i.e. strings, vectors, conses that are all made
|
evaluating user code i.e. strings, vectors, conses that are all made
|
||||||
as part of evaluating code.
|
as part of evaluating code.
|
||||||
- Unmanaged objects are allocations we do as part of the runtime.
|
- Unmanaged objects are allocations we do as part of the runtime.
|
||||||
These are things that we expect to have near infinite lifetimes
|
These are things that we expect to have near infinite lifetimes
|
||||||
(such as the symbol table, vector of allocated objects, etc).
|
(such as the symbol table, vector of allocated objects, etc).
|
||||||
|
*** TODO Design an allocator
|
||||||
We need to perform garbage collection against the managed objects, and
|
We'll need an allocator for all our managed objects. Requirements:
|
||||||
leave the unmanaged objects to the runtime.
|
- Stable pointers (memory that has already been allocated should be
|
||||||
|
free to utilise via the same pointer for the lifetime of the
|
||||||
|
allocator)
|
||||||
|
- Able to tag allocations as unused (i.e. "free") and able to reuse
|
||||||
|
these allocations
|
||||||
|
- This will link into the garbage collector, which should yield a
|
||||||
|
sequence of objects that should be "freed".
|
||||||
|
- Able to allocate all the managed types we have
|
||||||
|
**** TODO Design allocation data structures
|
||||||
|
**** TODO Design allocation methods for different lisp types
|
||||||
|
- Conses
|
||||||
|
- Vectors
|
||||||
|
- Strings (when implemented)
|
||||||
|
**** TODO Design allocation freeing methods
|
||||||
|
*** TODO Design garbage collection scheme :gc:
|
||||||
|
Really, regardless of what I do, we need to have some kind of garbage
|
||||||
|
collection header on whatever managed objects we allocate. We need to
|
||||||
|
perform garbage collection against the managed objects, and leave the
|
||||||
|
unmanaged objects to the runtime.
|
||||||
**** TODO Mark stage
|
**** TODO Mark stage
|
||||||
We need to mark all objects that are currently accessible from the
|
We need to mark all objects that are currently accessible from the
|
||||||
environment. This means we need to have a root environment which we
|
environment. This means we need to have a root environment which we
|
||||||
@@ -201,16 +175,57 @@ Latter approach time complexity:
|
|||||||
|
|
||||||
Former approach is better time complexity wise, but latter is way
|
Former approach is better time complexity wise, but latter is way
|
||||||
better in terms of simplicity of code. Must deliberate.
|
better in terms of simplicity of code. Must deliberate.
|
||||||
*** TODO Capitalise symbols (TBD) :optimisation:
|
** Unit tests :tests:
|
||||||
Should we capitalise symbols? This way, we limit the symbol table's
|
*** TODO Test streams :streams:
|
||||||
possible options a bit (potentially we could design a better hashing
|
**** DONE Test file init
|
||||||
algorithm?) and it would be kinda like an actual Lisp.
|
[[file:test/test_stream.c::void stream_test_file(void)]]
|
||||||
*** TODO Consider reader macros :reader:
|
***** DONE Test successful init from real files
|
||||||
Common Lisp has so-called "reader macros" which allows users to write
|
Ensure stream_size is 0 i.e. we don't read anything on creation.
|
||||||
Lisp code that affects further Lisp code reading. It's quite
|
Also ensure stream_eoc is false.
|
||||||
powerful.
|
***** DONE Test failed init from fake files
|
||||||
|
**** DONE Test peeking and next
|
||||||
Scheme doesn't have it. Should we implement this?
|
[[file:test/test_stream.c::void stream_test_peek_next(void)]]
|
||||||
|
- Peeking with bad streams ('\0' return)
|
||||||
|
- Peeking with good streams (no effect on position)
|
||||||
|
- Next with bad streams ('\0' return, no effect on position)
|
||||||
|
- Next with good streams (effects position)
|
||||||
|
- Peeking after next (should just work)
|
||||||
|
**** DONE Test seeking
|
||||||
|
[[file:test/test_stream.c::void stream_test_seek(void)]]
|
||||||
|
- Seeking forward/backward on a bad stream (should stop at 0)
|
||||||
|
- Seeking forward/backward too far (should clamp)
|
||||||
|
- Seeking forward/backward zero sum via relative index (stream_seek)
|
||||||
|
**** DONE Test substring
|
||||||
|
[[file:test/test_stream.c::void stream_test_substr(void)]]
|
||||||
|
- Substr on bad stream (NULL sv)
|
||||||
|
- Substr on bad position/size (NULL sv)
|
||||||
|
- Substr relative/absolute (good SV)
|
||||||
|
**** TODO Test till
|
||||||
|
[[file:test/test_stream.c::void stream_test_till(void)]]
|
||||||
|
- till on a bad stream (NULL SV)
|
||||||
|
- till on an ended stream (NULL SV)
|
||||||
|
- till on a stream with no items in search string (eoc)
|
||||||
|
- till on a stream with all items in search string (no effect)
|
||||||
|
- till on a stream with prefix being all search string (no effect)
|
||||||
|
- till on a stream with suffix being all search string (stops at
|
||||||
|
suffix)
|
||||||
|
**** TODO Test while
|
||||||
|
[[file:test/test_stream.c::void stream_test_while(void)]]
|
||||||
|
- while on a bad stream (NULL SV)
|
||||||
|
- while on an ended stream (NULL SV)
|
||||||
|
- while on a stream with no items in search string (no effect)
|
||||||
|
- while on a stream with all items in search string (eoc)
|
||||||
|
- while on a stream with prefix being all search string (effect)
|
||||||
|
- while on a stream with suffix being all search string (no effect)
|
||||||
|
**** TODO Test line_col
|
||||||
|
[[file:test/test_stream.c::void stream_test_line_col(void)]]
|
||||||
|
- line_col on bad stream (no effect on args)
|
||||||
|
- line_col on eoc stream (should go right to the end)
|
||||||
|
- line_col on random points in a stream
|
||||||
|
*** TODO Test reader :reader:
|
||||||
|
*** DONE Test system registration of allocated units
|
||||||
|
In particular, does clean up work as we expect? Do we have situations
|
||||||
|
where we may double free or not clean up something we should've?
|
||||||
** Completed
|
** Completed
|
||||||
*** DONE Test value constructors and destructors :test:
|
*** DONE Test value constructors and destructors :test:
|
||||||
Test if ~make_int~ works with ~as_int,~ ~intern~ with ~as_sym~.
|
Test if ~make_int~ works with ~as_int,~ ~intern~ with ~as_sym~.
|
||||||
|
|||||||
Reference in New Issue
Block a user