Made try/catch actually work
This commit is contained in:
parent
462c0c69b4
commit
a8315d649f
|
@ -278,6 +278,7 @@ int main( int argc, char *argv[] ) {
|
||||||
bind_special( L"progn", &lisp_progn );
|
bind_special( L"progn", &lisp_progn );
|
||||||
bind_special( L"quote", &lisp_quote );
|
bind_special( L"quote", &lisp_quote );
|
||||||
bind_special( L"set!", &lisp_set_shriek );
|
bind_special( L"set!", &lisp_set_shriek );
|
||||||
|
bind_special( L"try", &lisp_try );
|
||||||
debug_print( L"Initialised oblist\n", DEBUG_BOOTSTRAP );
|
debug_print( L"Initialised oblist\n", DEBUG_BOOTSTRAP );
|
||||||
debug_dump_object( oblist, DEBUG_BOOTSTRAP );
|
debug_dump_object( oblist, DEBUG_BOOTSTRAP );
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ struct cons_pointer eval_forms( struct stack_frame *frame,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OK, the idea here (and I know this is less than perfect) is that the basic `try`
|
* OK, the idea here (and I know this is less than perfect) is that the basic `try`
|
||||||
* function in PSSE takes two arguments, the first, `body`, being a list of forms,
|
* special form in PSSE takes two arguments, the first, `body`, being a list of forms,
|
||||||
* and the second, `catch`, being a catch handler (which is also a list of forms).
|
* and the second, `catch`, being a catch handler (which is also a list of forms).
|
||||||
* Forms from `body` are evaluated in turn until one returns an exception object,
|
* Forms from `body` are evaluated in turn until one returns an exception object,
|
||||||
* or until the list is exhausted. If the list was exhausted, then the value of
|
* or until the list is exhausted. If the list was exhausted, then the value of
|
||||||
|
@ -158,7 +158,7 @@ struct cons_pointer lisp_try( struct stack_frame *frame,
|
||||||
// TODO: need to put the exception into the environment!
|
// TODO: need to put the exception into the environment!
|
||||||
result = c_progn( frame, frame_pointer, frame->arg[1],
|
result = c_progn( frame, frame_pointer, frame->arg[1],
|
||||||
make_cons( make_cons
|
make_cons( make_cons
|
||||||
( c_string_to_lisp_keyword
|
( c_string_to_lisp_symbol
|
||||||
( L"*exception*" ), result ), env ) );
|
( L"*exception*" ), result ), env ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,9 +440,8 @@ c_apply( struct stack_frame *frame, struct cons_pointer frame_pointer,
|
||||||
result = next_pointer;
|
result = next_pointer;
|
||||||
} else {
|
} else {
|
||||||
result =
|
result =
|
||||||
( *fn_cell.payload.
|
( *fn_cell.payload.special.
|
||||||
special.executable ) ( get_stack_frame
|
executable ) ( get_stack_frame( next_pointer ),
|
||||||
( next_pointer ),
|
|
||||||
next_pointer, env );
|
next_pointer, env );
|
||||||
debug_print( L"Special form returning: ", DEBUG_EVAL );
|
debug_print( L"Special form returning: ", DEBUG_EVAL );
|
||||||
debug_print_object( result, DEBUG_EVAL );
|
debug_print_object( result, DEBUG_EVAL );
|
||||||
|
@ -1238,8 +1237,7 @@ lisp_exception( struct stack_frame *frame, struct cons_pointer frame_pointer,
|
||||||
struct cons_pointer env ) {
|
struct cons_pointer env ) {
|
||||||
struct cons_pointer message = frame->arg[0];
|
struct cons_pointer message = frame->arg[0];
|
||||||
return exceptionp( message ) ? message : throw_exception( message,
|
return exceptionp( message ) ? message : throw_exception( message,
|
||||||
frame->
|
frame->previous );
|
||||||
previous );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1406,14 +1404,13 @@ struct cons_pointer c_append( struct cons_pointer l1, struct cons_pointer l2 ) {
|
||||||
if ( pointer2cell( l1 ).tag.value == pointer2cell( l2 ).tag.value ) {
|
if ( pointer2cell( l1 ).tag.value == pointer2cell( l2 ).tag.value ) {
|
||||||
if ( nilp( c_cdr( l1 ) ) ) {
|
if ( nilp( c_cdr( l1 ) ) ) {
|
||||||
return
|
return
|
||||||
make_string_like_thing( ( pointer2cell( l1 ).
|
make_string_like_thing( ( pointer2cell( l1 ).payload.
|
||||||
payload.string.character ),
|
string.character ), l2,
|
||||||
l2,
|
|
||||||
pointer2cell( l1 ).tag.value );
|
pointer2cell( l1 ).tag.value );
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
make_string_like_thing( ( pointer2cell( l1 ).
|
make_string_like_thing( ( pointer2cell( l1 ).payload.
|
||||||
payload.string.character ),
|
string.character ),
|
||||||
c_append( c_cdr( l1 ), l2 ),
|
c_append( c_cdr( l1 ), l2 ),
|
||||||
pointer2cell( l1 ).tag.value );
|
pointer2cell( l1 ).tag.value );
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,4 +219,8 @@ struct cons_pointer lisp_list( struct stack_frame *frame,
|
||||||
struct cons_pointer lisp_let( struct stack_frame *frame,
|
struct cons_pointer lisp_let( struct stack_frame *frame,
|
||||||
struct cons_pointer frame_pointer,
|
struct cons_pointer frame_pointer,
|
||||||
struct cons_pointer env );
|
struct cons_pointer env );
|
||||||
|
|
||||||
|
struct cons_pointer lisp_try( struct stack_frame *frame,
|
||||||
|
struct cons_pointer frame_pointer,
|
||||||
|
struct cons_pointer env );
|
||||||
#endif
|
#endif
|
||||||
|
|
45
unit-tests/try.sh
Executable file
45
unit-tests/try.sh
Executable file
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
expected=':foo'
|
||||||
|
actual=`echo "(try ((+ 2 (/ 1 'a))) (:foo))" | target/psse | tail -1`
|
||||||
|
|
||||||
|
if [ "${expected}" = "${actual}" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
expected='4'
|
||||||
|
actual=`echo "(try ((+ 2 (/ 1 'a))) ((+ 2 2)))" | target/psse | tail -1`
|
||||||
|
|
||||||
|
if [ "${expected}" = "${actual}" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
expected='8'
|
||||||
|
actual=`echo "(try (:body (+ 2 (/ 1 'a))) (:catch (* 2 2 2)))" | target/psse | tail -1`
|
||||||
|
|
||||||
|
if [ "${expected}" = "${actual}" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
expected=''
|
||||||
|
actual=`echo "(try (:body (+ 2 (/ 1 'a))) (:catch *exception*))" | target/psse | tail -1`
|
||||||
|
|
||||||
|
if [ "${expected}" = "${actual}" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
Loading…
Reference in a new issue