Runtime evaluation/In an environment: Difference between revisions
Content added Content deleted
m (Fixed lang tags.) |
|||
Line 20: | Line 20: | ||
<!-- {{does not work with|ELLA ALGOL 68|Any This implementation is a compiler}} --> |
<!-- {{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'''. |
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 |
<lang algol68>PROC eval_with_x = (STRING code, INT a, b)STRING: |
||
(INT x=a; evaluate(code) ) + (INT x=b; evaluate(code)); |
(INT x=a; evaluate(code) ) + (INT x=b; evaluate(code)); |
||
print((eval_with_x("2 ** x", 3, 5), new line))</lang> |
print((eval_with_x("2 ** x", 3, 5), new line))</lang> |
||
Line 29: | Line 29: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
<lang 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))) |
(let ((at-a (eval `(let ((x ',a)) ,program))) |
||
(at-b (eval `(let ((x ',b)) ,program)))) |
(at-b (eval `(let ((x ',b)) ,program)))) |
||
(- at-b at-a))) |
(- at-b at-a)))</lang> |
||
⚫ | |||
<lang lisp> |
<lang lisp>(eval-with-x '(exp x) 0 1) |
||
⚫ | |||
(eval-with-x '(exp x) 0 1) |
|||
⚫ | |||
</lang> |
|||
This version ensures that the program is compiled, once, for more efficient execution: |
This version ensures that the program is compiled, once, for more efficient execution: |
||
<lang lisp> |
<lang lisp>(defun eval-with-x (program a b) |
||
(defun eval-with-x (program a b) |
|||
(let* ((f (compile nil `(lambda (x) ,program))) |
(let* ((f (compile nil `(lambda (x) ,program))) |
||
(at-a (funcall f a)) |
(at-a (funcall f a)) |
||
(at-b (funcall f b))) |
(at-b (funcall f b))) |
||
(- at-b at-a))) |
(- at-b at-a)))</lang> |
||
</lang> |
|||
=={{header|E}}== |
=={{header|E}}== |
||
Line 72: | Line 66: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
EVALUATE invokes the Forth interpreter on the given string. |
EVALUATE invokes the Forth interpreter on the given string. |
||
<lang forth> |
<lang forth>: f-" ( a b snippet" -- ) |
||
: f-" ( a b snippet" -- ) |
|||
[char] " parse ( code len ) |
[char] " parse ( code len ) |
||
2dup 2>r evaluate |
2dup 2>r evaluate |
||
Line 79: | Line 72: | ||
- . ; |
- . ; |
||
2 3 f-" dup *" \ 5 (3*3 - 2*2) |
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. |
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> |
<lang forth>: :macro ( "name <char> ccc<char>" -- ) |
||
: :macro ( "name <char> ccc<char>" -- ) |
|||
: [CHAR] ; PARSE POSTPONE SLITERAL POSTPONE EVALUATE |
: [CHAR] ; PARSE POSTPONE SLITERAL POSTPONE EVALUATE |
||
POSTPONE ; IMMEDIATE |
POSTPONE ; IMMEDIATE |
||
Line 97: | Line 88: | ||
DO .\" spam " |
DO .\" spam " |
||
LOOP |
LOOP |
||
; ok |
; ok</lang> |
||
</lang> |
|||
=={{header|Genyris}}== |
=={{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: |
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 python> |
|||
⚫ | |||
var x 23 |
var x 23 |
||
Line 115: | Line 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. |
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 |
<lang genyris>def add100() (+ .x 100) |
||
(dict) # create an environment capable of holding dynamic bindings |
(dict) # create an environment capable of holding dynamic bindings |
||
Line 124: | Line 113: | ||
+ firstresult (add100)</lang> |
+ 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. |
Dictionaries can hold bindings to dynamic symbols. To minimize the danger of dynamic scope there is no recursive ascent in the binding lookup. |
||
⚫ | |||
<lang python> |
|||
⚫ | |||
var .x 23 |
var .x 23 |
||
(dict) |
(dict) |
||
Line 150: | Line 138: | ||
===Explicit=== |
===Explicit=== |
||
The following satisfies the requirements: |
The following satisfies the requirements: |
||
<lang j> |
<lang j> EvalWithX=. monad : 0 |
||
EvalWithX=. monad : 0 |
|||
'CODE V0 V1'=. y |
'CODE V0 V1'=. y |
||
(". CODE [ x=. V1) - (". CODE [ x=. V0) |
(". CODE [ x=. V1) - (". CODE [ x=. V0) |
||
Line 157: | Line 144: | ||
EvalWithX '^x';0;1 |
EvalWithX '^x';0;1 |
||
1.71828183 |
1.71828183</lang> |
||
</lang> |
|||
===Tacit=== |
===Tacit=== |
||
However, it is easier via point-free coding: |
However, it is easier via point-free coding: |
||
⚫ | |||
<lang j> |
|||
⚫ | |||
⚫ | |||
1.71828183 |
|||
</lang> |
|||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
Line 312: | Line 296: | ||
=={{header|TI-89 BASIC}}== |
=={{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]] |
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]] |