(NUMBER) ( -- n flag ), entry 2: decimal with a leading -, or hex after $; 1 a number, 0 not one, -1 one that does not fit a cell. Every case is also given to text.c, the oracle, at both widths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
2.8 KiB
C
77 lines
2.8 KiB
C
/* test_host_rom_num.c -- the ROM reads numbers as v4/src/text.c does.
|
|
*
|
|
* Plan Task 3. (NUMBER) ( -- n flag ) looks at the token (TOKEN) read: flag
|
|
* 1 if the whole token is a number, 0 if it is not one, -1 if it is one that
|
|
* does not fit a cell. A number is decimal with an optional leading `-`, or
|
|
* hexadecimal after `$` (a-f in either case), and must fit a cell read as
|
|
* signed or as unsigned. Every case is also given to text.c, the oracle,
|
|
* so the test cannot drift from it.
|
|
*/
|
|
#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;
|
|
|
|
/* text.c's verdict on `tok`: 1 and its value, 0, or -1 */
|
|
static int oracle(const char *tok, v4_cell *value)
|
|
{
|
|
char src[160];
|
|
v4_node_reset(&oracle_node);
|
|
v4_text_begin(&tx, &oracle_node, 16);
|
|
snprintf(src, sizeof src, "constant X %s : T X ;", tok);
|
|
if (v4_text_assemble(&tx, src) && v4_text_finish(&tx)) { *value = oracle_node.mem[17]; return 1; }
|
|
if (strstr(v4_text_error(&tx), "does not fit")) return -1;
|
|
return 0;
|
|
}
|
|
|
|
/* the ROM's verdict on `tok` */
|
|
static int rom(const char *tok, v4_cell *value)
|
|
{
|
|
char in[80];
|
|
v4_cell flag;
|
|
rom_boot(&n);
|
|
snprintf(in, sizeof in, "%s \x04", tok);
|
|
v4_node_console_feed(&n, in, (unsigned)strlen(in));
|
|
if (!rom_call(&n, "(TOKEN)", 100000)) return 99;
|
|
(void)v4_dstack_pop(&n.ds);
|
|
if (!rom_call(&n, "(NUMBER)", 100000)) return 98;
|
|
flag = v4_dstack_pop(&n.ds);
|
|
*value = v4_dstack_pop(&n.ds);
|
|
return (int)flag;
|
|
}
|
|
|
|
static void same(const char *tok)
|
|
{
|
|
v4_cell ov = 0, rv = 0;
|
|
int o = oracle(tok, &ov), r = rom(tok, &rv);
|
|
CHECK(o == r && (o != 1 || ov == rv), "%s: text.c %d %ld, ROM %d %ld", tok, o, (long)ov, r, (long)rv);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
#if V4_CELL_BITS == 64
|
|
static const char *const width[] = {
|
|
"$FFFFFFFFFFFFFFFF", "$10000000000000000", "18446744073709551615", "18446744073709551616",
|
|
"-9223372036854775808", "-9223372036854775809", "$7FFFFFFFFFFFFFFF", "99999999999999999999999"
|
|
};
|
|
#else
|
|
static const char *const width[] = {
|
|
"$FFFFFFFF", "$100000000", "4294967295", "4294967296",
|
|
"-2147483648", "-2147483649", "$7FFFFFFF", "99999999999"
|
|
};
|
|
#endif
|
|
static const char *const any[] = {
|
|
"0", "1", "7", "10", "-1", "-0", "123456", "$0", "$ff", "$FF", "$aBcD", "$10",
|
|
"-$1", "1a", "-", "$", "$g", "a", "--1", "+1", "1-", "00012", "$000"
|
|
};
|
|
unsigned i;
|
|
for (i = 0; i < sizeof any / sizeof any[0]; i++) same(any[i]);
|
|
for (i = 0; i < sizeof width / sizeof width[0]; i++) same(width[i]);
|
|
printf("test_host_rom_num: %d checks, %d failures\n", checks, failures);
|
|
return failures != 0;
|
|
}
|