62 lines
2.4 KiB
Forth
62 lines
2.4 KiB
Forth
create data 20000 allot \ create a 20K buffer
|
|
variable fileid \ create a variable `fileid`
|
|
s" data/03.txt" r/o open-file \ open data file
|
|
drop \ drop the top value from the stack, it's just a status code and we aren't going to bother handling errors
|
|
fileid ! \ save the file id to the variable
|
|
|
|
variable data-len
|
|
data 20000 fileid @ read-file
|
|
drop
|
|
data-len !
|
|
|
|
: data-str ( -- addr u )
|
|
data data-len @ ;
|
|
|
|
: chop-prefix ( addr u u2 -- addr2 u2 )
|
|
\ chop the first `u2` bytes off the beginning of the string at `addr u`
|
|
tuck \ duplicate `u2` and store it "under" the length of the string
|
|
- \ subtract `u2` from the length of the string
|
|
-rot \ stick the new string length underneath the start pointer
|
|
+ \ increment the start pointer by `u2`
|
|
swap \ put them back in the right order
|
|
;
|
|
|
|
require regexp.fs
|
|
|
|
: mul-instr ( addr u -- flag )
|
|
(( =" mul(" \( {++ \d ++} \) ` , \( {++ \d ++} \) ` ) )) ;
|
|
|
|
|
|
: get-product ( addr u -- u2 )
|
|
mul-instr \ match the string from `addr u` against the above regex
|
|
if \ if the regex matches, then:
|
|
\1 s>number drop \ convert the first capture from string to number, drop the status code (we already know it will succeed)
|
|
\2 s>number drop \ convert the second capture from string to number, drop the status code
|
|
* \ multiply, and leave the answer on the stack
|
|
else
|
|
0 \ otherwise, leave 0 on the stack
|
|
then
|
|
;
|
|
|
|
variable result
|
|
0 result !
|
|
|
|
: sum-mul-instrs ( addr u -- u2 )
|
|
begin \ start looping
|
|
s" mul(" search \ search for the string "mul("
|
|
if \ if successful, top 2 values on stack will be start address of "mul(" and remainder of original string
|
|
2dup \ duplicate address and remaining length of string
|
|
get-product \ pass those to get-product above
|
|
result @ + \ load `result` and add to product
|
|
result ! \ store this new value back in `result`
|
|
4 chop-prefix \ bump the start of the string by 4 characters
|
|
else \ if not successful, we have finished scanning through the string
|
|
2drop \ dump the string address and length
|
|
result @ exit \ put the result on top of the stack and return to caller
|
|
then
|
|
again
|
|
;
|
|
|
|
data-str sum-mul-instrs .
|
|
bye
|