Runtime evaluation/In an environment: Difference between revisions

m
Fixed lang tags.
m (Fixed lang tags.)
Line 20:
<!-- {{does not work with|ELLA ALGOL 68|Any This implementation is a compiler}} -->
Variable names are generally not visible at run time with classic compilers. However '''ALGOL 68G''' is an interpretor and it retains this ability. Note that ''evaluate'' returns a '''string'''.
<lang algolalgol68>PROC eval_with_x = (STRING code, INT a, b)STRING:
(INT x=a; evaluate(code) ) + (INT x=b; evaluate(code));
print((eval_with_x("2 ** x", 3, 5), new line))</lang>
Line 29:
=={{header|Common Lisp}}==
 
<lang lisp>(defun eval-with-x (program a b)
(defun eval-with-x (program a b)
(let ((at-a (eval `(let ((x ',a)) ,program)))
(at-b (eval `(let ((x ',b)) ,program))))
(- at-b at-a)))</lang>
</lang>
 
<lang lisp>(eval-with-x '(exp x) 0 1)
=> 1.7182817</lang>
(eval-with-x '(exp x) 0 1)
=> 1.7182817
</lang>
 
This version ensures that the program is compiled, once, for more efficient execution:
 
<lang lisp>(defun eval-with-x (program a b)
(defun eval-with-x (program a b)
(let* ((f (compile nil `(lambda (x) ,program)))
(at-a (funcall f a))
(at-b (funcall f b)))
(- at-b at-a)))</lang>
</lang>
 
=={{header|E}}==
Line 72 ⟶ 66:
=={{header|Forth}}==
EVALUATE invokes the Forth interpreter on the given string.
<lang forth>: f-" ( a b snippet" -- )
: f-" ( a b snippet" -- )
[char] " parse ( code len )
2dup 2>r evaluate
Line 79 ⟶ 72:
- . ;
 
2 3 f-" dup *" \ 5 (3*3 - 2*2)</lang>
</lang>
This can be used to treat a data stream as code, or to provide a lightweight macro facility when used in an IMMEDIATE word.
<lang forth>: :macro ( "name <char> ccc<char>" -- )
: :macro ( "name <char> ccc<char>" -- )
: [CHAR] ; PARSE POSTPONE SLITERAL POSTPONE EVALUATE
POSTPONE ; IMMEDIATE
Line 97 ⟶ 88:
DO .\" spam "
LOOP
; ok</lang>
</lang>
 
=={{header|Genyris}}==
One way is to use a macro. In genyris, macros are lazy functions which execute twice, the return value is also evaluated in the caller's environment:
<lang genyris>defmacro add100() (+ x 100)
<lang python>
defmacro add100() (+ x 100)
 
var x 23
Line 115 ⟶ 104:
Another way is to use dynamically scoped variables. In Genyris, symbols prefixed with a period are looked up in the caller's environment, not the lexical environment of the closure. When a dictionary is the first element of the expression, an environment is created and the &rest is evaluated.
 
<lang pythongenyris>def add100() (+ .x 100)
 
(dict) # create an environment capable of holding dynamic bindings
Line 124 ⟶ 113:
+ firstresult (add100)</lang>
Dictionaries can hold bindings to dynamic symbols. To minimize the danger of dynamic scope there is no recursive ascent in the binding lookup.
<lang genyris>(dict)
<lang python>
(dict)
var .x 23
(dict)
Line 150 ⟶ 138:
===Explicit===
The following satisfies the requirements:
<lang j> EvalWithX=. monad : 0
EvalWithX=. monad : 0
'CODE V0 V1'=. y
(". CODE [ x=. V1) - (". CODE [ x=. V0)
Line 157 ⟶ 144:
EvalWithX '^x';0;1
1.71828183</lang>
</lang>
===Tacit===
However, it is easier via point-free coding:
<lang j> (0&({::) -~&>/@:(128!:2&.>) 1 2&{) '^';0;1
<lang j>
1.71828183</lang>
(0&({::) -~&>/@:(128!:2&.>) 1 2&{) '^';0;1
1.71828183
</lang>
 
=={{header|JavaScript}}==
Line 312 ⟶ 296:
=={{header|TI-89 BASIC}}==
 
<lang ti89b>evalx(prog, a, b)
Func
Local x,eresult1,eresult2
a→x
expr(prog)→eresult1
b→x
expr(prog)→eresult2
Return eresult2-eresult1
EndFunc
 
■ evalx("ℯ^x", 0., 1)
1.71828</lang>
 
There are no facilities for control over the environment; expr() evaluates in the same environment as the caller, including local variables. [Someone please verify this statement.] [[Category:TI-89 BASIC examples needing attention]]
Anonymous user