Written the constructor for exceptions; in the process, added a
metadata slot as a first class slot of exceptions.
This commit is contained in:
parent
f915a9993f
commit
83537391a6
11 changed files with 85 additions and 20 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -55,3 +55,4 @@ post-scarcity.kdev4
|
||||||
\.zig-cache/
|
\.zig-cache/
|
||||||
sq/
|
sq/
|
||||||
tmp/
|
tmp/
|
||||||
|
utils_src/a.out
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ struct pso_pointer initialise_environment( uint32_t node ) {
|
||||||
result =
|
result =
|
||||||
make_exception( c_string_to_lisp_string
|
make_exception( c_string_to_lisp_string
|
||||||
( L"Unexpected cell while allocating `nil`." ),
|
( L"Unexpected cell while allocating `nil`." ),
|
||||||
nil, n );
|
nil, nil, n );
|
||||||
debug_print( L"fail\n", DEBUG_BOOTSTRAP, 0 );
|
debug_print( L"fail\n", DEBUG_BOOTSTRAP, 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +79,7 @@ struct pso_pointer initialise_environment( uint32_t node ) {
|
||||||
result =
|
result =
|
||||||
make_exception( c_string_to_lisp_string
|
make_exception( c_string_to_lisp_string
|
||||||
( L"Unexpected cell while allocating `t`." ),
|
( L"Unexpected cell while allocating `t`." ),
|
||||||
nil, n );
|
nil, nil, n );
|
||||||
debug_print( L"fail\n", DEBUG_BOOTSTRAP, 0 );
|
debug_print( L"fail\n", DEBUG_BOOTSTRAP, 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ struct pso_pointer initialise_memory( uint32_t node ) {
|
||||||
if ( memory_initialised ) {
|
if ( memory_initialised ) {
|
||||||
result =
|
result =
|
||||||
make_exception( c_string_to_lisp_string
|
make_exception( c_string_to_lisp_string
|
||||||
( L"Attenpt to reinitialise memory." ), nil, nil );
|
( L"Attenpt to reinitialise memory." ), nil, nil, nil );
|
||||||
} else {
|
} else {
|
||||||
for ( uint8_t i = 0; i <= MAX_SIZE_CLASS; i++ ) {
|
for ( uint8_t i = 0; i <= MAX_SIZE_CLASS; i++ ) {
|
||||||
freelists[i] = nil;
|
freelists[i] = nil;
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,35 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "memory/node.h"
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
#include "memory/pso2.h"
|
#include "memory/pso2.h"
|
||||||
|
|
||||||
|
#include "ops/string_ops.h"
|
||||||
|
|
||||||
uint32_t get_tag_value( struct pso_pointer p ) {
|
uint32_t get_tag_value( struct pso_pointer p ) {
|
||||||
struct pso2 *object = pointer_to_object( p );
|
struct pso2 *object = pointer_to_object( p );
|
||||||
|
|
||||||
return object->header.tag.value & 0xffffff;
|
return object->header.tag.value & 0xffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the tag of the object indicated by this pointer as a Lisp
|
||||||
|
* string.
|
||||||
|
*
|
||||||
|
* @param p must be a struct pso_pointer, indicating the appropriate object.
|
||||||
|
*/
|
||||||
|
struct pso_pointer get_tag_string( struct pso_pointer p) {
|
||||||
|
struct pso_pointer result = nil;
|
||||||
|
struct pso2 *object = pointer_to_object( p );
|
||||||
|
|
||||||
|
for ( int i = 2 - 1; i >= 0; i-- ) {
|
||||||
|
result = make_string( (wchar_t)(object->header.tag.bytes.mnemonic[i]), result );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief check that the tag of the object indicated by this poiner has this
|
* @brief check that the tag of the object indicated by this poiner has this
|
||||||
* value.
|
* value.
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,8 @@
|
||||||
// #define get_tag_value(p)((pointer_to_object(p)->header.tag.value) & 0xffffff)
|
// #define get_tag_value(p)((pointer_to_object(p)->header.tag.value) & 0xffffff)
|
||||||
uint32_t get_tag_value( struct pso_pointer p );
|
uint32_t get_tag_value( struct pso_pointer p );
|
||||||
|
|
||||||
|
struct pso_pointer get_tag_string( struct pso_pointer p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief check that the tag of the object indicated by this poiner has this
|
* @brief check that the tag of the object indicated by this poiner has this
|
||||||
* value.
|
* value.
|
||||||
|
|
@ -103,6 +105,7 @@ bool check_type( struct pso_pointer p, char *s );
|
||||||
#define exceptionp(p) (check_tag(p, EXCEPTIONTV))
|
#define exceptionp(p) (check_tag(p, EXCEPTIONTV))
|
||||||
#define freep(p) (check_tag(p, FREETV))
|
#define freep(p) (check_tag(p, FREETV))
|
||||||
#define functionp(p) (check_tag(p, FUNCTIONTV))
|
#define functionp(p) (check_tag(p, FUNCTIONTV))
|
||||||
|
#define hashtabp(p) (check_tag(p, HASHTV))
|
||||||
#define integerp(p) (check_tag(p, INTEGERTV))
|
#define integerp(p) (check_tag(p, INTEGERTV))
|
||||||
#define keywordp(p) (check_tag(p, KEYTV))
|
#define keywordp(p) (check_tag(p, KEYTV))
|
||||||
#define lambdap(p) (check_tag(p,LAMBDATV))
|
#define lambdap(p) (check_tag(p,LAMBDATV))
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,9 @@ struct pso_pointer eval(
|
||||||
make_exception( c_cons
|
make_exception( c_cons
|
||||||
( c_string_to_lisp_string
|
( c_string_to_lisp_string
|
||||||
( L"Can't yet evaluate things of this type: " ),
|
( L"Can't yet evaluate things of this type: " ),
|
||||||
result ), frame_pointer, nil );
|
result ), frame_pointer,
|
||||||
|
c_cons( c_cons( c_string_to_lisp_keyword(L"tag"),
|
||||||
|
get_tag_string(result)), nil), nil );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( exceptionp( result ) ) {
|
if ( exceptionp( result ) ) {
|
||||||
|
|
@ -95,9 +97,8 @@ struct pso_pointer eval(
|
||||||
EXCEPTIONTV );
|
EXCEPTIONTV );
|
||||||
|
|
||||||
if ( nilp( x->payload.exception.stack ) ) {
|
if ( nilp( x->payload.exception.stack ) ) {
|
||||||
inc_ref( result );
|
|
||||||
result =
|
result =
|
||||||
make_exception( x->payload.exception.message, frame_pointer,
|
make_exception( x->payload.exception.message, frame_pointer, nil,
|
||||||
result );
|
result );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,9 @@ struct pso_pointer c_reverse( struct pso_pointer sequence ) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result =
|
result =
|
||||||
make_exception( c_string_to_lisp_string
|
make_exception( c_cons( c_string_to_lisp_string
|
||||||
( L"Invalid object in sequence" ), nil,
|
( L"Invalid object in sequence" ), cursor), nil,
|
||||||
nil );
|
nil , nil);
|
||||||
goto exit;
|
goto exit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,3 +182,5 @@ struct pso_pointer c_string_to_lisp_keyword( wchar_t *symbol ) {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,11 @@ struct pso_pointer c_cdr( struct pso_pointer p ) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result =
|
result =
|
||||||
make_exception( c_cons
|
make_exception(
|
||||||
( c_string_to_lisp_string
|
c_cons(
|
||||||
( L"Invalid type for cdr" ), p ), nil, nil );
|
c_string_to_lisp_string( L"Invalid type for cdr" ),
|
||||||
|
get_tag_string( p) ),
|
||||||
|
nil, nil, nil );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,45 @@
|
||||||
#include "memory/node.h"
|
#include "memory/node.h"
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
#include "memory/pso.h"
|
#include "memory/pso.h"
|
||||||
|
#include "memory/pso3.h"
|
||||||
#include "memory/pso4.h"
|
#include "memory/pso4.h"
|
||||||
#include "memory/tags.h"
|
#include "memory/tags.h"
|
||||||
|
|
||||||
#include "payloads/exception.h"
|
#include "payloads/exception.h"
|
||||||
|
|
||||||
|
#include "ops/truth.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief allocate an exception object, and, if successful, return a pointer
|
||||||
|
* to it.
|
||||||
|
*
|
||||||
|
* Throwing an exception while generating an exception is meaningless. If
|
||||||
|
* allocation fails utterly (i.e. out of heap, out of page space) this will
|
||||||
|
* have to return `nil`, which might give rise to hard to trace bugs. But
|
||||||
|
* otherwise it will return a pointer to a new exception.
|
||||||
|
*
|
||||||
|
* @param message expected to be a string, but anything printable is accepted.
|
||||||
|
* @param frame the stack frame in which the exception was `thrown`, if any.
|
||||||
|
* @param meta metadata for this exception. Must be an assoc list, hashtable,
|
||||||
|
* or `nil`
|
||||||
|
* @param cause the exception that caused this exception to be `thrown`.
|
||||||
|
*/
|
||||||
struct pso_pointer make_exception( struct pso_pointer message,
|
struct pso_pointer make_exception( struct pso_pointer message,
|
||||||
struct pso_pointer frame_pointer,
|
struct pso_pointer frame,
|
||||||
|
struct pso_pointer meta,
|
||||||
struct pso_pointer cause ) {
|
struct pso_pointer cause ) {
|
||||||
// TODO: not yet implemented
|
struct pso_pointer result = allocate(EXCEPTIONTAG, 3);
|
||||||
return nil;
|
|
||||||
|
if (!nilp(result) && !exceptionp(result)) {
|
||||||
|
struct pso3* object = (struct pso3*)pointer_to_object( result);
|
||||||
|
|
||||||
|
object->payload.exception.message = message;
|
||||||
|
object->payload.exception.stack = stackp(frame) ? frame : nil;
|
||||||
|
object->payload.exception.meta = (consp(meta) || hashtabp(meta)) ? meta : nil;
|
||||||
|
object->payload.exception.cause = exceptionp(cause) ? cause : nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -34,8 +63,12 @@ struct pso_pointer destroy_exception( struct pso_pointer fp,
|
||||||
if ( stackp( fp ) ) {
|
if ( stackp( fp ) ) {
|
||||||
struct pso4 *frame = pointer_to_pso4( fp );
|
struct pso4 *frame = pointer_to_pso4( fp );
|
||||||
struct pso_pointer p = frame->payload.stack_frame.arg[0];
|
struct pso_pointer p = frame->payload.stack_frame.arg[0];
|
||||||
|
struct pso3* object = (struct pso3*)pointer_to_object( p);
|
||||||
|
|
||||||
// TODO: decrement every pointer indicated by an exception.
|
dec_ref( object->payload.exception.message);
|
||||||
|
dec_ref( object->payload.exception.stack);
|
||||||
|
dec_ref( object->payload.exception.meta);
|
||||||
|
dec_ref( object->payload.exception.cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,15 @@ struct exception_payload {
|
||||||
struct pso_pointer message;
|
struct pso_pointer message;
|
||||||
/** @brief the stack frame at which the exception was thrown. */
|
/** @brief the stack frame at which the exception was thrown. */
|
||||||
struct pso_pointer stack;
|
struct pso_pointer stack;
|
||||||
|
/** a store (assoc list or hashtable (or `nil` of metadata */
|
||||||
|
struct pso_pointer meta;
|
||||||
/** @brief the cause; expected to be another exception, or (usually) `nil`. */
|
/** @brief the cause; expected to be another exception, or (usually) `nil`. */
|
||||||
struct pso_pointer cause;
|
struct pso_pointer cause;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pso_pointer make_exception( struct pso_pointer message,
|
struct pso_pointer make_exception( struct pso_pointer message,
|
||||||
struct pso_pointer frame_pointer,
|
struct pso_pointer frame_pointer,
|
||||||
|
struct pso_pointer meta,
|
||||||
struct pso_pointer cause );
|
struct pso_pointer cause );
|
||||||
|
|
||||||
struct pso_pointer destroy_exception( struct pso_pointer fp,
|
struct pso_pointer destroy_exception( struct pso_pointer fp,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue