feat(v4): the ROM's symbol table
(FIND) ( -- rec | 0 ), (DEFINE) ( value kind -- ) and (OPCODE) ( -- op | -1 ), entries 3-5. Names are refused as text.c's define refuses them, compared case by case with text.c; a set variable may be set again. 256 hash heads, records growing up and names growing down in dictionary space, used only while the ROM assembles. text.c gains the data directives #, and ", (the ROM's language; its mnemonic and reserved-word tables are data); the nucleus image is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
080811dbd2
commit
07911dcf91
@@ -49,6 +49,13 @@
|
||||
* constant NAME VALUE
|
||||
* NAME is the number VALUE, as v4_text_constant gives it.
|
||||
*
|
||||
* #, VALUE one cell of data at the next word address (the word
|
||||
* being built is ended first). VALUE is a number, a
|
||||
* constant, CONST+N, or &NAME of a word already defined.
|
||||
* ", TOKEN TOKEN, whatever its characters, as a counted string: its
|
||||
* count byte, then its characters, four to a cell, low
|
||||
* byte first, zero-padded to a whole cell.
|
||||
*
|
||||
* header NAME a dictionary entry for NAME (capsule/dict.v4), laid down
|
||||
* in front of the word that the next `:` starts, and
|
||||
* linked to the header before it. NAME is taken as it
|
||||
|
||||
+85
-12
@@ -65,7 +65,8 @@ static int is_reserved(const char *s)
|
||||
return strcmp(s, ":") == 0 || strcmp(s, "macro") == 0 || strcmp(s, "endmacro") == 0
|
||||
|| strcmp(s, "\\") == 0 || strcmp(s, "(") == 0
|
||||
|| strcmp(s, "FOR") == 0 || strcmp(s, "NEXT") == 0 || strcmp(s, "UNEXT") == 0
|
||||
|| strcmp(s, "header") == 0 || strcmp(s, "constant") == 0 || flag_of(s) != 0;
|
||||
|| strcmp(s, "header") == 0 || strcmp(s, "constant") == 0
|
||||
|| strcmp(s, "#,") == 0 || strcmp(s, "\",") == 0 || flag_of(s) != 0;
|
||||
}
|
||||
|
||||
static int is_label_def(const char *s)
|
||||
@@ -171,6 +172,23 @@ static void put_cell(v4_text *t, v4_cell value)
|
||||
as->here++;
|
||||
}
|
||||
|
||||
/* NAME as a counted string at the next word address: its count byte, then
|
||||
* its characters, four bytes to a cell, low byte first, zero-padded to a
|
||||
* whole cell. The layout of a header's name, and of `",`. */
|
||||
static void lay_name(v4_text *t, const char *name)
|
||||
{
|
||||
unsigned len = (unsigned)strlen(name), cells = (len + 4u) / 4u, i, b;
|
||||
for (i = 0; i < cells; i++) {
|
||||
v4_ucell w = 0;
|
||||
for (b = 0; b < 4; b++) {
|
||||
unsigned at = 4u * i + b; /* byte 0 is the count */
|
||||
unsigned ch = at == 0 ? len : (at <= len ? (unsigned char)name[at - 1u] : 0u);
|
||||
w |= (v4_ucell)ch << (8u * b);
|
||||
}
|
||||
put_cell(t, (v4_cell)w);
|
||||
}
|
||||
}
|
||||
|
||||
/* `header NAME`: a dictionary entry for NAME, as capsule/dict.v4 lays one
|
||||
* out, in front of the word the next `:` starts:
|
||||
* the name: its count byte, then its characters, four bytes to a cell,
|
||||
@@ -180,7 +198,7 @@ static void put_cell(v4_text *t, v4_cell value)
|
||||
static void header(v4_text *t, reader *r)
|
||||
{
|
||||
char name[V4_TEXT_MAX_TOKEN + 1u];
|
||||
unsigned len, cells, i;
|
||||
unsigned len;
|
||||
v4_cell nfa;
|
||||
|
||||
if (r->depth != 1) { fail(t, "not allowed in a macro", "header"); return; }
|
||||
@@ -190,16 +208,7 @@ static void header(v4_text *t, reader *r)
|
||||
if (len > 31) { fail(t, "a header's name is at most 31 characters", name); return; }
|
||||
end_word(t);
|
||||
nfa = v4_asm_label(&t->as);
|
||||
cells = (len + 4u) / 4u;
|
||||
for (i = 0; i < cells; i++) {
|
||||
v4_ucell w = 0;
|
||||
for (unsigned b = 0; b < 4; b++) {
|
||||
unsigned at = 4u * i + b; /* byte 0 is the count */
|
||||
unsigned ch = at == 0 ? len : (at <= len ? (unsigned char)name[at - 1u] : 0u);
|
||||
w |= (v4_ucell)ch << (8u * b);
|
||||
}
|
||||
put_cell(t, (v4_cell)w);
|
||||
}
|
||||
lay_name(t, name);
|
||||
put_cell(t, 0);
|
||||
put_cell(t, nfa);
|
||||
put_cell(t, t->latest);
|
||||
@@ -357,6 +366,68 @@ static void constant_directive(v4_text *t, reader *r)
|
||||
define(t, name, KIND_CONST, v);
|
||||
}
|
||||
|
||||
/* A VALUE in a directive: a number, a constant, CONST+N, or &NAME of a word
|
||||
* already defined. 1 and its value, or 0 having failed. */
|
||||
static int value_of(v4_text *t, const char *tok, v4_cell *out)
|
||||
{
|
||||
const v4_text_symbol *s;
|
||||
int big;
|
||||
if (number_of(tok, out, &big)) {
|
||||
if (big) { fail(t, "number does not fit a cell", tok); return 0; }
|
||||
return 1;
|
||||
}
|
||||
if (tok[0] == '&' && tok[1] != 0) {
|
||||
s = find(t, tok + 1);
|
||||
if (s && s->kind == KIND_WORD) { *out = s->value; return 1; }
|
||||
fail(t, "& needs a word that is already defined", tok + 1);
|
||||
return 0;
|
||||
}
|
||||
s = find(t, tok);
|
||||
if (s && s->kind == KIND_CONST) { *out = s->value; return 1; }
|
||||
if (!s) {
|
||||
const char *plus = strrchr(tok, '+');
|
||||
if (plus && plus != tok && plus[1] != 0) {
|
||||
char left[V4_TEXT_MAX_TOKEN + 1u];
|
||||
const v4_text_symbol *c;
|
||||
v4_cell n;
|
||||
size_t len = (size_t)(plus - tok);
|
||||
memcpy(left, tok, len);
|
||||
left[len] = 0;
|
||||
c = find(t, left);
|
||||
if (c && c->kind == KIND_CONST && number_of(plus + 1, &n, &big) && !big) {
|
||||
*out = (v4_cell)((v4_ucell)c->value + (v4_ucell)n);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
fail(t, "not a value", tok);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* `#, VALUE`: one cell of data at the next word address. */
|
||||
static void cell_directive(v4_text *t, reader *r)
|
||||
{
|
||||
char tok[V4_TEXT_MAX_TOKEN + 1u];
|
||||
v4_cell v;
|
||||
if (r->depth != 1) { fail(t, "not allowed in a macro", "#,"); return; }
|
||||
if (!next_token(t, r, tok)) { if (!t->failed) fail(t, "#, without a value", NULL); return; }
|
||||
if (!value_of(t, tok, &v)) return;
|
||||
(void)v4_asm_label(&t->as);
|
||||
put_cell(t, v);
|
||||
check_asm(t, "#,");
|
||||
}
|
||||
|
||||
/* `", TOKEN`: TOKEN, whatever its characters, as a counted string. */
|
||||
static void string_directive(v4_text *t, reader *r)
|
||||
{
|
||||
char tok[V4_TEXT_MAX_TOKEN + 1u];
|
||||
if (r->depth != 1) { fail(t, "not allowed in a macro", "\","); return; }
|
||||
if (!raw_token(t, r, tok)) { fail(t, "\", without a string, or one too long", NULL); return; }
|
||||
(void)v4_asm_label(&t->as);
|
||||
lay_name(t, tok);
|
||||
check_asm(t, tok);
|
||||
}
|
||||
|
||||
static void one_token(v4_text *t, reader *r, const char *tok)
|
||||
{
|
||||
const v4_text_symbol *s;
|
||||
@@ -381,6 +452,8 @@ static void one_token(v4_text *t, reader *r, const char *tok)
|
||||
}
|
||||
if (strcmp(tok, "macro") == 0) { define_macro(t, r); return; }
|
||||
if (strcmp(tok, "constant") == 0) { constant_directive(t, r); return; }
|
||||
if (strcmp(tok, "#,") == 0) { cell_directive(t, r); return; }
|
||||
if (strcmp(tok, "\",") == 0) { string_directive(t, r); return; }
|
||||
if (strcmp(tok, "endmacro") == 0) { fail(t, "endmacro without macro", NULL); return; }
|
||||
|
||||
if (is_label_def(tok)) {
|
||||
|
||||
@@ -133,9 +133,32 @@
|
||||
#define ROM_NI (OUT_W - 72) /* the next character of the token */
|
||||
#define ROM_NU (OUT_W - 71) /* the value so far, unsigned */
|
||||
#define ROM_NBIG (OUT_W - 70) /* 1 once it has not fitted a cell */
|
||||
#define ROM_RECN (OUT_W - 128) /* (DEFINE): cells of symbol records used */
|
||||
#define ROM_POOLN (OUT_W - 127) /* cells of the name pool used */
|
||||
#define ROM_REC (OUT_W - 126) /* (FIND): the record being looked at */
|
||||
#define ROM_CNT (OUT_W - 125) /* (DEFINE): cells in the token's name */
|
||||
#define ROM_PTR (OUT_W - 124) /* (SAME?), (DEFINE): where in a name */
|
||||
#define ROM_I (OUT_W - 123) /* where in the token */
|
||||
#define ROM_WI (OUT_W - 122) /* (WALK): which entry of a table */
|
||||
/* THE ROM'S SYMBOL TABLE, used only while it assembles, in dictionary space (cleared at `start`): 256 hash heads,
|
||||
* then records growing up -- link, name, kind, value -- and names, as counted strings, growing down from the top. */
|
||||
#define ROM_SYMH DICT_W
|
||||
#define ROM_SYMREC (DICT_W + 256)
|
||||
#define ROM_POOLTOP DICT_END_W
|
||||
#define ROM_REC_LINK 0
|
||||
#define ROM_REC_NAME 1
|
||||
#define ROM_REC_KIND 2
|
||||
#define ROM_REC_VALUE 3
|
||||
#define ROM_KIND_WORD 1
|
||||
#define ROM_KIND_CONST 2
|
||||
#define ROM_KIND_MACRO 3
|
||||
#define ROM_KIND_SET 4
|
||||
/* the ROM's error codes */
|
||||
#define ROM_ERR_TOO_LONG 1 /* a token longer than 63 characters: "name too long" */
|
||||
#define ROM_ERR_COMMENT 2 /* a ( with no ) before the end: "comment not closed" */
|
||||
#define ROM_ERR_BAD_NAME 3 /* an opcode, a reserved word, a label, a number or &...: "cannot be used as a name" */
|
||||
#define ROM_ERR_DEFINED 4 /* "already defined" */
|
||||
#define ROM_ERR_NAMES 5 /* the symbol table is full: "too many names" */
|
||||
#define WORD_DEFINED (BUF0_W - 11) /* the xt of the word that is told of each new entry, or 0 */
|
||||
#define WORD_FORGOTTEN (BUF0_W - 12) /* the xt of the word that is told when entries go, or 0 */
|
||||
#define LOG_LEVEL (BUF0_W - 5) /* the level at or below which a message is printed */
|
||||
|
||||
@@ -29,7 +29,7 @@ extern const unsigned v4_rom_32_words;
|
||||
|
||||
/* The entry table, in its fixed order: entry i is at V4_ROM_BASE + i. */
|
||||
static const char *const rom_entries[] = {
|
||||
"(KEY)", "(TOKEN)", "(NUMBER)", "(FIND)", "(DEFINE)",
|
||||
"(KEY)", "(TOKEN)", "(NUMBER)", "(FIND)", "(DEFINE)", "(OPCODE)",
|
||||
"(OP)", "(LIT)", "(BRANCH)", "(BRANCH>)", "(RESOLVE)", "(LABEL)"
|
||||
};
|
||||
#define ROM_ENTRIES (sizeof rom_entries / sizeof rom_entries[0])
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/* test_host_rom_sym.c -- the ROM's symbol table.
|
||||
*
|
||||
* Plan Task 4. (DEFINE) ( value kind -- ) gives the token (TOKEN) read a
|
||||
* value and a kind; (FIND) ( -- rec | 0 ) finds it, newest first; (OPCODE)
|
||||
* ( -- op | -1 ) says which of the 32 mnemonics it is. A name is refused as
|
||||
* v4/src/text.c's define refuses one -- an opcode, a reserved word, a label
|
||||
* (NAME:), a number, &... -- and every such case is also given to text.c,
|
||||
* the oracle. A set variable (kind 4) may be set again; nothing else may be
|
||||
* defined twice. The table is in dictionary space: records growing up,
|
||||
* names growing down, and "too many names" when they meet.
|
||||
*/
|
||||
#include "rom_harness.h"
|
||||
#include "v4/text.h"
|
||||
|
||||
static int failures = 0, checks = 0;
|
||||
#define CHECK(c,...) do{checks++; if(!(c)){failures++; printf("FAIL %s:%d: ",__FILE__,__LINE__); printf(__VA_ARGS__); printf("\n");}}while(0)
|
||||
|
||||
static v4_node n, oracle_node;
|
||||
static v4_text tx;
|
||||
|
||||
static void tokenize(const char *name)
|
||||
{
|
||||
char in[80];
|
||||
snprintf(in, sizeof in, "%s ", name);
|
||||
v4_node_console_feed(&n, in, (unsigned)strlen(in));
|
||||
if (!rom_call(&n, "(TOKEN)", 100000)) printf(" (TOKEN) did not return for %s\n", name);
|
||||
(void)v4_dstack_pop(&n.ds);
|
||||
}
|
||||
|
||||
/* (DEFINE) the name; the error code it raised (0: none), cleared again */
|
||||
static v4_cell define(const char *name, v4_cell value, v4_cell kind)
|
||||
{
|
||||
v4_cell err;
|
||||
tokenize(name);
|
||||
v4_dstack_push(&n.ds, value);
|
||||
v4_dstack_push(&n.ds, kind);
|
||||
if (!rom_call(&n, "(DEFINE)", 1000000)) return -99;
|
||||
err = n.mem[ROM_FAILED];
|
||||
n.mem[ROM_FAILED] = 0;
|
||||
if (n.ds.depth != 0) return -98; /* (DEFINE) leaves nothing, refused or not */
|
||||
return err;
|
||||
}
|
||||
|
||||
static v4_cell find(const char *name)
|
||||
{
|
||||
tokenize(name);
|
||||
if (!rom_call(&n, "(FIND)", 1000000)) return -99;
|
||||
return v4_dstack_pop(&n.ds);
|
||||
}
|
||||
|
||||
static v4_cell opcode(const char *name)
|
||||
{
|
||||
tokenize(name);
|
||||
if (!rom_call(&n, "(OPCODE)", 1000000)) return -99;
|
||||
return v4_dstack_pop(&n.ds);
|
||||
}
|
||||
|
||||
/* text.c's verdict on NAME as a name: 0 accepted, ROM_ERR_BAD_NAME refused */
|
||||
static v4_cell oracle(const char *name)
|
||||
{
|
||||
char src[120];
|
||||
v4_node_reset(&oracle_node);
|
||||
v4_text_begin(&tx, &oracle_node, 16);
|
||||
snprintf(src, sizeof src, "constant %s 1", name);
|
||||
if (v4_text_assemble(&tx, src)) return 0;
|
||||
return strstr(v4_text_error(&tx), "cannot be used as a name") ? ROM_ERR_BAD_NAME : -1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
static const char *const mnemonic[32] = {
|
||||
";", "ex", "jump", "call", "unext", "next", "if", "-if", "@p", "@+", "@b", "@", "!p", "!+", "!b", "!",
|
||||
"+*", "2*", "2/", "inv", "+", "and", "xor", "drop", "dup", "pop", "over", "a", "nop", "push", "b!", "a!"
|
||||
};
|
||||
static const char *const names[] = {
|
||||
"dup", "a!", ";", "-if", ":", "macro", "endmacro", "FOR", "NEXT", "UNEXT", "constant", "#,", "\",",
|
||||
"x:", "ab:", "12", "$ff", "-1", "99999999999999999999999", "&y", "&",
|
||||
"a1", "abc", "(x", "x:y", "DUP", "Dup", "+1", "-", "$", "LONGERNAME", ":x"
|
||||
};
|
||||
unsigned i, count;
|
||||
v4_cell rec;
|
||||
char nm[16];
|
||||
|
||||
rom_boot(&n);
|
||||
|
||||
/* the 32 mnemonics, and things that are not one */
|
||||
for (i = 0; i < 32; i++) CHECK(opcode(mnemonic[i]) == (v4_cell)i, "%s is opcode %u", mnemonic[i], i);
|
||||
CHECK(opcode("DUP") == -1 && opcode("dupe") == -1 && opcode("du") == -1 && opcode("@pp") == -1, "not mnemonics");
|
||||
|
||||
/* define and find */
|
||||
CHECK(define("A", 5, ROM_KIND_CONST) == 0, "A defined");
|
||||
CHECK(define("B", 100, ROM_KIND_WORD) == 0, "B defined");
|
||||
CHECK(define("Cee", 7, ROM_KIND_MACRO) == 0, "Cee defined");
|
||||
rec = find("A");
|
||||
CHECK(rec > 0 && n.mem[rec + ROM_REC_KIND] == ROM_KIND_CONST && n.mem[rec + ROM_REC_VALUE] == 5, "A found: rec %ld", (long)rec);
|
||||
rec = find("B");
|
||||
CHECK(rec > 0 && n.mem[rec + ROM_REC_KIND] == ROM_KIND_WORD && n.mem[rec + ROM_REC_VALUE] == 100, "B found");
|
||||
rec = find("Cee");
|
||||
CHECK(rec > 0 && n.mem[rec + ROM_REC_KIND] == ROM_KIND_MACRO && n.mem[rec + ROM_REC_VALUE] == 7, "Cee found");
|
||||
CHECK(find("C") == 0 && find("Ce") == 0 && find("Ceee") == 0 && find("a") == 0, "near misses are not found");
|
||||
|
||||
/* twice */
|
||||
CHECK(define("A", 6, ROM_KIND_CONST) == ROM_ERR_DEFINED, "A twice: already defined");
|
||||
CHECK(define("A", 6, ROM_KIND_SET) == ROM_ERR_DEFINED, "a set variable over a constant: already defined");
|
||||
CHECK(define("V", 1, ROM_KIND_SET) == 0 && define("V", 2, ROM_KIND_SET) == 0, "a set variable may be set again");
|
||||
rec = find("V");
|
||||
CHECK(rec > 0 && n.mem[rec + ROM_REC_VALUE] == 2, "and has its new value");
|
||||
CHECK(define("V", 3, ROM_KIND_CONST) == ROM_ERR_DEFINED, "but not defined as something else");
|
||||
|
||||
/* names refused as text.c refuses them */
|
||||
for (i = 0; i < sizeof names / sizeof names[0]; i++) {
|
||||
v4_cell o = oracle(names[i]), r = define(names[i], 1, ROM_KIND_CONST);
|
||||
CHECK(o == r, "%s: text.c %ld, ROM %ld", names[i], (long)o, (long)r);
|
||||
}
|
||||
/* and the ROM's own directives, which text.c does not have */
|
||||
CHECK(define("set", 1, ROM_KIND_CONST) == ROM_ERR_BAD_NAME && define("here", 1, ROM_KIND_CONST) == ROM_ERR_BAD_NAME
|
||||
&& define("store", 1, ROM_KIND_CONST) == ROM_ERR_BAD_NAME && define("start", 1, ROM_KIND_CONST) == ROM_ERR_BAD_NAME,
|
||||
"set here store start are reserved");
|
||||
|
||||
/* capacity: fill the table, then find every name with its value */
|
||||
rom_boot(&n);
|
||||
for (count = 0; count < 5000; count++) {
|
||||
v4_cell err;
|
||||
snprintf(nm, sizeof nm, "S%04u", count);
|
||||
err = define(nm, (v4_cell)count * 3, ROM_KIND_WORD);
|
||||
if (err == ROM_ERR_NAMES) break;
|
||||
if (err != 0) { CHECK(0, "%s: error %ld", nm, (long)err); break; }
|
||||
}
|
||||
CHECK(count >= 800, "at least 800 five-character names fit: %u", count);
|
||||
CHECK(count < 5000, "and the table does fill");
|
||||
for (i = 0; i < count; i++) {
|
||||
snprintf(nm, sizeof nm, "S%04u", i);
|
||||
rec = find(nm);
|
||||
if (!(rec > 0 && n.mem[rec + ROM_REC_VALUE] == (v4_cell)i * 3)) { CHECK(0, "%s not found with its value", nm); break; }
|
||||
}
|
||||
CHECK(i == count, "every one of them is found");
|
||||
|
||||
printf("test_host_rom_sym: %d checks, %d failures\n", checks, failures);
|
||||
return failures != 0;
|
||||
}
|
||||
@@ -499,6 +499,28 @@ int main(void)
|
||||
CHECK(refused("constant K x", "not a number", 1), "a constant's value is a number");
|
||||
CHECK(refused(": constant ;", "cannot be used as a name", 1), "constant is reserved");
|
||||
|
||||
/* ---- `#, VALUE` and `", TOKEN`, data in the text (the ROM's language) ---- */
|
||||
{
|
||||
v4_ucell ab = 2u | ((v4_ucell)'a' << 8) | ((v4_ucell)'b' << 16), paren = 1u | ((v4_ucell)'(' << 8);
|
||||
v4_ucell five_l = 5u | ((v4_ucell)'a' << 8) | ((v4_ucell)'b' << 16) | ((v4_ucell)'c' << 24);
|
||||
v4_ucell five_h = (v4_ucell)'d' | ((v4_ucell)'e' << 8);
|
||||
CHECK(ok("constant K 9 : T ; #, 5 #, -1 #, K #, K+2 #, &T \", ab \", ( \", abcde"),
|
||||
"data assembles: %s", v4_text_error(&tx));
|
||||
CHECK(nb.mem[ORIGIN + 1] == 5 && nb.mem[ORIGIN + 2] == -1 && nb.mem[ORIGIN + 3] == 9 && nb.mem[ORIGIN + 4] == 11
|
||||
&& nb.mem[ORIGIN + 5] == ORIGIN, "#, lays a number, a constant, CONST+N and &NAME");
|
||||
CHECK((v4_ucell)nb.mem[ORIGIN + 6] == ab && (v4_ucell)nb.mem[ORIGIN + 7] == paren,
|
||||
"\", lays a counted string, padded to a whole cell; ( is a name here");
|
||||
CHECK((v4_ucell)nb.mem[ORIGIN + 8] == five_l && (v4_ucell)nb.mem[ORIGIN + 9] == five_h && v4_text_here(&tx) == ORIGIN + 10,
|
||||
"a longer one runs on into the next cell");
|
||||
CHECK(ok(": T dup #, 7 ;") && nb.mem[ORIGIN + 1] == 7 && v4_text_word(&tx, "T") == ORIGIN,
|
||||
"#, inside a word ends the instruction word first");
|
||||
CHECK(refused("#, x", "not a value", 1), "#, needs a value");
|
||||
CHECK(refused("#,", "#, without a value", 1), "#, at the end");
|
||||
CHECK(refused("\",", "\", without a string", 1), "\", at the end");
|
||||
CHECK(refused(": #, ;", "cannot be used as a name", 1) && refused(": \", ;", "cannot be used as a name", 1),
|
||||
"#, and \", are reserved");
|
||||
}
|
||||
|
||||
CHECK(v4_node_guards_intact(&na) && v4_node_guards_intact(&nb), "guards intact");
|
||||
|
||||
printf(" %d checks, %d failures\n", checks, failures);
|
||||
|
||||
@@ -36,6 +36,19 @@ int main(void)
|
||||
constant("(NI)", (long)ROM_NI);
|
||||
constant("(NU)", (long)ROM_NU);
|
||||
constant("(NBIG)", (long)ROM_NBIG);
|
||||
constant("(RECN)", (long)ROM_RECN);
|
||||
constant("(POOLN)", (long)ROM_POOLN);
|
||||
constant("(REC)", (long)ROM_REC);
|
||||
constant("(CNT)", (long)ROM_CNT);
|
||||
constant("(PTR)", (long)ROM_PTR);
|
||||
constant("(I)", (long)ROM_I);
|
||||
constant("(WI)", (long)ROM_WI);
|
||||
constant("(SYMH)", (long)ROM_SYMH);
|
||||
constant("SYMREC", (long)ROM_SYMREC);
|
||||
constant("POOLTOP", (long)ROM_POOLTOP);
|
||||
constant("ERR-BAD-NAME", (long)ROM_ERR_BAD_NAME);
|
||||
constant("ERR-DEFINED", (long)ROM_ERR_DEFINED);
|
||||
constant("ERR-NAMES", (long)ROM_ERR_NAMES);
|
||||
/* the cell width's constants (NUMBER) needs, written as signed cells */
|
||||
constant("MSB", (long)(v4_cell)V4_MSB);
|
||||
constant("DEC-LIMIT", (long)(v4_cell)(~(v4_ucell)0 / 10u));
|
||||
|
||||
Reference in New Issue
Block a user