2021-11-03 19:21:50 +03:00
#lang racket
( require rackunit )
2021-11-16 22:07:10 +03:00
;; This interpreter converts the implicit stack of continuations from (j)
;; (represented by every continuation closure other than empty-k receiving
;; the current continuation as its last argument) into an explicit stack.
;;
;; It removes the continuation variable from all continuation closures
;; and adds a `push-k` operation to push a continuation closure onto the stack.
;;
;; The apply-k function now functions explicitly as a stack-popping operation.
2021-11-03 19:21:50 +03:00
( define stack ' ( ) )
( define ( push-k k )
( set! stack ( cons k stack ) ) )
( define ( nock-noun subject formula gates err-k trace )
( begin
( push-k empty-k )
( nock-noun-cps subject formula gates err-k trace ) ) )
( define ( nock-noun-cps subject formula gates err-k trace )
( match formula
( [ cons ( cons ( var b ) ( var c ) ) ( var d ) ]
( begin
( push-k ( nock-cons-k-1 subject d gates err-k trace ) )
( nock-noun-cps subject ( cons b c ) gates err-k trace ) ) )
( [ cons 0 ( var b ) ]
( nock-tree-find subject b err-k trace ) )
( [ cons 1 ( var b ) ]
( apply-k b ) )
( [ cons 2 ( cons ( var b ) ( var c ) ) ]
( begin
( push-k ( nock-2-k-1 subject c gates err-k trace ) )
( nock-noun-cps subject b gates err-k trace ) ) )
( [ cons 3 ( var b ) ]
( begin
( push-k nock-3-k )
( nock-noun-cps subject b gates err-k trace ) ) )
( [ cons 4 ( var b ) ]
( begin
( push-k nock-4-k )
( nock-noun-cps subject b gates err-k trace ) ) )
( [ cons 5 ( cons ( var b ) ( var c ) ) ]
( begin
( push-k ( nock-5-k-1 subject c gates err-k trace ) )
( nock-noun-cps subject b gates err-k trace ) ) )
( [ cons 6 ( cons ( var b ) ( cons ( var c ) ( var d ) ) ) ]
( begin
( push-k ( nock-6-k subject c d gates err-k trace ) )
( nock-noun-cps subject b gates err-k trace ) ) )
( [ cons 7 ( cons ( var b ) ( var c ) ) ]
( begin
( push-k ( nock-7-k c gates err-k trace ) )
( nock-noun-cps subject b gates err-k trace ) ) )
( [ cons 8 ( cons ( var b ) ( var c ) ) ]
( begin
( push-k ( nock-8-k subject c gates err-k trace ) )
( nock-noun-cps subject b gates err-k trace ) ) )
( [ cons 9 ( cons ( var b ) ( var c ) ) ]
( begin
( push-k ( nock-9-k-1 b gates err-k trace ) )
( nock-noun-cps subject c gates err-k trace ) ) )
( [ cons 10 ( cons ( cons ( var b ) ( var c ) ) ( var d ) ) ]
( begin
( push-k ( nock-10-k-1 subject d b gates err-k trace ) )
( nock-noun-cps subject c gates err-k trace ) ) )
( [ cons 11 ( cons ( cons ( var b ) ( var c ) ) ( var d ) ) ]
( begin
( push-k ( nock-11-k subject b d gates err-k trace ) )
( nock-noun-cps subject c gates err-k trace ) ) )
( [ cons 11 ( cons ( var b ) ( var c ) ) ]
( nock-noun-cps subject c gates err-k trace ) )
( [ cons 12 ( cons ( var ref ) ( var path ) ) ]
( begin
( push-k ( nock-12-k-1 subject path gates err-k trace ) )
( nock-noun-cps subject ref gates err-k trace ) ) ) ) )
( define ( reverse-address address ) ( reverse-address-acc address 1 ) )
( define ( reverse-address-acc address reversed )
( if ( = address 1 )
( apply-k reversed )
( reverse-address-acc ( arithmetic-shift address -1 ) ( bitwise-ior ( arithmetic-shift reversed 1 ) ( bitwise-and address 1 ) ) ) ) )
( define ( nock-tree-find-reversed tree reversed )
( if ( = reversed 1 )
( apply-k tree )
( if ( even? reversed )
( nock-tree-find-reversed ( car tree ) ( arithmetic-shift reversed -1 ) )
( nock-tree-find-reversed ( cdr tree ) ( arithmetic-shift reversed -1 ) ) ) ) )
( define ( nock-tree-find tree address err-k trace )
( if ( = address 0 )
( apply-err-k err-k ( cons 2 trace ) )
( begin
( push-k ( nock-tree-find-k tree ) )
( reverse-address address ) ) ) )
( define ( nock-tree-edit-reversed subtree reversed tree )
( if ( = reversed 1 )
( apply-k subtree )
( if ( even? reversed )
( begin
( push-k ( nock-tree-edit-car-k tree ) )
( nock-tree-edit-reversed subtree ( arithmetic-shift reversed -1 ) ( car tree ) ) )
( begin
( push-k ( nock-tree-edit-cdr-k tree ) )
( nock-tree-edit-reversed subtree ( arithmetic-shift reversed -1 ) ( cdr tree ) ) ) ) ) )
; # operator in nock spec: tree editing
( define ( nock-tree-edit subtree address tree err-k trace )
( if ( = address 0 )
( apply-err-k err-k ( cons 2 trace ) )
( begin
( push-k ( nock-tree-edit-k subtree tree ) )
( reverse-address address ) ) ) )
( define empty-k ( list ' empty-k ) )
( define ( nock-cons-k-1 subject d gates err-k trace ) ( list ' nock-cons-k-2 subject d gates err-k trace ) )
( define ( nock-cons-k-2 u ) ( list ' nock-cons-k-2 u ) )
( define ( nock-2-k-1 subject c gates err-k trace ) ( list ' nock-2-k-1 subject c gates err-k trace ) )
( define ( nock-2-k-2 u gates err-k trace ) ( list ' nock-2-k-2 u gates err-k trace ) )
( define nock-3-k ( list ' nock-3-k ) )
( define nock-4-k ( list ' nock-4-k ) )
( define ( nock-5-k-1 subject c gates err-k trace ) ( list ' nock-5-k-1 subject c gates err-k trace ) )
( define ( nock-5-k-2 u ) ( list ' nock-5-k-2 u ) )
( define ( nock-6-k subject c d gates err-k trace ) ( list ' nock-6-k subject c d gates err-k trace ) )
( define ( nock-7-k c gates err-k trace ) ( list ' nock-7-k c gates err-k trace ) )
( define ( nock-8-k subject c gates err-k trace ) ( list ' nock-8-k subject c gates err-k trace ) )
( define ( nock-9-k-1 b gates err-k trace ) ( list ' nock-9-k-1 b gates err-k trace ) )
( define ( nock-9-k-2 u gates err-k trace ) ( list ' nock-9-k-2 u gates err-k trace ) )
( define ( nock-10-k-1 subject d b gates err-k trace ) ( list ' nock-10-k-1 subject d b gates err-k trace ) )
( define ( nock-10-k-2 u b err-k trace ) ( list ' nock-10-k-2 u b err-k trace ) )
( define ( nock-11-k subject b d gates err-k trace ) ( list ' nock-11-k subject b d gates err-k trace ) )
( define ( nock-12-k-1 subject path gates err-k trace ) ( list ' nock-12-k-1 subject path gates err-k trace ) )
( define ( nock-12-k-2 gates err-k trace u ) ( list ' nock-12-k-2 gates err-k trace u ) )
( define ( nock-12-k-3 u v outer-err-k outer-trace ) ( list ' nock-12-k u v outer-err-k outer-trace ) )
( define ( nock-tree-find-k tree ) ( list ' nock-tree-find-k tree ) )
( define ( nock-tree-edit-car-k tree ) ( list ' nock-tree-edit-car-k tree ) )
( define ( nock-tree-edit-cdr-k tree ) ( list ' nock-tree-edit-cdr-k tree ) )
( define ( nock-tree-edit-k subtree tree ) ( list ' nock-tree-edit-k subtree tree ) )
( define ( apply-k x )
( let
[ ( k ( car stack ) ) ]
( begin
( set! stack ( cdr stack ) )
( match k
( [ list ' empty-k ] x )
( [ list ' nock-cons-k-1 ( var subject ) ( var d ) ( var gates ) ( var err-k ) ( var trace ) ]
( begin
( push-k ( nock-cons-k-2 x ) )
( nock-noun-cps subject d gates err-k trace ) ) )
( [ list ' nock-cons-k-2 ( var u ) ( var k^ ) ]
( apply-k ( cons u x ) ) )
( [ list ' nock-2-k-1 ( var subject ) ( var c ) ( var gates ) ( var err-k ) ( var trace ) ]
( begin
( push-k ( nock-2-k-2 x gates err-k trace ) )
( nock-noun-cps subject c gates err-k trace ) ) )
( [ list ' nock-2-k-2 ( var u ) ( var gates ) ( var err-k ) ( var trace ) ]
( nock-noun-cps u x gates err-k trace ) )
( [ list ' nock-3-k ]
( if ( pair? x ) ( apply-k 0 ) ( apply-k 1 ) ) )
( [ list ' nock-4-k ]
( apply-k ( + 1 x ) ) )
( [ list ' nock-5-k-1 ( var subject ) ( var c ) ( var gates ) ( var err-k ) ( var trace ) ]
( begin
( push-k ( nock-5-k-2 x ) )
( nock-noun-cps subject c gates err-k trace ) ) )
( [ list ' nock-5-k-2 ( var u ) ]
( if ( eqv? u x ) ( apply-k 0 ) ( apply-k 1 ) ) )
( [ list ' nock-6-k ( var subject ) ( var c ) ( var d ) ( var gates ) ( var err-k ) ( var trace ) ]
( if ( = 0 x )
( nock-noun-cps subject c gates err-k trace )
( if ( = 1 x )
( nock-noun-cps subject d gates err-k trace )
( apply-err-k err-k ( cons 2 trace ) ) ) ) )
( [ list ' nock-7-k ( var c ) ( var gates ) ( var err-k ) ( var trace ) ]
( nock-noun-cps x c gates err-k trace ) )
( [ list ' nock-8-k ( var subject ) ( var c ) ( var gates ) ( var err-k ) ( var trace ) ]
( nock-noun-cps ( cons x subject ) c gates err-k trace ) )
( [ list ' nock-9-k-1 ( var b ) ( var gates ) ( var err-k ) ( var trace ) ]
( begin
( push-k ( nock-9-k-2 x gates err-k trace ) )
( nock-tree-find x b err-k trace ) ) )
( [ list ' nock-9-k-2 ( var u ) ( var gates ) ( var err-k ) ( var trace ) ]
( nock-noun-cps u x gates err-k trace ) )
( [ list ' nock-10-k-1 ( var subject ) ( var d ) ( var b ) ( var gates ) ( var err-k ) ( var trace ) ]
( begin
( push-k ( nock-10-k-2 x b err-k trace ) )
( nock-noun-cps subject d gates err-k trace ) ) )
( [ list ' nock-10-k-2 ( var u ) ( var b ) ( var err-k ) ( var trace ) ]
( nock-tree-edit u b x err-k trace ) )
( [ list ' nock-11-k ( var subject ) ( var b ) ( var d ) ( var gates ) ( var err-k ) ( var trace ) ]
( if ( member b ( list ( tas " hunk " ) ( tas " hand " ) ( tas " lose " ) ( tas " mean " ) ( tas " spot " ) ) )
( nock-noun-cps subject d gates err-k ( cons ( cons b x ) trace ) )
( nock-noun-cps subject d gates err-k trace ) ) )
( [ list ' nock-12-k-1 ( var subject ) ( var path ) ( var gates ) ( var err-k ) ( var trace ) ]
( begin
( push-k ( nock-12-k-2 gates err-k trace x ) )
( nock-noun-cps subject path gates err-k trace ) ) )
( [ list ' nock-12-k-2 ( var gates ) ( var err-k ) ( var trace ) ( var u ) ]
( let*
[ ( gate ( car ( car gates ) ) )
( outer-err-k err-k )
( err-k ( car ( cdr ( car gates ) ) ) )
( outer-trace trace )
( trace ( cdr ( cdr ( car gates ) ) ) )
( gates ( cdr gates ) )
( core ( cons ( car gate ) ( cons ( cons u x ) ( cdr ( cdr gate ) ) ) ) ) ]
( begin
( push-k ( nock-12-k-3 u x outer-err-k outer-trace ) )
( nock-noun-cps core ( car core ) gates err-k trace ) ) ) )
( [ list ' nock-12-k-3 ( var u ) ( var v ) ( var outer-err-k ) ( var outer-trace ) ]
( if ( equal? 0 x )
; ~
( outer-err-k ( cons 1 ( cdr v ) ) )
( if ( equal? 0 ( car x ) )
( outer-err-k ( cons 2 ( cons ( cons ( tas " hunk " ) ( cons u v ) ) outer-trace ) ) )
( apply-k ( cdr ( cdr x ) ) ) ) ) )
( [ list ' nock-tree-edit-car-k ( var tree ) ]
( apply-k ( cons x ( cdr tree ) ) ) )
( [ list ' nock-tree-edit-cdr-k ( var tree ) ]
( apply-k ( cons ( car tree ) x ) ) )
( [ list ' nock-tree-edit-k ( var subtree ) ( var tree ) ]
( nock-tree-edit-reversed subtree x tree ) )
( [ list ' nock-tree-find-k ( var tree ) ]
( nock-tree-find-reversed tree x ) )
( ( var k^ ) #:when ( procedure? k^ ) ( k^ x ) ) ) ) ) )
( define ( apply-err-k err-k err ) ( err-k err ) )
;; macro for %tas literals:
;; converts input string into a numeric literal of that string represented as a %tas, i.e. an
;; atom with the ascii bytes of the string in sequence (first->LSB, last->MSB)
( define-syntax ( tas str )
( quasisyntax
( unsyntax
( foldr
( lambda ( char atom ) ( bitwise-ior ( bitwise-and #xFF ( char->integer char ) ) ( arithmetic-shift atom 8 ) ) )
0
( string->list ( car ( cdr ( syntax->datum str ) ) ) ) ) ) ) )
( define nock-here 1 )
( define ( nock-car address ) ( * address 2 ) )
( define ( nock-cdr address ) ( + 1 ( * address 2 ) ) )
( define ( get-0 x ) ( cons 0 x ) )
( define ( literal-1 x ) ( cons 1 x ) )
( define ( eval-2 x y ) ( cons 2 ( cons x y ) ) )
( define ( cell?-3 x ) ( cons 3 x ) )
( define ( inc-4 x ) ( cons 4 x ) )
( define ( =-5 x y ) ( cons 5 ( cons x y ) ) )
( define ( if-6 x y z ) ( cons 6 ( cons x ( cons y z ) ) ) )
( define ( compose-7 x y ) ( cons 7 ( cons x y ) ) )
( define ( declare-8 x y ) ( cons 8 ( cons x y ) ) )
( define ( call-9 x y ) ( cons 9 ( cons x y ) ) )
( define ( update-10 x y z ) ( cons 10 ( cons ( cons x y ) z ) ) )
( define ( hint-11 x y ) ( cons 11 ( cons x y ) ) )
( define lootru 0 )
( define loofal 1 )
( define test-tree ( cons ( cons 4 5 ) 3 ) )
( define decrement-4-core
( cons
( if-6 ( =-5 ( get-0 ( nock-car ( nock-cdr nock-here ) ) ) ( inc-4 ( get-0 ( nock-cdr ( nock-cdr nock-here ) ) ) ) )
( get-0 ( nock-cdr ( nock-cdr nock-here ) ) )
( call-9 ( nock-car nock-here ) ( update-10 ( nock-cdr ( nock-cdr nock-here ) ) ( inc-4 ( get-0 ( nock-cdr ( nock-cdr nock-here ) ) ) ) ( get-0 nock-here ) ) ) )
( cons 4 0 ) ) )
( define ( nock-test subject formula ) ( nock-noun subject formula ' ( ) test-err-k ' ( ) ) )
( define ( test-err-k err )
( printf " Error: ~v " err )
( error ' nock-err ) )
( check-equal? ( nock-test test-tree ( get-0 nock-here ) ) test-tree " tree address 1 " )
( check-equal? ( nock-test test-tree ( get-0 ( nock-car nock-here ) ) ) ( car test-tree ) " tree address 2 " )
( check-equal? ( nock-test test-tree ( get-0 ( nock-cdr nock-here ) ) ) ( cdr test-tree ) " tree address 3 " )
( check-equal? ( nock-test test-tree ( get-0 ( nock-car ( nock-car nock-here ) ) ) ) ( car ( car test-tree ) ) " tree address 4 " )
( check-equal? ( nock-test test-tree ( get-0 ( nock-cdr ( nock-car nock-here ) ) ) ) ( cdr ( car test-tree ) ) " tree address 5 " )
( check-equal? ( nock-test 0 ( literal-1 test-tree ) ) test-tree " literal " )
( check-equal? ( nock-test 0 ( eval-2 ( literal-1 test-tree ) ( literal-1 ( get-0 2 ) ) ) ) ( car test-tree ) " eval " )
( check-equal? ( nock-test test-tree ( cell?-3 ( get-0 1 ) ) ) lootru " test cell true " )
( check-equal? ( nock-test test-tree ( cell?-3 ( get-0 3 ) ) ) loofal " test cell false " )
( check-equal? ( nock-test 0 ( inc-4 ( literal-1 0 ) ) ) 1 " increment " )
( check-equal? ( nock-test test-tree ( =-5 ( literal-1 test-tree ) ( get-0 1 ) ) ) lootru " test equals true " )
( check-equal? ( nock-test test-tree ( =-5 ( literal-1 test-tree ) ( get-0 2 ) ) ) loofal " test equals false " )
( check-equal? ( nock-test test-tree ( if-6 ( literal-1 lootru ) ( literal-1 5 ) ( get-0 100 ) ) ) 5 " test if tru " )
( check-equal? ( nock-test test-tree ( if-6 ( literal-1 loofal ) ( get-0 100 ) ( literal-1 5 ) ) ) 5 " test if false " )
( check-equal? ( nock-test 0 ( compose-7 ( literal-1 test-tree ) ( get-0 2 ) ) ) ( car test-tree ) " test compose " )
( check-equal? ( nock-test 0 ( declare-8 ( literal-1 test-tree ) ( get-0 2 ) ) ) test-tree " test declare " )
( check-equal? ( nock-test 0 ( call-9 ( nock-car nock-here ) ( literal-1 decrement-4-core ) ) ) 3 " test call " )
( check-equal? ( nock-test 0 ( update-10 ( nock-cdr nock-here ) ( literal-1 ( cons 6 7 ) ) ( literal-1 test-tree ) ) ) ( cons ( cons 4 5 ) ( cons 6 7 ) ) " test update " )
( check-equal? ( nock-test 0 ( call-9 ( nock-car nock-here ) ( update-10 ( nock-car ( nock-cdr nock-here ) ) ( literal-1 8 ) ( literal-1 decrement-4-core ) ) ) ) 7 " test slam i.e. update sample and call " )
; test 11 static and dynamic