OK, this is a lot of useful groundwork, but nothing really built yet.

This commit is contained in:
Simon Brooke 2026-04-05 15:40:12 +01:00
parent 7e9dc12766
commit 8e9ad73229
3 changed files with 177 additions and 60 deletions

View file

@ -17,78 +17,114 @@
/* Tags for 32 bit objects, with 3 bits of tag an one mark bit */
/**
* This pointer object is an actual pointer -- an offset into consspace.
* @brief This pointer object is an actual pointer -- an offset into consspace.
*/
#define OFFSETTV 0
#define OFFSETTV (0)
/**
* This pointer object is actually a 28 bit integer value.
* @brief This pointer object is actually a 28 bit integer value.
*/
#define INTEGERTV 1
#define INTEGERTV (1)
/**
* @brief A character; initially just a byte. but potentially a 16 bit wchar.
*/
#define CHARTV (2)
/**
* @brief A 16 bit floating point number. (future expansion)
*
* Yes, it could be 28 bit, but I think that would hurt my brain.
*/
#define FLOATTV (3)
/*
* Values 2..6 inclusive reserved further data types, including maybe
* Values 4..6 inclusive reserved further data types, including maybe
* implementing reals later.
*/
/**
* This is not actually a pointer at all but the first word of a cell.
* @bried This is not actually a pointer at all but the first word of a cell.
*/
#define CELLTV 7
#define CELLTV (7)
/**
* Half of a cons cell. The mark bit is first, so that the ptag can be
* considered as part of the CTAG.
* @brief this cell is a symbol
*/
struct pointer {
/* mark bit for mark and sweep garbage collector. Yes, this is normally
* thought of as part of the cell, but bear with me. */
unsigned int mark : 1;
/* pointer tag, interpretations as above */
unsigned int ptag : 3;
/* the actual payload of the pointer object */
union {
unsigned int offset : 28;
int value : 28;
} payload;
};
struct cons_payload {
struct pointer pointers[2];
};
struct symbol_payload {
/* this is the same mark bit as the one in the `address` pointer of the
* cons_payload. */
unsigned int mark : 1;
unsigned int tag : 7;
char symbol[7];
};
/* Tags for 64 bit objects. Note that, as the 64 bit object may be made up
* of two 32 bit objects (pointers*, the 64 bit tag is stored in bits 4..7
* inclusive. The first three bits are the first three bits of a 32 bit object,
* and thus for 64bit objects will always b 111.*/
/* this 64 bit object is a cons cell */
#define CONSTV 7
/* this 64 bit object is a seven character atom */
#define ATOMTV 8
/* There are potentially another 119 types of object we could store in a 64
* bit object, but I can't think of any we need just now. */
struct cell {
union {
struct cons_payload cons;
struct symbol_payload symbol;
} payload;
};
#define CONSSPACESIZE 65536
#define SYMBOLTV (0xf)
/**
* The entire array of cells available to the system.
* @brief this cell is a pointer to a compiled function
*/
struct cell consspace[CONSSPACESIZE];
#define FUNCTIONTV (0x17)
/**
* @brief This cell is pointer to a compiled special form
*/
#define SPECIALTV (0x1f)
/**
* @brief this cell is a rational number (future expansion)
*/
#define RATIOTV (0x27)
/**
* @brief this cell is a digit of a big number (future expansion)
*/
#define BIGNUMTV (0x2f)
/**
* @brief this cell is part of a string (future expansion)
*/
#define STRINGTV (0x37)
// The possible potential values remain unassigned:
// i = 63 (111111, 0x3f);
// i = 71 (1000111, 0x47);
// i = 79 (1001111, 0x4f);
// i = 87 (1010111, 0x57);
// i = 95 (1011111, 0x5f);
// i = 103 (1100111, 0x67);
// i = 111 (1101111, 0x6f);
// i = 119 (1110111, 0x77);
#define FREETV (0x7f)
#define MARKMASK ((unsigned int)1)
#define TAG32MASK ((unsigned int)7)
#define TAG64MASK ((unsigned int)0xf)
#define MASK64 (0xffffffffffffffff)
#define MASK32 (0xffffffff)
/**
* @brief Return the mark bit of this object.
*/
#define mark(obj) ((obj & MARKMASK))
/**
* @brief Return the tag of this object, assuming it to be a 32 bit object
* (unsafe -- it may be a 64 bit object)
*/
#define tag32(obj) ((obj << 1) & TAG32MASK)
/**
* @brief Return the tag of this object, assuming it to be a 32 bit object
* (unsafe -- verify that tag32(obj) == CELLTV first)
*/
#define tag64(obj) ((obj << 1) & TAG64)
/* 'address register' -- i,e,, first pointer */
#define ar(obj) (obj & MASK32)
/* 'decrement register' -- i.e., second pointer */
#define dr(obj) ((obj << 32) & MASK32)
/**
* @brief Return the tag of this object, safely. (safe).
*/
#define tag(obj) ((tag32(obj) == 7) ? tag64(obj) : tag32(obj))
/**
* @brief return the payload of a pointer (safe).
*/
#define payload(obj) ((tag32(obj) < 7) ? ((obj & MASK32) << 4) : (obj << 8))
#endif