home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
pocketbk
/
utilsr
/
rpn3a
/
RPNCALC.OPL
< prev
next >
Wrap
Text File
|
1994-10-11
|
16KB
|
831 lines
rem*************************************************************************
rem
rem RPN Calculator for the Psion Series 3a
rem Version 1.0
rem Copyright (c) 1992 Jaime Pereira
rem
rem This program is free software; you can redistribute it and/or modify
rem it under the terms of the GNU General Public License as published by
rem the Free Software Foundation; either version 1, or (at your option)
rem any later version.
rem
rem This program is distributed in the hope that it will be useful,
rem but WITHOUT ANY WARRANTY; without even the implied warranty of
rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
rem GNU General Public License for more details.
rem
rem You should have received a copy of the GNU General Public License
rem along with this program; if not, write to the Free Software
rem Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
rem
rem Revision: $Id: rpncalc.opl 1.3 92/12/10 00:32:02 jaime Exp Locker: jaime $
rem Ported to the Series 3A by Victor Alvarado 10/10/94
rem
rem*************************************************************************
app RPNcalc
type $1000
icon "\opl\rpncalc.pic"
enda
proc rpncalc:
global stack(20), tos%, wid%
global memory(10)
global editstr$(30), editpos%, udpos%
global frmtype%, frmprec&, frmtrig%
local k%, c$(1), inedit%
rem
rem Relocate the base window so we can see the
rem status window.
rem
screen 35,9
gsetwin 416, 160
statuswin on
gupdate off
rem
rem Create the display window
rem
wid% = gcreate(0, 0, 416, 160, 1)
guse wid%
gstyle 16
rem
rem Add the adornments
rem
gborder $200
k% = 0
gat 0, 140
while (k% < 416)
glineby 2, 0
gmove 2,0
k% = k% + 4
endwh
rem
rem Initialize asorted stuff
rem
tos% = 1
editpos% = 1
editstr$ = ""
frmtype% = 1
frmtrig% = 1
frmprec& = 12
udpos% = 0
showstk:
rem
rem The Loop!
rem
do
rem
rem Read from the keyboard
rem
guse wid%
k% = get
c$ = upper$(chr$(k%))
rem
rem Decode keystroke
rem
if k% = 632 rem Psion-X
break
elseif k% = 13 rem CR
rem
rem CR doubles as DUP if editstr is empty
rem
if len(editstr$) = 0 and tos% > 1
push:(stack(tos%-1))
else
pushstr:
endif
showstk:
rem Drop
elseif k% = 8 and len(editstr$) = 0
pop:
showstk:
elseif k% = 27 rem Escape key
inedit% = 0
editstr$ = ""
editpos% = 1
elseif k% = 290 rem Menu
menuop:
elseif k% = 291 rem Help
helpfunc:
elseif loc("+-/*X", c$) rem Math operation
binop:(c$)
showstk:
elseif k% > 512 rem Special Psion operation
psionop:(k%)
showstk:
rem Change sign
elseif c$ = "C" and len(editstr$)
chsop:
showcmd:
elseif loc("CSRIOP", c$) rem General manupulation
stkop:(c$)
showstk:
rem Up and Down arrows
elseif (k% = 257 or k% = 256) and tos% > 1
if len(editstr$) and inedit%
continue
endif
inedit% = 0
if (k% = 256)
udpos% = udpos% + 1
if udpos% >= tos% : udpos% = 0: endif
else
udpos% = udpos% - 1
if udpos% < 0 : udpos% = tos% - 1: endif
endif
if udpos% = 0
editstr$ = ""
editpos% = 1
else
editstr$ = gen$(stack(tos% - udpos%), 25)
editpos% = len(editstr$)+1
endif
showcmd:
else rem Otherwise to the edit box
inedit% = 1
myedit:(k%)
showcmd:
endif
until 0
endp
rem*******************************************
rem
rem My own field editor routine
rem
rem*******************************************
proc myedit:(k%)
local hstr$(40), tstr$(40)
local length%
length% = len(editstr$)
hstr$ = mid$(editstr$, 1, editpos%-1)
tstr$ = mid$(editstr$, editpos%, length%)
if k%=8
length% = len(hstr$)
if length% > 0
editstr$ = left$(hstr$, length%-1) + tstr$
editpos% = editpos% - 1
endif
elseif k% = 259
editpos% = editpos% - 1
if editpos% < 1
editpos% = 1
endif
elseif k% = 258
editpos% = editpos% + 1
if editpos% > length%+1
editpos% = length%+1
endif
elseif (length% > 22)
return
elseif (k% >= 48 and k% <= 57) or k% = 69 or k% = 101 or k% = 46
editstr$ = hstr$ + chr$(k%) + tstr$
editpos% = editpos% + 1
endif
endp
rem************************************************
rem
rem Show the stack display
rem
rem************************************************
proc showstk:
local i%, k%
local numstr$(25)
local xo%, yo%
cursor off
xo% = 5: yo% = 3
gat xo%, yo%
gfill 356, 136, 1
if tos% = 1
gat 220, yo% + 130
gprint " ** Empty **"
endif
i% = 10
k% = tos% - 1
while i% > 0 and k% > 0
gat xo%, i% * 13 + yo%
gprint fix$(tos% - k%, 0, -2);":"
if frmtype% = 1
numstr$ = gen$(stack(k%), 25)
elseif frmtype% = 2
numstr$ = fix$(stack(k%), frmprec&, 25)
elseif frmtype% = 3
numstr$ = sci$(stack(k%), frmprec&, 25)
endif
gprintb numstr$, 320, 1
i% = i% - 1
k% = k% - 1
endwh
showcmd:
endp
rem*******************************************
rem
rem Show the edit box
rem
rem*******************************************
proc showcmd:
local x%, cwidth%
local xo%, yo%
cwidth% = gtwidth("A")
xo% = 7: yo% = 145
cursor off
gat xo%, yo% - 1
gfill 356, 12, 1
gtmode 3
gat xo%, yo% + 10
gprint "Rpn:"
x% = gx + 3
gat x%, gy
gprint editstr$
gat x% + cwidth% * (editpos%-1), gy
cursor wid%
gupdate
endp
rem*******************************************
rem
rem Format window
rem
rem*******************************************
proc formatop:
dinit "Set RPN Calculator format"
dchoice frmtype%, "Format:", "General,Fixed,Scientific"
dlong frmprec&, "Decimal places:", 0, 12
dchoice frmtrig%, "Trigonometry units:", "Degrees,Radians"
if dialog
showstk:
endif
endp
rem*******************************************
rem
rem Push the edit box string into the
rem stack.
rem
rem*******************************************
proc pushstr:
onerr errhand
if len(editstr$)
push:(eval(editstr$))
endif
onerr off
editstr$ = ""
editpos% = 1
return 0
errhand::
onerr off
problem:(err$(err))
return 1
endp
rem*******************************************
rem
rem Push a number in the stack
rem
rem*******************************************
proc push:(data)
udpos% = 0
if tos% > 19
problem:("Stack Full")
else
stack(tos%) = data
tos% = tos% + 1
endif
endp
rem*******************************************
rem
rem Pop a number from the stack
rem
rem*******************************************
proc pop:
udpos% = 0
if tos% = 1
problem:("Stack empty")
return 0
endif
tos% = tos% - 1
return stack(tos%)
endp
rem*******************************************
rem
rem Clear the stack
rem
rem*******************************************
proc clrstk:
tos% = 1
showstk:
endp
rem*******************************************
rem
rem Stack operations
rem
rem*******************************************
proc stkop:(op$)
local mem, value
rem
rem Put the edit box in the stack
rem
if pushstr:
return
endif
if op$ = "S" and tos% > 2 rem Swap
stack(tos%) = stack(tos%-1)
stack(tos%-1) = stack(tos%-2)
stack(tos%-2) = stack(tos%)
elseif op$ = "R" and tos% > 3 rem Rot
stack(tos%) = stack(tos%-1)
stack(tos%-1) = stack(tos%-2)
stack(tos%-2) = stack(tos%-3)
stack(tos%-3) = stack(tos%)
elseif op$ = "I" and tos% > 2 rem Into memory
mem = pop:
if (mem >= 1 and mem <= 10)
value = stack(tos%-1)
memory(mem) = value
else
problem:("Illegal memory number")
endif
elseif op$ = "O" and tos% > 1 rem Out from memory
mem = pop:
if (mem >= 1 and mem <= 10)
push:(memory(mem))
else
problem:("Illegal memory number")
endif
elseif op$ = "C" and tos% > 1 rem Change sign
stack(tos%-1) = -stack(tos%-1)
elseif op$ = "P" rem Pi