diff --git a/fx92/lexer.py b/fx92/lexer.py index 40e646d..fca309a 100644 --- a/fx92/lexer.py +++ b/fx92/lexer.py @@ -90,6 +90,22 @@ class Token: return base + args +#--- +# Utilities +#--- + +def str2float(integer, decimal, exponent, percent): + m1 = integer or "0" + m2 = ".0" if decimal == "." else (decimal or "") + m3 = exponent or "" + + f = float(m1 + m2 + m3) + + if percent == "%": + f /= 100 + + return f + #--- # Lexer base #--- @@ -184,18 +200,25 @@ class BitcodeLexer(LexerBase): return Token(T.CONST, math.pi) # Constants - if code in range(0x30, 0x39+1): + if code in range(0x30, 0x39+1) or code == 0x2E: # Never thought pointer arithmetic would beat Python. Grr! - re_const = rb'([0-9]+(?:\x2E[0-9]*)?(?:\x2D[0-9]+)?)(%?)' - match = re.match(re_const, h[p:]) + re_const=rb'([0-9]*)(\x2E[0-9]*)?(\x2D[\xA6\xA7\xC0]?[0-9]+)?(%)?' + m = re.match(re_const, h[p:]) - if match is not None: - text = match.group(1).replace(b'\x2E', b'.').replace(b'\x2D', b'e') - self.pos += len(text) - 1 + if m is not None: + integer = (m[1] or b"").decode() + decimal = (m[2] or b".").replace(b'\x2E', b'.').decode() + exp = (m[3] or b"") + percent = (m[4] or b"").decode() - f = float(text.decode('utf-8')) - if match.group(2) == "%": - f /= 100 + exp = exp.replace(b'\x2D', b'e') + exp = exp.replace(b'\xA6', b'+') + exp = exp.replace(b'\xA7', b'-') + exp = exp.replace(b'\xC0', b'-') + exp = exp.decode() + + self.pos += len(m[0]) - 1 + f = str2float(integer, decimal, exp, percent) return Token(T.CONST, f) # Variables @@ -302,7 +325,7 @@ class TextLexer(LexerBase): r"IFELSE_END|IFELSE|IF", re.IGNORECASE) RE_CONST = re.compile( - r"([0-9]+(?:\.[0-9]+)?(?:[eE][0-9]+)?)(%?)") + r"([0-9]*)(\.[0-9]*)?([eE][+-]?[0-9]+)?(%)?") RE_FUN = re.compile( r"([a-zA-Z]+)\(") @@ -375,11 +398,10 @@ class TextLexer(LexerBase): return Token(punct[c[0]]) # Constants - m = re.match(self.RE_CONST, c) - if m is not None: - f = float(m[1]) - if m[2] == "%": - f /= 100 + if c[0] in "0123456789.": + m = re.match(self.RE_CONST, c) + if m is not None: + f = str2float(m[1], m[2], m[3], m[4]) self.code = c[len(m[0]):] self.pending_param = True diff --git a/tests/constants.out b/tests/constants.out new file mode 100644 index 0000000..5678eb2 --- /dev/null +++ b/tests/constants.out @@ -0,0 +1,11 @@ +173.0 +-374.0 +37.947 +913390.0 +9.454 +0.034 +1445.0 +0.0 +100000.0 +0.38 +-0.02434 diff --git a/tests/constants.txt b/tests/constants.txt new file mode 100644 index 0000000..b3dd1c4 --- /dev/null +++ b/tests/constants.txt @@ -0,0 +1,12 @@ +print 173 +print -374 +print 37.947 +print 913.39e3 +print 945.4e-2 +print .034 +print 1445. +print . +print 1.e5 +print 38% +print -24.34e-1% +