new-entry
use function build as new_entry ;
lookup-in-entry
function lookup_in_entry
( $name , $entry , $entry_f )
{ return
lookup_in_entry_help ( $name ,
first ( $entry ),
second ( $entry ),
$entry_f );
}
lookup-in-entry-help
function lookup_in_entry_help
( $name , $names , $values , $entry_f )
{ return
is_nulll ( $names ) ? $entry_f ( $name )
: ( is_eq ( car ( $names ), $name ) ? car ( $values )
: lookup_in_entry_help ( $name ,
cdr ( $names ),
cdr ( $values ),
$entry_f ));
}
extend-table
use function cons as extend_table ;
lookup-in-table
function lookup_in_table
( $name , $table , $table_f )
{ return
is_nulll ( $table ) ? $table_f ( $name )
: lookup_in_entry ( $name , car ( $table ),
function ( $name ) use ( $table , $table_f )
{ return
lookup_in_table ( $name ,
cdr ( $table ),
$table_f );
});
}
atom-to-function
function atom_to_action
( $e )
{ return
is_number ( $e )
|| is_eq ( $e , '#t' )
|| is_eq ( $e , '#f' )
|| is_eq ( $e , 'cons' )
|| is_eq ( $e , 'car' )
|| is_eq ( $e , 'cdr' )
|| is_eq ( $e , 'null?' )
|| is_eq ( $e , 'eq?' )
|| is_eq ( $e , 'atom?' )
|| is_eq ( $e , 'zero?' )
|| is_eq ( $e , 'add1?' )
|| is_eq ( $e , 'sub1?' )
|| is_eq ( $e , 'number?' ) ?
'_const'
: '_identifier' ;
}
list-to-action
function list_to_aciton
( $e )
{ return
is_atom ( car ( $e )) ?
is_eq ( car ( $e ), 'quote' ) ? '_quote'
: ( is_eq ( car ( $e ), 'lambda' ) ? '_lambda'
: ( is_eq ( car ( $e ), 'cond' ) ? '_cond'
: '_application' ))
: '_application' ;
}
expression-to-action
function expression_to_action
( $e )
{ return
is_atom ( $e ) ? atom_to_action ( $e )
: list_to_aciton ( $e );
}
value
function value
( $e )
{ return
meaning ( $e , []);
}
meaning
function meaning
( $e , $table )
{ return
expression_to_action ( $e )( $e , $table );
}
*const
function _const
( $e , $table )
{ return
is_number ( $e ) ? $e
: ( is_eq ( $e , '#t' ) ? TRUE
: ( is_eq ( $e , '#f' ) ? FALSE
: build ( 'primitive' , $e )));
}
*quote
function _quote
( $e , $table )
{ return
text_of ( $e );
}
text-of
use function second as text_of ;
*identifier
function _identifier
( $e , $table )
{ return
lookup_in_table ( $e , $table , 'initial_table' );
}
initial-table
function initial_table
( $name )
{ return
car ([]);
}
*lambda
function _lambda
( $e , $table )
{ return
build ( 'non-primitive' , cons ( $table , cdr ( $e )));
}
table-of
use function first as table_of ;
formals-of
use function second as formals_of ;
body-of
use function third as body_of ;
evcon
function evcon
( $lines , $table )
{ return
is_else ( question_of ( car ( $lines ))) ?
meaning ( answer_of ( car ( $lines )), $table )
: ( meaning ( question_of ( car ( $lines )), $table ) ?
meaning ( answer_of ( car ( $lines )), $table )
: evcon ( cdr ( $lines ), $table ));
}
else?
function is_else
( $x )
{ return
is_atom ( $x ) && is_eq ( $x , 'else' );
}
question-of
use function first as question_of ;
answer-of
use function second as answer_of ;
*cond
function _cond
( $e , $table )
{ return
evcon ( cond_lines_of ( $e ), $table );
}
cond-line-of
use function cdr as cond_lines_of ;
*application
function _application
( $e , $table )
{ return
apply ( meaning ( function_of ( $e ), $table ),
evlis ( arguments_of ( $e ), $table ));
}
evlis
function evlis
( $args , $table )
{ return
is_nulll ( $args ) ? []
: cons ( meaning ( car ( $args ), $table ),
evlis ( cdr ( $args ), $table ));
}
function-of
use function car as function_of ;
arguments-of
use function cdr as arguments_of ;
primitive?
function is_primitive
( $l )
{ return
is_eq ( first ( $l ), 'primitive' );
}
non-primitive?
function is_non_primitive
( $l )
{ return
is_eq ( first ( $l ), 'non-primitive' );
}
apply
function apply
( $fun , $vals )
{ return
is_primitive ( $fun ) ?
apply_primitive ( second ( $fun ), $vals )
: ( is_non_primitive ( $fun ) ?
apply_closure ( second ( $fun ), $vals )
: $fun ); // no answer
}
apply-primitive
function apply_primitive
( $name , $vals )
{ return
is_eq ( $name , 'car' ) ? car ( first ( $vals ))
: ( is_eq ( $name , 'cdr' ) ? cdr ( first ( $vals ))
: ( is_eq ( $name , 'cons' ) ? cons ( first ( $vals ), second ( $vals ))
: ( is_eq ( $name , 'null?' ) ? is_nulll ( first ( $vals ))
: ( is_eq ( $name , 'atom?' ) ? _is_atom ( first ( $vals ))
: ( is_eq ( $name , 'eq?' ) ? is_eq ( first ( $vals ), second ( $vals ))
: ( is_eq ( $name , 'zero?' ) ? is_zero ( first ( $vals ))
: ( is_eq ( $name , 'add1' ) ? add1 ( first ( $vals ))
: ( is_eq ( $name , 'sub1' ) ? sub1 ( first ( $vals ))
: ( is_eq ( $name , 'number?' ) ? is_number ( first ( $vals ))
: $name ))))))))); // no answer
}
:atom?
function _is_atom
( $s )
{ return
is_atom ( $s ) ? TRUE
: ( is_nulll ( $s ) ? FALSE
: ( is_eq ( car ( $s ), 'primitive' ) ? TRUE
: ( is_eq ( car ( $s ), 'non-primitive' ) ? TRUE
: FALSE )));
}
apply-closure
function apply_closure
( $closure , $vals )
{ return
meaning ( body_of ( $closure ),
extend_table ( new_entry ( formals_of ( $closure ),
$vals ),
table_of ( $closure )));
}