2009-08-17 21:12:05 -04:00
|
|
|
! Copyright (C) 2009 Slava Pestov
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: accessors combinators io kernel lists math math.parser
|
|
|
|
sequences splitting ;
|
|
|
|
IN: rpn
|
|
|
|
|
|
|
|
SINGLETONS: add-insn sub-insn mul-insn div-insn ;
|
|
|
|
TUPLE: push-insn value ;
|
|
|
|
|
|
|
|
GENERIC: eval-insn ( stack insn -- stack )
|
|
|
|
|
|
|
|
: binary-op ( stack quot: ( x y -- z ) -- stack )
|
2014-01-05 23:30:38 -05:00
|
|
|
[ uncons uncons swapd ] dip dip cons ; inline
|
2009-08-17 21:12:05 -04:00
|
|
|
|
|
|
|
M: add-insn eval-insn drop [ + ] binary-op ;
|
|
|
|
M: sub-insn eval-insn drop [ - ] binary-op ;
|
|
|
|
M: mul-insn eval-insn drop [ * ] binary-op ;
|
|
|
|
M: div-insn eval-insn drop [ / ] binary-op ;
|
|
|
|
M: push-insn eval-insn value>> swons ;
|
|
|
|
|
|
|
|
: rpn-tokenize ( string -- string' )
|
|
|
|
" " split harvest sequence>list ;
|
|
|
|
|
|
|
|
: rpn-parse ( string -- tokens )
|
|
|
|
rpn-tokenize [
|
|
|
|
{
|
|
|
|
{ "+" [ add-insn ] }
|
|
|
|
{ "-" [ sub-insn ] }
|
|
|
|
{ "*" [ mul-insn ] }
|
|
|
|
{ "/" [ div-insn ] }
|
|
|
|
[ string>number push-insn boa ]
|
|
|
|
} case
|
|
|
|
] lmap ;
|
|
|
|
|
|
|
|
: print-stack ( list -- )
|
|
|
|
[ number>string print ] leach ;
|
|
|
|
|
2009-09-23 18:33:03 -04:00
|
|
|
: rpn-eval ( tokens -- stack )
|
|
|
|
nil [ eval-insn ] foldl ;
|
2009-08-17 21:12:05 -04:00
|
|
|
|
|
|
|
: rpn ( -- )
|
|
|
|
"RPN> " write flush
|
2009-09-23 18:33:03 -04:00
|
|
|
readln [ rpn-parse rpn-eval print-stack rpn ] when* ;
|
2009-08-17 21:12:05 -04:00
|
|
|
|
|
|
|
MAIN: rpn
|