diff --git a/source/qb64.bas b/source/qb64.bas index 7ad652b85..4a72fe292 100644 --- a/source/qb64.bas +++ b/source/qb64.bas @@ -21,9 +21,9 @@ DEFLNG A-Z '-------- Optional IDE Component (1/2) -------- '$INCLUDE:'ide\ide_global.bas' -REDIM SHARED OName(0) AS STRING 'Operation Name -REDIM SHARED PL(0) AS INTEGER 'Priority Level -DIM SHARED QuickReturn AS INTEGER +REDIM SHARED OName(1000) AS STRING 'Operation Name +REDIM SHARED PL(1000) AS INTEGER 'Priority Level +REDIM SHARED PP_TypeMod(0) AS STRING, PP_ConvertedMod(0) AS STRING 'Prepass Name Conversion variables. Set_OrderOfOperations REDIM EveryCaseSet(100), SelectCaseCounter AS _UNSIGNED LONG @@ -23762,14 +23762,8 @@ END SUB 'Steve Subs/Functins for _MATH support with CONST FUNCTION Evaluate_Expression$ (e$) t$ = e$ 'So we preserve our original data, we parse a temp copy of it - - b = INSTR(UCASE$(e$), "EQL") 'take out assignment before the preparser sees it - IF b THEN t$ = MID$(e$, b + 3): var$ = UCASE$(LTRIM$(RTRIM$(MID$(e$, 1, b - 1)))) - - QuickReturn = 0 PreParse t$ - IF QuickReturn THEN Evaluate_Expression$ = t$: EXIT FUNCTION IF LEFT$(t$, 5) = "ERROR" THEN Evaluate_Expression$ = t$: EXIT FUNCTION @@ -23787,16 +23781,14 @@ FUNCTION Evaluate_Expression$ (e$) END IF LOOP s = Eval_E - c + 1 - IF s < 1 THEN PRINT "ERROR -- BAD () Count": END + IF s < 1 THEN Evaluate_Expression$ = "ERROR -- BAD () Count": EXIT SUB eval$ = " " + MID$(exp$, s, Eval_E - s) + " " 'pad with a space before and after so the parser can pick up the values properly. - ParseExpression eval$ + ParseExpression eval$ eval$ = LTRIM$(RTRIM$(eval$)) IF LEFT$(eval$, 5) = "ERROR" THEN Evaluate_Expression$ = eval$: EXIT SUB exp$ = DWD(LEFT$(exp$, s - 2) + eval$ + MID$(exp$, Eval_E + 1)) IF MID$(exp$, 1, 1) = "N" THEN MID$(exp$, 1) = "-" - - temppp$ = DWD(LEFT$(exp$, s - 2) + " ## " + eval$ + " ## " + MID$(exp$, E + 1)) END IF LOOP UNTIL Eval_E = 0 c = 0 @@ -23815,8 +23807,9 @@ END FUNCTION SUB ParseExpression (exp$) DIM num(10) AS STRING + 'PRINT exp$ + exp$ = DWD(exp$) 'We should now have an expression with no () to deal with - IF MID$(exp$, 2, 1) = "-" THEN exp$ = "0+" + MID$(exp$, 2) FOR J = 1 TO 250 lowest = 0 DO UNTIL lowest = LEN(exp$) @@ -23848,6 +23841,7 @@ SUB ParseExpression (exp$) CASE "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "N": numset = -1 'Valid digit CASE "-" 'We need to check if it's a minus or a negative IF OName(OpOn) = "_PI" OR numset THEN EXIT DO + CASE ",": numset = 0 CASE ELSE 'Not a valid digit, we found our separator EXIT DO END SELECT @@ -23883,13 +23877,14 @@ SUB ParseExpression (exp$) num(2) = MID$(exp$, op + LEN(OName(OpOn)), E - op - LEN(OName(OpOn)) + 1) 'Get our second number IF MID$(num(1), 1, 1) = "N" THEN MID$(num(1), 1) = "-" IF MID$(num(2), 1, 1) = "N" THEN MID$(num(2), 1) = "-" - num(3) = EvaluateNumbers(OpOn, num()) + IF num(1) = "-" THEN + num(3) = "N" + EvaluateNumbers(OpOn, num()) + ELSE + num(3) = EvaluateNumbers(OpOn, num()) + END IF IF MID$(num(3), 1, 1) = "-" THEN MID$(num(3), 1) = "N" - 'PRINT "*************" - 'PRINT num(1), OName(OpOn), num(2), num(3), exp$ IF LEFT$(num(3), 5) = "ERROR" THEN exp$ = num(3): EXIT SUB exp$ = LTRIM$(N2S(DWD(LEFT$(exp$, s) + RTRIM$(LTRIM$(num(3))) + MID$(exp$, E + 1)))) - 'PRINT exp$ END IF op = 0 LOOP @@ -23903,205 +23898,344 @@ SUB Set_OrderOfOperations 'PL sets our priortity level. 1 is highest to 65535 for the lowest. 'I used a range here so I could add in new priority levels as needed. 'OName ended up becoming the name of our commands, as I modified things.... Go figure! LOL! - + REDIM OName(10000) AS STRING, PL(10000) AS INTEGER 'Constants get evaluated first, with a Priority Level of 1 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_PI" - REDIM _PRESERVE PL(i): PL(i) = 1 - 'I'm not certain where exactly percentages should go. They kind of seem like a special case to me. COS10% should be COS.1 I'd think... - 'I'm putting it here for now, and if anyone knows someplace better for it in our order of operations, let me know. - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "%" - REDIM _PRESERVE PL(i): PL(i) = 5 + + i = i + 1: OName(i) = "C_UOF": PL(i) = 5 'convert to unsigned offset + i = i + 1: OName(i) = "C_OF": PL(i) = 5 'convert to offset + i = i + 1: OName(i) = "C_UBY": PL(i) = 5 'convert to unsigned byte + i = i + 1: OName(i) = "C_BY": PL(i) = 5 'convert to byte + i = i + 1: OName(i) = "C_UIN": PL(i) = 5 'convert to unsigned integer + i = i + 1: OName(i) = "C_IN": PL(i) = 5 'convert to integer + i = i + 1: OName(i) = "C_UIF": PL(i) = 5 'convert to unsigned int64 + i = i + 1: OName(i) = "C_IF": PL(i) = 5 'convert to int64 + i = i + 1: OName(i) = "C_ULO": PL(i) = 5 'convert to unsigned long + i = i + 1: OName(i) = "C_LO": PL(i) = 5 'convert to long + i = i + 1: OName(i) = "C_SI": PL(i) = 5 'convert to single + i = i + 1: OName(i) = "C_FL": PL(i) = 5 'convert to float + i = i + 1: OName(i) = "C_DO": PL(i) = 5 'convert to double + i = i + 1: OName(i) = "C_UBI": PL(i) = 5 'convert to unsigned bit + i = i + 1: OName(i) = "C_BI": PL(i) = 5 'convert to bit + 'Then Functions with PL 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ACOS" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ASIN" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ARCSEC" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ARCCSC" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ARCCOT" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_SECH" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_CSCH" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_COTH" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "COS" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SIN" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "TAN" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "LOG" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "EXP" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ATN" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_D2R" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_D2G" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_R2D" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_R2G" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_G2D" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_G2R" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ABS" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SGN" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "INT" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ROUND" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "FIX" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_SEC" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_CSC" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_COT" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ASC" - REDIM _PRESERVE PL(i): PL(i) = 10 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "CHR$" - REDIM _PRESERVE PL(i): PL(i) = 10 + i = i + 1:: OName(i) = "_PI": PL(i) = 10 + i = i + 1: OName(i) = "_ACOS": PL(i) = 10 + i = i + 1: OName(i) = "_ASIN": PL(i) = 10 + i = i + 1: OName(i) = "_ARCSEC": PL(i) = 10 + i = i + 1: OName(i) = "_ARCCSC": PL(i) = 10 + i = i + 1: OName(i) = "_ARCCOT": PL(i) = 10 + i = i + 1: OName(i) = "_SECH": PL(i) = 10 + i = i + 1: OName(i) = "_CSCH": PL(i) = 10 + i = i + 1: OName(i) = "_COTH": PL(i) = 10 + i = i + 1: OName(i) = "COS": PL(i) = 10 + i = i + 1: OName(i) = "SIN": PL(i) = 10 + i = i + 1: OName(i) = "TAN": PL(i) = 10 + i = i + 1: OName(i) = "LOG": PL(i) = 10 + i = i + 1: OName(i) = "EXP": PL(i) = 10 + i = i + 1: OName(i) = "ATN": PL(i) = 10 + i = i + 1: OName(i) = "_D2R": PL(i) = 10 + i = i + 1: OName(i) = "_D2G": PL(i) = 10 + i = i + 1: OName(i) = "_R2D": PL(i) = 10 + i = i + 1: OName(i) = "_R2G": PL(i) = 10 + i = i + 1: OName(i) = "_G2D": PL(i) = 10 + i = i + 1: OName(i) = "_G2R": PL(i) = 10 + i = i + 1: OName(i) = "ABS": PL(i) = 10 + i = i + 1: OName(i) = "SGN": PL(i) = 10 + i = i + 1: OName(i) = "INT": PL(i) = 10 + i = i + 1: OName(i) = "_ROUND": PL(i) = 10 + i = i + 1: OName(i) = "_CEIL": PL(i) = 10 + i = i + 1: OName(i) = "FIX": PL(i) = 10 + i = i + 1: OName(i) = "_SEC": PL(i) = 10 + i = i + 1: OName(i) = "_CSC": PL(i) = 10 + i = i + 1: OName(i) = "_COT": PL(i) = 10 + i = i + 1: OName(i) = "ASC": PL(i) = 10 + i = i + 1: OName(i) = "CHR$": PL(i) = 10 + i = i + 1: OName(i) = "C_RG": PL(i) = 10 '_RGB32 converted + i = i + 1: OName(i) = "C_RA": PL(i) = 10 '_RGBA32 converted + i = i + 1: OName(i) = "_RGB": PL(i) = 10 + i = i + 1: OName(i) = "_RGBA": PL(i) = 10 + i = i + 1: OName(i) = "C_RX": PL(i) = 10 '_RED32 converted + i = i + 1: OName(i) = "C_GR": PL(i) = 10 ' _GREEN32 converted + i = i + 1: OName(i) = "C_BL": PL(i) = 10 '_BLUE32 converted + i = i + 1: OName(i) = "C_AL": PL(i) = 10 '_ALPHA32 converted + i = i + 1: OName(i) = "_RED": PL(i) = 10 + i = i + 1: OName(i) = "_GREEN": PL(i) = 10 + i = i + 1: OName(i) = "_BLUE": PL(i) = 10 + i = i + 1: OName(i) = "_ALPHA": PL(i) = 10 'Exponents with PL 20 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "^" - REDIM _PRESERVE PL(i): PL(i) = 20 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SQR" - REDIM _PRESERVE PL(i): PL(i) = 20 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ROOT" - REDIM _PRESERVE PL(i): PL(i) = 20 + i = i + 1: OName(i) = "^": PL(i) = 20 + i = i + 1: OName(i) = "SQR": PL(i) = 20 + i = i + 1: OName(i) = "ROOT": PL(i) = 20 'Multiplication and Division PL 30 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "*" - REDIM _PRESERVE PL(i): PL(i) = 30 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "/" - REDIM _PRESERVE PL(i): PL(i) = 30 + i = i + 1: OName(i) = "*": PL(i) = 30 + i = i + 1: OName(i) = "/": PL(i) = 30 'Integer Division PL 40 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "\" - REDIM _PRESERVE PL(i): PL(i) = 40 + i = i + 1: OName(i) = "\": PL(i) = 40 'MOD PL 50 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "MOD" - REDIM _PRESERVE PL(i): PL(i) = 50 + i = i + 1: OName(i) = "MOD": PL(i) = 50 'Addition and Subtraction PL 60 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "+" - REDIM _PRESERVE PL(i): PL(i) = 60 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "-" - REDIM _PRESERVE PL(i): PL(i) = 60 + i = i + 1: OName(i) = "+": PL(i) = 60 + i = i + 1: OName(i) = "-": PL(i) = 60 'Relational Operators =, >, <, <>, <=, >= PL 70 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "<>" - REDIM _PRESERVE PL(i): PL(i) = 70 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "><" 'These next three are just reversed symbols as an attempt to help process a common typo - REDIM _PRESERVE PL(i): PL(i) = 70 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "<=" - REDIM _PRESERVE PL(i): PL(i) = 70 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = ">=" - REDIM _PRESERVE PL(i): PL(i) = 70 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "=<" 'I personally can never keep these things straight. Is it < = or = <... - REDIM _PRESERVE PL(i): PL(i) = 70 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "=>" 'Who knows, check both! - REDIM _PRESERVE PL(i): PL(i) = 70 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = ">" - REDIM _PRESERVE PL(i): PL(i) = 70 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "<" - REDIM _PRESERVE PL(i): PL(i) = 70 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "=" - REDIM _PRESERVE PL(i): PL(i) = 70 + i = i + 1: OName(i) = "<>": PL(i) = 70 'These next three are just reversed symbols as an attempt to help process a common typo + i = i + 1: OName(i) = "><": PL(i) = 70 + i = i + 1: OName(i) = "<=": PL(i) = 70 + i = i + 1: OName(i) = ">=": PL(i) = 70 + i = i + 1: OName(i) = "=<": PL(i) = 70 'I personally can never keep these things straight. Is it < = or = <... + i = i + 1: OName(i) = "=>": PL(i) = 70 'Who knows, check both! + i = i + 1: OName(i) = ">": PL(i) = 70 + i = i + 1: OName(i) = "<": PL(i) = 70 + i = i + 1: OName(i) = "=": PL(i) = 70 'Logical Operations PL 80+ - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "NOT" - REDIM _PRESERVE PL(i): PL(i) = 80 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "AND" - REDIM _PRESERVE PL(i): PL(i) = 90 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "OR" - REDIM _PRESERVE PL(i): PL(i) = 100 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "XOR" - REDIM _PRESERVE PL(i): PL(i) = 110 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "EQV" - REDIM _PRESERVE PL(i): PL(i) = 120 - i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "IMP" - REDIM _PRESERVE PL(i): PL(i) = 130 + i = i + 1: OName(i) = "NOT": PL(i) = 80 + i = i + 1: OName(i) = "AND": PL(i) = 90 + i = i + 1: OName(i) = "OR": PL(i) = 100 + i = i + 1: OName(i) = "XOR": PL(i) = 110 + i = i + 1: OName(i) = "EQV": PL(i) = 120 + i = i + 1: OName(i) = "IMP": PL(i) = 130 + i = i + 1: OName(i) = ",": PL(i) = 1000 + REDIM _PRESERVE OName(i) AS STRING, PL(i) AS INTEGER END SUB FUNCTION EvaluateNumbers$ (p, num() AS STRING) DIM n1 AS _FLOAT, n2 AS _FLOAT, n3 AS _FLOAT - SELECT CASE OName(p) 'Depending on our operator.. - CASE "_PI": n1 = 3.14159265358979323846264338327950288## 'Future compatable in case something ever stores extra digits for PI - CASE "%": n1 = (VAL(num(1))) / 100 'Note percent is a special case and works with the number BEFORE the % command and not after - CASE "_ACOS": n1 = _ACOS(VAL(num(2))) - CASE "_ASIN": n1 = _ASIN(VAL(num(2))) - CASE "_ARCSEC": n1 = _ARCSEC(VAL(num(2))) - CASE "_ARCCSC": n1 = _ARCCSC(VAL(num(2))) - CASE "_ARCCOT": n1 = _ARCCOT(VAL(num(2))) - CASE "_SECH": n1 = _SECH(VAL(num(2))) - CASE "_CSCH": n1 = _CSCH(VAL(num(2))) - CASE "_COTH": n1 = _COTH(VAL(num(2))) - CASE "COS": n1 = COS(VAL(num(2))) - CASE "SIN": n1 = SIN(VAL(num(2))) - CASE "TAN": n1 = TAN(VAL(num(2))) - CASE "LOG": n1 = LOG(VAL(num(2))) - CASE "EXP": n1 = EXP(VAL(num(2))) - CASE "ATN": n1 = ATN(VAL(num(2))) - CASE "_D2R": n1 = 0.0174532925 * (VAL(num(2))) - CASE "_D2G": n1 = 1.1111111111 * (VAL(num(2))) - CASE "_R2D": n1 = 57.2957795 * (VAL(num(2))) - CASE "_R2G": n1 = 0.015707963 * (VAL(num(2))) - CASE "_G2D": n1 = 0.9 * (VAL(num(2))) - CASE "_G2R": n1 = 63.661977237 * (VAL(num(2))) - CASE "ABS": n1 = ABS(VAL(num(2))) - CASE "SGN": n1 = SGN(VAL(num(2))) - CASE "INT": n1 = INT(VAL(num(2))) - CASE "_ROUND": n1 = _ROUND(VAL(num(2))) - CASE "FIX": n1 = FIX(VAL(num(2))) - CASE "_SEC": n1 = _SEC(VAL(num(2))) - CASE "_CSC": n1 = _CSC(VAL(num(2))) - CASE "_COT": n1 = _COT(VAL(num(2))) - CASE "^": n1 = VAL(num(1)) ^ VAL(num(2)) - CASE "SQR": n1 = SQR(VAL(num(2))) - CASE "ROOT" - n1 = VAL(num(1)): n2 = VAL(num(2)) - IF n2 = 1 THEN EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1))): EXIT FUNCTION - IF n1 < 0 AND n2 >= 1 THEN sign = -1: n1 = -n1 ELSE sign = 1 - n3 = 1## / n2 - IF n3 <> INT(n3) AND n2 < 1 THEN sign = SGN(n1): n1 = ABS(n1) - n1 = sign * (n1 ^ n3) - CASE "*": n1 = VAL(num(1)) * VAL(num(2)) - CASE "/": n1 = VAL(num(1)) / VAL(num(2)) - CASE "\" - IF VAL(num(2)) <> 0 THEN - n1 = VAL(num(1)) \ VAL(num(2)) - ELSE - EvaluateNumbers$ = "ERROR - Division By Zero" - EXIT FUNCTION - END IF - CASE "MOD": n1 = VAL(num(1)) MOD VAL(num(2)) - CASE "+": n1 = VAL(num(1)) + VAL(num(2)) - CASE "-": n1 = VAL(num(1)) - VAL(num(2)) - CASE "=": n1 = VAL(num(1)) = VAL(num(2)) - CASE ">": n1 = VAL(num(1)) > VAL(num(2)) - CASE "<": n1 = VAL(num(1)) < VAL(num(2)) - CASE "<>", "><": n1 = VAL(num(1)) <> VAL(num(2)) - CASE "<=", "=<": n1 = VAL(num(1)) <= VAL(num(2)) - CASE ">=", "=>": n1 = VAL(num(1)) >= VAL(num(2)) - CASE "NOT": n1 = NOT VAL(num(2)) - CASE "AND": n1 = VAL(num(1)) AND VAL(num(2)) - CASE "OR": n1 = VAL(num(1)) OR VAL(num(2)) - CASE "XOR": n1 = VAL(num(1)) XOR VAL(num(2)) - CASE "EQV": n1 = VAL(num(1)) EQV VAL(num(2)) - CASE "IMP": n1 = VAL(num(1)) IMP VAL(num(2)) - CASE ELSE - EvaluateNumbers$ = "ERROR - Bad operation (We shouldn't see this)" 'Let's say we're bad... + 'PRINT "EVALNUM:"; OName(p), num(1), num(2) + IF INSTR(num(1), ",") THEN + EvaluateNumbers$ = "ERROR - Invalid comma (" + num(1) + ")": EXIT FUNCTION + END IF + l2 = INSTR(num(2), ",") + IF l2 THEN + SELECT CASE OName(p) 'only certain commands should pass a comma value + CASE "C_RG", "C_RA", "_RGB", "_RGBA", "_RED", "_GREEN", "C_BL", "_ALPHA" + CASE ELSE + C$ = MID$(num(2), l2) + num(2) = LEFT$(num(2), l2 - 1) + END SELECT + END IF + + SELECT CASE PL(p) 'divide up the work so we want do as much case checking + CASE 5 'Type conversions + 'Note, these are special cases and work with the number BEFORE the command and not after + SELECT CASE OName(p) 'Depending on our operator.. + CASE "C_UOF": n1~%& = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1~%&))) + CASE "C_ULO": n1%& = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1%&))) + CASE "C_UBY": n1~%% = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1~%%))) + CASE "C_UIN": n1~% = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1~%))) + CASE "C_BY": n1%% = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1%%))) + CASE "C_IN": n1% = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1%))) + CASE "C_UIF": n1~&& = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1~&&))) + CASE "C_OF": n1~& = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1~&))) + CASE "C_IF": n1&& = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1&&))) + CASE "C_LO": n1& = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1&))) + CASE "C_UBI": n1~` = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1~`))) + CASE "C_BI": n1` = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1`))) + CASE "C_FL": n1## = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1##))) + CASE "C_DO": n1# = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1#))) + CASE "C_SI": n1! = VAL(num(1)): EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1!))) + END SELECT + EXIT FUNCTION + CASE 10 'functions + SELECT CASE OName(p) 'Depending on our operator.. + CASE "_PI" + n1 = 3.14159265358979323846264338327950288## 'Future compatable in case something ever stores extra digits for PI + IF num(2) <> "" THEN n1 = n1 * VAL(num(2)) + CASE "_ACOS": n1 = _ACOS(VAL(num(2))) + CASE "_ASIN": n1 = _ASIN(VAL(num(2))) + CASE "_ARCSEC": n1 = _ARCSEC(VAL(num(2))) + CASE "_ARCCSC": n1 = _ARCCSC(VAL(num(2))) + CASE "_ARCCOT": n1 = _ARCCOT(VAL(num(2))) + CASE "_SECH": n1 = _SECH(VAL(num(2))) + CASE "_CSCH": n1 = _CSCH(VAL(num(2))) + CASE "_COTH": n1 = _COTH(VAL(num(2))) + CASE "C_RG" + n$ = num(2) + IF n$ = "" THEN EvaluateNumbers$ = "ERROR - Invalid null _RGB32": EXIT FUNCTION + c1 = INSTR(n$, ",") + IF c1 THEN c2 = INSTR(c1 + 1, n$, ",") + IF c2 THEN c3 = INSTR(c2 + 1, n$, ",") + IF c3 THEN c4 = INSTR(c3 + 1, n$, ",") + IF c1 = 0 THEN 'there's no comma in the command to parse. It's a grayscale value + n = VAL(num(2)) + n1 = _RGB32(n, n, n) + ELSEIF c2 = 0 THEN 'there's one comma and not 2. It's grayscale with alpha. + n = VAL(LEFT$(num(2), c1)) + n2 = VAL(MID$(num(2), c1 + 1)) + n1 = _RGBA32(n, n, n, n2) + ELSEIF c3 = 0 THEN 'there's two commas. It's _RGB values + n = VAL(LEFT$(num(2), c1)) + n2 = VAL(MID$(num(2), c1 + 1)) + n3 = VAL(MID$(num(2), c2 + 1)) + n1 = _RGB32(n, n2, n3) + ELSEIF c4 = 0 THEN 'there's three commas. It's _RGBA values + n = VAL(LEFT$(num(2), c1)) + n2 = VAL(MID$(num(2), c1 + 1)) + n3 = VAL(MID$(num(2), c2 + 1)) + n4 = VAL(MID$(num(2), c3 + 1)) + n1 = _RGBA32(n, n2, n3, n4) + ELSE 'we have more than three commas. I have no idea WTH type of values got passed here! + EvaluateNumbers$ = "ERROR - Invalid comma count (" + num(2) + ")": EXIT FUNCTION + END IF + CASE "C_RA" + n$ = num(2) + IF n$ = "" THEN EvaluateNumbers$ = "ERROR - Invalid null _RGBA32": EXIT FUNCTION + c1 = INSTR(n$, ",") + IF c1 THEN c2 = INSTR(c1 + 1, n$, ",") + IF c2 THEN c3 = INSTR(c2 + 1, n$, ",") + IF c3 THEN c4 = INSTR(c3 + 1, n$, ",") + IF c3 = 0 OR c4 <> 0 THEN EvaluateNumbers$ = "ERROR - Invalid comma count (" + num(2) + ")": EXIT FUNCTION + 'we have to have 3 commas; not more, not less. + n = VAL(LEFT$(num(2), c1)) + n2 = VAL(MID$(num(2), c1 + 1)) + n3 = VAL(MID$(num(2), c2 + 1)) + n4 = VAL(MID$(num(2), c3 + 1)) + n1 = _RGBA32(n, n2, n3, n4) + CASE "_RGB" + n$ = num(2) + IF n$ = "" THEN EvaluateNumbers$ = "ERROR - Invalid null _RGB": EXIT FUNCTION + c1 = INSTR(n$, ",") + IF c1 THEN c2 = INSTR(c1 + 1, n$, ",") + IF c2 THEN c3 = INSTR(c2 + 1, n$, ",") + IF c3 THEN c4 = INSTR(c3 + 1, n$, ",") + IF c3 = 0 OR c4 <> 0 THEN EvaluateNumbers$ = "ERROR - Invalid comma count (" + num(2) + "). _RGB requires 4 parameters for Red, Green, Blue, ScreenMode.": EXIT FUNCTION + 'we have to have 3 commas; not more, not less. + n = VAL(LEFT$(num(2), c1)) + n2 = VAL(MID$(num(2), c1 + 1)) + n3 = VAL(MID$(num(2), c2 + 1)) + n4 = VAL(MID$(num(2), c3 + 1)) + SELECT CASE n4 + CASE 0 TO 2, 7 TO 13, 256, 32 'these are the good screen values + CASE ELSE + EvaluateNumbers$ = "ERROR - Invalid Screen Mode (" + STR$(n4) + ")": EXIT FUNCTION + END SELECT + t = _NEWIMAGE(1, 1, n4) + n1 = _RGB(n, n2, n3, t) + _FREEIMAGE t + CASE "_RGBA" + n$ = num(2) + IF n$ = "" THEN EvaluateNumbers$ = "ERROR - Invalid null _RGBA": EXIT FUNCTION + c1 = INSTR(n$, ",") + IF c1 THEN c2 = INSTR(c1 + 1, n$, ",") + IF c2 THEN c3 = INSTR(c2 + 1, n$, ",") + IF c3 THEN c4 = INSTR(c3 + 1, n$, ",") + IF c4 THEN c5 = INSTR(c4 + 1, n$, ",") + IF c4 = 0 OR c5 <> 0 THEN EvaluateNumbers$ = "ERROR - Invalid comma count (" + num(2) + "). _RGBA requires 5 parameters for Red, Green, Blue, Alpha, ScreenMode.": EXIT FUNCTION + 'we have to have 4 commas; not more, not less. + n = VAL(LEFT$(num(2), c1)) + n2 = VAL(MID$(num(2), c1 + 1)) + n3 = VAL(MID$(num(2), c2 + 1)) + n4 = VAL(MID$(num(2), c3 + 1)) + n5 = VAL(MID$(num(2), c4 + 1)) + SELECT CASE n5 + CASE 0 TO 2, 7 TO 13, 256, 32 'these are the good screen values + CASE ELSE + EvaluateNumbers$ = "ERROR - Invalid Screen Mode (" + STR$(n5) + ")": EXIT FUNCTION + END SELECT + t = _NEWIMAGE(1, 1, n5) + n1 = _RGBA(n, n2, n3, n4, t) + _FREEIMAGE t + CASE "_RED", "_GREEN", "_BLUE", "_ALPHA" + n$ = num(2) + IF n$ = "" THEN EvaluateNumbers$ = "ERROR - Invalid null " + OName(p): EXIT FUNCTION + c1 = INSTR(n$, ",") + IF c1 = 0 THEN EvaluateNumbers$ = "ERROR - " + OName(p) + " requires 2 parameters for Color, ScreenMode.": EXIT FUNCTION + IF c1 THEN c2 = INSTR(c1 + 1, n$, ",") + IF c2 THEN EvaluateNumbers$ = "ERROR - " + OName(p) + " requires 2 parameters for Color, ScreenMode.": EXIT FUNCTION + n = VAL(LEFT$(num(2), c1)) + n2 = VAL(MID$(num(2), c1 + 1)) + SELECT CASE n2 + CASE 0 TO 2, 7 TO 13, 256, 32 'these are the good screen values + CASE ELSE + EvaluateNumbers$ = "ERROR - Invalid Screen Mode (" + STR$(n2) + ")": EXIT FUNCTION + END SELECT + t = _NEWIMAGE(1, 1, n4) + SELECT CASE OName(p) + CASE "_RED": n1 = _RED(n, t) + CASE "_BLUE": n1 = _BLUE(n, t) + CASE "_GREEN": n1 = _GREEN(n, t) + CASE "_ALPHA": n1 = _ALPHA(n, t) + END SELECT + _FREEIMAGE t + CASE "C_RX", "C_GR", "C_BL", "C_AL" + n$ = num(2) + IF n$ = "" THEN EvaluateNumbers$ = "ERROR - Invalid null " + OName(p): EXIT FUNCTION + n = VAL(num(2)) + SELECT CASE OName(p) + CASE "C_RX": n1 = _RED32(n) + CASE "C_BL": n1 = _BLUE32(n) + CASE "C_GR": n1 = _GREEN32(n) + CASE "C_AL": n1 = _ALPHA32(n) + END SELECT + CASE "COS": n1 = COS(VAL(num(2))) + CASE "SIN": n1 = SIN(VAL(num(2))) + CASE "TAN": n1 = TAN(VAL(num(2))) + CASE "LOG": n1 = LOG(VAL(num(2))) + CASE "EXP": n1 = EXP(VAL(num(2))) + CASE "ATN": n1 = ATN(VAL(num(2))) + CASE "_D2R": n1 = 0.0174532925 * (VAL(num(2))) + CASE "_D2G": n1 = 1.1111111111 * (VAL(num(2))) + CASE "_R2D": n1 = 57.2957795 * (VAL(num(2))) + CASE "_R2G": n1 = 0.015707963 * (VAL(num(2))) + CASE "_G2D": n1 = 0.9 * (VAL(num(2))) + CASE "_G2R": n1 = 63.661977237 * (VAL(num(2))) + CASE "ABS": n1 = ABS(VAL(num(2))) + CASE "SGN": n1 = SGN(VAL(num(2))) + CASE "INT": n1 = INT(VAL(num(2))) + CASE "_ROUND": n1 = _ROUND(VAL(num(2))) + CASE "_CEIL": n1 = _CEIL(VAL(num(2))) + CASE "FIX": n1 = FIX(VAL(num(2))) + CASE "_SEC": n1 = _SEC(VAL(num(2))) + CASE "_CSC": n1 = _CSC(VAL(num(2))) + CASE "_COT": n1 = _COT(VAL(num(2))) + END SELECT + CASE 20 TO 60 'Math Operators + SELECT CASE OName(p) 'Depending on our operator.. + CASE "^": n1 = VAL(num(1)) ^ VAL(num(2)) + CASE "SQR": n1 = SQR(VAL(num(2))) + CASE "ROOT" + n1 = VAL(num(1)): n2 = VAL(num(2)) + IF n2 = 1 THEN EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1))): EXIT FUNCTION + IF n1 < 0 AND n2 >= 1 THEN sign = -1: n1 = -n1 ELSE sign = 1 + n3 = 1## / n2 + IF n3 <> INT(n3) AND n2 < 1 THEN sign = SGN(n1): n1 = ABS(n1) + n1 = sign * (n1 ^ n3) + CASE "*": n1 = VAL(num(1)) * VAL(num(2)) + CASE "/": n1 = VAL(num(1)) / VAL(num(2)) + CASE "\" + IF VAL(num(2)) <> 0 THEN + n1 = VAL(num(1)) \ VAL(num(2)) + ELSE + EvaluateNumbers$ = "ERROR - Bad operation (We shouldn't see this)" + EXIT FUNCTION + END IF + CASE "MOD": n1 = VAL(num(1)) MOD VAL(num(2)) + CASE "+": n1 = VAL(num(1)) + VAL(num(2)) + CASE "-": + n1 = VAL(num(1)) - VAL(num(2)) + END SELECT + CASE 70 'Relational Operators =, >, <, <>, <=, >= + SELECT CASE OName(p) 'Depending on our operator.. + CASE "=": n1 = VAL(num(1)) = VAL(num(2)) + CASE ">": n1 = VAL(num(1)) > VAL(num(2)) + CASE "<": n1 = VAL(num(1)) < VAL(num(2)) + CASE "<>", "><": n1 = VAL(num(1)) <> VAL(num(2)) + CASE "<=", "=<": n1 = VAL(num(1)) <= VAL(num(2)) + CASE ">=", "=>": n1 = VAL(num(1)) >= VAL(num(2)) + END SELECT + CASE ELSE 'a value we haven't processed elsewhere + SELECT CASE OName(p) 'Depending on our operator.. + CASE "NOT": n1 = NOT VAL(num(2)) + CASE "AND": n1 = VAL(num(1)) AND VAL(num(2)) + CASE "OR": n1 = VAL(num(1)) OR VAL(num(2)) + CASE "XOR": n1 = VAL(num(1)) XOR VAL(num(2)) + CASE "EQV": n1 = VAL(num(1)) EQV VAL(num(2)) + CASE "IMP": n1 = VAL(num(1)) IMP VAL(num(2)) + END SELECT END SELECT - EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1))) + + EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1))) + C$ END FUNCTION FUNCTION DWD$ (exp$) 'Deal With Duplicates @@ -24129,14 +24263,42 @@ FUNCTION DWD$ (exp$) 'Deal With Duplicates l = INSTR(t$, "--") IF l THEN t$ = LEFT$(t$, l - 1) + "+" + MID$(t$, l + 2): bad = -1 LOOP UNTIL l = 0 + 'PRINT "FIXING: "; t$ LOOP UNTIL NOT bad DWD$ = t$ - VerifyString t$ END FUNCTION SUB PreParse (e$) DIM f AS _FLOAT + IF PP_TypeMod(0) = "" THEN + REDIM PP_TypeMod(100) AS STRING, PP_ConvertedMod(100) AS STRING 'Large enough to hold all values to begin with + PP_TypeMod(0) = "Initialized" 'Set so we don't do this section over and over, as we keep the values in shared memory. + Set_OrderOfOperations 'Call this once to set up our proper order of operations and variable list + 'and the below is a conversion list so symbols don't get cross confused. + i = i + 1: PP_TypeMod(i) = "~`": PP_ConvertedMod(i) = "C_UBI" 'unsigned bit + i = i + 1: PP_TypeMod(i) = "~%%": PP_ConvertedMod(i) = "C_UBY" 'unsigned byte + i = i + 1: PP_TypeMod(i) = "~%&": PP_ConvertedMod(i) = "C_UOF" 'unsigned offset + i = i + 1: PP_TypeMod(i) = "~%": PP_ConvertedMod(i) = "C_UIN" 'unsigned integer + i = i + 1: PP_TypeMod(i) = "~&&": PP_ConvertedMod(i) = "C_UIF" 'unsigned integer64 + i = i + 1: PP_TypeMod(i) = "~&": PP_ConvertedMod(i) = "C_ULO" 'unsigned long + i = i + 1: PP_TypeMod(i) = "`": PP_ConvertedMod(i) = "C_BI" 'bit + i = i + 1: PP_TypeMod(i) = "%%": PP_ConvertedMod(i) = "C_BY" 'byte + i = i + 1: PP_TypeMod(i) = "%&": PP_ConvertedMod(i) = "C_OF" 'offset + i = i + 1: PP_TypeMod(i) = "%": PP_ConvertedMod(i) = "C_IN" 'integer + i = i + 1: PP_TypeMod(i) = "&&": PP_ConvertedMod(i) = "C_IF" 'integer64 + i = i + 1: PP_TypeMod(i) = "&": PP_ConvertedMod(i) = "C_LO" 'long + i = i + 1: PP_TypeMod(i) = "!": PP_ConvertedMod(i) = "C_SI" 'single + i = i + 1: PP_TypeMod(i) = "##": PP_ConvertedMod(i) = "C_FL" 'float + i = i + 1: PP_TypeMod(i) = "#": PP_ConvertedMod(i) = "C_DO" 'double + i = i + 1: PP_TypeMod(i) = "_RGB32": PP_ConvertedMod(i) = "C_RG" 'rgb32 + i = i + 1: PP_TypeMod(i) = "_RGBA32": PP_ConvertedMod(i) = "C_RA" 'rgba32 + i = i + 1: PP_TypeMod(i) = "_RED32": PP_ConvertedMod(i) = "C_RX" 'red32 + i = i + 1: PP_TypeMod(i) = "_GREEN32": PP_ConvertedMod(i) = "C_GR" 'green32 + i = i + 1: PP_TypeMod(i) = "_BLUE32": PP_ConvertedMod(i) = "C_BL" 'blue32 + i = i + 1: PP_TypeMod(i) = "_ALPHA32": PP_ConvertedMod(i) = "C_AL" 'alpha32 + REDIM _PRESERVE PP_TypeMod(i) AS STRING, PP_ConvertedMod(i) AS STRING 'And then resized to just contain the necessary space in memory + END IF t$ = e$ 'First strip all spaces @@ -24179,6 +24341,34 @@ SUB PreParse (e$) END IF LOOP UNTIL l = 0 + FOR j = 1 TO UBOUND(PP_TypeMod) + l = 0 + DO + l = INSTR(l + 1, t$, PP_TypeMod(j)) + IF l = 0 THEN EXIT DO + i = 0: l1 = 0: l2 = 0: lo = LEN(PP_TypeMod(j)) + DO + IF PL(i) > 10 THEN + l2 = _INSTRREV(l, t$, OName$(i)) + IF l2 > 0 AND l2 > l1 THEN l1 = l2 + END IF + i = i + lo + LOOP UNTIL i > UBOUND(PL) + l$ = LEFT$(t$, l1) + m$ = MID$(t$, l1 + 1, l - l1 - 1) + r$ = PP_ConvertedMod(j) + MID$(t$, l + lo) + IF j > 15 THEN + t$ = l$ + m$ + r$ 'replacement routine for commands which might get confused with others, like _RGB and _RGB32 + ELSE + 'the first 15 commands need to properly place the parenthesis around the value we want to convert. + t$ = l$ + "(" + m$ + ")" + r$ + END IF + l = l + 2 + LEN(PP_TypeMod(j)) 'move forward from the length of the symbol we checked + the new "(" and ")" + LOOP + NEXT + + + 'Check for bad operators before a ( bracket l = 0 DO @@ -24186,7 +24376,8 @@ SUB PreParse (e$) IF l AND l > 2 THEN 'Don't check the starting bracket; there's nothing before it. good = 0 FOR i = 1 TO UBOUND(OName) - IF MID$(t$, l - LEN(OName(i)), LEN(OName(i))) = OName(i) AND PL(i) > 1 AND PL(i) <= 250 THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) + m$ = MID$(t$, l - LEN(OName(i)), LEN(OName(i))) + IF m$ = OName(i) THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) NEXT IF NOT good THEN e$ = "ERROR - Improper operations before (.": EXIT SUB l = l + 1 @@ -24199,8 +24390,9 @@ SUB PreParse (e$) l = INSTR(l + 1, t$, ")") IF l AND l < LEN(t$) THEN good = 0 - FOR i = 1 TO UBOUND(OName) - IF MID$(t$, l + 1, LEN(OName(i))) = OName(i) AND PL(i) > 1 AND PL(i) <= 250 THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) + FOR i = 1 TO UBOUND(oname) + m$ = MID$(t$, l + 1, LEN(OName(i))) + IF m$ = OName(i) THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI NEXT IF MID$(t$, l + 1, 1) = ")" THEN good = -1 IF NOT good THEN e$ = "ERROR - Improper operations after ).": EXIT SUB @@ -24221,7 +24413,7 @@ SUB PreParse (e$) CASE "0" TO "9", "A" TO "F" 'All is good, our next digit is a number, continue to add to the hex$ CASE ELSE good = 0 - FOR i = 1 TO UBOUND(OName) + FOR i = 1 TO UBOUND(oname) IF MID$(t$, E, LEN(OName(i))) = OName(i) AND PL(i) > 1 AND PL(i) <= 250 THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) NEXT IF NOT good THEN e$ = "ERROR - Improper &H value. (" + comp$ + ")": EXIT SUB @@ -24246,7 +24438,7 @@ SUB PreParse (e$) CASE "0", "1" 'All is good, our next digit is a number, continue to add to the hex$ CASE ELSE good = 0 - FOR i = 1 TO UBOUND(OName) + FOR i = 1 TO UBOUND(oname) IF MID$(t$, E, LEN(OName(i))) = OName(i) AND PL(i) > 1 AND PL(i) <= 250 THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) NEXT IF NOT good THEN e$ = "ERROR - Improper &B value. (" + comp$ + ")": EXIT SUB @@ -24262,9 +24454,9 @@ SUB PreParse (e$) END IF LOOP UNTIL l = 0 + t$ = N2S(t$) VerifyString t$ - e$ = t$ END SUB @@ -24276,7 +24468,7 @@ SUB VerifyString (t$) DO comp$ = MID$(t$, j, 1) SELECT CASE comp$ - CASE "0" TO "9", ".", "(", ")": j = j + 1 + CASE "0" TO "9", ".", "(", ")", ",": j = j + 1 CASE ELSE good = 0 FOR i = 1 TO UBOUND(OName) @@ -24289,8 +24481,9 @@ SUB VerifyString (t$) END SUB FUNCTION N2S$ (exp$) 'scientific Notation to String + t$ = LTRIM$(RTRIM$(exp$)) - IF LEFT$(t$, 1) = "-" THEN sign$ = "-": t$ = MID$(t$, 2) + IF LEFT$(t$, 1) = "-" OR LEFT$(t$, 1) = "N" THEN sign$ = "-": t$ = MID$(t$, 2) dp = INSTR(t$, "D+"): dm = INSTR(t$, "D-") ep = INSTR(t$, "E+"): em = INSTR(t$, "E-")