270 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Factor
		
	
	
			
		
		
	
	
			270 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Factor
		
	
	
! Copyright (C) 2006 Adam Langley and Chris Double.
 | 
						|
! Adam Langley was the original author of this work.
 | 
						|
!
 | 
						|
! Chris Double modified it to fix bugs and get it working
 | 
						|
! correctly under the latest versions of Factor.
 | 
						|
!
 | 
						|
! See http://factorcode.org/license.txt for BSD license.
 | 
						|
!
 | 
						|
IN: serialize
 | 
						|
USING: namespaces sequences kernel math io math.functions
 | 
						|
io.binary strings classes words sbufs tuples arrays
 | 
						|
vectors byte-arrays bit-arrays quotations hashtables
 | 
						|
assocs help.syntax help.markup float-arrays splitting ;
 | 
						|
 | 
						|
! Variable holding a sequence of objects already serialized
 | 
						|
SYMBOL: serialized
 | 
						|
 | 
						|
: add-object ( obj -- id )
 | 
						|
    #! Add an object to the sequence of already serialized
 | 
						|
    #! objects. Return the id of that object.
 | 
						|
    serialized get [ push ] keep length 1 - ;
 | 
						|
 | 
						|
: object-id ( obj -- id )
 | 
						|
    #! Return the id of an already serialized object 
 | 
						|
    serialized get [ eq? ] curry* find [ drop f ] unless ;
 | 
						|
 | 
						|
USE: prettyprint 
 | 
						|
 | 
						|
! Serialize object
 | 
						|
GENERIC: (serialize) ( obj -- )
 | 
						|
 | 
						|
: serialize-cell 8 >be write ;
 | 
						|
 | 
						|
: deserialize-cell 8 read be> ;
 | 
						|
 | 
						|
: serialize-shared ( obj quot -- )
 | 
						|
    >r dup object-id
 | 
						|
    [ "o" write serialize-cell drop ] r> if* ; inline
 | 
						|
 | 
						|
M: f (serialize) ( obj -- )
 | 
						|
    drop "n" write ;
 | 
						|
 | 
						|
: bytes-needed ( number -- int )
 | 
						|
    log2 8 + 8 /i ; inline
 | 
						|
 | 
						|
M: integer (serialize) ( obj -- )
 | 
						|
    dup 0 = [
 | 
						|
        drop "z" write
 | 
						|
    ] [
 | 
						|
        dup 0 < [ neg "m" ] [ "p" ] if write 
 | 
						|
        dup bytes-needed dup serialize-cell
 | 
						|
        >be write 
 | 
						|
    ] if ;
 | 
						|
 | 
						|
M: float (serialize) ( obj -- )
 | 
						|
    "F" write
 | 
						|
    double>bits serialize-cell ;
 | 
						|
 | 
						|
M: complex (serialize) ( obj -- )
 | 
						|
    "c" write
 | 
						|
    dup real (serialize)
 | 
						|
    imaginary (serialize) ;
 | 
						|
 | 
						|
M: ratio (serialize) ( obj -- )
 | 
						|
    "r" write
 | 
						|
    dup numerator (serialize)
 | 
						|
    denominator (serialize) ;
 | 
						|
 | 
						|
M: string (serialize) ( obj -- )
 | 
						|
    [
 | 
						|
        "s" write
 | 
						|
        dup add-object serialize-cell
 | 
						|
        dup length serialize-cell
 | 
						|
        write 
 | 
						|
    ] serialize-shared ;
 | 
						|
 | 
						|
M: sbuf (serialize) ( obj -- )
 | 
						|
    [
 | 
						|
        "S" write
 | 
						|
        dup add-object serialize-cell
 | 
						|
        dup length serialize-cell
 | 
						|
        >string write 
 | 
						|
    ] serialize-shared ;
 | 
						|
 | 
						|
M: tuple (serialize) ( obj -- )
 | 
						|
    [
 | 
						|
        "T" write
 | 
						|
        dup add-object serialize-cell
 | 
						|
        tuple>array
 | 
						|
        dup length serialize-cell
 | 
						|
        [ (serialize) ] each
 | 
						|
    ] serialize-shared ;
 | 
						|
 | 
						|
: serialize-seq ( seq code -- )
 | 
						|
    [
 | 
						|
        write
 | 
						|
        dup add-object serialize-cell
 | 
						|
        dup length serialize-cell
 | 
						|
        [ (serialize) ] each
 | 
						|
    ] curry serialize-shared ;
 | 
						|
 | 
						|
M: array (serialize) ( obj -- )
 | 
						|
    "a" serialize-seq ;
 | 
						|
 | 
						|
M: vector (serialize) ( obj -- )
 | 
						|
    "v" serialize-seq ;
 | 
						|
 | 
						|
M: byte-array (serialize) ( obj -- )
 | 
						|
    "A" serialize-seq ;
 | 
						|
 | 
						|
M: bit-array (serialize) ( obj -- )
 | 
						|
    "b" serialize-seq ;
 | 
						|
 | 
						|
M: quotation (serialize) ( obj -- )
 | 
						|
    "q" serialize-seq ;
 | 
						|
 | 
						|
M: curry (serialize) ( obj -- )
 | 
						|
    [
 | 
						|
        "C" write
 | 
						|
        dup add-object serialize-cell
 | 
						|
        dup curry-obj (serialize) curry-quot (serialize)
 | 
						|
    ] serialize-shared ;
 | 
						|
 | 
						|
M: float-array (serialize) ( obj -- )
 | 
						|
    [
 | 
						|
        "f" write
 | 
						|
        dup add-object serialize-cell
 | 
						|
        dup length serialize-cell
 | 
						|
        [ double>bits 8 >be write ] each
 | 
						|
    ] serialize-shared ;
 | 
						|
 | 
						|
M: hashtable (serialize) ( obj -- )
 | 
						|
    [
 | 
						|
        "h" write
 | 
						|
        dup add-object serialize-cell
 | 
						|
        >alist (serialize)
 | 
						|
    ] serialize-shared ;
 | 
						|
 | 
						|
M: word (serialize) ( obj -- )
 | 
						|
    "w" write
 | 
						|
    dup word-name (serialize)
 | 
						|
    word-vocabulary (serialize) ;
 | 
						|
 | 
						|
M: wrapper (serialize) ( obj -- )
 | 
						|
    "W" write
 | 
						|
    wrapped (serialize) ;
 | 
						|
 | 
						|
DEFER: (deserialize) ( -- obj )
 | 
						|
 | 
						|
: intern-object ( id obj -- obj )
 | 
						|
    dup rot serialized get set-nth ;
 | 
						|
 | 
						|
: deserialize-false ( -- f )
 | 
						|
    f ;
 | 
						|
 | 
						|
: deserialize-positive-integer ( -- number )
 | 
						|
    deserialize-cell read be> ;
 | 
						|
 | 
						|
: deserialize-negative-integer ( -- number )
 | 
						|
    deserialize-positive-integer neg ;
 | 
						|
 | 
						|
: deserialize-zero ( -- number )
 | 
						|
    0 ;
 | 
						|
 | 
						|
: deserialize-float ( -- float )
 | 
						|
    deserialize-cell bits>double ;
 | 
						|
 | 
						|
: deserialize-ratio ( -- ratio )
 | 
						|
    (deserialize) (deserialize) / ;
 | 
						|
 | 
						|
: deserialize-complex ( -- complex )
 | 
						|
    (deserialize) (deserialize) rect> ;
 | 
						|
 | 
						|
: deserialize-string ( -- string )
 | 
						|
    deserialize-cell deserialize-cell read intern-object ;
 | 
						|
 | 
						|
: deserialize-sbuf ( -- sbuf )
 | 
						|
    deserialize-cell deserialize-cell read >sbuf intern-object ;
 | 
						|
 | 
						|
: deserialize-word ( -- word )
 | 
						|
    (deserialize) dup (deserialize) lookup
 | 
						|
    [ ] [ "Unknown word" throw ] ?if ;
 | 
						|
 | 
						|
: deserialize-wrapper ( -- wrapper )
 | 
						|
    (deserialize) <wrapper> ;
 | 
						|
 | 
						|
: deserialize-seq ( seq -- array )
 | 
						|
    deserialize-cell deserialize-cell
 | 
						|
    [ drop (deserialize) ] roll map-as
 | 
						|
    intern-object ;
 | 
						|
 | 
						|
: deserialize-array ( -- array )
 | 
						|
    { } deserialize-seq ;
 | 
						|
 | 
						|
: deserialize-vector ( -- array )
 | 
						|
    V{ } deserialize-seq ;
 | 
						|
 | 
						|
: deserialize-quotation ( -- array )
 | 
						|
    [ ] deserialize-seq ;
 | 
						|
 | 
						|
: deserialize-byte-array ( -- byte-array )
 | 
						|
    B{ } deserialize-seq ;
 | 
						|
 | 
						|
: deserialize-bit-array ( -- bit-array )
 | 
						|
    ?{ } deserialize-seq ;
 | 
						|
 | 
						|
: deserialize-float-array ( -- float-array )
 | 
						|
    deserialize-cell deserialize-cell
 | 
						|
    8 * read 8 <groups> [ be> bits>double ] F{ } map-as
 | 
						|
    intern-object ;
 | 
						|
 | 
						|
: deserialize-hashtable ( -- hashtable )
 | 
						|
    deserialize-cell (deserialize) >hashtable intern-object ;
 | 
						|
 | 
						|
: deserialize-tuple ( -- array )
 | 
						|
    deserialize-cell
 | 
						|
    deserialize-cell [ drop (deserialize) ] map >tuple
 | 
						|
    intern-object ;
 | 
						|
 | 
						|
: deserialize-curry ( -- curry )
 | 
						|
    deserialize-cell
 | 
						|
    (deserialize) (deserialize) curry
 | 
						|
    intern-object ;
 | 
						|
 | 
						|
: deserialize-unknown ( -- object )
 | 
						|
    deserialize-cell serialized get nth ;
 | 
						|
 | 
						|
: deserialize* ( -- object ? )
 | 
						|
    read1 [
 | 
						|
        H{
 | 
						|
            { CHAR: A deserialize-byte-array }
 | 
						|
            { CHAR: C deserialize-curry }
 | 
						|
            { CHAR: F deserialize-float }
 | 
						|
            { CHAR: S deserialize-sbuf }
 | 
						|
            { CHAR: T deserialize-tuple }
 | 
						|
            { CHAR: W deserialize-wrapper }
 | 
						|
            { CHAR: a deserialize-array }
 | 
						|
            { CHAR: b deserialize-bit-array }
 | 
						|
            { CHAR: c deserialize-complex }
 | 
						|
            { CHAR: f deserialize-float-array }
 | 
						|
            { CHAR: h deserialize-hashtable }
 | 
						|
            { CHAR: m deserialize-negative-integer }
 | 
						|
            { CHAR: n deserialize-false }
 | 
						|
            { CHAR: o deserialize-unknown }
 | 
						|
            { CHAR: p deserialize-positive-integer }
 | 
						|
            { CHAR: q deserialize-quotation }
 | 
						|
            { CHAR: r deserialize-ratio }
 | 
						|
            { CHAR: s deserialize-string }
 | 
						|
            { CHAR: v deserialize-vector }
 | 
						|
            { CHAR: w deserialize-word }
 | 
						|
            { CHAR: z deserialize-zero }
 | 
						|
        } at dup [ "Unknown typecode" throw ] unless execute t
 | 
						|
    ] [
 | 
						|
        f f
 | 
						|
    ] if* ;
 | 
						|
 | 
						|
: (deserialize) ( -- obj )
 | 
						|
    deserialize* [ "End of stream" throw ] unless ;
 | 
						|
 | 
						|
: with-serialized ( quot -- )
 | 
						|
    V{ } clone serialized rot with-variable ; inline
 | 
						|
 | 
						|
: deserialize-sequence ( -- seq )
 | 
						|
    [ [ deserialize* ] [ ] [ drop ] unfold ] with-serialized ;
 | 
						|
 | 
						|
: deserialize ( -- obj )
 | 
						|
    [ (deserialize) ] with-serialized ;
 | 
						|
 | 
						|
: serialize ( obj -- )
 | 
						|
    [ (serialize) ] with-serialized ; |