From 604fca3c245b53d55aa2648f26fceaadf6c1341c Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Wed, 25 Mar 2026 11:24:33 +0000 Subject: [PATCH] Got most of the new memory architecture roughed out. --- .gitmodules | 3 ++ munit | 1 + src/c/memory/header.h | 40 +++++++++++++++++++++ src/c/memory/page.h | 61 +++++++++++++++++++++++++++++++++ src/c/memory/pointer.h | 39 +++++++++++++++++++++ src/c/memory/pso2.h | 53 ++++++++++++++++++++++++++++ src/c/memory/pso3.h | 35 +++++++++++++++++++ src/c/memory/pso4.h | 32 +++++++++++++++++ src/c/memory/pso5.h | 30 ++++++++++++++++ src/c/memory/pso6.h | 30 ++++++++++++++++ src/c/memory/pso7.h | 30 ++++++++++++++++ src/c/memory/pso8.h | 30 ++++++++++++++++ src/c/memory/pso9.h | 30 ++++++++++++++++ src/c/memory/psoa.h | 30 ++++++++++++++++ src/c/memory/psob.h | 30 ++++++++++++++++ src/c/memory/psoc.h | 30 ++++++++++++++++ src/c/memory/psod.h | 30 ++++++++++++++++ src/c/memory/psoe.h | 30 ++++++++++++++++ src/c/memory/psof.h | 30 ++++++++++++++++ src/c/payloads/cons.h | 32 +++++++++++++++++ src/c/payloads/exception.h | 28 +++++++++++++++ src/c/payloads/free.h | 30 ++++++++++++++++ src/c/payloads/function.h | 47 +++++++++++++++++++++++++ src/c/payloads/integer.h | 27 +++++++++++++++ src/c/payloads/keyword.h | 24 +++++++++++++ src/c/payloads/lambda.h | 32 +++++++++++++++++ src/c/payloads/nlambda.h | 22 ++++++++++++ src/c/payloads/read_stream.h | 34 ++++++++++++++++++ src/c/payloads/special.h | 43 +++++++++++++++++++++++ src/c/payloads/stack_frame.h | 38 ++++++++++++++++++++ src/c/payloads/string.h | 42 +++++++++++++++++++++++ src/c/payloads/symbol.h | 25 ++++++++++++++ src/c/payloads/time.h | 29 ++++++++++++++++ src/c/payloads/vector_pointer.h | 39 +++++++++++++++++++++ src/c/payloads/write_stream.h | 21 ++++++++++++ src/c/version.h | 11 ++++++ 36 files changed, 1118 insertions(+) create mode 100644 .gitmodules create mode 160000 munit create mode 100644 src/c/memory/header.h create mode 100644 src/c/memory/page.h create mode 100644 src/c/memory/pointer.h create mode 100644 src/c/memory/pso2.h create mode 100644 src/c/memory/pso3.h create mode 100644 src/c/memory/pso4.h create mode 100644 src/c/memory/pso5.h create mode 100644 src/c/memory/pso6.h create mode 100644 src/c/memory/pso7.h create mode 100644 src/c/memory/pso8.h create mode 100644 src/c/memory/pso9.h create mode 100644 src/c/memory/psoa.h create mode 100644 src/c/memory/psob.h create mode 100644 src/c/memory/psoc.h create mode 100644 src/c/memory/psod.h create mode 100644 src/c/memory/psoe.h create mode 100644 src/c/memory/psof.h create mode 100644 src/c/payloads/cons.h create mode 100644 src/c/payloads/exception.h create mode 100644 src/c/payloads/free.h create mode 100644 src/c/payloads/function.h create mode 100644 src/c/payloads/integer.h create mode 100644 src/c/payloads/keyword.h create mode 100644 src/c/payloads/lambda.h create mode 100644 src/c/payloads/nlambda.h create mode 100644 src/c/payloads/read_stream.h create mode 100644 src/c/payloads/special.h create mode 100644 src/c/payloads/stack_frame.h create mode 100644 src/c/payloads/string.h create mode 100644 src/c/payloads/symbol.h create mode 100644 src/c/payloads/time.h create mode 100644 src/c/payloads/vector_pointer.h create mode 100644 src/c/payloads/write_stream.h create mode 100644 src/c/version.h diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1bfece3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "munit"] + path = munit + url = https://github.com/nemequ/munit.git diff --git a/munit b/munit new file mode 160000 index 0000000..fbbdf14 --- /dev/null +++ b/munit @@ -0,0 +1 @@ +Subproject commit fbbdf1467eb0d04a6ee465def2e529e4c87f2118 diff --git a/src/c/memory/header.h b/src/c/memory/header.h new file mode 100644 index 0000000..ebd101d --- /dev/null +++ b/src/c/memory/header.h @@ -0,0 +1,40 @@ +/** + * memory/header.h + * + * Header for all page space objects + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_header_h +#define __psse_memory_header_h + +#include + +#define TAGLENGTH 3 + +/** + * @brief Header for all paged space objects. + * + */ +struct pso_header { + union { + /** the tag (type) of this cell, + * considered as bytes */ + struct { + /** mnemonic for this type; */ + char mnemonic[TAGLENGTH]; + /** sizetag for this object */ + uint8_t sizetag; + } tag; + /** the tag considered as a number */ + uint32_t value; + } tag; + /** the count of the number of references to this cell */ + uint32_t count; + /** cons pointer to the access control list of this cell */ + struct cons_pointer access; +}; + +#endif diff --git a/src/c/memory/page.h b/src/c/memory/page.h new file mode 100644 index 0000000..c4e1fe8 --- /dev/null +++ b/src/c/memory/page.h @@ -0,0 +1,61 @@ +/** + * memory/page.h + * + * Page for paged space psoects. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_page_h +#define __psse_memory_page_h + +#include "memory/pso2.h" +#include "memory/pso3.h" +#include "memory/pso4.h" +#include "memory/pso5.h" +#include "memory/pso6.h" +#include "memory/pso7.h" +#include "memory/pso8.h" +#include "memory/pso9.h" +#include "memory/psoa.h" +#include "memory/psob.h" +#include "memory/psoc.h" +#include "memory/psod.h" +#include "memory/psoe.h" +#include "memory/psof.h" + +#define PAGE_SIZE 1048576 + +/** + * @brief A page is a megabyte of memory which contains objects all of which + * are of the same size class. + * + * No page will contain both pso2s and pso4s, for example. We know what size + * objects are in a page by looking at the size tag of the first object, which + * will always be the fourth byte in the page (i.e page.bytes[3]). However, we + * will not normally have to worry about what size class the objects on a page + * are, since on creation all objects will be linked onto the freelist for + * their size class, they will be allocated from that free list, and on garbage + * collection they will be returned to that freelist. + */ +union page { + uint8_t[PAGE_SIZE] bytes; + uint64_t[PAGE_SIZE / 8] words; + struct pso2[PAGE_SIZE / 32] pso2s; + struct pso3[PAGE_SIZE / 64] pso3s; + struct pso4[PAGE_SIZE / 128] pso4s; + struct pso5[PAGE_SIZE / 256] pso5s; + struct pso6[PAGE_SIZE / 512] pso6s; + struct pso7[PAGE_SIZE / 1024] pso7s; + struct pso8[PAGE_SIZE / 2048] pso8s; + struct pso9[PAGE_SIZE / 4096] pso9s; + struct psoa[PAGE_SIZE / 8192] psoas; + struct psob[PAGE_SIZE / 16384] psobs; + struct psoc[PAGE_SIZE / 32768] psocs; + struct psod[PAGE_SIZE / 65536] psods; + struct psoe[PAGE_SIZE / 131072] psoes; + struct psof[PAGE_SIZE / 262144] psofs; +}; + +#endif diff --git a/src/c/memory/pointer.h b/src/c/memory/pointer.h new file mode 100644 index 0000000..8b3b3bf --- /dev/null +++ b/src/c/memory/pointer.h @@ -0,0 +1,39 @@ +/** + * memory/pointer.h + * + * A pointer to a paged space object. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_pointer_h +#define __psse_memory_pointer_h + +#include + +/** + * @brief A pointer to an object in page space. + * + */ +struct pso_pointer { + /** + * @brief The index of the node on which this object is curated. + * + * NOTE: This will always be NULL until we have the hypercube router + * working. + */ + uint32_t node; + /** + * @brief The index of the allocated page in which this object is stored. + */ + uint16_t page; + /** + * @brief The offset of the object within the page **in words**. + * + * NOTE THAT: This value is always **in words**, regardless of the size + * class of the objects stored in the page, because until we've got hold + * of the page we don't know its size class. + */ + uint16_t offset; +}; diff --git a/src/c/memory/pso2.h b/src/c/memory/pso2.h new file mode 100644 index 0000000..86febbc --- /dev/null +++ b/src/c/memory/pso2.h @@ -0,0 +1,53 @@ +/** + * memory/pso2.h + * + * Paged space object of size class 2, four words total, two words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_pso2_h +#define __psse_memory_pso2_h + +#include + +#include "memory/header.h" +#include "payloads/cons.h" +#include "payloads/free.h" +#include "payloads/function.h" +#include "payloads/integer.h" +#include "payloads/ketwod.h" +#include "payloads/lambda.h" +#include "payloads/nlambda.h" +#include "payloads/read_stream.h" +#include "payloads/special.h" +#include "payloads/string.h" +#include "payloads/symbol.h" +#include "payloads/time.h" +#include "payloads/vector_pointer.h" +#include "payloads/write_stream.h" + +/** + * @brief A paged space object of size class 2, four words total, two words + * payload. + * + */ +struct pso2 { + struct pso_header header; + union { + char[16] bytes; + uint64_t[2] words; + struct cons_payload cons; + struct free_payload free; + struct function_payload function; + struct integer_payload integer; + struct lambda_payload lambda; + struct special_payload special; + struct stream_payload stream; + struct time_payload time; + struct vectorp_payload vectorp; + } payload; +}; + +#endif diff --git a/src/c/memory/pso3.h b/src/c/memory/pso3.h new file mode 100644 index 0000000..c3e03ce --- /dev/null +++ b/src/c/memory/pso3.h @@ -0,0 +1,35 @@ +/** + * memory/pso3.h + * + * Paged space object of size class 3, 8 words total, 6 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_pso3_h +#define __psse_memory_pso3_h + +#include + +#include "memory/header.h" +#include "payloads/exception.h" +#include "payloads/free.h" + + +/** + * @brief A paged space object of size class 3, 8 words total, 6 words + * payload. + * + */ +struct pso3 { + struct pso_header header; + union { + char[48] bytes; + uint64_t[6] words; + struct exception_payload exception; + struct free_payload free; + } payload; +}; + +#endif diff --git a/src/c/memory/pso4.h b/src/c/memory/pso4.h new file mode 100644 index 0000000..68a351d --- /dev/null +++ b/src/c/memory/pso4.h @@ -0,0 +1,32 @@ +/** + * memory/pso4.h + * + * Paged space object of size class 4, 16 words total, 14 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_pso4_h +#define __psse_memory_pso4_h + +#include + +#include "memory/header.h" +#include "payloads/stack_frame.h" + +/** + * @brief A paged space object of size class 4, 16 words total, 14 words + * payload. + * + */ +struct pso4 { + struct pso_header header; + union { + char[112] bytes; + uint64_t[14] words; + struct stack_frame_payload stack_frame; + } payload; +}; + +#endif diff --git a/src/c/memory/pso5.h b/src/c/memory/pso5.h new file mode 100644 index 0000000..311b544 --- /dev/null +++ b/src/c/memory/pso5.h @@ -0,0 +1,30 @@ +/** + * memory/pso5.h + * + * Paged space object of size class 5, 32 words total, 30 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_pso5_h +#define __psse_memory_pso5_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class 5, 32 words total, 30 words + * payload. + * + */ +struct pso5 { + struct pso_header header; + union { + char[240] bytes; + uint64_t[30] words; + } payload; +}; + +#endif diff --git a/src/c/memory/pso6.h b/src/c/memory/pso6.h new file mode 100644 index 0000000..8f94393 --- /dev/null +++ b/src/c/memory/pso6.h @@ -0,0 +1,30 @@ +/** + * memory/pso6.h + * + * Paged space object of size class 6, 64 words total, 62 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_pso6_h +#define __psse_memory_pso6_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class 6, 64 words total, 62 words + * payload. + * + */ +struct pso6 { + struct pso_header header; + union { + char[496] bytes; + uint64_t[62] words; + } payload; +}; + +#endif diff --git a/src/c/memory/pso7.h b/src/c/memory/pso7.h new file mode 100644 index 0000000..2ef9ad3 --- /dev/null +++ b/src/c/memory/pso7.h @@ -0,0 +1,30 @@ +/** + * memory/pso7.h + * + * Paged space object of size class 7, 128 words total, 126 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_pso7_h +#define __psse_memory_pso7_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class 7, 128 words total, 126 words + * payload. + * + */ +struct pso7 { + struct pso_header header; + union { + char[1008] bytes; + uint64_t[126] words; + } payload; +}; + +#endif diff --git a/src/c/memory/pso8.h b/src/c/memory/pso8.h new file mode 100644 index 0000000..c46a2c1 --- /dev/null +++ b/src/c/memory/pso8.h @@ -0,0 +1,30 @@ +/** + * memory/pso8.h + * + * Paged space object of size class 8, 256 words total, 254 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_pso8_h +#define __psse_memory_pso8_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class 8, 256 words total, 254 words + * payload. + * + */ +struct pso8 { + struct pso_header header; + union { + char[2032] bytes; + uint64_t[254] words; + } payload; +}; + +#endif diff --git a/src/c/memory/pso9.h b/src/c/memory/pso9.h new file mode 100644 index 0000000..4d07231 --- /dev/null +++ b/src/c/memory/pso9.h @@ -0,0 +1,30 @@ +/** + * memory/pso9.h + * + * Paged space object of size class 9, 512 words total, 510 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_pso9_h +#define __psse_memory_pso9_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class 9, 512 words total, 510 words + * payload. + * + */ +struct pso9 { + struct pso_header header; + union { + char[4080] bytes; + uint64_t[510] words; + } payload; +}; + +#endif diff --git a/src/c/memory/psoa.h b/src/c/memory/psoa.h new file mode 100644 index 0000000..a7d7d19 --- /dev/null +++ b/src/c/memory/psoa.h @@ -0,0 +1,30 @@ +/** + * memory/psoa.h + * + * Paged space object of size class a, 1024 words total, 1022 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_psoa_h +#define __psse_memory_psoa_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class a, 1024 words total, 1022 words + * payload. + * + */ +struct psoa { + struct pso_header header; + union { + char[8176] bytes; + uint64_t[1022] words; + } payload; +}; + +#endif diff --git a/src/c/memory/psob.h b/src/c/memory/psob.h new file mode 100644 index 0000000..24a9fa2 --- /dev/null +++ b/src/c/memory/psob.h @@ -0,0 +1,30 @@ +/** + * memory/psob.h + * + * Paged space object of size class b, 2048 words total, 2046 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_psob_h +#define __psse_memory_psob_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class b, 2048 words total, 2046 words + * payload. + * + */ +struct psob { + struct pso_header header; + union { + char[16368] bytes; + uint64_t[2046] words; + } payload; +}; + +#endif diff --git a/src/c/memory/psoc.h b/src/c/memory/psoc.h new file mode 100644 index 0000000..99c2a55 --- /dev/null +++ b/src/c/memory/psoc.h @@ -0,0 +1,30 @@ +/** + * memory/psoc.h + * + * Paged space object of size class c, 4096 words total, 4094 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_psoc_h +#define __psse_memory_psoc_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class c, 4096 words total, 4094 words + * payload. + * + */ +struct psoc { + struct pso_header header; + union { + char[32752] bytes; + uint64_t[4094] words; + } payload; +}; + +#endif diff --git a/src/c/memory/psod.h b/src/c/memory/psod.h new file mode 100644 index 0000000..803cf90 --- /dev/null +++ b/src/c/memory/psod.h @@ -0,0 +1,30 @@ +/** + * memory/psod.h + * + * Paged space object of size class d, 8192 words total, 8190 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_psod_h +#define __psse_memory_psod_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class d, 8192 words total, 8190 words + * payload. + * + */ +struct psod { + struct pso_header header; + union { + char[65520] bytes; + uint64_t[8190] words; + } payload; +}; + +#endif diff --git a/src/c/memory/psoe.h b/src/c/memory/psoe.h new file mode 100644 index 0000000..d0313f7 --- /dev/null +++ b/src/c/memory/psoe.h @@ -0,0 +1,30 @@ +/** + * memory/psoe.h + * + * Paged space object of size class e, 16384 words total, 16382 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_psoe_h +#define __psse_memory_psoe_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class e, 16384 words total, 16382 words + * payload. + * + */ +struct psoe { + struct pso_header header; + union { + char[131056] bytes; + uint64_t[16382] words; + } payload; +}; + +#endif diff --git a/src/c/memory/psof.h b/src/c/memory/psof.h new file mode 100644 index 0000000..30ead84 --- /dev/null +++ b/src/c/memory/psof.h @@ -0,0 +1,30 @@ +/** + * memory/psof.h + * + * Paged space object of size class f, 32768 words total, 32766 words payload. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_memory_psof_h +#define __psse_memory_psof_h + +#include + +#include "memory/header.h" + +/** + * @brief A paged space object of size class f, 32768 words total, 32766 words + * payload. + * + */ +struct psof { + struct pso_header header; + union { + char[262128] bytes; + uint64_t[32766] words; + } payload; +}; + +#endif diff --git a/src/c/payloads/cons.h b/src/c/payloads/cons.h new file mode 100644 index 0000000..a1b0d4d --- /dev/null +++ b/src/c/payloads/cons.h @@ -0,0 +1,32 @@ +/** + * payloads/cons.h + * + * A cons cell. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_cons_h +#define __psse_payloads_cons_h + +#include "memory/pointer.h" + +/** + * An ordinary cons cell: + */ +#define CONSTAG "CNS" + +/** + * @brief A cons cell. + * + */ +struct cons_payload { + /** Contents of the Address Register, naturally. */ + struct pso_pointer car; + /** Contents of the Decrement Register, naturally. */ + struct pso_pointer cdr; +}; + + +#endif diff --git a/src/c/payloads/exception.h b/src/c/payloads/exception.h new file mode 100644 index 0000000..0363daa --- /dev/null +++ b/src/c/payloads/exception.h @@ -0,0 +1,28 @@ +/** + * payloads/exception.h + * + * An exception; required three pointers, so use object of size class 3. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_exception_h +#define __psse_payloads_exception_h + +#include "memory/pointer.h" + +/** + * @brief An exception; required three pointers, so use object of size class 3. + */ +struct exception_payload { + /** @brief the exception message. Expected to be a string, but may be anything printable. */ + struct pso_pointer message; + /** @brief the stack frame at which the exception was thrown. */ + struct pso_pointer stack; + /** @brief the cause; expected to be another exception, or (usually) `nil`. */ + struct cons_pointer cause; +}; + + +#endif diff --git a/src/c/payloads/free.h b/src/c/payloads/free.h new file mode 100644 index 0000000..3871c36 --- /dev/null +++ b/src/c/payloads/free.h @@ -0,0 +1,30 @@ +/** + * payloads/free.h + * + * An unassigned object, on a freelist; may be of any size class. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_free_h +#define __psse_payloads_free_h + +#include "memory/pointer.h" + +/** + * @brief Tag for an unassigned object; may be of any size class. + */ +#define FREETAG "FRE" + +/** + * @brief An unassigned object, on a freelist; may be of any size class. + * + */ +struct free_payload { + /** the next object on the free list for my size class */ + struct pso_pointer next; +}; + + +#endif diff --git a/src/c/payloads/function.h b/src/c/payloads/function.h new file mode 100644 index 0000000..66ac8bc --- /dev/null +++ b/src/c/payloads/function.h @@ -0,0 +1,47 @@ +/** + * payloads/function.h + * + * an ordinary Lisp function - one whose arguments are pre-evaluated. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_function_h +#define __psse_payloads_function_h + +#include "memory/pointer.h" + +/** + * @brief Tag for an ordinary Lisp function - one whose arguments are pre-evaluated. + * \see LAMBDATAG for interpretable functions. + * \see SPECIALTAG for functions whose arguments are not pre-evaluated. + */ +#define FUNCTIONTAG "FUN" + +/** + * @brief Payload of a function cell. + * `source` points to the source from which the function was compiled, or NIL + * if it is a primitive. + * `executable` points to a function which takes a pointer to a stack frame + * (representing its stack frame) and a cons pointer (representing its + * environment) as arguments and returns a cons pointer (representing its + * result). + */ +struct function_payload { + /** + * pointer to metadata (e.g. the source from which the function was compiled). + */ + struct cons_pointer meta; + /** pointer to a function which takes a cons pointer (representing + * its argument list) and a cons pointer (representing its environment) and a + * stack frame (representing the previous stack frame) as arguments and returns + * a cons pointer (representing its result). + * \todo check this documentation is current! + */ + struct cons_pointer ( *executable ) ( struct stack_frame *, + struct cons_pointer, + struct cons_pointer ); +}; + +#endif diff --git a/src/c/payloads/integer.h b/src/c/payloads/integer.h new file mode 100644 index 0000000..69d0617 --- /dev/null +++ b/src/c/payloads/integer.h @@ -0,0 +1,27 @@ +/** + * payloads/integer.h + * + * An integer. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_integer_h +#define __psse_payloads_integer_h + +#include + +/** + * @brief An integer . + * + * Integers can in principal store a 128 bit value, but in practice we'll start + * promoting them to bignums when they pass the 64 bit barrier. However, that's + * in the Lisp layer, not the substrate. + */ +struct integer_payload { + int128_t value; +}; + + +#endif diff --git a/src/c/payloads/keyword.h b/src/c/payloads/keyword.h new file mode 100644 index 0000000..164d31c --- /dev/null +++ b/src/c/payloads/keyword.h @@ -0,0 +1,24 @@ +/** + * payloads/keyword.h + * + * A keyword cell. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_keyword_h +#define __psse_payloads_keyword_h + +#include "memory/pointer.h" + +/** + * Tag for a keyword - an interned, self-evaluating string. + */ +#define KEYTAG "KEY" + +/* TODO: for now, Keyword shares a payload with String, but this may change. + * Strings are of indefinite length, but keywords are really not, and might + * fit into any size class. */ + +#endif diff --git a/src/c/payloads/lambda.h b/src/c/payloads/lambda.h new file mode 100644 index 0000000..f457339 --- /dev/null +++ b/src/c/payloads/lambda.h @@ -0,0 +1,32 @@ +/** + * payloads/lambda.h + * + * A lambda cell. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_lambda_h +#define __psse_payloads_lambda_h + +#include "memory/pointer.h" + +/** + * @brief Tag for lambda cell. Lambdas are the interpretable (source) versions of functions. + * \see FUNCTIONTAG. + */ +#define LAMBDATAG "LMD" + +/** + * @brief payload for lambda and nlambda cells. + */ +struct lambda_payload { + /** the arument list */ + struct pso_pointer args; + /** the body of the function to be applied to the arguments. */ + struct pso_pointer body; +}; + + +#endif diff --git a/src/c/payloads/nlambda.h b/src/c/payloads/nlambda.h new file mode 100644 index 0000000..bf96361 --- /dev/null +++ b/src/c/payloads/nlambda.h @@ -0,0 +1,22 @@ +/** + * payloads/nlambda.h + * + * A nlambda cell. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_nlambda_h +#define __psse_payloads_nlambda_h + +#include "memory/pointer.h" + +/** + * An ordinary nlambda cell: + */ +#define CONSTAG "CNS" + +/* nlambda shares a payload with lambda */ + +#endif diff --git a/src/c/payloads/read_stream.h b/src/c/payloads/read_stream.h new file mode 100644 index 0000000..5489308 --- /dev/null +++ b/src/c/payloads/read_stream.h @@ -0,0 +1,34 @@ +/** + * payloads/read_stream.h + * + * A read stream. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_read_stream_h +#define __psse_payloads_read_stream_h + +#include + +#include "memory/pointer.h" + +/** + * An open read stream. + */ +#define READTAG "REA" + +/** + * payload of a read or write stream cell. + */ +struct stream_payload { + /** the stream to read from or write to. */ + URL_FILE *stream; + /** metadata on the stream (e.g. its file attributes if a file, its HTTP + * headers if a URL, etc). Expected to be an association, or nil. Not yet + * implemented. */ + struct cons_pointer meta; +}; + +#endif diff --git a/src/c/payloads/special.h b/src/c/payloads/special.h new file mode 100644 index 0000000..96f616d --- /dev/null +++ b/src/c/payloads/special.h @@ -0,0 +1,43 @@ +/** + * payloads/special.h + * + * A special form. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_special_h +#define __psse_payloads_special_h + +#include "memory/pointer.h" + +/** + * A special form - one whose arguments are not pre-evaluated but passed as + * provided. + * \see NLAMBDATAG. + */ +#define SPECIALTAG "SFM" + +/** + * @brief Payload of a special form cell. + * + * Currently identical to the payload of a function cell. + * \see function_payload + */ +struct special_payload { + /** + * pointer to the source from which the special form was compiled, or NIL + * if it is a primitive. + */ + struct cons_pointer meta; + /** pointer to a function which takes a cons pointer (representing + * its argument list) and a cons pointer (representing its environment) and a + * stack frame (representing the previous stack frame) as arguments and returns + * a cons pointer (representing its result). */ + struct cons_pointer ( *executable ) ( struct stack_frame *, + struct cons_pointer, + struct cons_pointer ); +}; + +#endif diff --git a/src/c/payloads/stack_frame.h b/src/c/payloads/stack_frame.h new file mode 100644 index 0000000..2aefcfc --- /dev/null +++ b/src/c/payloads/stack_frame.h @@ -0,0 +1,38 @@ +/** + * payloads/stack_frame.h + * + * A stack frame. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_stack_frame_h +#define __psse_payloads_stack_frame_h +#include + +#include "memory/pointer.h" +/* + * number of arguments stored in a stack frame + */ +#define args_in_frame 8 + +/** + * A stack frame. + */ +struct stack_frame_payload { + /** the previous frame. */ + struct cons_pointer previous; + /** first 8 arument bindings. */ + struct cons_pointer arg[args_in_frame]; + /** list of any further argument bindings. */ + struct cons_pointer more; + /** the function to be called. */ + struct cons_pointer function; + /** the number of arguments provided. */ + int args; + /** the depth of the stack below this frame */ + int depth; +}; + +#endif diff --git a/src/c/payloads/string.h b/src/c/payloads/string.h new file mode 100644 index 0000000..dbc45ca --- /dev/null +++ b/src/c/payloads/string.h @@ -0,0 +1,42 @@ +/** + * payloads/string.h + * + * A string cell. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_string_h +#define __psse_payloads_string_h +/* + * wide characters + */ +#include +#include + +#include "memory/pointer.h" + + +/** + * @brief Tag for string of characters, organised as a linked list. + */ +#define STRINGTAG "STR" + +/** + * @brief payload of a string cell. + * + * At least at first, only one UTF character will be stored in each cell. At + * present the payload of a symbol or keyword cell is identical + * to the payload of a string cell. + */ +struct string_payload { + /** the actual character stored in this cell */ + wint_t character; + /** a hash of the string value, computed at store time. */ + uint32_t hash; + /** the remainder of the string following this character. */ + struct cons_pointer cdr; +}; + +#endif diff --git a/src/c/payloads/symbol.h b/src/c/payloads/symbol.h new file mode 100644 index 0000000..9e7afd5 --- /dev/null +++ b/src/c/payloads/symbol.h @@ -0,0 +1,25 @@ +/** + * payloads/symbol.h + * + * A symbol cell. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_symbol_h +#define __psse_payloads_symbol_h + +#include "memory/pointer.h" + + +/** + * Tag for a symbol: just like a keyword except not self-evaluating. + */ +#define SYMBOLTAG "SYM" + +/* TODO: for now, Symbol shares a payload with String, but this may change. + * Strings are of indefinite length, but symbols are really not, and might + * fit into any size class. */ + +#endif diff --git a/src/c/payloads/time.h b/src/c/payloads/time.h new file mode 100644 index 0000000..e304e67 --- /dev/null +++ b/src/c/payloads/time.h @@ -0,0 +1,29 @@ +/** + * payloads/cons.h + * + * A cons cell. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_cons_h +#define __psse_payloads_cons_h + +#include "memory/pointer.h" + +/** + * @brief Tag for a time stamp. + */ +#define TIMETAG "TIME" + +/** + * The payload of a time cell: an unsigned 128 bit value representing micro- + * seconds since the estimated date of the Big Bang (actually, for + * convenience, 14Bn years before 1st Jan 1970 (the UNIX epoch)) + */ +struct time_payload { + unsigned __int128 value; +}; + +#endif diff --git a/src/c/payloads/vector_pointer.h b/src/c/payloads/vector_pointer.h new file mode 100644 index 0000000..b5e5f1c --- /dev/null +++ b/src/c/payloads/vector_pointer.h @@ -0,0 +1,39 @@ +/** + * payloads/vector_pointer.h + * + * A pointer to an object in vector space. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_vector_pointer_h +#define __psse_payloads_vector_pointer_h + +#include "memory/pointer.h" + +/** + * A pointer to an object in vector space. + */ +#define VECTORPOINTTAG "VSP" + +/** + * @brief payload of a vector pointer cell. + */ +struct vectorp_payload { + /** the tag of the vector-space object. NOTE that the vector space object + * should itself have the identical tag. */ + union { + /** the tag (type) of the vector-space object this cell + * points to, considered as bytes. */ + char bytes[TAGLENGTH]; + /** the tag considered as a number */ + uint32_t value; + } tag; + /** unused padding to word-align the address */ + uint32_t padding; + /** the address of the actual vector space object */ + void *address; +}; + +#endif diff --git a/src/c/payloads/write_stream.h b/src/c/payloads/write_stream.h new file mode 100644 index 0000000..757f7d0 --- /dev/null +++ b/src/c/payloads/write_stream.h @@ -0,0 +1,21 @@ +/** + * payloads/write_stream.h + * + * A write_stream cell. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_payloads_write_stream_h +#define __psse_payloads_write_stream_h + +#include "memory/pointer.h" + +/** + * @brief Tag for an open write stream. + */ +#define WRITETAG "WRT" + +/* write stream shares a payload with /see read_streem.h */ +#endif diff --git a/src/c/version.h b/src/c/version.h new file mode 100644 index 0000000..d6b3f2b --- /dev/null +++ b/src/c/version.h @@ -0,0 +1,11 @@ +/** + * version.h + * + * Just the version number. There's DEFINITELY a better way to do this! + * + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#define VERSION "0.1.0-SNAPSHOT"