I like the fact that rebol doesn't support operator precedence. It is so much easier
when things are being evaluated from left to right. No need to remember a table and it
is easy to work with without parenthesis. just remember one concept...left->right
rishi
Previously, you (chaz) wrote:
> This is delightful! Thank you!
>
> At 01:12 PM 10/14/00 +0200, you wrote:
> >Hi all!
> >
> >Have you been sometimes annoyed by tha fact REBOL does not support
> >operator precedence? Here's the answer:
> >
> >>> a: 2 b: 4 c: 3
> >== 3
> >>> eval [b ^ 2 - 4 * a * c]
> >== -8
> >
> >The magic trick is:
> >
> >>> eval/translate [b ^ 2 - 4 * a * c]
> >== [subtract power b 2 multiply multiply 4 a c]
> >
> >Other examples:
> >
> >>> eval/translate [1 / k !]
> >== [divide 1 factorial k]
> >>> eval/translate [a * - b]
> >== [multiply a negate b]
> >>> eval/translate [e ^ (i / h * (p * x - E * t))]
> >== [power e multiply divide i h subtract multiply p x multiply E t]
> >
> >NOTE: it still needs improvements, such as error handling. They
> >are "left to the reader as an exercise". :-)
> >
> >Enjoy!,
> > Gabriele.
> >--
> >Gabriele Santilli <[EMAIL PROTECTED]> - Amigan - REBOL programmer
> >Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
> >
> >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.
>
>
--
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the
subject, without the quotes.