#!/bin/sh "exec" "gst" "-f" "$0" "$@" " Written for the RPN Calculator at http://www.stacken.kth.se/~foo/rpn/ by Stewart Stremler, January 2009, using GST 3.0. This code is released to the public domain. " "I prefer a basic stack class that looks like a stack" Object subclass: Stack [ | data | ] Stack class extend [ new [ | me | me := super new. ^me init ] ] Stack extend [ init [ data := OrderedCollection new. ^self ] size [ ^data size ] isEmpty [ ^data isEmpty ] pop [ data isEmpty ifFalse: [ ^data removeLast ]. ^nil ] push: anObject [ data addLast: anObject. ^self ] peek [ | anObject | anObject := self pop. anObject = nil ifFalse: [ self push: anObject ]. ^anObject ] ] "----------------------------------------------------------------" "An RPN Calculator" Object subclass: RPNCalculator [ | stack ops | ] RPNCalculator class extend [ new [ | me | me := super new. ^me init ] ] RPNCalculator extend [ init [ ops := Dictionary new. stack := Stack new. ops at: '+' put: [ :s | s push: ( s pop + ( s pop ) ) ]. ops at: '*' put: [ :s | s push: ( s pop * ( s pop ) ) ]. ops at: '-' put: [ :s | | x y | x := s pop. y := s pop. s push: ( y - x ) ]. ops at: '/' put: [ :s | | x y | x := s pop. y := s pop. s push: ( y / x ) ]. ops at: '_' put: [ :s | s push: (s pop asFloat) ]. ^self ] compute: aStream [ | line | ( aStream = stdin ) ifTrue: [ 'A blank line exits, Newline computes.' displayNl ]. line := aStream nextLine. [ line isEmpty ] whileFalse: [ (line tokenize: ' ') do: [ :token | self process: token ]. 'result = ' display. stack peek displayNl. line := aStream nextLine. ]. "loop" stack isEmpty ifTrue: [ ^'empty stack' ] ifFalse: [ ^stack pop ]. ] process: aString [ (ops at: aString ifAbsent: [ [:s | s push: (aString asNumber) ]] ) value: stack. ] ] ! " ---------------------------------------------------------- " |rpnc| rpnc := RPNCalculator new. "(rpnc compute: (ReadStream on: '10 20 30 + 4 + \n +')) displayNl ." (rpnc compute: stdin) displayNl.