nga-python: add decimal io device (#32)
FossilOrigin-Name: 4a0a1184f66f855840fa7229013d6b4b68026584dfc72906f3e4994fd346f3f6
This commit is contained in:
parent
71a3eb4c31
commit
77b2ccc463
4 changed files with 227 additions and 8 deletions
100
interface/decimal.retro
Normal file
100
interface/decimal.retro
Normal file
|
@ -0,0 +1,100 @@
|
|||
# Decimal Numbers
|
||||
|
||||
~~~
|
||||
{{
|
||||
'DPU var
|
||||
:identify
|
||||
@DPU n:zero? 0; drop
|
||||
#20 io:scan-for dup n:negative?
|
||||
[ drop 'IO_DEVICE_TYPE_0020_NOT_FOUND s:put nl ]
|
||||
[ !DPU ] choose ;
|
||||
---reveal---
|
||||
:decimal:operation identify @DPU io:invoke ;
|
||||
}}
|
||||
~~~
|
||||
|
||||
~~~
|
||||
:n:to-decimal (n-_dec:-n) #0 decimal:operation ;
|
||||
:s:to-decimal (s-_dec:-n) #1 decimal:operation ;
|
||||
:dec:to-number (dec:a-__-n) #2 decimal:operation ;
|
||||
:dec:to-string (dec:n-__-s) s:empty dup #3 decimal:operation ;
|
||||
:dec:+ (dec:ab-c) #4 decimal:operation ;
|
||||
:dec:- (dec:ab-c) #5 decimal:operation ;
|
||||
:dec:* (dec:ab-c) #6 decimal:operation ;
|
||||
:dec:/ (dec:ab-c) #7 decimal:operation ;
|
||||
:dec:floor (dec:ab-c) #8 decimal:operation ;
|
||||
:dec:ceiling (dec:f-f) #9 decimal:operation ;
|
||||
:dec:sqrt (dec:f-f) #10 decimal:operation ;
|
||||
:dec:eq? (dec:ab-c) #11 decimal:operation ;
|
||||
:dec:-eq? (dec:ab-c) #12 decimal:operation ;
|
||||
:dec:lt? (dec:ab-c) #13 decimal:operation ;
|
||||
:dec:gt? (dec:ab-c) #14 decimal:operation ;
|
||||
:dec:depth (-n) #15 decimal:operation ;
|
||||
:dec:dup (dec:a-aa) #16 decimal:operation ;
|
||||
:dec:drop (dec:a-) #17 decimal:operation ;
|
||||
:dec:swap (dec:ab-ba) #18 decimal:operation ;
|
||||
:dec:log (dec:ab-c) #19 decimal:operation ;
|
||||
:dec:power (dec:ab-c) #20 decimal:operation ;
|
||||
:dec:sin (dec:f-f) #21 decimal:operation ;
|
||||
:dec:cos (dec:f-f) #22 decimal:operation ;
|
||||
:dec:tan (dec:f-f) #23 decimal:operation ;
|
||||
:dec:asin (dec:f-f) #24 decimal:operation ;
|
||||
:dec:acos (dec:f-f) #25 decimal:operation ;
|
||||
:dec:atan (dec:f-f) #26 decimal:operation ;
|
||||
:dec:push (dec:f-) #27 decimal:operation ;
|
||||
:dec:pop (dec:-f) #28 decimal:operation ;
|
||||
:dec:adepth (-n) #29 decimal:operation ;
|
||||
~~~
|
||||
|
||||
Above this, additional functions are defined. First are words
|
||||
to aid in structuring the floating point stack.
|
||||
|
||||
~~~
|
||||
:dec:over (dec:ab-aba) dec:push dec:dup dec:pop dec:swap ;
|
||||
:dec:tuck (dec:ab-bab) dec:dup dec:push dec:swap dec:pop ;
|
||||
:dec:nip (dec:ab-b) dec:swap dec:drop ;
|
||||
:dec:drop-pair (dec:ab-) dec:drop dec:drop ;
|
||||
:dec:dup-pair (dec:ab-abab) dec:over dec:over ;
|
||||
:dec:rot (dec:abc-bca) dec:push dec:swap dec:pop dec:swap ;
|
||||
~~~
|
||||
|
||||
Then a word to allow creation of floating point values via a
|
||||
`,` prefix.
|
||||
|
||||
~~~
|
||||
:prefix:, (s-__dec:-a)
|
||||
compiling? &s:keep &s:temp choose &s:to-decimal class:word ; immediate
|
||||
~~~
|
||||
|
||||
~~~
|
||||
:dec:square (dec:n-m) dec:dup dec:* ;
|
||||
:dec:positive? (-f__dec:a-) #0 n:to-decimal dec:gt? ;
|
||||
:dec:negative? (-f__dec:a-) #0 n:to-decimal dec:lt? ;
|
||||
:dec:negate (dec:a-b) #-1 n:to-decimal dec:* ;
|
||||
:dec:abs (dec:a-b) dec:dup dec:negative? &dec:negate if ;
|
||||
:dec:put (dec:a-) dec:to-string s:put ;
|
||||
|
||||
:dec:PI (dec:-F) ,3.141592 ;
|
||||
:dec:E (dec:-F) ,2.718281 ;
|
||||
:dec:NAN (dec:-n) ,0 ,0 dec:/ ;
|
||||
:dec:INF (dec:-n) ,1.0 ,0 dec:/ ;
|
||||
:dec:-INF (dec:-n) ,-1.0 ,0 dec:/ ;
|
||||
:dec:nan? (dec:n-,-f) dec:dup dec:-eq? ;
|
||||
:dec:inf? (dec:n-,-f) dec:INF dec:eq? ;
|
||||
:dec:-inf? (dec:n-,-f) dec:-INF dec:eq? ;
|
||||
:dec:round (-|dec:a-b)
|
||||
dec:dup dec:negative?
|
||||
[ ,0.5 dec:- dec:ceiling ]
|
||||
[ ,0.5 dec:+ dec:floor ] choose ;
|
||||
:dec:min (dec:nn-n) dec:dup-pair dec:lt? &dec:drop &dec:nip choose ;
|
||||
:dec:max (dec:nn-n) dec:dup-pair dec:gt? &dec:drop &dec:nip choose ;
|
||||
:dec:limit (dec:nlu-n) dec:swap dec:push dec:min dec:pop dec:max ;
|
||||
:dec:between? (dec:nlu-n) dec:rot dec:dup dec:push dec:rot dec:rot dec:limit dec:pop dec:eq? ;
|
||||
:dec:inc (dec:n-n) ,1 dec:+ ;
|
||||
:dec:dec (dec:n-n) ,1 dec:- ;
|
||||
:dec:case (dec:ff-,q-)
|
||||
dec:over dec:eq? [ dec:drop call #-1 ] [ drop #0 ] choose 0; pop drop-pair ;
|
||||
:dec:sign (-n|dec:a-)
|
||||
dec:dup ,0 dec:eq? [ #0 dec:drop ] if;
|
||||
,0 dec:gt? [ #1 ] [ #-1 ] choose ;
|
||||
~~~
|
|
@ -3,7 +3,7 @@
|
|||
#define CELL int32_t
|
||||
#endif
|
||||
CELL ngaImageCells = 13846;
|
||||
CELL ngaImage[] = { 1793,13757,13747,13845,202101,0,10,1,10,2,10,3,10,4,10,5,10,6,10,
|
||||
CELL ngaImage[] = { 1793,13757,13747,13845,202104,0,10,1,10,2,10,3,10,4,10,5,10,6,10,
|
||||
7,10,8,10,9,10,10,11,10,12,10,13,10,14,10,15,10,16,10,17,
|
||||
10,18,10,19,10,20,10,21,10,22,10,23,10,24,10,25,10,68223234,1,2575,
|
||||
85000450,1,656912,3211,3220,268505089,63,62,285281281,0,63,2063,10,101384453,0,9,10,2049,56,25,
|
||||
|
|
|
@ -1,7 +1,83 @@
|
|||
# Stub for Decimal I/O device
|
||||
from decimal import *
|
||||
|
||||
import decimal
|
||||
class DecimalStack(object):
|
||||
def __init__(self, *d):
|
||||
self.data = list(d)
|
||||
|
||||
class Decimal:
|
||||
def __init__(self):
|
||||
pass
|
||||
def __getitem__(self, id):
|
||||
return self.data[id]
|
||||
|
||||
def add(self):
|
||||
self.data.append(self.data.pop() + self.data.pop())
|
||||
|
||||
def sub(self):
|
||||
self.data.append(0 - (self.data.pop() - self.data.pop()))
|
||||
|
||||
def mul(self):
|
||||
self.data.append(self.data.pop() * self.data.pop())
|
||||
|
||||
def div(self):
|
||||
a, b = self.data.pop(), self.data.pop()
|
||||
self.data.append(b / a)
|
||||
|
||||
def ceil(self):
|
||||
self.data.append(math.ceil(self.data.pop()))
|
||||
|
||||
def floor(self):
|
||||
self.data.append(math.floor(self.data.pop()))
|
||||
|
||||
def eq(self):
|
||||
return 0 - (self.data.pop() == self.data.pop())
|
||||
|
||||
def neq(self):
|
||||
return 0 - (self.data.pop() != self.data.pop())
|
||||
|
||||
def gt(self):
|
||||
a, b = self.data.pop(), self.data.pop()
|
||||
return 0 - (b > a)
|
||||
|
||||
def lt(self):
|
||||
a, b = self.data.pop(), self.data.pop()
|
||||
return 0 - (b < a)
|
||||
|
||||
def depth(self):
|
||||
return len(self.data)
|
||||
|
||||
def drop(self):
|
||||
self.data.pop()
|
||||
|
||||
def pop(self):
|
||||
return self.data.pop()
|
||||
|
||||
def swap(self):
|
||||
a, b = self.data.pop(), self.data.pop()
|
||||
self.data += [a, b]
|
||||
|
||||
def push(self, n):
|
||||
self.data.append(n)
|
||||
|
||||
def log(self):
|
||||
a, b = self.data.pop(), self.data.pop()
|
||||
self.data.append(math.log(b, a))
|
||||
|
||||
def power(self):
|
||||
a, b = self.data.pop(), self.data.pop()
|
||||
self.data.append(math.pow(a, b))
|
||||
|
||||
def sin(self):
|
||||
self.data.append(math.sin(self.data.pop()))
|
||||
|
||||
def cos(self):
|
||||
self.data.append(math.cos(self.data.pop()))
|
||||
|
||||
def tan(self):
|
||||
self.data.append(math.tan(self.data.pop()))
|
||||
|
||||
def asin(self):
|
||||
self.data.append(math.asin(self.data.pop()))
|
||||
|
||||
def acos(self):
|
||||
self.data.append(math.acos(self.data.pop()))
|
||||
|
||||
def atan(self):
|
||||
self.data.append(math.atan(self.data.pop()))
|
||||
|
|
|
@ -24,13 +24,14 @@
|
|||
# combine the separate files into a single one for deployment.
|
||||
# -------------------------------------------------------------
|
||||
|
||||
import os, sys, math, time, struct, random, datetime
|
||||
import os, sys, math, time, struct, random, datetime, decimal
|
||||
|
||||
from ClockDevice import Clock
|
||||
from RNGDevice import RNG
|
||||
from FileSystemDevice import FileSystem
|
||||
|
||||
from FloatStack import FloatStack
|
||||
from DecimalDevice import DecimalStack
|
||||
from IntegerStack import IntegerStack
|
||||
from Memory import Memory
|
||||
from InitialImage import InitialImage
|
||||
|
@ -50,6 +51,9 @@ class Retro:
|
|||
self.files = FileSystem()
|
||||
self.floats = FloatStack()
|
||||
self.afloats = FloatStack()
|
||||
self.decimals = DecimalStack()
|
||||
self.adecimals = DecimalStack()
|
||||
|
||||
self.Dictionary = self.populate_dictionary()
|
||||
self.Cached = self.cache_words()
|
||||
|
||||
|
@ -319,7 +323,7 @@ class Retro:
|
|||
self.ip = 9000000
|
||||
|
||||
def i_ienumerate(self):
|
||||
self.stack.push(6)
|
||||
self.stack.push(7)
|
||||
|
||||
def i_iquery(self):
|
||||
device = self.stack.pop()
|
||||
|
@ -341,6 +345,9 @@ class Retro:
|
|||
if device == 5: # scripting
|
||||
self.stack.push(0)
|
||||
self.stack.push(9)
|
||||
if device == 6: # decimal
|
||||
self.stack.push(0)
|
||||
self.stack.push(20)
|
||||
|
||||
def file_open_params(self):
|
||||
mode = self.stack.pop()
|
||||
|
@ -416,6 +423,39 @@ class Retro:
|
|||
29: lambda: self.stack.push(self.afloats.depth()),
|
||||
}
|
||||
|
||||
self.decimal_instr = {
|
||||
0: lambda: self.decimals.push(decimal.Decimal(self.stack.pop())),
|
||||
1: lambda: self.decimals.push(decimal.Decimal(self.extract_string(self.stack.pop()))),
|
||||
2: lambda: self.stack.push(int(self.decimals.pop())),
|
||||
3: lambda: self.inject_string(str(self.decimals.pop()), self.stack.pop()),
|
||||
4: lambda: self.decimals.add(),
|
||||
5: lambda: self.decimals.sub(),
|
||||
6: lambda: self.decimals.mul(),
|
||||
7: lambda: self.decimals.div(),
|
||||
8: lambda: self.decimals.floor(),
|
||||
9: lambda: self.decimals.ceil(),
|
||||
10: lambda: self.decimals.sqrt(),
|
||||
11: lambda: self.stack.push(self.decimals.eq()),
|
||||
12: lambda: self.stack.push(self.decimals.neq()),
|
||||
13: lambda: self.stack.push(self.decimals.lt()),
|
||||
14: lambda: self.stack.push(self.decimals.gt()),
|
||||
15: lambda: self.stack.push(self.decimals.depth()),
|
||||
16: lambda: self.decimals.dup(),
|
||||
17: lambda: self.decimals.drop(),
|
||||
18: lambda: self.decimals.swap(),
|
||||
19: lambda: self.decimals.log(),
|
||||
20: lambda: self.decimals.pow(),
|
||||
21: lambda: self.decimals.sin(),
|
||||
22: lambda: self.decimals.cos(),
|
||||
23: lambda: self.decimals.tan(),
|
||||
24: lambda: self.decimals.asin(),
|
||||
25: lambda: self.decimals.atan(),
|
||||
26: lambda: self.decimals.acos(),
|
||||
27: lambda: self.adecimals.push(self.decimals.pop()),
|
||||
28: lambda: self.decimals.push(self.adecimals.pop()),
|
||||
29: lambda: self.stack.push(self.adecimals.depth()),
|
||||
}
|
||||
|
||||
def i_iinvoke(self):
|
||||
device = self.stack.pop()
|
||||
# print('dev:', device)
|
||||
|
@ -445,6 +485,9 @@ class Retro:
|
|||
if action == 3:
|
||||
b = self.stack.pop()
|
||||
self.stack.push(self.inject_string(sys.argv[0], b))
|
||||
if device == 6:
|
||||
action = self.stack.pop()
|
||||
self.decimal_instr[int(action)]()
|
||||
|
||||
def validate_opcode(self, I0, I1, I2, I3):
|
||||
if (
|
||||
|
|
Loading…
Reference in a new issue