/* * This header provides an interface between a generated code and the * runtime system. */ # ifndef CXGR_COMMON_H # define CXGR_COMMON_H /* # include */ /* * cxgr_word type * * The memory spaces are viewed as arrays of cxgr_word objects. * The runtime system always operates on words, not on bytes or * halfwords. * * cxgr_word must be an unsigned integer type that is large enough to * store a void pointer. */ /* typedef uintptr_t cxgr_word; */ typedef unsigned long cxgr_word; /* * Active memory space * * An active memory space is a contiguous array of cxgr_word objects, * containing the allocation area and the stack space. * Two pointers named hp and sp points onto the array, and a * invariance "hp <= sp" holds. * hp and sp indicates the end of the allocation area and the * beginning of the stack, respectively. * * <-LOW------------------------------------------------HIGH-> * allocation area | freespace | stack * ----------------------------------------------------------- * ^ ^ * hp sp */ typedef struct { cxgr_word *hp; cxgr_word *sp; } cxgr_space; typedef struct cxgr_runtime_info_struct cxgr_runtime_info; /* * Object layout * * An object is an array of 3 or more cxgr_words. The layout is as * follows. * * head: a nonzero integer. * k: an integer. * n: an integer. (invariant: k <= n) * body: an array of (n-k) values. * * A value is a cxgr_word, containing one of the following: * * (a) A pointer to an object in the heap. * (b) A pointer to somewhere outside the heap. * (c) An odd number. * * Of these, only (a) is modified during a GC. Therefore you cannot * safely maintain a pointer into the stack as a value. * * The stack is an array of values, and the heap contains objects. * The heap includes the allocation area, but there may be other heap * areas as well. You cannot directly allocate objects there, but a * GC may place an object there. */ /* Functions provided by a generated code */ /* Exit status of the generated code */ typedef enum { cxgr_success, /* The program terminated successfully */ cxgr_error_out_notchar, /* The primitive Out was called with an argument that is not a character */ cxgr_error_succ_notchar, /* Similar but the primitive Succ was used */ cxgr_error_stack_oob, /* An out-of-bound Grass stack refererence was made */ cxgr_error_internal /* An error ocurred because of a compiler bug */ } cxgr_status; typedef struct { cxgr_status status; cxgr_word *sp; cxgr_word *hp; } cxgr_result; /* * The entry point of the code. * * sp: initial sp * hp: initial hp * statics: a pointer to an array, which is to be used to hold static * values. Initially it is filled with arbitrary odd numbers. * info: extra information managed by the runtime system */ cxgr_result cxgr_code(cxgr_word *sp, cxgr_word *hp, cxgr_word *statics, cxgr_runtime_info *info); /* returns how many static objects the program will use. */ int cxgr_static_count(void); /* * Functions provided by the runtime system * * These functions are to be called by cxgr_code. * They may or may not be return. If they do not return, they longjmp * directly to a caller of cxgr_code. */ /* * Performs GC. * * sp: the current sp * hp: the current hp * request: the minimum number of elements that must be available * between sp and hp, after the function returns. * * During a GC, the active memory space will be moved and may be * resized, but the static object array will not be moved. * The function returns a pair consisting of the new sp and hp. */ cxgr_space cxgr_gc(cxgr_word *sp, cxgr_word *hp, int request, cxgr_runtime_info *); /* * Output a character to stdout, without buffering. * * c: a encoded character. A character of ASCII code x will be * represented by a odd number (2*x+1). */ void cxgr_putchar(cxgr_word c); /* * Read a character from stdin, and returns it encoded in the same * manner as cxgr_putchar. * On EOF, it returns CXGR_EOF. */ cxgr_word cxgr_getchar(void); # define CXGR_EOF 0xffff /* * Show a message to the user. */ void cxgr_message(const char *msg, cxgr_runtime_info *); # endif