作者: 機械伯爵
日時: 2003/5/8(12:10)
import sys,os
from math import *
stack = []
pop = stack.pop
push = stack.append
stack2 = []
length = stack.__len__

class Paren:
  def __init__(self):
    self.num = 0
    self._list = ""
  def nest(self):
    self.num += 1
  def unnest(self):
    self.num -= 1
    if self.num < 0:
      print "Error Out of Nest!"
      self.num = 0
  def __call__(self):
    return self.num
  def list(self, v = None):
    if v == None:
      r = self._list
      self._list = ""
      return r
    else:
      self._list += (" " + v)

paren = Paren()

def PUSH():
  stack2.append(stack.pop())

def POP():
  stack.append(stack2.pop())

def output(n):
  print n

def isnum(n):
  for x in n:
    if not x in "0123456789.-":
      return 0
  return 1

def replace(a, b):
  if length() < max([a,b]):
    "Stack Over Range!"
  else:
    stack[-a], stack[-b] = stack[-b], stack[-a]

def dup():
  a = pop()
  push(a)
  push(a)

def sum():
  r = 0
  for x in stack:
    r += x
  while stack:
    n = pop()
  push(r)

syntax={
  "Q":sys.exit,
  ".":(lambda :output(pop())),#
  "P":(lambda :output(stack[-1])),#Print TOS
  "L":(lambda :output(stack)),#List
  "S":(lambda :replace(1,2)), #Swap
  "D":dup,
  "SUM":sum,
  "|<":PUSH,
  "|>":POP,
  "><":stack.pop
}

opr=[
  "+","-","*","/",
  "<",">","<=",">=","<>","!=",
  "^","**","%"
]

tokenList = []
udic = {}

def analyze():
  global tokenList
  while tokenList:
    t = tokenList[0]
    tokenList = tokenList[1:]
    if paren(): # List
      if t == ")":
        paren.unnest()
        if not paren():
          push(paren.list())
        else:
          paren.list(t)
      elif t == "(":
        paren.nest()
        paren.list(t)
      else:
        paren.list(t)
    elif t == "(":
      paren.nest()
    elif syntax.has_key(t):
      syntax[t]()
    elif t in opr:
      if length() < 2:
        print "Stack Over Range!"
      else:
        b, a = pop(), pop()
        push(eval(str(a) + t + str(b)))
    elif t in ["=","=="]:
      b, a = pop(), pop()
      push(eval(a == b))
    elif t[-1] == "=":
      udic[t[:-1]]=pop()
    elif udic.has_key(t):
      push(udic[t])
    elif t == "!":
      if length():
        tokenList = (pop().split()) + tokenList
    elif isnum(t):
      push(float(t))
    elif t[0] == "@":
      os.system(t[1:])
    elif t[0] == "_":
      f = t[1:]
      push(eval(f+"("+str(pop())+")"))
    elif t[0] == "$":
      r = t.split("$")
      replace(int(r[1]),int(r[2]))
    elif t == "?": # t f test
      if pop():
        n = pop()
      else:
        replace(1,2)
        n = pop()
    elif t == "?!":
      if pop():
        n = pop()
        tokenList = (pop().split()) + tokenList
      else:
        replace(1,2)
        n = pop()
        tokenList = (pop().split()) + tokenList
    else:
      push(t)

# Main Loop

while 1:
  if not tokenList:
    instr = raw_input("%03.3d>>>" % length())
    if instr[0] == '"':
      push(instr[1:] + " ")
      continue
    else:
      tokenList += instr.split()
  analyze()