| 
									
										
										
										
											2008-07-02 01:20:01 -04:00
										 |  |  | USING: parser lexer kernel math sequences namespaces assocs summary | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | words splitting math.parser arrays sequences.next mirrors | 
					
						
							| 
									
										
										
										
											2008-01-10 15:47:57 -05:00
										 |  |  | shuffle compiler.units ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: bitfields | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Example: | 
					
						
							|  |  |  | ! BITFIELD: blah short:16 char:8 nothing:5 ; | 
					
						
							|  |  |  | ! defines <blah> blah-short blah-char blah-nothing. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! An efficient bitfield has a sum of 29 bits or less | 
					
						
							|  |  |  | ! so it can fit in a fixnum. | 
					
						
							|  |  |  | ! No class is defined and there is no overflow checking. | 
					
						
							|  |  |  | ! The first field is the most significant. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : >ranges ( slots/sizes -- slots/ranges )
 | 
					
						
							|  |  |  |     ! range is { start length } | 
					
						
							|  |  |  |     reverse 0 swap [ | 
					
						
							|  |  |  |         swap >r tuck >r [ + ] keep r> 2array r> swap
 | 
					
						
							|  |  |  |     ] assoc-map nip reverse ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: safe-bitfields? ! default f; set at parsetime | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: check< number bound ;
 | 
					
						
							|  |  |  | M: check< summary drop "Number exceeds upper bound" ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check< ( num cmp -- num )
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:27 -04:00
										 |  |  |     2dup < [ drop ] [ \ check< boa throw ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : ?check ( length -- )
 | 
					
						
							|  |  |  |     safe-bitfields? get [ 2^ , \ check< , ] [ drop ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : put-together ( lengths -- )
 | 
					
						
							|  |  |  |     ! messy because of bounds checking | 
					
						
							|  |  |  |     dup length 1- [ \ >r , ] times [ 0 swap ] % [ | 
					
						
							|  |  |  |         ?check [ \ bitor , , [ shift r> ] % ] when*
 | 
					
						
							|  |  |  |     ] each-next \ bitor , ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : padding-name? ( string -- ? )
 | 
					
						
							|  |  |  |     [ "10" member? ] all? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : pad ( i name -- )
 | 
					
						
							|  |  |  |     bin> , , \ -nrot , ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : add-padding ( names -- )  | 
					
						
							|  |  |  |     <enum>
 | 
					
						
							|  |  |  |     [ dup padding-name? [ pad ] [ 2drop ] if ] assoc-each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : [constructor] ( names lengths -- quot )
 | 
					
						
							|  |  |  |     [ swap add-padding put-together ] [ ] make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : define-constructor ( classname slots -- )
 | 
					
						
							|  |  |  |     [ keys ] keep values [constructor] | 
					
						
							|  |  |  |     >r in get constructor-word dup save-location r> | 
					
						
							| 
									
										
										
										
											2008-01-10 15:47:57 -05:00
										 |  |  |     define ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : range>accessor ( range -- quot )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         dup first neg , \ shift , | 
					
						
							|  |  |  |         second 2^ 1- , \ bitand , | 
					
						
							|  |  |  |     ] [ ] make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : [accessors] ( lengths -- accessors )
 | 
					
						
							|  |  |  |     [ range>accessor ] map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : clear-range ( range -- num )
 | 
					
						
							| 
									
										
										
										
											2008-03-29 21:36:58 -04:00
										 |  |  |     first2 dupd + [ 2^ 1- ] bi@ bitnot bitor ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : range>setter ( range -- quot )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         \ >r , dup second ?check \ r> , | 
					
						
							|  |  |  |         dup clear-range , | 
					
						
							|  |  |  |         [ bitand >r ] % | 
					
						
							|  |  |  |         first , [ shift r> bitor ] % | 
					
						
							|  |  |  |     ] [ ] make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : [setters] ( lengths -- setters )
 | 
					
						
							|  |  |  |     [ range>setter ] map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : parse-slots ( slotspecs -- slots )
 | 
					
						
							|  |  |  |     [ ":" split1 string>number [ dup length ] unless* ] { } map>assoc ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : define-slots ( prefix names quots -- )
 | 
					
						
							| 
									
										
										
										
											2008-01-09 17:36:30 -05:00
										 |  |  |     >r [ "-" swap 3append create-in ] with map r> | 
					
						
							| 
									
										
										
										
											2008-01-10 15:47:57 -05:00
										 |  |  |     [ define ] 2each ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : define-accessors ( classname slots -- )
 | 
					
						
							|  |  |  |     dup values [accessors] | 
					
						
							|  |  |  |     >r keys r> define-slots ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : define-setters ( classname slots -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-19 20:15:32 -04:00
										 |  |  |     >r "with-" prepend r> | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     dup values [setters] | 
					
						
							|  |  |  |     >r keys r> define-slots ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : filter-pad ( slots -- slots )
 | 
					
						
							| 
									
										
										
										
											2008-04-26 00:17:08 -04:00
										 |  |  |     [ drop padding-name? not ] assoc-filter ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : define-bitfield ( classname slots -- )  | 
					
						
							| 
									
										
										
										
											2008-01-10 15:47:57 -05:00
										 |  |  |     [ | 
					
						
							|  |  |  |         [ define-constructor ] 2keep
 | 
					
						
							|  |  |  |         >ranges filter-pad [ define-setters ] 2keep define-accessors | 
					
						
							|  |  |  |     ] with-compilation-unit ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  | : parse-bitfield ( -- )
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     scan ";" parse-tokens parse-slots define-bitfield ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : BITFIELD: | 
					
						
							|  |  |  |     parse-bitfield ; parsing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : SAFE-BITFIELD: | 
					
						
							|  |  |  |     [ safe-bitfields? on parse-bitfield ] with-scope ; parsing |