Minimal RPN

Richard Suchenwirth 2004-01-13 - In RPN in Tcl I've played a bit with emulating Forth in Tcl. Here is a much shorter take that defines a single rpn proc, which takes a body in Reverse Polish Notation, and the rest of the arguments as the initial stack. The words in the body are executed from left to right, either as Forth-like stack operations, or as a Tcl command which has to have one argument (popped from stack) and whose result is pushed on the stack.

 proc rpn {body args} {
    foreach word $body {
        switch -- $word {
            drop {pop args}
            dup  {push args [lindex $args end]}
            swap {push args [pop args] [pop args]}
            + - "-" - * - / - % {
                #-- binary arithmetic operators:
                set 1 [pop args]
                push args [expr [pop args] $word $1]
            }
            default {push args [$word [pop args]]}
        }
    }
    set args
 }
# Simple stack routines:
 interp alias {} push {} lappend
 proc pop stackName {
    upvar 1 $stackName stack
    K [lindex $stack end] [set stack [lrange $stack 0 end-1]]
 }
# ..and the indispensable [K] combinator:
 proc K {a b} {set a}

This test will display the source file on stdout. Notice how no variables are needed at all (if you don't count the stack as the Big Variable :

 puts [rpn {open dup read swap close drop} rpn.tcl]

What happens is the same as with

 proc readfile fn {
    set fp [open $fn]
    set res [read $fp]
    close $fp
    return $res
 }

but the code feels quite different ;-) Schematic of how it works:

 (initial stack:)   rpn.tcl
 open               filexxx
 dup                filexxx filexxx
 read               filexxx (text)
 swap               (text) filexxx
 close              (text) ""
 drop               (text)

and the final stack, which in one element contains the file's contents, is returned to the caller.

# Testing the newly added arithmetics, which cost the 4 LOC above:

 puts [rpn {+ *} 4 2 1] ;# (2+1)*4 -> 12

Wow, Richard, what a delightful wizzlet! -jcw


A less minimal, but much more capable version is at RPN again.