> The "flash" question was, how to parse the expressions like:
>
>   a: x + random 10
>
> in any dialect... unfortunately there was no reply...

Oh bother, I'd even thought up a response, but neglected to send it :(

The response is, Gabriele Santilli some time ago posted a script called
expression-evaluator.r.

This fairly small script evaluates expressions and I feel it is similar to
what you want to achieve. Might be worth studying for ideas. I include it
below (I'm guessing it is ok with Gabriele - i hope anyway :) ).

Brett
...

REBOL [
    Title: "Expression evaluator"
    Author: "Gabriele Santilli <[EMAIL PROTECTED]>"
    Comment: {
        Evaluates expressions taking usual operator precedence
        into account.
        1. (...)
        2. - [negation], ! [factorial]
        3. ^ [power]
        4. *, /
        5. +, - [subtraction]
    }
]

; A simple iterative implementation; returns 1 for negative
; numbers. FEEL FREE TO IMPROVE THIS!
factorial: func [n [integer!] /local res] [
    if n < 2 [return 1]
    res: 1
    ; should avoid doing the loop for i = 1...
    repeat i n [res: res * i]
]

expression-parser: make object! [
    slash: to-lit-word first [/]
    expr-val:
    expr-op: none
    expression: [
        term (expr-val: term-val)
        any [
            ['+ (expr-op: 'add) | '- (expr-op: 'subtract)]
            term (expr-val: compose [(expr-op) (expr-val) (term-val)])
        ]
    ]
    term-val:
    term-op: none
    term: [
        pow (term-val: power-val)
        any [
            ['* (term-op: 'multiply) | slash (term-op: 'divide)]
            pow (term-val: compose [(term-op) (term-val) (power-val)])
        ]
    ]
    power-val: none
    pow: [
        unary (power-val: unary-val)
        opt ['^ unary (power-val: compose [power (power-val) (unary-val)])]
    ]
    unary-val:
    pre-uop:
    post-uop: none
    unary: [
        (post-uop: pre-uop: [])
        opt ['- (pre-uop: 'negate)]
        primary
        opt ['! (post-uop: 'factorial)]
        (unary-val: compose [(post-uop) (pre-uop) (prim-val)])
    ]
    prim-val: none
    ; WARNING: uses recursion for parens.
    primary: [
        set prim-val [number! | word!]
        | set prim-val paren! (prim-val: translate to-block :prim-val)
    ]
    translate: func [expr [block!] /local res recursion] [
        ; to allow recursive calling, we need to preserve our state
        recursion: reduce [
            :expr-val :expr-op :term-val :term-op :power-val :unary-val
            :pre-uop :post-uop :prim-val
        ]
        res: if parse expr expression [expr-val]
        set [
            expr-val expr-op term-val term-op power-val unary-val
            pre-uop post-uop prim-val
        ] recursion
        res
    ]
    set 'eval func [expr [block!] /translate] [
        expr: self/translate expr
        either translate [expr] [do expr]
    ]
]



-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.

Reply via email to