Paste: RPN calculator
Author: | slava |
Mode: | factor |
Date: | Tue, 18 Aug 2009 00:37:36 |
Plain Text |
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 )
[ uncons uncons ] dip dip cons ; inline
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 ;
: rpn-eval ( tokens -- )
nil [ eval-insn ] foldl print-stack ;
: rpn ( -- )
"RPN> " write flush
readln [ rpn-parse rpn-eval rpn ] when* ;
Author: | earl |
Mode: | python |
Date: | Tue, 18 Aug 2009 13:59:24 |
Plain Text |
import operator
def mk_push(token):
return lambda stack: push_insn(stack, int(token))
def binary_op(stack, op):
stack.append(op(stack.pop(), stack.pop())); return stack
def add_insn(stack): return binary_op(stack, operator.add)
def sub_insn(stack): return binary_op(stack, operator.sub)
def mul_insn(stack): return binary_op(stack, operator.mul)
def div_insn(stack): return binary_op(stack, operator.div)
def push_insn(stack, value): stack.append(value); return stack
def eval_insn(stack, fn):
return fn(stack)
def rpn_tokenize(string):
return string.split()
def rpn_parse(string):
return map(lambda token: {'+': add_insn,
'-': sub_insn,
'*': mul_insn,
'/': div_insn}.get(token, mk_push(token)),
rpn_tokenize(string))
def print_stack(stack):
for item in stack: print item
def rpn_eval(tokens):
print_stack(reduce(eval_insn, tokens, []))
def rpn():
try:
while True: rpn_eval(rpn_parse(raw_input('RPN> ')))
except EOFError:
pass
New Annotation