Added all the error codes from the manual.

Some will be irrelevant to this project, but they're all here.
This commit is contained in:
Simon Brooke 2026-04-06 12:47:41 +01:00
parent 882f991db4
commit 643d255a21
3 changed files with 65 additions and 13 deletions

View file

@ -60,3 +60,16 @@ Tags will be allocated as follows:
| 7 | 119 | | unassigned | | 7 | 119 | | unassigned |
| 7 | 127 | 0x7f | a free cell | | 7 | 127 | 0x7f | a free cell |
## Problems with building a Ghuloum-style compiler in Lisp 1.5
Ghuloum's compiler emits strings in the form of assembly language statements into a file which is then run through a separate assembler to produce a binary which is finally integrated with a launcher stub written in C using a linker. This makes it possible to write a Lisp largely in that Lisp itself (provided you have an existing Lisp fostermother image to run the initial compilation); but it does not dirctly enable you to compile a single function into the existing image at runtime, and then immediately use the newly compiled function; and as far as I'm concerned, until you have that you don't have a working Lisp compiler.
Furthermore, Lisp 1.5 does not have a concept of a string, and cannot manipulate strings. I *could* add strings as an extension, but that feels somewhat outwith the scope of this project.
I don't feel that any of this is insuperable. Lisp 1.5 supports the functions `PRINT`, `PRIN1`, and `TERPRI` which respectively make it possible to print complete S-expressions, individual atoms, and linefeeds. It would be possible to create a symbol whose print name was a single blank space. It would be perverse, and annoying, and `READ` would not recognise such a symbol so if it were included in a sysout file that sysout could not be read back in; but it would be possible.
Or else, we could assemble the assembly language statements as a list of individual S-expressions, print that, run it through an external preprocessor and the assembler, and then link the resulting binary. It does not seem to me that using an external pre-processor is any more 'cheating' than using an external assembler.
But finally, and this will be my preferred outcome, one could create that list of assembly language statements in memory; one could estimate from it the size of the compiled function; one could malloc a block of memory of that size on the heap; and one could then assemble the function by writing bytes into that block of memory as specified in the assembly language statements.
If I'm going to use this side-project as an exercise to learn how to write the Post Scarcity compiler, the Post Scarcity compiler has got to be able to do that; so I should try.

View file

@ -13,17 +13,16 @@
* Licensed under GPL version 2.0, or, at your option, any later version. * Licensed under GPL version 2.0, or, at your option, any later version.
*/ */
#include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "error.h" #include "error.h"
#include "memory.h"
uint32_t make_error( char* code) { uint32_t make_error( char* code) {
uint32_t error = 0; uint32_t error = 0;
char* dest = (char *)&error;
strncpy( (char *)((&error) &1), code, 3); strncpy( (char *)(dest + 1), code, 3);
return error; return error;
} }

View file

@ -25,21 +25,61 @@ uint32_t make_error( char* code);
* *
* Error codes are detailed in section 6.3, page 32, of the * Error codes are detailed in section 6.3, page 32, of the
* Lisp 1.5 Programmer's Manual. I shall in so far as possible follow * Lisp 1.5 Programmer's Manual. I shall in so far as possible follow
* those codes. * reproduce those codes.
* *
* Error codes comprise a one or two alphabetic character category, followed * Error codes comprise a one or two alphabetic character category, followed
* by a single digit number. A space is shown in the manual between the * by a single digit number. A space is shown in the manual between the
* category and the number, but I have not followed that here for reasons. * category and the number, but I have not followed that here for reasons.
*/ */
#define APPLIED_FUNCTION_CALLED_ERROR (make_error( "A1")) #define ERROR_APPLIED_FUNCTION_CALLED (make_error( "A1"))
#define UNDEFINED_FUNCTION_APPLY_ERROR (make_error( "A2")) #define ERROR_UNDEFINED_FUNCTION_APPLY (make_error( "A2"))
#define COND_UNSATISFIED_ERROR (make_error( "A3")) #define ERROR_COND_UNSATISFIED (make_error( "A3"))
#define SETQ_ON_NONEXISTANT_VAR_ERROR (make_error( "A4")) #define ERROR_SETQ_ON_NONEXISTANT_VAR (make_error( "A4"))
#define SET_ON_NONEXISTANT_VAR_ERROR (make_error( "A5")) #define ERROR_SET_ON_NONEXISTANT_VAR (make_error( "A5"))
#define NO_TARGET_FOR_GO_ERROR (make_error( "A6")) #define ERROR_NO_TARGET_FOR_GO (make_error( "A6"))
#define TOO_MANY_ARGUMENTS_ERROR (make_error( "A7")) #define ERROR_TOO_MANY_ARGUMENTS (make_error( "A7"))
#define UNBOUND_VARIABLE_ERROR (make_error( "A8")) #define ERROR_UNBOUND_VARIABLE (make_error( "A8"))
#define UNDEFINED_FUNCTION_EVAL_ERROR (make_error( "A9")) #define ERROR_UNDEFINED_FUNCTION_EVAL (make_error( "A9"))
#define ERROR_TOO_MANY_CHARS_IN_NAME (make_error( "CH1"))
#define ERROR_FLOAT_NUMBER_OUT_OF_RANGE (make_error( "CH2"))
#define ERROR_TAPE_READING (make_error( "CH3"))
#define ERROR_CONS_COUNTER_TRAP (make_error( "F1"))
#define ERROR_FIRST_ARG_LIST_TOO_SHORT (make_error( "F2"))
#define ERROR_SECOND_ARG_LIST_TOO_SHORT (make_error( "F3"))
// I wonder what happened to F4?
#define ERROR_STR_TRAP (make_error( "F5"))
#define ERROR_FLOAT_TRAP (make_error( "G1"))
#define ERROR_OUT_OF_PUSHDOWN_LIST (make_error( "G2"))
#define ERROR_FATAL_RECLAIMER (make_error( "GC1"))
#define ERROR_NOT_ENOUGH_RECLAIMED (make_error( "GC2"))
#define ERROR_NOT_ENOUGH_ROOM_ARRAY (make_error( "I1"))
#define ERROR_FIRST_ARG_NEGATIVE (make_error( "I2"))
#define ERROR_UNABLE_TO_DETERMINE_ORIGIN (make_error( "L1"))
#define ERROR_OUT_OF_BINARY_SPACE (make_error( "L2"))
#define ERROR_UNDEFINED_SYMBOL (make_error( "L3"))
#define ERROR_FIELD_CONTAINED_SUB_SUBS (make_error( "L4"))
#define ERROR_ERROR_IN_SIZE_CARD (make_error( "O1"))
#define ERROR_INVALID_TAPE_DESIGNATION (make_error( "O2"))
#define ERROR_NO_SIZECARD (make_error( "O3"))
#define ERROR_BAD_DUMP_ARGUMENTS (make_error( "O4"))
#define ERROR_BAD_INPUT_BUT_GOING_ON (make_error( "O5"))
#define ERROR_OVERLAPPING_PARAMETERS (make_error( "O7"))
#define ERROR_PRIN1_NON_OBJECT (make_error( "P1"))
#define ERROR_FIRST_OBJECT_ILLEGAL (make_error( "R1"))
#define ERROR_CONTEXT_WITH_DOT_NOTATION (make_error( "R2"))
#define ERROR_ILLEGAL_CHARACTER (make_error( "R3"))
#define ERROR_END_OF_FILE_ON_READ_IN (make_error( "R4"))
#define ERROR_PRINT_NAME_TOO_LONG (make_error( "R5"))
#define ERROR_NUMBER_TOO_LARGE (make_error( "R6"))
#endif #endif