home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # File: calc.icn
- #
- # Subject: Program to simulate desk calculator
- #
- # Author: Ralph E. Griswold
- #
- # Date: April 7, 1992
- #
- ###########################################################################
- #
- # This is a simple Polish "desk calculator". It accepts as values Icon
- # integers, reals, csets, and strings (as they would appear in an Icon
- # program) as well as an empty line for the null value.
- #
- # Other lines of input are interpreted as operations. These may be Icon
- # operators, functions, or the commands listed below.
- #
- # In the case of operator symbols, such as +, that correspond to both unary
- # and binary operations, the binary one is used. Thus, the unary operation
- # is not available.
- #
- # In case of Icon functions like write() that take an arbitrary number of
- # arguments, one argument is used.
- #
- # The commands are:
- #
- # clear remove all values from the calculator's stack
- # dump write out the contents of the stack
- # quit exit from the calculator
- #
- # Example: the input lines
- #
- # "abc"
- # 3
- # repl
- # write
- #
- # writes abcabcabc and leaves this as the top value on the stack.
- #
- # Failure and most errors are detected, but in these cases, arguments are
- # consumed and not restored to the stack.
- #
- ############################################################################
- #
- # Links: ivalue, usage
- #
- ############################################################################
-
- link ivalue, usage
-
- global stack
-
- procedure main()
- local line
-
- stack := []
-
- while line := read() do
- (value | operation | command)(line) |
- Error("erroneous input ", image(line))
-
- end
-
- procedure command(line)
-
- case line of {
- "clear": stack := []
- "dump": every write(image(!stack))
- "quit": exit()
- default: fail
- }
-
- return
-
- end
-
- procedure operation(line)
- local p, n, arglist
-
- if p := proc(line, 2 | 1 | 3) then { # function or operation?
- n := abs(args(p))
- arglist := stack[-n : *stack + 1] | {
- Error("too few arguments")
- fail
- }
- stack := stack[1 : -n]
- &error := 1 # anticipate possible error
- put(stack, p ! arglist) | { # invoke
- if &error = 0 then
- Error("error ", &errornumber, " evaluating ", image(line))
- else
- Error("failure evaluating ", image(line))
- stack |||:= arglist # restore unused arguments
- }
- &error := 0
- return
- }
-
- else fail
-
- end
-
- procedure value(line)
-
- put(stack,ivalue(line)) | fail
-
- return
-
- end
-