Arithmetic evaluation: Difference between revisions

→‎{{header|TXR}}: Code-generating solution.
(→‎{{header|TXR}}: Section created.)
(→‎{{header|TXR}}: Code-generating solution.)
Line 2,983:
 
=={{header|TXR}}==
 
This implementation flouts the requirement to build an AST, and goes straight to code generation. The handlers for the grammar are endowed with semantic actions. Each element must parse the expression and produce two semantic values: the code, and the output register of that code. The target language is the Unix shell, so we can just <code>eval</code> the output in the shell to run the "machine code".
 
<lang txr>@(next :args)
@(bind nl "\n")
@(bind gen "0")
@(define genreg (r))
@ (local ngen)
@ (next `!echo $((1 + @gen))`)
@ ngen
@ (set gen ngen)
@ (bind r `R@gen`)
@(end)
@(define ws ())@/[ \t]*/@(end)
@(define mulop (o))@(ws)@{o /[\/*]/}@(ws)@(end)
@(define addop (o))@(ws)@{o /[\-+]/}@(ws)@(end)
@(define number (reg code))@\
@(local n)@\
@(ws)@{n /[0-9]+/}@(ws)@\
@(genreg reg)@\
@(bind code `@reg=@n@nl`)@\
@(end)
@(define factor (reg code))@\
@(local r1 c1 op r2 c2)@\
@(cases)@\
(@(expr reg code))@\
@(or)@\
@(number reg code)@\
@(end)@\
@(end)
@(define term (reg code))@\
@(local r1 c1 op r2 c2)@\
@(factor r1 c1)@\
@(cases)@\
@(mulop op)@(term r2 c2)@\
@(genreg reg)@\
@(bind code `@c1@c2@reg=$((@r1 @op @r2))@nl`)@\
@(or)@\
@(bind (reg code) (r1 c1))@\
@(end)@\
@(end)
@(define expr (reg code))@\
@(local r1 c1 op r2 c2)@\
@(term r1 c1)@\
@(cases)@\
@(addop op)@(expr r2 c2)@\
@(genreg reg)@\
@(bind code `@c1@c2@reg=$((@r1 @op @r2))@nl`)@\
@(or)@\
@(bind (reg code) (r1 c1))@\
@(end)@\
@(end)
@(expr reg code)
@(output)
@code
echo $@reg
@(end)</lang>
 
Run:
 
<lang bash>$ ./txr exprtran.txr '3 + 3/4 * (2 + 2) + (4*4)'
R1=3
R2=3
R3=4
R4=2
R5=2
R6=$((R4 + R5))
R7=$((R3 * R6))
R8=$((R2 / R7))
R9=4
R10=4
R11=$((R9 * R10))
R12=$((R8 + R11))
R13=$((R1 + R12))
 
echo $R13</lang>
 
<lang bash>$ eval "$(./txr exprtran.txr '3 + 3/4 * (2 + 2) + (4*4)')"
19</lang>
 
 
 
{{omit from|gnuplot}}
Anonymous user