198 lines
5.8 KiB
Scheme
198 lines
5.8 KiB
Scheme
|
;;;; symbol-table-access.scm -*- Scheme -*-
|
||
|
;;;; Kon Lovett, Jul '18
|
||
|
|
||
|
#>
|
||
|
/*special stuff from the runtime & scheme API*/
|
||
|
#define ROOT_SYMBOL_TABLE_NAME "."
|
||
|
|
||
|
#define raw_symbol_table_size( stable ) ((stable)->size)
|
||
|
#define raw_symbol_table_chain( stable, i ) ((stable)->table[ (i) ])
|
||
|
|
||
|
#define raw_bucket_symbol( bucket ) (C_block_item( (bucket), 0 ))
|
||
|
#define raw_bucket_link( bucket ) (C_block_item( (bucket), 1 ))
|
||
|
|
||
|
static C_regparm C_SYMBOL_TABLE *
|
||
|
find_root_symbol_table()
|
||
|
{
|
||
|
return C_find_symbol_table( ROOT_SYMBOL_TABLE_NAME );
|
||
|
}
|
||
|
|
||
|
static C_regparm C_SYMBOL_TABLE *
|
||
|
remember_root_symbol_table()
|
||
|
{
|
||
|
static C_SYMBOL_TABLE *root_symbol_table = NULL;
|
||
|
if(!root_symbol_table) {
|
||
|
root_symbol_table = find_root_symbol_table();
|
||
|
}
|
||
|
|
||
|
return root_symbol_table;
|
||
|
}
|
||
|
|
||
|
/* FIXME root_symbol_table re-allocated?
|
||
|
#define use_root_symbol_table find_root_symbol_table
|
||
|
*/
|
||
|
#define use_root_symbol_table remember_root_symbol_table
|
||
|
<#
|
||
|
|
||
|
(module symbol-table-access
|
||
|
|
||
|
(;export
|
||
|
;
|
||
|
#; ;UNUSED
|
||
|
cursor-current
|
||
|
#; ;UNUSED
|
||
|
cursor-first
|
||
|
#; ;UNUSED
|
||
|
cursor-next
|
||
|
;
|
||
|
cursor-foldl)
|
||
|
|
||
|
(import scheme)
|
||
|
(import (chicken base))
|
||
|
(import (chicken fixnum))
|
||
|
(import (chicken foreign))
|
||
|
(import (chicken type))
|
||
|
(import (chicken syntax))
|
||
|
|
||
|
;internal
|
||
|
(define-inline (%immediate? obj) (not (##core#inline "C_blockp" obj)))
|
||
|
|
||
|
(define-type symbol-table-cursor (pair fixnum list))
|
||
|
(define-type symbol-table-cursor* (or false symbol-table-cursor))
|
||
|
|
||
|
#; ;UNUSED
|
||
|
(: cursor-current (symbol-table-cursor* --> (or false symbol)))
|
||
|
#; ;UNUSED
|
||
|
(: cursor-first (--> symbol-table-cursor*))
|
||
|
#; ;UNUSED
|
||
|
(: cursor-next (symbol-table-cursor* --> symbol-table-cursor*))
|
||
|
|
||
|
(: cursor-foldl (('a symbol -> 'a) 'a #!optional symbol-table-cursor --> 'a))
|
||
|
|
||
|
#; ;closer than fold ;=)
|
||
|
(: cursor-unfold (('a -> booleam) ('a symbol -> 'a) 'a #!optional symbol-table-cursor --> 'a))
|
||
|
|
||
|
;;
|
||
|
|
||
|
(: root-symbol-table-size (-> fixnum))
|
||
|
(: root-symbol-table-element (fixnum -> pair))
|
||
|
(: bucket-symbol (pair -> symbol))
|
||
|
(: bucket-link (pair -> list))
|
||
|
|
||
|
(: bucket-last? (list --> boolean))
|
||
|
#; ;UNUSED
|
||
|
(: bucket-symbol-ref (list -> (or false symbol)))
|
||
|
#; ;UNUSED
|
||
|
(: bucket-link-ref (list -> (or false list)))
|
||
|
(: make-symbol-table-cursor (* * -> symbol-table-cursor))
|
||
|
(: cursor-active? (* -> boolean))
|
||
|
(: symbol-table-cursor? (* -> boolean))
|
||
|
(: cursor-index (symbol-table-cursor -> *))
|
||
|
#; ;UNUSED
|
||
|
(: set-cursor-index! (symbol-table-cursor * -> void))
|
||
|
(: cursor-bucket (symbol-table-cursor -> *))
|
||
|
#; ;UNUSED
|
||
|
(: set-cursor-bucket! (symbol-table-cursor * -> void))
|
||
|
(: symbol-table-cursor (-> symbol-table-cursor))
|
||
|
|
||
|
;; Symbol Table
|
||
|
|
||
|
(define root-symbol-table-size
|
||
|
(foreign-lambda* int ()
|
||
|
"return( raw_symbol_table_size( use_root_symbol_table() ) );") )
|
||
|
|
||
|
(define root-symbol-table-element
|
||
|
(foreign-lambda* scheme-object ((unsigned-integer i))
|
||
|
"return( raw_symbol_table_chain( use_root_symbol_table(), i ) );") )
|
||
|
|
||
|
(define bucket-symbol
|
||
|
(foreign-lambda* scheme-object ((scheme-object bkt))
|
||
|
"return( raw_bucket_symbol( bkt ) );"))
|
||
|
|
||
|
(define bucket-link
|
||
|
(foreign-lambda* scheme-object ((scheme-object bkt))
|
||
|
"return( raw_bucket_link( bkt ) );"))
|
||
|
|
||
|
(define-inline (bucket-last? bkt) (null? bkt))
|
||
|
|
||
|
#; ;UNUSED
|
||
|
(define-inline (bucket-symbol-ref bkt)
|
||
|
(and (not (bucket-last? bkt))
|
||
|
(bucket-symbol bkt) ) )
|
||
|
|
||
|
#; ;UNUSED
|
||
|
(define-inline (bucket-link-ref bkt)
|
||
|
(and (not (bucket-last? bkt))
|
||
|
(bucket-link bkt)) )
|
||
|
|
||
|
(define-inline (bucket-active? bkt)
|
||
|
(and bkt
|
||
|
(not (bucket-last? bkt))
|
||
|
(not (%immediate? (bucket-symbol bkt)))) )
|
||
|
|
||
|
;; Symbol Table Cursor
|
||
|
|
||
|
(define-inline (make-symbol-table-cursor a b) (cons a b))
|
||
|
(define-inline (cursor-active? x) (pair? x))
|
||
|
(define-inline (cursor-index x) (car x))
|
||
|
#; ;UNUSED
|
||
|
(define-inline (set-cursor-index! a b) (set-car! a b))
|
||
|
(define-inline (cursor-bucket x) (cdr x))
|
||
|
#; ;UNUSED
|
||
|
(define-inline (set-cursor-bucket! a b) (set-cdr! a b))
|
||
|
|
||
|
(define-inline (symbol-table-cursor) (make-symbol-table-cursor -1 '()))
|
||
|
|
||
|
(define-inline (symbol-table-cursor? obj) (or (not obj) (cursor-active? obj)))
|
||
|
|
||
|
;;
|
||
|
|
||
|
#; ;UNUSED
|
||
|
(define (cursor-current cursor)
|
||
|
(and (cursor-active? cursor)
|
||
|
(bucket-symbol-ref (cursor-bucket cursor)) ) )
|
||
|
|
||
|
#; ;UNUSED
|
||
|
(define (cursor-first) (cursor-next (symbol-table-cursor)))
|
||
|
|
||
|
#; ;UNUSED
|
||
|
(define (cursor-next cursor)
|
||
|
(and (cursor-active? cursor)
|
||
|
;cache table size since assuming no shape-shifting
|
||
|
(let ((siz (root-symbol-table-size)))
|
||
|
;starting from the "next" bucket!
|
||
|
(let loop ((bkt (bucket-link-ref (cursor-bucket cursor)))
|
||
|
(idx (cursor-index cursor)) )
|
||
|
;gotta bucket ?
|
||
|
(if (bucket-active? bkt)
|
||
|
;then found something => where we are
|
||
|
(make-symbol-table-cursor idx bkt)
|
||
|
;else try next hash-root slot
|
||
|
(let ((idx (fx+ idx 1)))
|
||
|
(and ;more to go ?
|
||
|
(fx< idx siz)
|
||
|
;this slot
|
||
|
(loop (root-symbol-table-element idx) idx) ) ) ) ) ) ) )
|
||
|
|
||
|
;;
|
||
|
|
||
|
(define (cursor-foldl g seed #!optional (cursor (symbol-table-cursor)))
|
||
|
;cache table size since assuming no shape-shifting
|
||
|
(let ((siz (root-symbol-table-size)))
|
||
|
(if (or (fx= 0 siz) (not (cursor-active? cursor))) seed
|
||
|
;starting at the current bucket!
|
||
|
(let loop ((bkt (cursor-bucket cursor))
|
||
|
(idx (cursor-index cursor))
|
||
|
(seed seed) )
|
||
|
(if (bucket-active? bkt)
|
||
|
;then continue to walk the bucket chain
|
||
|
(loop (bucket-link bkt) idx (g seed (bucket-symbol bkt)))
|
||
|
;else walk the next bucket chain
|
||
|
(let ((idx (fx+ idx 1)))
|
||
|
;exit when no more buckets
|
||
|
(if (fx>= idx siz) seed
|
||
|
;else continue w/ next bucket chain
|
||
|
(loop (root-symbol-table-element idx) idx seed) ) ) ) ) ) ) )
|
||
|
|
||
|
) ;module symbol-table-access
|