diff --git a/examples/kinematics.oph b/examples/kinematics.oph index ff00c46..5240402 100644 --- a/examples/kinematics.oph +++ b/examples/kinematics.oph @@ -95,11 +95,11 @@ impact_point_2: height_1: .byte "MAXIMUM HEIGHT OF ",0 -f_0_125: .byte 126,0,0,0,0 -f_9_8: .byte 132,28,204,204,204 -f_90: .byte 135,52,0,0,0 -f_100: .byte 135,72,0,0,0 -f_180: .byte 136,52,0,0,0 +f_0_125: .cbmfloat "0.125" +f_9_8: .cbmfloat "9.8" +f_90: .cbmfloat "90" +f_100: .cbmfloat "100" +f_180: .cbmfloat "180" get_num: .scope diff --git a/src/Ophis/CorePragmas.py b/src/Ophis/CorePragmas.py index 090dd6a..b57dbb3 100644 --- a/src/Ophis/CorePragmas.py +++ b/src/Ophis/CorePragmas.py @@ -10,7 +10,7 @@ import Ophis.CmdLine import Ophis.IR as IR import Ophis.Frontend as FE import Ophis.Errors as Err -import os.path +import math, os.path basecharmap = "".join([chr(x) for x in range(256)]) currentcharmap = basecharmap @@ -219,6 +219,40 @@ def pragmaData(ppt, line, result): result.append(IR.Node(ppt, "DataSegment", segment)) +def pragmaCbmfloat(ppt, line, result): + "Parses a string into a CBM BASIC format floating point number" + data = [] + while True: + try: + v_str = line.expect("STRING").value + v = float(v_str) + if v == 0.0: + data.extend([0,0,0,0,0]) + else: + if v < 0.0: + sign = 128 + v = -v + else: + sign = 0 + expt = math.floor(math.log(v, 2)) + if expt >= -128 and expt <= 126: + mantissa = v / (2**expt) + m1 = (mantissa - 1.0) * 128 + sign + m2 = m1 * 256 + m3 = m2 * 256 + m4 = m3 * 256 + data.extend([int(x) % 256 for x in [expt+129,m1,m2,m3,m4]]) + else: + Err.log("Floating point constant out of range") + except ValueError: + Err.log("Expected: floating point") + next = line.expect(',', 'EOL').type + if next == 'EOL': + break + bytes = [IR.ConstantExpr(x) for x in data] + result.append(IR.Node(ppt, "Byte", *bytes)) + + def readData(line): "Read raw data from a comma-separated list" if line.lookahead(0).type == "STRING": diff --git a/tests/testdata.bin b/tests/testdata.bin index 6279ccb..88d0f89 100644 Binary files a/tests/testdata.bin and b/tests/testdata.bin differ diff --git a/tests/testdata.oph b/tests/testdata.oph index c0fc1aa..e1129d2 100644 --- a/tests/testdata.oph +++ b/tests/testdata.oph @@ -1,5 +1,5 @@ -; This data file just dumps out $00-$0F repeatedly with different forms, -; bracketed by $00s and then $60s. +; This part of the file just dumps out $00-$0F repeatedly with +; different forms, bracketed by $00s and then $60s. .advance $10, ^ .byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 .word 256, $0302, $0504, $0706, $0908, $0b0a, $0d0c, $0f0e @@ -7,3 +7,21 @@ .wordbe 1, $0203, $0405, $0607, $0809, $0a0b, $0c0d, $0e0f .dwordbe $010203, $04050607, $08090a0b, $0c0d0e0f .advance $70, ^ + +; To verify that that these numbers match up, we use the following +; BASIC program, which works on both the C64 and the VIC-20. + +; 10 clr:v=0:pv=peek(45)+256*peek(46)+2 +; 20 input "convert what";v +; 30 for i=0 to 4:print peek(pv+i);:next i +; 40 print:if v<>0 then 10 + +.cbmfloat "0.0", "0.125","9.8","90","100","180" + +; The program tells us that these are the right answers. +; We'd like to test more exotic choices like the 4.3e12 or what have you, +; but the fact that these are two different kinds of floating point +; results in slight variations at the very bottom of the mantissa. +; caveat emptor. +; .byte 0,0,0,0,0,126,0,0,0,0,132,28,204,204,204,135,52,0,0,0 +; .byte 135,72,0,0,0,136,52,0,0,0