PROGN working
This commit is contained in:
parent
45d129facb
commit
b989b5e041
|
@ -78,23 +78,24 @@ int main( int argc, char *argv[] ) {
|
||||||
/*
|
/*
|
||||||
* primitive function operations
|
* primitive function operations
|
||||||
*/
|
*/
|
||||||
|
bind_function( "add", &lisp_add );
|
||||||
|
bind_function( "apply", &lisp_apply );
|
||||||
bind_function( "assoc", &lisp_assoc );
|
bind_function( "assoc", &lisp_assoc );
|
||||||
bind_function( "car", &lisp_car );
|
bind_function( "car", &lisp_car );
|
||||||
bind_function( "cdr", &lisp_cdr );
|
bind_function( "cdr", &lisp_cdr );
|
||||||
bind_function( "cons", &lisp_cons );
|
bind_function( "cons", &lisp_cons );
|
||||||
bind_function( "eq", &lisp_eq );
|
bind_function( "eq", &lisp_eq );
|
||||||
bind_function( "equal", &lisp_equal );
|
bind_function( "equal", &lisp_equal );
|
||||||
|
bind_function( "multiply", &lisp_multiply );
|
||||||
bind_function( "read", &lisp_read );
|
bind_function( "read", &lisp_read );
|
||||||
bind_function( "print", &lisp_print );
|
bind_function( "print", &lisp_print );
|
||||||
|
bind_function( "progn", &lisp_progn );
|
||||||
|
bind_function( "subtract", &lisp_subtract );
|
||||||
bind_function( "type", &lisp_type );
|
bind_function( "type", &lisp_type );
|
||||||
|
|
||||||
bind_function( "add", &lisp_add );
|
|
||||||
bind_function( "+", &lisp_add );
|
bind_function( "+", &lisp_add );
|
||||||
bind_function( "multiply", &lisp_multiply );
|
|
||||||
bind_function( "*", &lisp_multiply );
|
bind_function( "*", &lisp_multiply );
|
||||||
bind_function( "subtract", &lisp_subtract );
|
|
||||||
bind_function( "-", &lisp_subtract );
|
bind_function( "-", &lisp_subtract );
|
||||||
bind_function( "apply", &lisp_apply );
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* primitive special forms
|
* primitive special forms
|
||||||
|
|
|
@ -366,7 +366,7 @@ lisp_print( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Lisp type of the single argument.
|
* Function: Get the Lisp type of the single argument.
|
||||||
* @param frame My stack frame.
|
* @param frame My stack frame.
|
||||||
* @param env My environment (ignored).
|
* @param env My environment (ignored).
|
||||||
* @return As a Lisp string, the tag of the object which is the argument.
|
* @return As a Lisp string, the tag of the object which is the argument.
|
||||||
|
@ -384,6 +384,35 @@ lisp_type( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function; evaluate the forms which are listed in my single argument
|
||||||
|
* sequentially and return the value of the last. This function is called 'do'
|
||||||
|
* in some dialects of Lisp.
|
||||||
|
*
|
||||||
|
* @param frame My stack frame.
|
||||||
|
* @param env My environment (ignored).
|
||||||
|
* @return the value of the last form on the sequence which is my single
|
||||||
|
* argument.
|
||||||
|
*/
|
||||||
|
struct cons_pointer
|
||||||
|
lisp_progn( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
|
struct cons_pointer remaining = frame->arg[0];
|
||||||
|
struct cons_pointer result = NIL;
|
||||||
|
|
||||||
|
while ( consp(remaining)) {
|
||||||
|
struct cons_space_object cell = pointer2cell( remaining );
|
||||||
|
struct stack_frame * next = make_empty_frame(frame, env);
|
||||||
|
next->arg[0] = cell.payload.cons.car;
|
||||||
|
inc_ref( next->arg[0] );
|
||||||
|
result = lisp_eval(next, env);
|
||||||
|
free_stack_frame( next);
|
||||||
|
|
||||||
|
remaining = cell.payload.cons.cdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: make this do something sensible somehow.
|
* TODO: make this do something sensible somehow.
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct cons_pointer lisp_read( struct stack_frame *frame,
|
||||||
struct cons_pointer lisp_print( struct stack_frame *frame,
|
struct cons_pointer lisp_print( struct stack_frame *frame,
|
||||||
struct cons_pointer env );
|
struct cons_pointer env );
|
||||||
/**
|
/**
|
||||||
* Get the Lisp type of the single argument.
|
* Function: Get the Lisp type of the single argument.
|
||||||
* @param frame My stack frame.
|
* @param frame My stack frame.
|
||||||
* @param env My environment (ignored).
|
* @param env My environment (ignored).
|
||||||
* @return As a Lisp string, the tag of the object which is the argument.
|
* @return As a Lisp string, the tag of the object which is the argument.
|
||||||
|
@ -57,6 +57,20 @@ struct cons_pointer lisp_print( struct stack_frame *frame,
|
||||||
struct cons_pointer
|
struct cons_pointer
|
||||||
lisp_type( struct stack_frame *frame, struct cons_pointer env );
|
lisp_type( struct stack_frame *frame, struct cons_pointer env );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function; evaluate the forms which are listed in my single argument
|
||||||
|
* sequentially and return the value of the last. This function is called 'do'
|
||||||
|
* in some dialects of Lisp.
|
||||||
|
*
|
||||||
|
* @param frame My stack frame.
|
||||||
|
* @param env My environment (ignored).
|
||||||
|
* @return the value of the last form on the sequence which is my single
|
||||||
|
* argument.
|
||||||
|
*/
|
||||||
|
struct cons_pointer
|
||||||
|
lisp_progn( struct stack_frame *frame, struct cons_pointer env );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* neither, at this stage, really
|
* neither, at this stage, really
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,14 +6,13 @@ actual=`echo "(add 2 3)" | target/psse 2> /dev/null | head -2 | tail -1`
|
||||||
if [ "${expected}" = "${actual}" ]
|
if [ "${expected}" = "${actual}" ]
|
||||||
then
|
then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
exit 0
|
|
||||||
else
|
else
|
||||||
echo "Fail: expected '${expected}', got '${actual}'"
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
expected='5.5000'
|
expected='5.500000'
|
||||||
actual=`echo "(add 2.5 3)" | target/psse 2> /dev/null | head -1`
|
actual=`echo "(add 2.5 3)" | target/psse 2> /dev/null | head -2 | tail -1`
|
||||||
|
|
||||||
if [ "${expected}" = "${actual}" ]
|
if [ "${expected}" = "${actual}" ]
|
||||||
then
|
then
|
||||||
|
|
24
unit-tests/multiply.sh
Normal file
24
unit-tests/multiply.sh
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
expected='6'
|
||||||
|
actual=`echo "(multiply 2 3)" | target/psse 2> /dev/null | head -2 | tail -1`
|
||||||
|
|
||||||
|
if [ "${expected}" = "${actual}" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
expected='7.500000'
|
||||||
|
actual=`echo "(multiply 2.5 3)" | target/psse 2> /dev/null | head -2 | tail -1`
|
||||||
|
|
||||||
|
if [ "${expected}" = "${actual}" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
24
unit-tests/progn.sh
Normal file
24
unit-tests/progn.sh
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
expected='5'
|
||||||
|
actual=`echo "(progn '((add 2 3)))" | target/psse 2> /dev/null | head -2 | tail -1`
|
||||||
|
|
||||||
|
if [ "${expected}" = "${actual}" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
expected='"foo"'
|
||||||
|
actual=`echo "(progn '((add 2.5 3) \"foo\"))" | target/psse 2> /dev/null | head -1`
|
||||||
|
|
||||||
|
if [ "${expected}" = "${actual}" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Fail: expected '${expected}', got '${actual}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
Loading…
Reference in a new issue