uxn-gfx/arg.tal

83 lines
2.5 KiB
Tal

( arg.tal )
( )
( by d_m )
( )
( by calling arg/init during the reset vector )
( the author can skip all the details of reading )
( and detecting command-line arguments. )
( )
( instead they can "wait" until the arguments )
( are all read before accessing the argument )
( count and argument string values in a more )
( ergonomic way. )
( )
( when using arg/init authors provide two things: )
( - callback to run when all args are read )
( - stdin vector to use once args are read )
( )
( the callback can load arg/count to see how many )
( arguments were given, and run arg/read to get )
( the address of a particular argument as a )
( null-terminated string. )
@arg ( arg namespace )
( initialize the arg library. )
( call this during the reset vector. )
&init ( callback* stdin* -> )
;arg/stdin STA2
;arg/callback STA2
#00 ;arg/count STA
;arg/buffer ;arg/pos STA2
;arg/on-read #10 DEO2
#17 DEI #00 EQU ?&no-args JMP2r
&no-args !arg/complete
( read the nth argument, starting with n=0. )
( call this during the callback. )
&read ( n^ -> s* )
LITr 00 STH SUBr
;arg/buffer ( buf* [-n^] )
&loop STHkr ?&ok POPr JMP2r ( pos* [-i^] )
&ok LDAk ?&notnull INCr ( pos* [-i+1^] )
&notnull INC2 !&loop ( pos+1* [-j] )
( internal: console vector to use during argument parsing )
&on-read ( -> BRK )
#17 DEI
DUP #02 NEQ ?&b POP arg/store BRK ( 2: arg data )
&b DUP #03 NEQ ?&c POP arg/next BRK ( 3: next arg )
&c DUP #04 NEQ ?&d POP arg/finish BRK ( 4: finished with args )
&d #0000 DIV BRK ( 0/1 are unexpected, error )
( internal: read a character )
&store ( -> )
#12 DEI !arg/save
( internal: finish an argument and store null )
&next ( -> )
;arg/count LDAk INC ROT ROT STA
#00 ( fall-through to save )
( internal: store character c in the buffer and update position )
&save ( c^ -> )
LIT2r :arg/pos LDA2kr STH2r ( c^ addr* [pos*] )
STA LDA2kr INC2r SWP2r ( [addr1* pos*] ; addr<-c )
STA2r JMP2r ( ; pos<-addr+1 )
( internal: called when last argument is complete )
&finish ( -> )
arg/next ( fall-through to complete )
( internal: called when arg parsing is done )
&complete ( -> )
;arg/stdin LDA2 #10 DEO2
;arg/callback LDA2 JMP2
( some handy variables )
&stdin $2 ( f: -> BRK )
&callback $2 ( f: -> )
&count $1 ( number of args given )
&pos $2 ( position in buffer )
&buffer $200 ( argument buffer )