Author Topic: a super simple eval  (Read 271 times)

Online jack

  • Forum Regular
  • Posts: 198
a super simple eval
« on: May 22, 2020, 01:10:32 PM »
example input
5!
-2^2
Code: [Select]
a$ = " "

WHILE a$ <> ""
    INPUT a$
    result# = eval(a$)
    PRINT result#
WEND
END

FUNCTION eval# (ee AS STRING)
    DIM i AS INTEGER
    DIM id AS INTEGER
    DIM l AS INTEGER
    DIM aa AS STRING
    DIM d2 AS STRING
    DIM e2 AS STRING
    DIM s2 AS STRING
    DIM ch2 AS STRING
    DIM g AS DOUBLE
    DIM x AS DOUBLE
    DIM fc AS DOUBLE
    DIM v#(20)
    e2 = UCASE$(ee)

    IF LEN(e2) = 0 THEN e2 = "0"

    i = 1: id = 0: l = LEN(e2): s2 = ""
    GOSUB scan
    GOSUB expr

    IF ch2 <> " " THEN
        PRINT
        PRINT "Syntax Error"
        PRINT
    END IF
    eval# = v#(0)
    EXIT FUNCTION
    '================================
    scan:
    IF i > l THEN
        ch2 = " "
        RETURN
    END IF
    ch2 = MID$(e2, i, 1)
    i = i + 1
    IF ch2 = " " THEN GOSUB scan
    RETURN

    unary:
    IF ch2 = "-" OR ch2 = "+" THEN
        s2 = s2 + ch2
        GOSUB scan
        GOSUB term
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa <> "-" THEN RETURN
        v#(id - 1) = -v#(id - 1)
        RETURN
    END IF
    GOSUB factor
    RETURN

    gamma:
    GOSUB unary
    WHILE ch2 = "!"
        x = v#(id - 1)
        GOSUB factorial
        v#(id - 1) = g
        GOSUB scan
    WEND
    RETURN

    expon:
    GOSUB gamma
    WHILE ch2 = "^"
        GOSUB scan
        GOSUB gamma
        id = id - 1
        v#(id - 1) = v#(id - 1) ^ v#(id)
    WEND
    RETURN

    term:
    GOSUB expon
    WHILE (ch2 = "*" OR ch2 = "/")
        s2 = s2 + ch2
        GOSUB scan
        GOSUB expon
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa = "*" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) * v#(id)
        END IF
        IF aa = "/" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) / v#(id)
        END IF
    WEND
    RETURN

    expr:
    GOSUB term
    WHILE (ch2 = "-" OR ch2 = "+")
        s2 = s2 + ch2
        GOSUB scan
        GOSUB term
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa = "-" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) - v#(id)
        END IF
        IF aa = "+" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) + v#(id)
        END IF
    WEND
    RETURN


    factor:
    IF INSTR(".0123456789", ch2) THEN
        d2 = ""
        WHILE INSTR("DE.0123456789", ch2)
            d2 = d2 + ch2
            GOSUB scan
        WEND
        v#(id) = VAL(d2)
        id = id + 1
        RETURN
    END IF
    IF ch2 = "-" OR ch2 = "+" THEN GOSUB unary
    GOSUB scan
    GOSUB expr
    IF ch2 = ")" THEN
        GOSUB scan
    ELSE
        PRINT
        PRINT "Missing ')'"
    END IF
    RETURN


    factorial:
    g = 1
    FOR fc = 1 TO x
        g = g * fc
    NEXT fc
    RETURN

END FUNCTION
« Last Edit: Yesterday at 03:00:27 AM by jack »

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 758
  • Savage.
Re: a super simple eval
« Reply #1 on: May 22, 2020, 01:34:44 PM »
Nice, someone can probably make a decent calculator out of this.
(spaghetti) code and (meat)balls

Online jack

  • Forum Regular
  • Posts: 198
Re: a super simple eval
« Reply #2 on: May 22, 2020, 02:11:20 PM »
it's very basic, I mainly wrote it so I could enter coefficients for polynomial calculations like -1/3!
« Last Edit: Yesterday at 01:46:58 AM by jack »

Offline MasterGy

  • Newbie
  • Posts: 40
  • people lie, math never lies
Re: a super simple eval
« Reply #3 on: May 22, 2020, 02:30:54 PM »
i like it !

Online jack

  • Forum Regular
  • Posts: 198
Re: a super simple eval
« Reply #4 on: May 22, 2020, 02:48:38 PM »
to illustrate, this program calculates the reverse of a power series, the first term must <>0 and no zero term as for example the cosine function
example input
"Number of input polynomial "; 7
1
ENTER
-1/3!
ENTER
1/5!
ENTER
-1/7!

Code: [Select]
a$ = ""

CLS
PRINT
PRINT "this program computes g(y)=f(h(x)^-1)."
PRINT "where the f(i) coefficients are optional."
PRINT "if the f(i) are omitted, then g(y)=h(x)^-1 is computed."
PRINT
INPUT "Number of input polynomial "; n%

DIM a#(n%), b#(n%), c#(n%), d#(n%), e#, t#
DIM i3%, j%, k%, k0%
a$ = ""
PRINT
PRINT "Enter coefficients as prompted"
PRINT "if the coefficient is 0 then just press Enter"
PRINT
FOR i3% = 1 TO n%
    PRINT USING "a(###) = "; i3%;
    INPUT a$
    IF a$ = "" THEN a$ = "0"
    c#(i3%) = eval(a$)
NEXT i3%
PRINT
INPUT "Want to enter a transformation polynomial (y/n) "; a$
a$ = UCASE$(a$)
IF a$ <> "Y" THEN
    a#(1) = 1
    GOTO skipt
END IF
PRINT
PRINT "Enter transformation coefficients as prompted"
PRINT "if the coefficient is 0 then just press Enter"
PRINT
FOR i3% = 1 TO n%
    PRINT USING "a(###) = "; i3%;
    INPUT a$
    IF a$ = "" THEN a$ = "0"
    a#(i3%) = eval(a$)
NEXT i3%
skipt:
t# = 1
FOR i3% = 1 TO n%
    t# = t# / c#(1)
    b#(i3%) = a#(i3%) * t#
    d#(i3%) = c#(i3%) * t#
NEXT i3%
IF n% < 2 THEN GOTO skip
FOR k% = 2 TO n%
    e# = -d#(k%)
    k0% = k% - 1
    FOR i3% = k% TO n%
        FOR j% = i3% TO n%
            b#(j%) = e# * b#(j% - k0%) + b#(j%)
            d#(j%) = e# * d#(j% - k0%) + d#(j%)
        NEXT j%
    NEXT i3%
NEXT k%
skip:
CLS
PRINT
PRINT "The reversed Polynomial coefficients are:"
PRINT
FOR i3% = 1 TO n%
    IF b#(i3%) <> 0 THEN
        PRINT USING "b(###) = "; i3%;
        PRINT b#(i3%)
    END IF
NEXT i3%
INPUT "press return to end"; a$
END

FUNCTION eval# (ee AS STRING)
    DIM i AS INTEGER
    DIM id AS INTEGER
    DIM l AS INTEGER
    DIM aa AS STRING
    DIM d2 AS STRING
    DIM e2 AS STRING
    DIM s2 AS STRING
    DIM ch2 AS STRING
    DIM g AS DOUBLE
    DIM x AS DOUBLE
    DIM fc AS DOUBLE
    DIM v#(20)
    e2 = UCASE$(ee)

    IF LEN(e2) = 0 THEN e2 = "0"

    i = 1: id = 0: l = LEN(e2): s2 = ""
    GOSUB scan
    GOSUB expr

    IF ch2 <> " " THEN
        PRINT
        PRINT "Syntax Error"
        PRINT
    END IF
    eval# = v#(0)
    EXIT FUNCTION
    '================================
    scan:
    IF i > l THEN
        ch2 = " "
        RETURN
    END IF
    ch2 = MID$(e2, i, 1)
    i = i + 1
    IF ch2 = " " THEN GOSUB scan
    RETURN

    unary:
    IF ch2 = "-" OR ch2 = "+" THEN
        s2 = s2 + ch2
        GOSUB scan
        GOSUB term
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa <> "-" THEN RETURN
        v#(id - 1) = -v#(id - 1)
        RETURN
    END IF
    GOSUB factor
    RETURN

    gamma:
    GOSUB unary
    WHILE ch2 = "!"
        x = v#(id - 1)
        GOSUB factorial
        v#(id - 1) = g
        GOSUB scan
    WEND
    RETURN

    expon:
    GOSUB gamma
    WHILE ch2 = "^"
        GOSUB scan
        GOSUB gamma
        id = id - 1
        v#(id - 1) = v#(id - 1) ^ v#(id)
    WEND
    RETURN

    term:
    GOSUB expon
    WHILE (ch2 = "*" OR ch2 = "/")
        s2 = s2 + ch2
        GOSUB scan
        GOSUB expon
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa = "*" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) * v#(id)
        END IF
        IF aa = "/" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) / v#(id)
        END IF
    WEND
    RETURN

    expr:
    GOSUB term
    WHILE (ch2 = "-" OR ch2 = "+")
        s2 = s2 + ch2
        GOSUB scan
        GOSUB term
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa = "-" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) - v#(id)
        END IF
        IF aa = "+" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) + v#(id)
        END IF
    WEND
    RETURN


    factor:
    IF INSTR(".0123456789", ch2) THEN
        d2 = ""
        WHILE INSTR("DE.0123456789", ch2)
            d2 = d2 + ch2
            GOSUB scan
        WEND
        v#(id) = VAL(d2)
        id = id + 1
        RETURN
    END IF
    IF ch2 = "-" OR ch2 = "+" THEN GOSUB unary
    GOSUB scan
    GOSUB expr
    IF ch2 = ")" THEN
        GOSUB scan
    ELSE
        PRINT
        PRINT "Missing ')'"
    END IF
    RETURN


    factorial:
    g = 1
    FOR fc = 1 TO x
        g = g * fc
    NEXT fc
    RETURN

END FUNCTION
« Last Edit: Yesterday at 03:00:54 AM by jack »

Online jack

  • Forum Regular
  • Posts: 198
Re: a super simple eval
« Reply #5 on: May 22, 2020, 04:49:32 PM »
cleaned it up a bit and put all the sub's related to the eval function inside the eval function, looks much better

Offline Ashish

  • Forum Resident
  • Posts: 552
  • The joy of coding is endless.
Re: a super simple eval
« Reply #6 on: May 23, 2020, 01:03:26 AM »
Nice! Is it only for integers? As, It does seems to be work for decimal inputs.
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Online jack

  • Forum Regular
  • Posts: 198
Re: a super simple eval
« Reply #7 on: May 23, 2020, 11:14:55 PM »
I made a small modification, it will accept floating point numbers, however, there's no error checking for proper floating point number, but as long as it's a valid float it will work.
« Last Edit: Yesterday at 01:51:36 AM by jack »

Online jack

  • Forum Regular
  • Posts: 198
Re: a super simple eval
« Reply #8 on: Yesterday at 04:16:39 AM »
this is a quick&dirty way to add functions like trig and exp functions, see the subroutine factor for details
only the trig functions starting with "A" are implemented as an example

Code: [Select]
a$ = " "

WHILE a$ <> ""
    INPUT a$
    result# = eval(a$)
    PRINT result#
WEND
END

FUNCTION eval# (ee AS STRING)
    DIM i AS INTEGER
    DIM id AS INTEGER
    DIM l AS INTEGER
    DIM aa AS STRING
    DIM d2 AS STRING
    DIM e2 AS STRING
    DIM s2 AS STRING
    DIM ch2 AS STRING
    DIM g AS DOUBLE
    DIM x AS DOUBLE
    DIM fc AS DOUBLE
    DIM v#(20)
    e2 = UCASE$(ee)

    IF LEN(e2) = 0 THEN e2 = "0"

    i = 1: id = 0: l = LEN(e2): s2 = ""
    GOSUB scan
    GOSUB expr

    IF ch2 <> " " THEN
        PRINT
        PRINT "Syntax Error"
        PRINT
    END IF
    eval# = v#(0)
    EXIT FUNCTION
    '================================
    scan:
    IF i > l THEN
        ch2 = " "
        RETURN
    END IF
    ch2 = MID$(e2, i, 1)
    i = i + 1
    IF ch2 = " " THEN GOSUB scan
    RETURN

    unary:
    IF ch2 = "-" OR ch2 = "+" THEN
        s2 = s2 + ch2
        GOSUB scan
        GOSUB term
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa <> "-" THEN RETURN
        v#(id - 1) = -v#(id - 1)
        RETURN
    END IF
    GOSUB factor
    RETURN

    gamma:
    GOSUB unary
    WHILE ch2 = "!"
        x = v#(id - 1)
        GOSUB factorial
        v#(id - 1) = g
        GOSUB scan
    WEND
    RETURN

    expon:
    GOSUB gamma
    WHILE ch2 = "^"
        GOSUB scan
        GOSUB gamma
        id = id - 1
        v#(id - 1) = v#(id - 1) ^ v#(id)
    WEND
    RETURN

    term:
    GOSUB expon
    WHILE (ch2 = "*" OR ch2 = "/")
        s2 = s2 + ch2
        GOSUB scan
        GOSUB expon
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa = "*" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) * v#(id)
        END IF
        IF aa = "/" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) / v#(id)
        END IF
    WEND
    RETURN

    expr:
    GOSUB term
    WHILE (ch2 = "-" OR ch2 = "+")
        s2 = s2 + ch2
        GOSUB scan
        GOSUB term
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa = "-" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) - v#(id)
        END IF
        IF aa = "+" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) + v#(id)
        END IF
    WEND
    RETURN


    factor:
    IF INSTR(".0123456789", ch2) THEN
        d2 = ""
        WHILE INSTR("DE.0123456789", ch2)
            d2 = d2 + ch2
            GOSUB scan
        WEND
        v#(id) = VAL(d2)
        id = id + 1
        RETURN
    END IF
    IF ch2 = "-" OR ch2 = "+" THEN GOSUB unary
    IF ch2 = "(" THEN
        GOSUB scan
        GOSUB expr
        IF ch2 = "," THEN
            GOSUB scan
            GOSUB expr
        END IF
        IF ch2 <> ")" THEN
            PRINT
            PRINT "Missing ')'"
        END IF
        GOSUB scan
        RETURN
    END IF
    IF ch2 = "A" THEN
        IF MID$(e2, i - 1, 5) = "ACOS(" THEN
            i = i + 3 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ACOS(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 6) = "ACOSH(" THEN
            i = i + 4
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ACOSH(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 7) = "ARCCOT(" THEN
            i = i + 5
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ARCCOT(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 7) = "ARCCSC(" THEN
            i = i + 5
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ARCCSC(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 7) = "ARCSEC(" THEN
            i = i + 5
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ARCSEC(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 5) = "ASIN(" THEN
            i = i + 3
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ASIN(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 6) = "ASINH(" THEN
            i = i + 4
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ASINH(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 4) = "ATN(" THEN
            i = i + 2
            GOSUB scan
            GOSUB term
            v#(id - 1) = ATN(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 6) = "ATAN2(" THEN
            i = i + 4
            GOSUB scan
            GOSUB term
            id = id - 1
            v#(id - 1) = _ATAN2(v#(id - 1), v#(id))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function A" + MID$(e2, i, k% - i)
        END IF
    END IF
    RETURN
    IF ch2 = "S" THEN
        IF MID$(e2, i - 1, 4) = "SIN(" THEN
            i = i + 2
            GOSUB scan
            GOSUB term
            v#(id - 1) = SIN(v#(id - 1))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function S" + MID$(e2, i, k% - i)
        END IF
    END IF
    RETURN


    factorial:
    g = 1
    FOR fc = 1 TO x
        g = g * fc
    NEXT fc
    RETURN

END FUNCTION
« Last Edit: Yesterday at 11:36:47 AM by jack »

Online jack

  • Forum Regular
  • Posts: 198
Re: a super simple eval
« Reply #9 on: Yesterday at 11:45:51 AM »
ok, I think that this could actually be useful, a modified the factor subroutine to deal with "," separated arguments, only tested with 2 arguments as that's what's needed for the atan2 function, post right above is updated.
now you can call the eval function like:y = eval#("atan2(atan2(.5+.5,4*.5),4*.5)")

Online jack

  • Forum Regular
  • Posts: 198
Re: a super simple eval
« Reply #10 on: Yesterday at 01:45:15 PM »
ok, I think that I have beaten the horse to death, here's the not so simple anymore eval function that includes all the QB64 math functions plus two derived functions, log10 and exp10
if anyone wishes to improve on this, may I suggest error trapping because there's hardly any
Code: [Select]
a$ = " "

WHILE a$ <> ""
    INPUT a$
    result# = eval(a$)
    PRINT result#
WEND
END

FUNCTION eval# (ee AS STRING)
    DIM i AS INTEGER
    DIM id AS INTEGER
    DIM l AS INTEGER
    DIM aa AS STRING
    DIM d2 AS STRING
    DIM e2 AS STRING
    DIM s2 AS STRING
    DIM ch2 AS STRING
    DIM g AS DOUBLE
    DIM x AS DOUBLE
    DIM fc AS DOUBLE
    DIM v#(20)
    e2 = UCASE$(ee)

    IF LEN(e2) = 0 THEN e2 = "0"

    i = 1: id = 0: l = LEN(e2): s2 = ""
    GOSUB scan
    GOSUB expr

    IF ch2 <> " " THEN
        PRINT
        PRINT "Syntax Error"
        PRINT
    END IF
    eval# = v#(0)
    EXIT FUNCTION
    '================================
    scan:
    IF i > l THEN
        ch2 = " "
        RETURN
    END IF
    ch2 = MID$(e2, i, 1)
    i = i + 1
    IF ch2 = " " THEN GOSUB scan
    RETURN

    unary:
    IF ch2 = "-" OR ch2 = "+" THEN
        s2 = s2 + ch2
        GOSUB scan
        GOSUB term
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa <> "-" THEN RETURN
        v#(id - 1) = -v#(id - 1)
        RETURN
    END IF
    GOSUB factor
    RETURN

    gamma:
    GOSUB unary
    WHILE ch2 = "!"
        x = v#(id - 1)
        GOSUB factorial
        v#(id - 1) = g
        GOSUB scan
    WEND
    RETURN

    expon:
    GOSUB gamma
    WHILE ch2 = "^"
        GOSUB scan
        GOSUB gamma
        id = id - 1
        v#(id - 1) = v#(id - 1) ^ v#(id)
    WEND
    RETURN

    term:
    GOSUB expon
    WHILE (ch2 = "*" OR ch2 = "/")
        s2 = s2 + ch2
        GOSUB scan
        GOSUB expon
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa = "*" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) * v#(id)
        END IF
        IF aa = "/" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) / v#(id)
        END IF
    WEND
    RETURN

    expr:
    GOSUB term
    WHILE (ch2 = "-" OR ch2 = "+")
        s2 = s2 + ch2
        GOSUB scan
        GOSUB term
        aa = RIGHT$(s2, 1)
        s2 = LEFT$(s2, LEN(s2) - 1)
        IF aa = "-" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) - v#(id)
        END IF
        IF aa = "+" THEN
            id = id - 1
            v#(id - 1) = v#(id - 1) + v#(id)
        END IF
    WEND
    RETURN


    factor:
    IF INSTR(".0123456789", ch2) THEN
        d2 = ""
        WHILE INSTR("DE.0123456789", ch2)
            d2 = d2 + ch2
            GOSUB scan
        WEND
        v#(id) = VAL(d2)
        id = id + 1
        RETURN
    END IF
    IF ch2 = "-" OR ch2 = "+" THEN GOSUB unary
    IF ch2 = "(" THEN
        GOSUB scan
        GOSUB expr
        IF ch2 = "," THEN
            GOSUB scan
            GOSUB expr
        END IF
        IF ch2 <> ")" THEN
            PRINT
            PRINT "Missing ')'"
        END IF
        GOSUB scan
        RETURN
    END IF
    IF ch2 = "A" THEN
        IF MID$(e2, i - 1, 4) = "ABS(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = ABS(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 5) = "ACOS(" THEN
            i = i + 3 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ACOS(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 6) = "ACOSH(" THEN
            i = i + 4
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ACOSH(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 7) = "ARCCOT(" THEN
            i = i + 5
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ARCCOT(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 7) = "ARCCSC(" THEN
            i = i + 5
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ARCCSC(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 7) = "ARCSEC(" THEN
            i = i + 5
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ARCSEC(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 5) = "ASIN(" THEN
            i = i + 3
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ASIN(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 6) = "ASINH(" THEN
            i = i + 4
            GOSUB scan
            GOSUB term
            v#(id - 1) = _ASINH(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 4) = "ATN(" THEN
            i = i + 2
            GOSUB scan
            GOSUB term
            v#(id - 1) = ATN(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 6) = "ATAN2(" THEN
            i = i + 4
            GOSUB scan
            GOSUB term
            id = id - 1
            v#(id - 1) = _ATAN2(v#(id - 1), v#(id))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function A" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "C" THEN
        IF MID$(e2, i - 1, 4) = "COS(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = COS(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 5) = "COSH(" THEN
            i = i + 3
            GOSUB scan
            GOSUB term
            v#(id - 1) = _COSH(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 4) = "COT(" THEN
            i = i + 2
            GOSUB scan
            GOSUB term
            v#(id - 1) = _COT(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 5) = "COTH(" THEN
            i = i + 3
            GOSUB scan
            GOSUB term
            v#(id - 1) = _COTH(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 4) = "CSC(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = _CSC(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 5) = "CSCH(" THEN
            i = i + 3 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = _CSCH(v#(id - 1))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function C" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "D" THEN
        IF MID$(e2, i - 1, 4) = "D2G(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = _D2G(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 4) = "D2R(" THEN
            i = i + 2
            GOSUB scan
            GOSUB term
            v#(id - 1) = _D2R(v#(id - 1))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function D" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "E" THEN
        IF MID$(e2, i - 1, 4) = "EXP(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = EXP(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 6) = "EXP10(" THEN
            i = i + 4 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = EXP(v#(id - 1) * 2.3025850929940456840#)
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function E" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "G" THEN
        IF MID$(e2, i - 1, 4) = "G2D(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = _G2D(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 4) = "G2R(" THEN
            i = i + 2
            GOSUB scan
            GOSUB term
            v#(id - 1) = _G2R(v#(id - 1))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function G" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "H" THEN
        IF MID$(e2, i - 1, 6) = "HYPOT(" THEN
            i = i + 4 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            id = id - 1
            v#(id - 1) = _HYPOT(v#(id - 1), v#(id))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function G" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "I" THEN
        IF MID$(e2, i - 1, 4) = "INT(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = INT(v#(id - 1))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function I" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "L" THEN
        IF MID$(e2, i - 1, 4) = "LOG(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = LOG(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 6) = "LOG10(" THEN
            i = i + 4 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = LOG(v#(id - 1)) * 0.43429448190325182765#
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function L" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "R" THEN
        IF MID$(e2, i - 1, 4) = "R2D(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = _R2D(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 4) = "R2G(" THEN
            i = i + 2
            GOSUB scan
            GOSUB term
            v#(id - 1) = _R2G(v#(id - 1))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function R" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "S" THEN
        IF MID$(e2, i - 1, 4) = "SIN(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = SIN(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 5) = "SINH(" THEN
            i = i + 3
            GOSUB scan
            GOSUB term
            v#(id - 1) = _SINH(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 4) = "SEC(" THEN
            i = i + 2
            GOSUB scan
            GOSUB term
            v#(id - 1) = _SEC(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 5) = "SECH(" THEN
            i = i + 3
            GOSUB scan
            GOSUB term
            v#(id - 1) = _SECH(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 4) = "SQR(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = SQR(v#(id - 1))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function S" + MID$(e2, i, k% - i)
        END IF
    ELSEIF ch2 = "T" THEN
        IF MID$(e2, i - 1, 4) = "TAN(" THEN
            i = i + 2 'advance pointer to just before "("
            GOSUB scan
            GOSUB term
            v#(id - 1) = TAN(v#(id - 1))
        ELSEIF MID$(e2, i - 1, 5) = "TANH(" THEN
            i = i + 3
            GOSUB scan
            GOSUB term
            v#(id - 1) = _TANH(v#(id - 1))
        ELSE
            k% = INSTR(i, e2, "(")
            PRINT "unknown function T" + MID$(e2, i, k% - i)
        END IF
    END IF
    RETURN

    factorial:
    g = 1
    FOR fc = 1 TO x
        g = g * fc
    NEXT fc
    RETURN

END FUNCTION
« Last Edit: Yesterday at 02:38:15 PM by jack »

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 758
  • Savage.
Re: a super simple eval
« Reply #11 on: Yesterday at 07:12:11 PM »
Possible next steps:

1) Variable storage/recovery for simple numbers

2) Once (1) is mastered, use the same apparatus to store not just store numbers, but any valid input. You've got an interpreter, after all.

Carry on in that spirit for about a year and you might end up with Sxript: http://barnes.x10host.com/sxript/

(spaghetti) code and (meat)balls

Online jack

  • Forum Regular
  • Posts: 198
Re: a super simple eval
« Reply #12 on: Yesterday at 07:26:00 PM »
Hi STxAxTIC
single-leter variables should not be too hard to implement but I think that this code is a hack at best, not suited to go beyond that.