Download code

Jump to: navigation, search

Back to Desk_calculator_(Python)

Download for Windows: single file, zip

Download for UNIX: single file, zip, tar.gz, tar.bz2

dc.py

  1 # The authors of this work have released all rights to it and placed it
  2 # in the public domain under the Creative Commons CC0 1.0 waiver
  3 # (http://creativecommons.org/publicdomain/zero/1.0/).
  4 # 
  5 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  6 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  7 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  8 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  9 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 10 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 11 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 12 # 
 13 # Retrieved from: http://en.literateprograms.org/Desk_calculator_(Python)?oldid=18700
 14 
 15 #############################################
 16 import sys, math
 17 write=sys.stdout.write
 18 #############################################
 19 
 20 s,c,d = [],"",{}
 21 
 22 class SVal(str):
 23 	def execute(self):	cpush(self + '\0')
 24 	def sizeof(self):	len(self)
 25 	def prval(self):	write(self)
 26 
 27 class NVal(long):
 28 	def execute(self):	s.append(self)
 29 	def sizeof(self):
 30 		if self==0:	return 1
 31 		else:		return int(math.log10(self))+1
 32 	def prval(self):
 33 		q,str = self,""	
 34 		while q > 0:
 35 			q,r = divmod(q,0x100)
 36 			str = chr(r) + str
 37 		write(str)
 38 
 39 def cpop():
 40 	global c
 41 	r,c=c[0],c[1:]
 42 	return r
 43 def cpush(b):
 44 	global c
 45 	c = b+c
 46 def ctrim(upto):
 47 	global c
 48 	try:	c = c[c.index(upto)+1:]
 49 	except:	sys.exit(0)
 50 
 51 def debugpr(s):
 52 	for v in s:
 53 		print v
 54 def compare(how):
 55 	cmpfunc = {
 56 	'>':	lambda a,b: b > a,
 57 	'!>':	lambda a,b: b <= a,
 58 	'<':	lambda a,b: b < a,
 59 	'!<':	lambda a,b: b >= a,
 60 	'=':	lambda a,b: b == a,
 61 	'!=':	lambda a,b: b != a
 62 	}
 63 	if cmpfunc[how](s.pop(-2),s.pop()):
 64 		d[cpop()].execute()
 65 	else:
 66 		cpop()
 67 def donum(sign,acc):
 68 	while c[0].isdigit():
 69 		acc = 10*acc + int(cpop())
 70 	acc *= sign
 71 	s.append(NVal(acc))
 72 
 73 def dostr():
 74 	nest,acc = 1,[]
 75 	while nest:
 76 		c = cpop()
 77 		if   c == ']': nest-=1
 78 		elif c == '[': nest+=1
 79 		if not nest:	break
 80 		acc.append(c)
 81 	s.append(SVal("".join(acc)))
 82 def nop(): pass
 83 cmds = {
 84 'p':	lambda: debugpr(s[-1:]),
 85 'f':	lambda: debugpr(s),
 86 '+':	lambda: s.append(NVal(s.pop(-2) + s.pop())),
 87 '-':	lambda: s.append(NVal(s.pop(-2) - s.pop())),
 88 '*':	lambda: s.append(NVal(s.pop(-2) * s.pop())),
 89 '/':	lambda: s.append(NVal(s.pop(-2) //s.pop())),
 90 '%':	lambda: s.append(NVal(s.pop(-2) % s.pop())),
 91 '^':	lambda: s.append(NVal(s.pop(-2) **s.pop())),
 92 '~':	lambda: s.extend(map(NVal,divmod(s.pop(-2),s.pop()))),
 93 'd':	lambda: s.append(s[-1]),
 94 'c':	lambda: s.__setitem__(slice( 0,None),[]),
 95 'r':	lambda: s.__setitem__(slice(-3,None),s[-1:-3:-1]),
 96 'n':	lambda: write("%s" % s.pop()),
 97 'P':	lambda: s.pop().prval(),
 98 'Z':	lambda: s.append(NVal(s.pop().sizeof())),
 99 'z':	lambda: s.append(len(s)),
100 '#':	lambda: ctrim('\n'),
101 'q':	lambda: (ctrim('\0'),ctrim('\0')),
102 'l':	lambda: s.append(d[cpop()]),
103 's':	lambda: d.update([(cpop(),s.pop())]),
104 '>':	lambda: compare('>'),
105 '<':	lambda: compare('<'),
106 '=':	lambda: compare('='),
107 '!':	lambda: compare('!'+cpop()),
108 'x':	lambda: s.pop().execute(),
109 '?':	lambda: cpush(sys.stdin.readline()),
110 '[':	dostr,
111 '_':	lambda: donum(-1,0),
112 '0':	lambda: donum( 1,0),
113 '1':	lambda: donum( 1,1),
114 '2':	lambda: donum( 1,2),
115 '3':	lambda: donum( 1,3),
116 '4':	lambda: donum( 1,4),
117 '5':	lambda: donum( 1,5),
118 '6':	lambda: donum( 1,6),
119 '7':	lambda: donum( 1,7),
120 '8':	lambda: donum( 1,8),
121 '9':	lambda: donum( 1,9),
122 ' ':	nop,
123 '\t':	nop,
124 '\r':	nop,
125 '\n':	nop,
126 '\0':	nop
127 }
128 def interp(str):	
129 	cpush(str)
130 	while len(c):
131 		cmds[cpop()]()
132 
133 #############################################
134 
135 if __name__=="__main__":
136 	arg = sys.argv[1:]
137 	if not len(arg):
138 		while True:
139 			interp(sys.stdin.readline())
140 	while len(arg):
141 		if arg[0] == '-e':
142 			str = arg[1]
143 			arg = arg[2:]
144 		elif arg[0] == '-f':
145 			arg = arg[1:]
146 			continue	
147 		else:
148 			f = open(arg[0],"rb")
149 			str = f.read()
150 			f.close()
151 			arg = arg[1:]
152 		interp(str)
153 


hijacker
hijacker
hijacker
hijacker