\ generate IDs for tokenizer/token-compiler pairs.
\ based on author initials and date, should usually be unique
\ with no central registry.
( G: make a hopefully-unique ID from 3 initials and date )
: COMPUTE-ID ( S: 1c 2c 3c s m h d m y -- b1 b2 b3 b4 b5 b6)
100 MOD 2* OVER 3 RSHIFT 1 AND OR >R \ yyyyyyym
7 AND 5 LSHIFT OR >R \ mmmddddd
3 LSHIFT OVER 3 RSHIFT OR >R \ hhhhhmmm
7 AND 5 LSHIFT OVER 2/ OR >R \ mmmsssss
1 AND 7 LSHIFT SWAP 31 AND 2 LSHIFT OR
OVER 3 RSHIFT 3 AND OR >R \ s3333322
7 AND 5 LSHIFT SWAP 31 AND OR \ 22211111
R> R> R> R> R> ;
( G: make ID given only programmer's initials )
: MAKE-ID ( S: 1c 2c 3c -- b1 b2 b3 b4 b5 b6 )
TIME&DATE COMPUTE-ID ;
( G: convert 6-byte ID back to initials and date, 9 bytes )
: DECODE-ID ( S: b1 ... b6 -- initials date&time ) \ 9 items
>R >R >R >R >R
DUP 31 AND [CHAR] @ + SWAP \ char1
5 RSHIFT R@ 3 AND 3 LSHIFT OR 31 AND [CHAR] @ + \ char2
R@ 2 RSHIFT 31 AND [CHAR] @ + \ char3
R> 7 RSHIFT 5 LSHIFT R@ 31 AND OR \ ssssss
R> 5 RSHIFT R@ 7 AND 3 LSHIFT OR \ mmmmmm
R> 3 RSHIFT \ hhhhh
R@ 31 AND \ ddddd
R> 5 RSHIFT R@ 1 AND 3 LSHIFT OR \ mmmm
R> 2/ ;
\ a lot of trouble to reduce it from 9 bytes to 6 bytes.
\ or we could go the other way and make it
\ ABC 15:34:09 23 Mar 2004 24 chars but quite readable
\ ABC153409230304 something that looks more like an ID
\ \x81\x81\x81\x81\x81\x81 machine-readable and short
( G: to use inside a <# #> field to read a 2-digit number )
: NEW## ( S: n -- )
0 # # 2DROP ;
( G: Convert a 6-byte ID to a readable form in a buffer. )
: READABLE-ID ( S: b1 ... b6 -- addr len )
DECODE-ID
<# NEW## NEW## NEW## NEW## NEW## NEW## HOLD HOLD HOLD 0 0 #> ;
( G: Store ID as named string, name returns 6 stack items )
: SAVE-ID ( S: "name" 6 items -- )
CREATE HERE 6 CHARS ALLOT 5 CHARS + 6 0 DO
SWAP OVER C! 1 CHARS -
LOOP DROP ;
( G: named ID -> 6 on stack )
: RESTORE-ID ( S: addr -- 6 items )
6 0 DO DUP C@ SWAP CHAR+ LOOP DROP ;