Retro is a concatenative, stack based language with roots in Forth.
It is designed to be small, easily learned, and easily modified to meet specific needs, it has been developed and refined through continual use by a small community over the last decade.
This blog is written in Retro and has served as my primary means of posting things concerning Retro since 2010. The core code for Corpse is included in the Retro releases and can be freely studied and deployed.
The most recent posts are shown below. You can also view a list of all posts.
2011-12-07
In the comp.lang.forth newsgroup, I saw a post looking for a cleaner way to parse a string into separate fields. The string takes a form like:
"12 Dec 10:14:33 -0.21234"
There is a tab separating the timestamp from the final value. The code posted by Krishna on c.l.f. follows:
variable day
variable month
variable year ( not used )
variable hour
variable mins
variable secs
fvariable offset
: $>u ( c-addr u -- u2 ) 0 0 2swap >number 2drop d>s ;
: $>month ( c-addr u -- u2 ) 2drop 0 ; \ we won't use month field
\ parse next blank delimited token from string; a3 u3 is the token
: parse_token ( a u -- a2 u2 a3 u3)
bl skip 2dup bl scan 2>r r@ - 2r> 2swap ;
: parse-date ( a u -- a2 u2 )
parse_token $>u day !
parse_token $>month month !
\ parse_token $>u year ! ( we don't have year info)
;
: next-time-field ( a u char -- a2 u2 )
scan 2dup 2>r nip - $>u 2r> 1 /string rot ;
: parse-time ( a u -- a2 u2)
bl skip
2dup [char] : next-time-field hour !
2dup [char] : next-time-field mins !
2dup 9 next-time-field secs !
;
: parse-offset ( a u -- a2 u2)
parse_token >float drop offset f! ;
: parse-log-line ( c-addr u -- )
parse-date parse-time parse-offset 2drop ;
Personally I find this to be a bit messy. A quick stab at implementing this in Retro yields:
variables| day month year hour mins secs offset |
: extract ( $c-$$ )
^strings'splitAtChar ^strings'chop ;
: parse ( $- )
32 extract toNumber !day
32 extract keepString !month
': extract toNumber !hour
': extract toNumber !mins
9 extract toNumber !secs
keepString !offset ;
The only significant difference here is that Retro has no standard support for floating point, so I store the offset as a string. Apart from this, it seems to work just fine.