Runtime evaluation: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(14 intermediate revisions by 10 users not shown)
Line 14: Line 14:


This example runs on the Commodore 64 and prints the letter A using a crude "eval":
This example runs on the Commodore 64 and prints the letter A using a crude "eval":
<lang 6502asm>;Init Routine
<syntaxhighlight lang="6502asm">;Init Routine
*=$0801
*=$0801
db $0E,$08,$0A,$00,$9E,$20,$28,$32,$30,$36,$34,$29,$00,$00,$00
db $0E,$08,$0A,$00,$9E,$20,$28,$32,$30,$36,$34,$29,$00,$00,$00
Line 44: Line 44:


rts ;return to basic</lang>
rts ;return to basic</syntaxhighlight>


{{out}}
{{out}}
Line 65: Line 65:
<!-- {{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.
Variable names are generally not visible at run time with classic compilers. However '''ALGOL 68G''' is an interpretor and it retains this ability.
<lang algol68>print(evaluate("4.0*arctan(1.0)"))</lang>
<syntaxhighlight lang="algol68">print(evaluate("4.0*arctan(1.0)"))</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 74: Line 74:


{{works with|ALGOL 68G|tested with release 2.8.win32}}
{{works with|ALGOL 68G|tested with release 2.8.win32}}
<lang algol68># procedure to call the Algol 68G evaluate procedure #
<syntaxhighlight lang="algol68"># procedure to call the Algol 68G evaluate procedure #
# the environment of the evaluation will be the caller's environment #
# the environment of the evaluation will be the caller's environment #
# with "code", "x" and "y" defined as the procedure parameters #
# with "code", "x" and "y" defined as the procedure parameters #
Line 108: Line 108:
# if this next call was executed, a runtime error would occur as x and y #
# if this next call was executed, a runtime error would occur as x and y #
# do not exist anymore #
# do not exist anymore #
# ;print( ( evaluate( "x + y" ), newline ) ) #</lang>
# ;print( ( evaluate( "x + y" ), newline ) ) #</syntaxhighlight>


{{out}}
{{out}}
Line 118: Line 118:
code + codecode + code
code + codecode + code
</pre>
</pre>

=={{header|Arturo}}==

<syntaxhighlight lang="rebol">a: {print ["The result is:" 2+3]}
do a

userCode: input "Give me some code: "
do userCode</syntaxhighlight>

{{out}}

<pre>The result is: 5
Give me some code: print "Hello world!"
Hello world!</pre>


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
{{works with | AutoHotkey_H}}
{{works with | AutoHotkey_H}}
function [http://www.autohotkey.net/~HotKeyIt/AutoHotkey/addScript.htm addScript] can be used to dynamically add lines of code to a running script.
function [http://www.autohotkey.net/~HotKeyIt/AutoHotkey/addScript.htm addScript] can be used to dynamically add lines of code to a running script.
<lang AutoHotkey>; requires AutoHotkey_H or AutoHotkey.dll
<syntaxhighlight lang="autohotkey">; requires AutoHotkey_H or AutoHotkey.dll
msgbox % eval("3 + 4")
msgbox % eval("3 + 4")
msgbox % eval("4 + 4")
msgbox % eval("4 + 4")
Line 153: Line 167:
if fnp := FindFunc(funcName)
if fnp := FindFunc(funcName)
numput(&x%newname%, fnp+0, 0, "uint")
numput(&x%newname%, fnp+0, 0, "uint")
}</lang>
}</syntaxhighlight>


=={{header|BASIC}}==
=={{header|BASIC}}==
Line 206: Line 220:
In ZX Spectrum Basic, loading a new program will replace the existing program. The new program will sutomatically run, if it was saved to do so by using SAVE together with LINE:
In ZX Spectrum Basic, loading a new program will replace the existing program. The new program will sutomatically run, if it was saved to do so by using SAVE together with LINE:


<lang zxbasic>
<syntaxhighlight lang="zxbasic">
10 REM load the next program
10 REM load the next program
20 LOAD "PROG2"
20 LOAD "PROG2"
</syntaxhighlight>
</lang>


You can also include code in a text string as follows:
You can also include code in a text string as follows:
<lang zxbasic>10 LET f$=CHR$ 187+"(x)+"+CHR$ 178+"(x*3)/2": REM LET f$="SQR (x)+SIN (x*3)/2"
<syntaxhighlight lang="zxbasic">10 LET f$=CHR$ 187+"(x)+"+CHR$ 178+"(x*3)/2": REM LET f$="SQR (x)+SIN (x*3)/2"
20 FOR x=0 TO 2 STEP 0.2
20 FOR x=0 TO 2 STEP 0.2
30 LET y=VAL f$
30 LET y=VAL f$
40 PRINT y
40 PRINT y
50 NEXT x
50 NEXT x
</syntaxhighlight>
</lang>


CHR$ 178 is the token of function SQR, and CHR$ 178 is the token of function SIN.
CHR$ 178 is the token of function SQR, and CHR$ 178 is the token of function SIN.


In 48 k mode, you can also write this:
In 48 k mode, you can also write this:
<lang zxbasic>10 LET f= SQR (x)+SIN (x*3)/2</lang>
<syntaxhighlight lang="zxbasic">10 LET f= SQR (x)+SIN (x*3)/2</syntaxhighlight>
Then the type of the variable is changed and the formula is enclosed in quotation marks:
Then the type of the variable is changed and the formula is enclosed in quotation marks:
<lang zxbasic>10 LET f$=" SQR (x)+SIN (x*3)/2"</lang>
<syntaxhighlight lang="zxbasic">10 LET f$=" SQR (x)+SIN (x*3)/2"</syntaxhighlight>


=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
Line 230: Line 244:
===Expressions===
===Expressions===
Expressions can be evaluated using the EVAL function:
Expressions can be evaluated using the EVAL function:
<lang bbcbasic> expr$ = "PI^2 + 1"
<syntaxhighlight lang="bbcbasic"> expr$ = "PI^2 + 1"
PRINT EVAL(expr$)</lang>
PRINT EVAL(expr$)</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 239: Line 253:
===Statements===
===Statements===
Statements can be executed by being tokenised and then written to a temporary file:
Statements can be executed by being tokenised and then written to a temporary file:
<lang bbcbasic> exec$ = "PRINT ""Hello world!"""
<syntaxhighlight lang="bbcbasic"> exec$ = "PRINT ""Hello world!"""
bbc$ = FNtokenise(exec$)
bbc$ = FNtokenise(exec$)
Line 255: Line 269:
A$ = $(!332+2)
A$ = $(!332+2)
= CHR$(LENA$+4) + CHR$0 + CHR$0 + A$ + CHR$13
= CHR$(LENA$+4) + CHR$0 + CHR$0 + A$ + CHR$13
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 266: Line 280:
Evaluating a block:
Evaluating a block:


<lang burlesque>
<syntaxhighlight lang="burlesque">
blsq ) {5 5 .+}e!
blsq ) {5 5 .+}e!
10
10
</syntaxhighlight>
</lang>


Creating code at runtime (changing map (+5) to map (+6) at runtime):
Creating code at runtime (changing map (+5) to map (+6) at runtime):


<lang burlesque>
<syntaxhighlight lang="burlesque">
blsq ) 1 10r@{5.+}m[
blsq ) 1 10r@{5.+}m[
{6 7 8 9 10 11 12 13 14 15}
{6 7 8 9 10 11 12 13 14 15}
blsq ) 1 10r@{5.+}6 0sam[
blsq ) 1 10r@{5.+}6 0sam[
{7 8 9 10 11 12 13 14 15 16}
{7 8 9 10 11 12 13 14 15 16}
</syntaxhighlight>
</lang>


Code from string at runtime:
Code from string at runtime:


<lang burlesque>
<syntaxhighlight lang="burlesque">
blsq ) 1 10r@"5.+"psm[
blsq ) 1 10r@"5.+"psm[
{6 7 8 9 10 11 12 13 14 15}
{6 7 8 9 10 11 12 13 14 15}
</syntaxhighlight>
</lang>


Evaluating strings at runtime (reverse is just for demonstration):
Evaluating strings at runtime (reverse is just for demonstration):


<lang burlesque>
<syntaxhighlight lang="burlesque">
blsq ) "[m}+.5{@r01 1"<-pe
blsq ) "[m}+.5{@r01 1"<-pe
{6 7 8 9 10 11 12 13 14 15}
{6 7 8 9 10 11 12 13 14 15}
</syntaxhighlight>
</lang>


Injecting other functions into code:
Injecting other functions into code:


<lang burlesque>
<syntaxhighlight lang="burlesque">
blsq ) {3 2}(?*)[+e!
blsq ) {3 2}(?*)[+e!
6
6
</syntaxhighlight>
</lang>


Identifiers not contained in a block require to be quoted to push them to the stack. Note the difference:
Identifiers not contained in a block require to be quoted to push them to the stack. Note the difference:


<lang burlesque>
<syntaxhighlight lang="burlesque">
blsq ) ?+
blsq ) ?+
ERROR: Burlesque: (.+) Invalid arguments!
ERROR: Burlesque: (.+) Invalid arguments!
Line 312: Line 326:
blsq ) (?+)to
blsq ) (?+)to
"Ident"
"Ident"
</syntaxhighlight>
</lang>


(also note the fallback to ''.+'' from ''?+'').
(also note the fallback to ''.+'' from ''?+'').
Line 335: Line 349:
The <tt>eval</tt> function evaluates Lisp code at runtime.
The <tt>eval</tt> function evaluates Lisp code at runtime.


<lang lisp>(eval '(+ 4 5)) ; returns 9</lang>
<syntaxhighlight lang="lisp">(eval '(+ 4 5)) ; returns 9</syntaxhighlight>


In Common Lisp, programs are represented as trees (s-expressions). Therefore, it is easily possible to construct a program which includes externally specified values, particularly using backquote template syntax:
In Common Lisp, programs are represented as trees (s-expressions). Therefore, it is easily possible to construct a program which includes externally specified values, particularly using backquote template syntax:


<lang lisp>(defun add-four-complicated (a-number)
<syntaxhighlight lang="lisp">(defun add-four-complicated (a-number)
(eval `(+ 4 ',a-number)))</lang>
(eval `(+ 4 ',a-number)))</syntaxhighlight>


Or you can construct a function and then call it. (If the function is used more than once, it would be good to use <code>[http://www.lispworks.com/documentation/HyperSpec/Body/f_cmp.htm compile]</code> instead of <code>[http://www.lispworks.com/documentation/HyperSpec/Body/f_eval.htm eval]</code>, which compiles the code before returning the function. <code>eval</code> is permitted to compile as well, but <code>compile</code> requires it.)
Or you can construct a function and then call it. (If the function is used more than once, it would be good to use <code>[http://www.lispworks.com/documentation/HyperSpec/Body/f_cmp.htm compile]</code> instead of <code>[http://www.lispworks.com/documentation/HyperSpec/Body/f_eval.htm eval]</code>, which compiles the code before returning the function. <code>eval</code> is permitted to compile as well, but <code>compile</code> requires it.)


<lang lisp>(defun add-four-by-function (a-number)
<syntaxhighlight lang="lisp">(defun add-four-by-function (a-number)
(funcall (eval '(lambda (n) (+ 4 n)))) a-number)</lang>
(funcall (eval '(lambda (n) (+ 4 n)))) a-number)</syntaxhighlight>


If your program came from a file or user input, then you have it as a string, and [http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_rd.htm <code>read</code>] or <code>read-from-string</code> will convert it to s-expression form:
If your program came from a file or user input, then you have it as a string, and [http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_rd.htm <code>read</code>] or <code>read-from-string</code> will convert it to s-expression form:


<lang lisp>(eval (read-from-string "(+ 4 5)"))</lang>
<syntaxhighlight lang="lisp">(eval (read-from-string "(+ 4 5)"))</syntaxhighlight>


Common Lisp has lexical scope, but <code>eval</code> always evaluates “in the null lexical environment”. In particular, <code>eval</code> does not inherit the lexical variables from the enclosing code. (Note that <code>eval</code> is an ordinary function and as such does not have access to that environment anyway.)
Common Lisp has lexical scope, but <code>eval</code> always evaluates “in the null lexical environment”. In particular, <code>eval</code> does not inherit the lexical variables from the enclosing code. (Note that <code>eval</code> is an ordinary function and as such does not have access to that environment anyway.)


<lang lisp>(let ((x 11) (y 22))
<syntaxhighlight lang="lisp">(let ((x 11) (y 22))
;; This is an error! Inside the eval, x and y are unbound!
;; This is an error! Inside the eval, x and y are unbound!
(format t "~%x + y = ~a" (eval '(+ x y))))</lang>
(format t "~%x + y = ~a" (eval '(+ x y))))</syntaxhighlight>


One way to fix the error is to <tt>(declare (special x y))</tt> for dynamic variables; but the easier and shorter way is to insert the values of x and y with the backquote template syntax.
One way to fix the error is to <tt>(declare (special x y))</tt> for dynamic variables; but the easier and shorter way is to insert the values of x and y with the backquote template syntax.


<lang lisp>(let ((x 11) (y 22))
<syntaxhighlight lang="lisp">(let ((x 11) (y 22))
(format t "~%x + y = ~a" (eval `(+ ,x ,y))))</lang>
(format t "~%x + y = ~a" (eval `(+ ,x ,y))))</syntaxhighlight>


===Sandboxing Discussion===
===Sandboxing Discussion===
Line 368: Line 382:
One approach to define a sublanguage and validate expressions before passing them to <code>compile</code> or <code>eval</code>. Of course, a whole different language entirely can be defined, and translated to Lisp. This is essentially the classic "trusted compiler generating safe code in an untrusted target language" approach.
One approach to define a sublanguage and validate expressions before passing them to <code>compile</code> or <code>eval</code>. Of course, a whole different language entirely can be defined, and translated to Lisp. This is essentially the classic "trusted compiler generating safe code in an untrusted target language" approach.


One way to simplify the validator is to use the package system to create a sandbox. This is done by defining a package arbitrarily called <code>sandbox</code>. The validator then simply has to make sure that all symbols used in the expression are restricted to those which are visible inside the <code>sandbox</code> package. Inside <code>sandbox</code>, we include only those functions, operators, variables and other symbols from system packages that are safe: materials which don't allow sandboxed code to do anything harmful from within the sandbox, or to escape from the sandbox. For instance, suppose that some package <code>system</code> has a function called <code>run-shell-command</code>. We do not import <code>run-shell-command</code> into the <code>sandbox</code> package, and our validator will reject code which has references such as <lang lisp>(system:run-shell-command ...)</lang>. Therefore, the sandboxed code has no direct way to run that function. To gain access to it, it must exploit some flaw in the sandbox. One flaw in the sandbox would be the inclusion of certain package-related functions like <code>find-symbol</code>. The expression <lang lisp>(find-symbol "FOO" "BAR")</lang> will retrieve symbol <code>foo::bar</code> if it exists. The validator will not find this code because it has no embedded symbolic references to package <code>foo</code>; they are disguised as character string. A cautious approach to the sandbox should be taken: include less rather than more, and consider each expansion of the sandbox with meticulous care.
One way to simplify the validator is to use the package system to create a sandbox. This is done by defining a package arbitrarily called <code>sandbox</code>. The validator then simply has to make sure that all symbols used in the expression are restricted to those which are visible inside the <code>sandbox</code> package. Inside <code>sandbox</code>, we include only those functions, operators, variables and other symbols from system packages that are safe: materials which don't allow sandboxed code to do anything harmful from within the sandbox, or to escape from the sandbox. For instance, suppose that some package <code>system</code> has a function called <code>run-shell-command</code>. We do not import <code>run-shell-command</code> into the <code>sandbox</code> package, and our validator will reject code which has references such as <syntaxhighlight lang="lisp">(system:run-shell-command ...)</syntaxhighlight>. Therefore, the sandboxed code has no direct way to run that function. To gain access to it, it must exploit some flaw in the sandbox. One flaw in the sandbox would be the inclusion of certain package-related functions like <code>find-symbol</code>. The expression <syntaxhighlight lang="lisp">(find-symbol "FOO" "BAR")</syntaxhighlight> will retrieve symbol <code>foo::bar</code> if it exists. The validator will not find this code because it has no embedded symbolic references to package <code>foo</code>; they are disguised as character string. A cautious approach to the sandbox should be taken: include less rather than more, and consider each expansion of the sandbox with meticulous care.


===Debugging Notes===
===Debugging Notes===
Line 379: Line 393:
Each compiled fragment is considered to be a single "file", and cannot access any local variables from outside of itself.
Each compiled fragment is considered to be a single "file", and cannot access any local variables from outside of itself.


<lang dejavu>!run-blob !compile-string "(fake filename)" "!print \qHello world\q"</lang>
<syntaxhighlight lang="dejavu">!run-blob !compile-string "(fake filename)" "!print \qHello world\q"</syntaxhighlight>
{{out}}
{{out}}
<pre>Hello world</pre>
<pre>Hello world</pre>
Line 389: Line 403:
The lexical environment is provided as a parameter and cannot be omitted. The evaluated program has no access to anything but the provided environment.
The lexical environment is provided as a parameter and cannot be omitted. The evaluated program has no access to anything but the provided environment.


<lang e>? e`1 + 1`.eval(safeScope)
<syntaxhighlight lang="e">? e`1 + 1`.eval(safeScope)
# value: 2</lang>
# value: 2</syntaxhighlight>


<code>eval</code> returns the value of the expression. <code>evalToPair</code> also returns the modified environment for use with further evaluation, e.g. for implementing a [[REPL]].
<code>eval</code> returns the value of the expression. <code>evalToPair</code> also returns the modified environment for use with further evaluation, e.g. for implementing a [[REPL]].


<lang e>? def [value, env] := e`def x := 1 + 1`.evalToPair(safeScope)
<syntaxhighlight lang="e">? def [value, env] := e`def x := 1 + 1`.evalToPair(safeScope)
# value: [2, ...]
# value: [2, ...]


? e`x`.eval(env)
? e`x`.eval(env)
# value: 2</lang>
# value: 2</syntaxhighlight>


Eval from a string may be done by invoking the parser.
Eval from a string may be done by invoking the parser.


<lang e>? def prog := <elang:syntax.makeEParser>.run("1 + 1")
<syntaxhighlight lang="e">? def prog := <elang:syntax.makeEParser>.run("1 + 1")
# value: e`1.add(1)`
# value: e`1.add(1)`


? prog.eval(safeScope)
? prog.eval(safeScope)
# value: 2</lang>
# value: 2</syntaxhighlight>


=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
'''eval''' : The evaluation of the eval argument must give a symbolic expression, which is in turn evaluated. Alternatively, '''read-from-string''' produces a s-expression - any kind of program - from a string.
'''eval''' : The evaluation of the eval argument must give a symbolic expression, which is in turn evaluated. Alternatively, '''read-from-string''' produces a s-expression - any kind of program - from a string.
<lang scheme>
<syntaxhighlight lang="scheme">
(eval (list * 6 7))
(eval (list * 6 7))
→ 42
→ 42
Line 417: Line 431:
(eval (read-from-string "(* 6 7)"))
(eval (read-from-string "(* 6 7)"))
→ 42
→ 42
</syntaxhighlight>
</lang>


=={{header|Elena}}==
=={{header|Elena}}==
ELENA 5.0:
ELENA 6.x:
Using ELENA Script engine:
Using ELENA Script engine:
<lang elena>import extensions'scripting;
<syntaxhighlight lang="elena">import extensions'scripting;


public program()
public program()
{
{
lscript.interpret("system'console.writeLine(""Hello World"")");
lscript.interpretLine("system'console.writeLine(""Hello World"")");
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 434: Line 448:


=={{header|Elixir}}==
=={{header|Elixir}}==
<lang elixir>iex(1)> Code.eval_string("x + 4 * Enum.sum([1,2,3,4])", [x: 17])
<syntaxhighlight lang="elixir">iex(1)> Code.eval_string("x + 4 * Enum.sum([1,2,3,4])", [x: 17])
{57, [x: 17]}
{57, [x: 17]}
iex(2)> Code.eval_string("c = a + b", [a: 1, b: 2])
iex(2)> Code.eval_string("c = a + b", [a: 1, b: 2])
{3, [a: 1, b: 2, c: 3]}
{3, [a: 1, b: 2, c: 3]}
iex(3)> Code.eval_string("a = a + b", [a: 1, b: 2])
iex(3)> Code.eval_string("a = a + b", [a: 1, b: 2])
{3, [a: 3, b: 2]}</lang>
{3, [a: 3, b: 2]}</syntaxhighlight>


=={{header|Erlang}}==
=={{header|Erlang}}==


Erlang eval is a bit complex/verbose and requires the interaction of 3 modules: <tt>erl_scan</tt> (tokenizes), <tt>erl_parse</tt> (returns an abstract form) and <tt>erl_eval</tt> (variable binding, evaluate abstract form, etc).
Erlang eval is a bit complex/verbose and requires the interaction of 3 modules: <tt>erl_scan</tt> (tokenizes), <tt>erl_parse</tt> (returns an abstract form) and <tt>erl_eval</tt> (variable binding, evaluate abstract form, etc).
<lang erlang>1> {ok, Tokens, _} = erl_scan:string("X + 4 * lists:sum([1,2,3,4]).").
<syntaxhighlight lang="erlang">1> {ok, Tokens, _} = erl_scan:string("X + 4 * lists:sum([1,2,3,4]).").
...
...
2> {ok, [Form]} = erl_parse:parse_exprs(Tokens).
2> {ok, [Form]} = erl_parse:parse_exprs(Tokens).
Line 454: Line 468:
5> Value.
5> Value.
57
57
</syntaxhighlight>
</lang>


=={{header|Factor}}==
=={{header|Factor}}==
Line 482: Line 496:
=={{header|Forth}}==
=={{header|Forth}}==
EVALUATE invokes the interpreter on a string of Forth code, using and modifying the current dictionary and stack state.
EVALUATE invokes the interpreter on a string of Forth code, using and modifying the current dictionary and stack state.
<lang forth>s" variable foo 1e fatan 4e f*" evaluate
<syntaxhighlight lang="forth">s" variable foo 1e fatan 4e f*" evaluate


f. \ 3.14159...
f. \ 3.14159...
1 foo !</lang>
1 foo !</syntaxhighlight>


Sandboxing can be achieved in general by using MARKER, which defines a checkpoint for the dictionary state which can later be restored.
Sandboxing can be achieved in general by using MARKER, which defines a checkpoint for the dictionary state which can later be restored.


<lang forth>unused . \ show how much dictionary space is available
<syntaxhighlight lang="forth">unused . \ show how much dictionary space is available
marker restore
marker restore


Line 498: Line 512:


restore
restore
unused . \ same as first unused; restore, foo, and my-def no longer defined</lang>
unused . \ same as first unused; restore, foo, and my-def no longer defined</syntaxhighlight>

=={{header|FreeBASIC}}==
<syntaxhighlight lang="vb">#macro assign(sym, expr)
__fb_unquote__(__fb_eval__("#undef " + sym))
__fb_unquote__(__fb_eval__("#define " + sym + " " + __fb_quote__(__fb_eval__(expr))))
#endmacro

#define a, b, x

assign("a", 8)
assign("b", 7)
assign("x", Sqr(a) + (Sin(b*3)/2))
Print x

assign("x", "goodbye")
Print x

Sleep</syntaxhighlight>
{{out}}
<pre> 3.246754944014219
goodby</pre>


=={{header|Frink}}==
=={{header|Frink}}==
The <CODE>eval[]</CODE> function can be used to evaluate arbitrary Frink code in the current environment, or in a new context.
The <CODE>eval[]</CODE> function can be used to evaluate arbitrary Frink code in the current environment, or in a new context.
<lang frink>
<syntaxhighlight lang="frink">
eval["length = 1234 feet + 2 inches"]
eval["length = 1234 feet + 2 inches"]
</syntaxhighlight>
</lang>


There is also a two-argument version, <CODE>eval[expression, rethrows]</CODE> where the <CODE>rethrows</CODE> argument is a boolean flag indicating if we want evaluation errors to be thrown or just suppressed and <CODE>undef</CODE> returned. If it is true, errors will be rethrown as Java exceptions, otherwise an error returns undef.
There is also a two-argument version, <CODE>eval[expression, rethrows]</CODE> where the <CODE>rethrows</CODE> argument is a boolean flag indicating if we want evaluation errors to be thrown or just suppressed and <CODE>undef</CODE> returned. If it is true, errors will be rethrown as Java exceptions, otherwise an error returns undef.
Line 514: Line 549:
=={{header|Go}}==
=={{header|Go}}==
As a compiled, strongly typed language, <code>eval()</code> is not the strong suit of Go. Nevertheless, an <code>eval</code> package exists that does that. Just don't expect it to be as easy or efficient as in interpreted languages. The eval package was originally part of the Go standard library but is now hosted and maintained externally.
As a compiled, strongly typed language, <code>eval()</code> is not the strong suit of Go. Nevertheless, an <code>eval</code> package exists that does that. Just don't expect it to be as easy or efficient as in interpreted languages. The eval package was originally part of the Go standard library but is now hosted and maintained externally.
<lang go>package main
<syntaxhighlight lang="go">package main
import (
import (
"fmt"
"fmt"
Line 538: Line 573:
fmt.Println("Return value:", val) //prints, well, 3
fmt.Println("Return value:", val) //prints, well, 3


}</lang>
}</syntaxhighlight>


=={{header|Groovy}}==
=={{header|Groovy}}==
Line 549: Line 584:
A script is a either a set of statements to be executed in order, or a Groovy class with a '''main()''' method, or a Groovy '''Thread''' subclass or '''Runnable''' implementation.
A script is a either a set of statements to be executed in order, or a Groovy class with a '''main()''' method, or a Groovy '''Thread''' subclass or '''Runnable''' implementation.
The return value is the value of the last statement executed, or the value of an explicit '''return''' statement (if any).
The return value is the value of the last statement executed, or the value of an explicit '''return''' statement (if any).
<lang groovy>def years1 = new GroovyShell().evaluate('''
<syntaxhighlight lang="groovy">def years1 = new GroovyShell().evaluate('''
(2008..2121).findAll {
(2008..2121).findAll {
Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
Line 555: Line 590:
''')
''')


println years1</lang>
println years1</syntaxhighlight>


The last expression evaluated in the script, a list of years found, is the return value of the '''evaluate()''' method.
The last expression evaluated in the script, a list of years found, is the return value of the '''evaluate()''' method.
Line 567: Line 602:
'''GString''' embedded values<br>
'''GString''' embedded values<br>
Setting up the script as a '''GString''' with embedded value parsing is a "natural" ''ad hoc'' solution for Groovy programmers, but there are possible pitfalls if the script itself contains '''GString'''s.
Setting up the script as a '''GString''' with embedded value parsing is a "natural" ''ad hoc'' solution for Groovy programmers, but there are possible pitfalls if the script itself contains '''GString'''s.
<lang groovy>def startYear = 2008
<syntaxhighlight lang="groovy">def startYear = 2008
def endYear = 2121
def endYear = 2121
def years2 = new GroovyShell().evaluate("""
def years2 = new GroovyShell().evaluate("""
Line 575: Line 610:
""")
""")


println years2</lang>
println years2</syntaxhighlight>
The variables "startYear" and "endYear" are dynamically pulled into the script '''GString''' as embedded values before the script itself ever executes.
The variables "startYear" and "endYear" are dynamically pulled into the script '''GString''' as embedded values before the script itself ever executes.


Line 582: Line 617:
'''Binding''' variables<br>
'''Binding''' variables<br>
'''GroovyShell''' uses a '''Binding''' object to pass variable values to a script. This is the only way to pass variables if the script comes from a '''File''' or '''InputStream''', but even if the script is a string '''Binding''' avoids the nested quoting issue caused by the ''ad hoc'' use of '''GString'''.
'''GroovyShell''' uses a '''Binding''' object to pass variable values to a script. This is the only way to pass variables if the script comes from a '''File''' or '''InputStream''', but even if the script is a string '''Binding''' avoids the nested quoting issue caused by the ''ad hoc'' use of '''GString'''.
<lang groovy>def context = new Binding()
<syntaxhighlight lang="groovy">def context = new Binding()
context.startYear = 2008
context.startYear = 2008
context.endYear = 2121
context.endYear = 2121
Line 589: Line 624:
Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
}
}
''')</lang>
''')</syntaxhighlight>


We may instantiate '''Binding''' with the variables as named parameters, allowing a more terse syntax:
We may instantiate '''Binding''' with the variables as named parameters, allowing a more terse syntax:
<lang groovy>def years4 = new GroovyShell( new Binding(startYear: 2008, endYear: 2121) ).evaluate('''
<syntaxhighlight lang="groovy">def years4 = new GroovyShell( new Binding(startYear: 2008, endYear: 2121) ).evaluate('''
(startYear..endYear).findAll {
(startYear..endYear).findAll {
Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
Line 598: Line 633:
''')
''')


println years4</lang>
println years4</syntaxhighlight>


We may also access the '''Binding''' object ''after'' script evaluation to extract values of any global variables set during the evaluation:
We may also access the '''Binding''' object ''after'' script evaluation to extract values of any global variables set during the evaluation:
<lang groovy>def binding = new Binding(startYear: 2008, endYear: 2121)
<syntaxhighlight lang="groovy">def binding = new Binding(startYear: 2008, endYear: 2121)
new GroovyShell( binding ).evaluate('''
new GroovyShell( binding ).evaluate('''
yearList = (startYear..endYear).findAll {
yearList = (startYear..endYear).findAll {
Line 608: Line 643:
''')
''')


println binding.yearList</lang>
println binding.yearList</syntaxhighlight>


'''Eval''' shortcut<br>
'''Eval''' shortcut<br>
For simple evaluation of string-based scripts with only a few variables (like this one), the '''Eval''' class has static shortcut methods that do the '''Binding''' setup and '''GroovyShell''' evaluation under the surface. '''Eval.me(script)''' evaluates a script with no variables. '''Eval.x(x,script)''', '''Eval.xy(x,y,script)''', or '''Eval.xyz(x,y,z,script)''' each evaluates a script with 1, 2, or 3 variables, respectively. Here is an example with start and end years as script variables ''x'' and ''y''.
For simple evaluation of string-based scripts with only a few variables (like this one), the '''Eval''' class has static shortcut methods that do the '''Binding''' setup and '''GroovyShell''' evaluation under the surface. '''Eval.me(script)''' evaluates a script with no variables. '''Eval.x(x,script)''', '''Eval.xy(x,y,script)''', or '''Eval.xyz(x,y,z,script)''' each evaluates a script with 1, 2, or 3 variables, respectively. Here is an example with start and end years as script variables ''x'' and ''y''.
<lang groovy>def years5 = Eval.xy(2008, 2121, '''
<syntaxhighlight lang="groovy">def years5 = Eval.xy(2008, 2121, '''
(x..y).findAll {
(x..y).findAll {
Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
Line 618: Line 653:
''')
''')


println years5</lang>
println years5</syntaxhighlight>


=={{header|GW-BASIC}}==
=={{header|GW-BASIC}}==
<lang qbasic>10 LINE INPUT "Type an expression: ",A$
<syntaxhighlight lang="qbasic">10 LINE INPUT "Type an expression: ",A$
20 OPEN "CHAIN.TMP" FOR OUTPUT AS #1
20 OPEN "CHAIN.TMP" FOR OUTPUT AS #1
30 PRINT #1, "70 LET Y=("+A$+")"
30 PRINT #1, "70 LET Y=("+A$+")"
Line 630: Line 665:
80 PRINT X,Y
80 PRINT X,Y
90 NEXT X
90 NEXT X
100 GOTO 10</lang>
100 GOTO 10</syntaxhighlight>


=={{header|Harbour}}==
=={{header|Harbour}}==
<lang harbour>
<syntaxhighlight lang="harbour">
Procedure Main()
Procedure Main()
local bAdd := {|Label,n1,n2| Qout( Label ), QQout( n1 + n2 )}
local bAdd := {|Label,n1,n2| Qout( Label ), QQout( n1 + n2 )}
Line 643: Line 678:
5+5 = 10
5+5 = 10
5-5 = 0
5-5 = 0
</syntaxhighlight>
</lang>


=={{header|HicEst}}==
=={{header|HicEst}}==
XEQ invokes the interpreter on a string of HicEst code, but keeps the current dictionary and stack state. Blocks of expressions are not possible.
XEQ invokes the interpreter on a string of HicEst code, but keeps the current dictionary and stack state. Blocks of expressions are not possible.
<lang HicEst>value = XEQ( " temp = 1 + 2 + 3 ") ! value is assigned 6
<syntaxhighlight lang="hicest">value = XEQ( " temp = 1 + 2 + 3 ") ! value is assigned 6
! temp is undefined outside XEQ, if it was not defined before.
! temp is undefined outside XEQ, if it was not defined before.


Line 654: Line 689:
OPEN(FIle="my_file.txt")
OPEN(FIle="my_file.txt")
READ(FIle="my_file.txt", Row=6) string
READ(FIle="my_file.txt", Row=6) string
XEQ( string ) ! executes row 6 of my_file.txt</lang>
XEQ( string ) ! executes row 6 of my_file.txt</syntaxhighlight>

=={{Header|Insitux}}==

All valid Insitux code can be evaluated at runtime using <code>eval</code>, including function definitions which remain in global scope, with access to global scope but not local.

<syntaxhighlight lang="insitux">
(var x 123)
[
(eval "(var y 100) (+ x y)")
y
]
</syntaxhighlight>

{{out}}

<pre>
[223 100]
</pre>

Error messages differ between normal code and evaluated code.

<b>Normal invocation error output:</b>

<pre>
1:6 (let time 1)
Parse Error: "time" cannot be redefined: already exists.
</pre>

<b><code>eval</code> invocation error output:</b>

<pre>
1:2 (eval "(let time 1)")
Eval Error: error within evaluated code.
Parse Error: 1695133413649 eval line 1 col 6: "time" cannot be redefined: already exists
</pre>


=={{header|J}}==
=={{header|J}}==
Use monadic [http://www.jsoftware.com/help/dictionary/d601.htm <code>".</code>] (''Do'') to execute a string.
Use monadic [http://www.jsoftware.com/help/dictionary/d601.htm <code>".</code>] (''Do'') to execute a string.


<lang j>". 'a =: +/ 1 2 3' NB. execute a string to sum 1, 2 and 3 and assign to noun a</lang>
<syntaxhighlight lang="j">". 'a =: +/ 1 2 3' NB. execute a string to sum 1, 2 and 3 and assign to noun a</syntaxhighlight>


Only J expressions are allowed in strings used as as arguments for <code>".</code> (control words and blocks of expressions are not allowed).
Only J expressions are allowed in strings used as as arguments for <code>".</code> (control words and blocks of expressions are not allowed).
Line 665: Line 735:
Alterntively, you can use the conjunction [http://www.jsoftware.com/help/dictionary/d310n.htm <code>:</code>] (''Explicit Definition'') to create various kinds of functions and evaluate them. Arguments have names, such as "y", which are specified by the language definition. For example:
Alterntively, you can use the conjunction [http://www.jsoftware.com/help/dictionary/d310n.htm <code>:</code>] (''Explicit Definition'') to create various kinds of functions and evaluate them. Arguments have names, such as "y", which are specified by the language definition. For example:


<lang j>monad :'+/y' 1 2 3</lang>
<syntaxhighlight lang="j">monad :'+/y' 1 2 3</syntaxhighlight>


Rules of scope for such functions match those described on the [[Scope modifiers]] page. Also, control words (like if. or for. or while.) and blocks of expressions are allowed in strings which are evaluated in this fashion.
Rules of scope for such functions match those described on the [[Scope modifiers]] page. Also, control words (like if. or for. or while.) and blocks of expressions are allowed in strings which are evaluated in this fashion.
Line 678: Line 748:
You can kind-of do this in Java. The compiler has the relevant APIs, so it is "considered part of your language/library/platform". You have to get a compiler (which may fail), make a pseudo-file-system, compile your class, and make a class loader that will load it. Then you can use regular Java reflection to make an instance and call methods on it.
You can kind-of do this in Java. The compiler has the relevant APIs, so it is "considered part of your language/library/platform". You have to get a compiler (which may fail), make a pseudo-file-system, compile your class, and make a class loader that will load it. Then you can use regular Java reflection to make an instance and call methods on it.


Longest "Hello world" program ever?<lang Java>import java.io.ByteArrayOutputStream;
Longest "Hello world" program ever?<syntaxhighlight lang="java">import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStream;
Line 763: Line 833:
}
}
}
}
}</lang>
}</syntaxhighlight>


{{Out}}
{{Out}}
Line 770: Line 840:
at Evaluator.eval(Evaluator.java:33)
at Evaluator.eval(Evaluator.java:33)
at Evaluator.main(Evaluator.java:21)</pre>
at Evaluator.main(Evaluator.java:21)</pre>

===Java REPL===
Java has a REPL called jshell which can be used for runtime evaluation. It is started by entering the jshell command from the command line. Here is a typical session:
<pre>
C:\Program Files\JDK\bin> .\jshell
| Welcome to JShell -- Version 20
| For an introduction type: /help intro

jshell> double value = 12.0
value ==> 12.0

jshell> value * 3
$2 ==> 36.0

jshell> List<Integer> items = List.of( 1, 2, 3 )
items ==> [1, 2, 3]

jshell> for ( int item : items ) { System.out.print(item * item + " "); }
1 4 9

jshell> void helloWorld() { System.out.println("Hello World"); }
| created method helloWorld()

jshell> helloWorld()
Hello World

jshell> /exit
| Goodbye
</pre>


=={{header|JavaScript}}==
=={{header|JavaScript}}==
The eval method handles statements and expressions well:
The eval method handles statements and expressions well:
<lang javascript>
<syntaxhighlight lang="javascript">
var foo = eval('{value: 42}');
var foo = eval('{value: 42}');
eval('var bar = "Hello, world!";');
eval('var bar = "Hello, world!";');
Line 779: Line 878:
typeof foo; // 'object'
typeof foo; // 'object'
typeof bar; // 'string'
typeof bar; // 'string'
</syntaxhighlight>
</lang>


=={{header|Jsish}}==
=={{header|Jsish}}==
From Javascript entry.
From Javascript entry.
<lang javascript>/* Runtime evaluation, in Jsish */
<syntaxhighlight lang="javascript">/* Runtime evaluation, in Jsish */
var foo = eval('{value: 42}');
var foo = eval('{value: 42}');
eval('var bar = "Hello, world!";');
eval('var bar = "Hello, world!";');
Line 799: Line 898:
bar ==> Hello, world!
bar ==> Hello, world!
=!EXPECTEND!=
=!EXPECTEND!=
*/</lang>
*/</syntaxhighlight>


{{out}}
{{out}}
Line 813: Line 912:
To run an entire script in the current env:
To run an entire script in the current env:


<lang julia>include("myfile.jl")</lang>
<syntaxhighlight lang="julia">include("myfile.jl")</syntaxhighlight>


To run a string in the current env:
To run a string in the current env:


<lang julia>include_string("""
<syntaxhighlight lang="julia">include_string("""
x = sum([1, 2, 3])
x = sum([1, 2, 3])
@show x
@show x
""")
""")


@show typeof(x) # Int64</lang>
@show typeof(x) # Int64</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
Line 844: Line 943:
48
48
>>> :quit
>>> :quit
</pre>

=={{header|Lang}}==
<syntaxhighlight lang="lang">
# Simple assignements are used so that rvalues are parsed as TEXT values
$code=fn.println(Hello World!)
# Returns VOID unless return or throw is explicitly used
fn.exec($code)

$code=return Hello World!
fn.println(fn.exec($code))

$code=throw $LANG_ERROR_DIV_BY_ZERO
# Will print "Dividing by 0" in the Standard Lang implementation (Error texts are not standardized)
fn.println(fn.errorText(fn.exec($code)))

$code=parser.op(20//0)
# Will return VOID because no error was thrown explicitly
fn.println(fn.exec($code))
</syntaxhighlight>
This is the output for the Standard Lang implementation.
{{out}}
<pre>
Hello World!
Hello World!
An error occured [error output: redacted]
Dividing by 0
An error occured [error output: redacted]

</pre>
</pre>


Line 861: Line 989:
the third parameter in the sourcefile invocation.
the third parameter in the sourcefile invocation.


<lang Lasso>//code, fragment name, autocollect, inplaintext
<syntaxhighlight lang="lasso">//code, fragment name, autocollect, inplaintext
local(mycode = "'Hello world, it is '+date")
local(mycode = "'Hello world, it is '+date")
sourcefile('['+#mycode+']','arbritraty_name', true, true)->invoke
sourcefile('['+#mycode+']','arbritraty_name', true, true)->invoke
Line 890: Line 1,018:
local(mycode = "var(x) *= var(z)")
local(mycode = "var(x) *= var(z)")
sourcefile(#mycode,'arbritraty_name', false, false)->invoke
sourcefile(#mycode,'arbritraty_name', false, false)->invoke
'var x is now: '+$x</lang>
'var x is now: '+$x</syntaxhighlight>


{{out}}
{{out}}
Line 901: Line 1,029:
=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
Liberty BASIC has the ability to evaluate arrays using a string for the array name and a variable for the element.
Liberty BASIC has the ability to evaluate arrays using a string for the array name and a variable for the element.
<syntaxhighlight lang="lb">
<lang lb>
'Dimension a numerical and string array
'Dimension a numerical and string array
Dim myArray(5)
Dim myArray(5)
Line 921: Line 1,049:
Print Eval$(numArrayName$ + "(" + str$(i) + ")")
Print Eval$(numArrayName$ + "(" + str$(i) + ")")
Print Eval$(strArrayName$ + "$(" + str$(i) + ")")
Print Eval$(strArrayName$ + "$(" + str$(i) + ")")
Next i </lang>
Next i </syntaxhighlight>


An example using a struct and a pointer.
An example using a struct and a pointer.
<syntaxhighlight lang="lb">
<lang lb>
Struct myStruct, value As long, _
Struct myStruct, value As long, _
string As ptr
string As ptr
Line 938: Line 1,066:
'Pay close attention that this is EVAL() because we are
'Pay close attention that this is EVAL() because we are
'retrieving the PTR to the string which is essentially a ulong
'retrieving the PTR to the string which is essentially a ulong
Print Winstring(Eval(structName$ + "." + strElement$ + "." + "struct")) </lang>
Print Winstring(Eval(structName$ + "." + strElement$ + "." + "struct")) </syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>f = loadstring(s) -- load a string as a function. Returns a function.
<syntaxhighlight lang="lua">f = loadstring(s) -- load a string as a function. Returns a function.


one = loadstring"return 1" -- one() returns 1
one = loadstring"return 1" -- one() returns 1


two = loadstring"return ..." -- two() returns the arguments passed to it</lang>
two = loadstring"return ..." -- two() returns the arguments passed to it</syntaxhighlight>


In Lua 5.2 the <code>loadstring</code> function is superseded by the more general <code>load</code> function, which can be used in a compatible way. Nevertheless, <code>loadstring</code> is still available.
In Lua 5.2 the <code>loadstring</code> function is superseded by the more general <code>load</code> function, which can be used in a compatible way. Nevertheless, <code>loadstring</code> is still available.
Line 951: Line 1,079:
{{works with|Lua|5.2}}
{{works with|Lua|5.2}}


<lang lua>f = load("return 42")
<syntaxhighlight lang="lua">f = load("return 42")
f() --> returns 42</lang>
f() --> returns 42</syntaxhighlight>


In Lua 5.3+ (5.3, 5.4) <code>loadstring</code> is no longer available, use <code>load</code> instead.
In Lua 5.3+ (5.3, 5.4) <code>loadstring</code> is no longer available, use <code>load</code> instead.
<lang lua>> f = load("return 42")
<syntaxhighlight lang="lua">> f = load("return 42")
> f()
> f()
42
42
> n = load("return 42")()
> n = load("return 42")()
> n
> n
42</lang>
42</syntaxhighlight>


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module checkit {
Module checkit {
Module dummy {
Module dummy {
Line 999: Line 1,127:
}
}
CheckIt
CheckIt
</syntaxhighlight>
</lang>


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Mathematica's <code>ToExpression</code> evaluates an expression string as if it were placed directly in the code. Statements are just <code>CompoundExpression</code>s, so they also work. Any evaluation can be limited with <code>TimeConstrained</code> and <code>MemoryConstrained</code>.
Mathematica's <code>ToExpression</code> evaluates an expression string as if it were placed directly in the code. Statements are just <code>CompoundExpression</code>s, so they also work. Any evaluation can be limited with <code>TimeConstrained</code> and <code>MemoryConstrained</code>.
<lang Mathematica>Print[ToExpression["1 + 1"]];
<syntaxhighlight lang="mathematica">Print[ToExpression["1 + 1"]];
Print[ToExpression["Print[\"Hello, world!\"]; 10!"]];
Print[ToExpression["Print[\"Hello, world!\"]; 10!"]];
x = 5;
x = 5;
Line 1,011: Line 1,139:
Print[MemoryConstrained[ToExpression["Range[10^5]"], 10000, {}]];
Print[MemoryConstrained[ToExpression["Range[10^5]"], 10000, {}]];
Print[TimeConstrained[ToExpression["Pause[1]; True"], 2, False]];
Print[TimeConstrained[ToExpression["Pause[1]; True"], 2, False]];
Print[TimeConstrained[ToExpression["Pause[60]; True"], 2, False]];</lang>
Print[TimeConstrained[ToExpression["Pause[60]; True"], 2, False]];</syntaxhighlight>
{{out}}
{{out}}
<pre>2
<pre>2
Line 1,026: Line 1,154:
The eval and evalin functions handles any kind of code. It can handle multi-line code, although it needs the lines to be separated by the newline character. It can even allow you to program at runtime, as illustrated in the last example in the code and output below.
The eval and evalin functions handles any kind of code. It can handle multi-line code, although it needs the lines to be separated by the newline character. It can even allow you to program at runtime, as illustrated in the last example in the code and output below.
Errors can occur when mixing eval statements with regular code, especially "compile-time" errors if the code appears to be missing key elements (ending brackets or end statements, etc). Some of these are also demonstrated.
Errors can occur when mixing eval statements with regular code, especially "compile-time" errors if the code appears to be missing key elements (ending brackets or end statements, etc). Some of these are also demonstrated.
<lang MATLAB>function testEval
<syntaxhighlight lang="matlab">function testEval
fprintf('Expressions:\n')
fprintf('Expressions:\n')
x = eval('5+10^2')
x = eval('5+10^2')
Line 1,062: Line 1,190:
end
end
eval(codeBlock)
eval(codeBlock)
end</lang>
end</syntaxhighlight>
{{out}}
{{out}}
<pre>Expressions:
<pre>Expressions:
Line 1,104: Line 1,232:
=={{header|Maxima}}==
=={{header|Maxima}}==


<lang maxima>/* Here is how to create a function and return a value at runtime. In the first example,
<syntaxhighlight lang="maxima">/* Here is how to create a function and return a value at runtime. In the first example,
the function is made global, i.e. it still exists after the statement is run. In the second example, the function
the function is made global, i.e. it still exists after the statement is run. In the second example, the function
is declared local. The evaluated string may read or write any variable defined before eval_string is run. */
is declared local. The evaluated string may read or write any variable defined before eval_string is run. */
Line 1,120: Line 1,248:


fundef(f);
fundef(f);
/* f(x) := x^2 + 1 */</lang>
/* f(x) := x^2 + 1 */</syntaxhighlight>


=={{header|Nanoquery}}==
=={{header|Nanoquery}}==
The exec() function runs code contained within a string as if it were being read from a file, so any valid code may be run.
The exec() function runs code contained within a string as if it were being read from a file, so any valid code may be run.
<lang nanoquery>exec("println \"hello, world\"")
<syntaxhighlight lang="nanoquery">exec("println \"hello, world\"")
exec("a = 1\nif a = 1\nprintln \"a is 1\"\nend\nprintln \"test\"")</lang>
exec("a = 1\nif a = 1\nprintln \"a is 1\"\nend\nprintln \"test\"")</syntaxhighlight>
{{out}}
{{out}}
<pre>hello, world
<pre>hello, world
Line 1,132: Line 1,260:
=={{header|Nim}}==
=={{header|Nim}}==
'''File: runtime_eval.nim'''
'''File: runtime_eval.nim'''
<lang nim>import ../compiler/[nimeval, llstream, ast], strformat, os
<syntaxhighlight lang="nim">import ../compiler/[nimeval, llstream, ast], strformat, os


let std = findNimStdLibCompileTime()
let std = findNimStdLibCompileTime()
Line 1,165: Line 1,293:
discard
discard


destroyInterpreter(intr)</lang>
destroyInterpreter(intr)</syntaxhighlight>
'''Usage'''
'''Usage'''
<pre>nim c runtime_eval.nim
<pre>nim c runtime_eval.nim
Line 1,190: Line 1,318:
In order to restrict evaluation, perform is used on strings. With perform, only objects can be evaluated. If a function or a method is included into the string an exception is raised and the function is not evaluated.
In order to restrict evaluation, perform is used on strings. With perform, only objects can be evaluated. If a function or a method is included into the string an exception is raised and the function is not evaluated.


<lang Oforth>"[ [ $a, 12], [$b, 1.2], [ $c, [ $aaa, $bbb, $ccc ] ], [ $torun, #first ] ]" perform .s
<syntaxhighlight lang="oforth">"[ [ $a, 12], [$b, 1.2], [ $c, [ $aaa, $bbb, $ccc ] ], [ $torun, #first ] ]" perform .s
[1] (List) [[a, 12], [b, 1.2], [c, [aaa, bbb, ccc]], [torun, #first]]
[1] (List) [[a, 12], [b, 1.2], [c, [aaa, bbb, ccc]], [torun, #first]]


"12 13 +" perform
"12 13 +" perform
[1:interpreter] ExCompiler : Can't evaluate <+></lang>
[1:interpreter] ExCompiler : Can't evaluate <+></syntaxhighlight>




In order to evaluate any Oforth code, eval can be used. This method should not be used on unsafe strings.
In order to evaluate any Oforth code, eval can be used. This method should not be used on unsafe strings.


<lang Oforth>"12 13 + println" eval
<syntaxhighlight lang="oforth">"12 13 + println" eval
25
25
": newFunction(a) a + ; 12 10 newFunction println" eval
": newFunction(a) a + ; 12 10 newFunction println" eval
22</lang>
22</syntaxhighlight>


=={{header|ooRexx}}==
=={{header|ooRexx}}==
The ooRexx INTERPRET instruction allows execution of dynamically constructed code. Almost any well-formed code can be executed dynamically, including multiple instructions at a time. The instructions are executed in the local context where the interpret instruction executes, so full access to the current variable context is available. For example:
The ooRexx INTERPRET instruction allows execution of dynamically constructed code. Almost any well-formed code can be executed dynamically, including multiple instructions at a time. The instructions are executed in the local context where the interpret instruction executes, so full access to the current variable context is available. For example:
<syntaxhighlight lang="oorexx">
<lang ooRexx>
a = .array~of(1, 2, 3)
a = .array~of(1, 2, 3)
ins = "loop num over a; say num; end"
ins = "loop num over a; say num; end"
interpret ins
interpret ins
</syntaxhighlight>
</lang>
Executes the LOOP instruction, displaying the contents of the array pointed to by variable A.
Executes the LOOP instruction, displaying the contents of the array pointed to by variable A.


Line 1,218: Line 1,346:
This demo produces tables of Y values, given a formula, and a range of X values to step through.
This demo produces tables of Y values, given a formula, and a range of X values to step through.


<lang oxygenbasic>
<syntaxhighlight lang="oxygenbasic">


function ExecSeries(string s,double b,e,i) as string
function ExecSeries(string s,double b,e,i) as string
Line 1,271: Line 1,399:
print ExecSeries "y=sqrt x",1, 9 , 1
print ExecSeries "y=sqrt x",1, 9 , 1


</syntaxhighlight>
</lang>


=={{header|Oz}}==
=={{header|Oz}}==
<lang oz>declare
<syntaxhighlight lang="oz">declare
%% simplest case: just evaluate expressions without bindings
%% simplest case: just evaluate expressions without bindings
R1 = {Compiler.virtualStringToValue "{Abs ~42}"}
R1 = {Compiler.virtualStringToValue "{Abs ~42}"}
Line 1,290: Line 1,418:
{Engine enqueue(setSwitch(expression false))} %% statements instead of expr.
{Engine enqueue(setSwitch(expression false))} %% statements instead of expr.
{Engine enqueue(mergeEnv(env('A':42 'System':System)))}
{Engine enqueue(mergeEnv(env('A':42 'System':System)))}
{Engine enqueue(feedVirtualString("{System.show A}"))}</lang>
{Engine enqueue(feedVirtualString("{System.show A}"))}</syntaxhighlight>


By restricting the environment it is possible to restrict what kind of programs can be run.
By restricting the environment it is possible to restrict what kind of programs can be run.
Line 1,297: Line 1,425:
Since GP is usually run from the [[wp:Read–eval–print loop|REPL]] gp, it is trivial to evaluate programs at runtime (most are run this way). Slightly less trivial is passing code around as a first-class object:
Since GP is usually run from the [[wp:Read–eval–print loop|REPL]] gp, it is trivial to evaluate programs at runtime (most are run this way). Slightly less trivial is passing code around as a first-class object:


<lang parigp>runme(f)={
<syntaxhighlight lang="parigp">runme(f)={
f()
f()
};
};


runme( ()->print("Hello world!") )</lang>
runme( ()->print("Hello world!") )</syntaxhighlight>


One facility designed for restricting such embedded programs is <code>default(secure,1)</code> which denies scripts the ability to run <code>system</code> and <code>extern</code>. This cannot be turned off except interactively.
One facility designed for restricting such embedded programs is <code>default(secure,1)</code> which denies scripts the ability to run <code>system</code> and <code>extern</code>. This cannot be turned off except interactively.
Line 1,311: Line 1,439:
* If the subprogram throws an exception, <code>eval</code> returns <code>undef</code>. The text of the exception is assigned to <code>$@</code>. (When the subprogram terminates without an exception, <code>$@</code> is set to the null string instead.)
* If the subprogram throws an exception, <code>eval</code> returns <code>undef</code>. The text of the exception is assigned to <code>$@</code>. (When the subprogram terminates without an exception, <code>$@</code> is set to the null string instead.)


<lang perl>my ($a, $b) = (-5, 7);
<syntaxhighlight lang="perl">my ($a, $b) = (-5, 7);
$ans = eval 'abs($a * $b)'; # => 35</lang>
$ans = eval 'abs($a * $b)'; # => 35</syntaxhighlight>

=={{header|Phix}}==
The eval() function can be used to run fragments of code. The code is run in a brand new context and
hence must be valid in a standalone sense, and cannot directly reference any external identifiers.
Any existing data that needs to be accessed must be provided via the ival and/or iset parameters, and
any results must be explicitly requested via the rset parameter, and any updates applied/extracted
once eval() returns. Passing large tables into and out of the eval context is actually quite efficient,
though some careful refcount management may improve performance, as detailed in the docs.<br>
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Runtime_evaluation.exw</span>
<span style="color: #008080;">without</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.1"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">include</span> <span style="color: #7060A8;">eval</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> <span style="color: #000080;font-style:italic;">-- (not an autoinclude, pulls in around 90% of the interpreter/compiler proper)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">code</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
integer i = 0
bool r_init = false
sequence r
if not r_init then r = {} end if
for k=1 to 4 do
i += k
r &= k
end for
"""</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #000000;">code</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"i"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- prints {10,{1,2,3,4}}</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #000000;">code</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">},{{</span><span style="color: #008000;">"r_init"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">}}})</span> <span style="color: #000080;font-style:italic;">-- prints {5,1,2,3,4}</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #000000;">code</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"i"</span><span style="color: #0000FF;">},{{</span><span style="color: #008000;">"i"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">}})</span> <span style="color: #000080;font-style:italic;">-- prints {25}</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`puts(1,"Hello World\n")`</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- prints Hello World</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
{10,{1,2,3,4}}
{{5,1,2,3,4}}
{25}
Hello World
</pre>

===Evaluating expressions===
Just as a bare (say) "3+4" in a normal source code file would trigger a syntax error, so too would
passing that directly to the eval() function. However it is of course trivial to assign the result
of an expression to a (newly declared) variable and return that:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">eval_expression</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">object</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"object x = %s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">}),{</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">eval_expression</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3+4"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- prints 7</span>
<!--</syntaxhighlight>-->

===Sandboxing===
It is perfectly possible to add a "with safe_mode" prefix to the code passed to eval(), however any runtime error message generated appears to use the wrong symbol table, and therefore is largely gibberish, but at least it blocks dangerous things properly. Slightly better or more readable error messages may be produced by compiling the program, as in the one that invokes eval(), instead of interpreting it.


=={{header|PHP}}==
=={{header|PHP}}==
The [http://www.php.net/eval eval construct] allow string evaluation as PHP code. Opening and closing tags are not required. Return statements immediatly terminates evaluation . Eval returns NULL, unless return is called in evalued code.
The [http://www.php.net/eval eval construct] allow string evaluation as PHP code. Opening and closing tags are not required. Return statements immediatly terminates evaluation . Eval returns NULL, unless return is called in evalued code.
<lang php>
<syntaxhighlight lang="php">
<?php
<?php
$code = 'echo "hello world"';
$code = 'echo "hello world"';
Line 1,322: Line 1,501:
$code = 'return "hello world"';
$code = 'return "hello world"';
print eval($code);
print eval($code);
</syntaxhighlight>
</lang>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Line 1,352: Line 1,531:
=={{header|Pike}}==
=={{header|Pike}}==
Pike provides [http://pike.ida.liu.se/doc/compile_string() <code>compile_string()</code>] and [http://pike.ida.liu.se/doc/compile_file() <code>compile_file()</code>] which can compile code into a class that can be instantiated:
Pike provides [http://pike.ida.liu.se/doc/compile_string() <code>compile_string()</code>] and [http://pike.ida.liu.se/doc/compile_file() <code>compile_file()</code>] which can compile code into a class that can be instantiated:
<lang Pike>program demo = compile_string(#"
<syntaxhighlight lang="pike">program demo = compile_string(#"
string name=\"demo\";
string name=\"demo\";
string hello()
string hello()
Line 1,360: Line 1,539:


demo()->hello();
demo()->hello();
Result: "hello, i am demo"</lang>
Result: "hello, i am demo"</syntaxhighlight>


an actual application of this is shown in [[Simple database]].
an actual application of this is shown in [[Simple database]].
Line 1,366: Line 1,545:
=={{header|PowerShell}}==
=={{header|PowerShell}}==
Evaluate an expression:
Evaluate an expression:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$test2plus2 = '2 + 2 -eq 4'
$test2plus2 = '2 + 2 -eq 4'
Invoke-Expression $test2plus2
Invoke-Expression $test2plus2
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 1,375: Line 1,554:
</pre>
</pre>
Evaluate a <code>[scriptblock]</code> (a statement or group of statements) with code surrounded by curly braces using the '''&''' ('''call''') operator:
Evaluate a <code>[scriptblock]</code> (a statement or group of statements) with code surrounded by curly braces using the '''&''' ('''call''') operator:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$say = {"Hello, world!"}
$say = {"Hello, world!"}
& $say
& $say
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 1,384: Line 1,563:
</pre>
</pre>
Scriptblocks behave just as functions so they may have parameters:
Scriptblocks behave just as functions so they may have parameters:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$say = {param ([string]$Subject) "Hello, $Subject!"}
$say = {param ([string]$Subject) "Hello, $Subject!"}
& $say -Subject "my friend"
& $say -Subject "my friend"
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 1,393: Line 1,572:
</pre>
</pre>
A slightly more complex example:
A slightly more complex example:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$say = {param ([string]$Exclamation, [string]$Subject) "$Exclamation, $Subject!"}
$say = {param ([string]$Exclamation, [string]$Subject) "$Exclamation, $Subject!"}
& $say -Exclamation "Goodbye" -Subject "cruel world"
& $say -Exclamation "Goodbye" -Subject "cruel world"
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 1,402: Line 1,581:
</pre>
</pre>
To reverse the normal behaviour of a <code>[scriptblock]</code> use the '''GetNewClosure''' method. This makes the scriptblock self-contained or closed; ie, the variable will only be read when the scriptblock is initialised:
To reverse the normal behaviour of a <code>[scriptblock]</code> use the '''GetNewClosure''' method. This makes the scriptblock self-contained or closed; ie, the variable will only be read when the scriptblock is initialised:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$title = "Dong Work For Yuda"
$title = "Dong Work For Yuda"
$scriptblock = {$title}
$scriptblock = {$title}
Line 1,409: Line 1,588:
& $scriptblock
& $scriptblock
& $closedScriptblock
& $closedScriptblock
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 1,416: Line 1,595:
</pre>
</pre>
Change the variable and execute the scriptblock, the closed version will not reflect the change:
Change the variable and execute the scriptblock, the closed version will not reflect the change:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$title = "I'm Too Sexy"
$title = "I'm Too Sexy"
& $scriptblock
& $scriptblock
& $closedScriptblock
& $closedScriptblock
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 1,432: Line 1,611:
The [http://docs.python.org/reference/simple_stmts.html#exec exec statement] allows the optional passing in of global and local names via mappings (See the link for full syntax). The example below shows exec being used to parse and execute a string containing two statements:
The [http://docs.python.org/reference/simple_stmts.html#exec exec statement] allows the optional passing in of global and local names via mappings (See the link for full syntax). The example below shows exec being used to parse and execute a string containing two statements:


<lang python>>>> exec '''
<syntaxhighlight lang="python">>>> exec '''
x = sum([1,2,3,4])
x = sum([1,2,3,4])
print x
print x
'''
'''
10</lang>
10</syntaxhighlight>


{{works with|Python|3.x}}
{{works with|Python|3.x}}
Note that in Python 3.x [http://docs.python.org/py3k/library/functions.html#exec exec] is a function:
Note that in Python 3.x [http://docs.python.org/py3k/library/functions.html#exec exec] is a function:


<lang python>>>> exec('''
<syntaxhighlight lang="python">>>> exec('''
x = sum([1,2,3,4])
x = sum([1,2,3,4])
print(x)
print(x)
''')
''')
10</lang>
10</syntaxhighlight>


=={{header|Quackery}}==
=={{header|Quackery}}==
Line 1,453: Line 1,632:
Any Quackery code fragment can be passed as a string to <code>quackery</code>, with parameters and results being passed via the stack. In the sample code, the string <code>"1 swap times [ i 1+ * ]"</code>, when compiled and evaluated by <code>quackery</code>, will take the <code>10</code> placed on the stack beforehand, compute its factorial and leave the result on the stack for <code>echo</code> to echo to the screen.
Any Quackery code fragment can be passed as a string to <code>quackery</code>, with parameters and results being passed via the stack. In the sample code, the string <code>"1 swap times [ i 1+ * ]"</code>, when compiled and evaluated by <code>quackery</code>, will take the <code>10</code> placed on the stack beforehand, compute its factorial and leave the result on the stack for <code>echo</code> to echo to the screen.


<lang>10 $ "1 swap times [ i 1+ * ]" quackery echo</lang>
<syntaxhighlight lang="text">10 $ "1 swap times [ i 1+ * ]" quackery echo</syntaxhighlight>


{{out}}
{{out}}
Line 1,468: Line 1,647:
Thus all these three are equivalent.
Thus all these three are equivalent.


<lang r>expr1 <- quote(a+b*c)
<syntaxhighlight lang="r">expr1 <- quote(a+b*c)
expr2 <- parse(text="a+b*c")[[1]]
expr2 <- parse(text="a+b*c")[[1]]
expr3 <- call("+", quote(`a`), call("*", quote(`b`), quote(`c`)))</lang>
expr3 <- call("+", quote(`a`), call("*", quote(`b`), quote(`c`)))</syntaxhighlight>


<tt>eval()</tt> evaluates a quoted expression. <tt>evalq()</tt> is a version of <tt>eval()</tt> which quotes its first argument.
<tt>eval()</tt> evaluates a quoted expression. <tt>evalq()</tt> is a version of <tt>eval()</tt> which quotes its first argument.


<lang r>> a <- 1; b <- 2; c <- 3
<syntaxhighlight lang="r">> a <- 1; b <- 2; c <- 3
> eval(expr1)
> eval(expr1)
[1] 7</lang>
[1] 7</syntaxhighlight>


<tt>eval()</tt> has an optional second environment which is the lexical environment to evaluate in.
<tt>eval()</tt> has an optional second environment which is the lexical environment to evaluate in.


<lang r>> env <- as.environment(list(a=1, b=3, c=2))
<syntaxhighlight lang="r">> env <- as.environment(list(a=1, b=3, c=2))
> evalq(a, env)
> evalq(a, env)
[1] 1
[1] 1
Line 1,490: Line 1,669:
> assign("b", 5, env) # assign() can assign into environments
> assign("b", 5, env) # assign() can assign into environments
> eval(expr1, env)
> eval(expr1, env)
[1] 11</lang>
[1] 11</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==
Line 1,496: Line 1,675:
Racket has the usual <tt>eval</tt> that is demonstrated [[Runtime_evaluation/In_an_environment#Racket|here]], and in addition, it has a sandbox environment that provides a safe evaluator that is restricted from accessing files, network, etc.
Racket has the usual <tt>eval</tt> that is demonstrated [[Runtime_evaluation/In_an_environment#Racket|here]], and in addition, it has a sandbox environment that provides a safe evaluator that is restricted from accessing files, network, etc.


<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
#lang racket
(require racket/sandbox)
(require racket/sandbox)
Line 1,505: Line 1,684:
;; (e '(delete-file "/etc/passwd"))
;; (e '(delete-file "/etc/passwd"))
;; --> delete-file: `delete' access denied for /etc/passwd
;; --> delete-file: `delete' access denied for /etc/passwd
</syntaxhighlight>
</lang>


And, of course, both of these methods can use Racket's multilingual capabilities and evaluate the code in a language with different semantics.
And, of course, both of these methods can use Racket's multilingual capabilities and evaluate the code in a language with different semantics.
Line 1,512: Line 1,691:
(formerly Perl 6)
(formerly Perl 6)
Any syntactically valid sequence of statements may be run, and the snippet to be run can see its outer lexical scope at the point of the <tt>eval</tt>:
Any syntactically valid sequence of statements may be run, and the snippet to be run can see its outer lexical scope at the point of the <tt>eval</tt>:
<lang perl6>use MONKEY-SEE-NO-EVAL;
<syntaxhighlight lang="raku" line>use MONKEY-SEE-NO-EVAL;


my ($a, $b) = (-5, 7);
my ($a, $b) = (-5, 7);
my $ans = EVAL 'abs($a * $b)'; # => 35</lang>
my $ans = EVAL 'abs($a * $b)'; # => 35</syntaxhighlight>
Unlike in Perl 5, <tt>eval</tt> in Raku only compiles and executes the string, but does not trap exceptions. You must say <tt>try eval</tt> to get that behavior (or supply a <tt>CATCH</tt> block within the text to be evaluated).
Unlike in Perl 5, <tt>eval</tt> in Raku only compiles and executes the string, but does not trap exceptions. You must say <tt>try eval</tt> to get that behavior (or supply a <tt>CATCH</tt> block within the text to be evaluated).


Line 1,522: Line 1,701:


It performs the fundamental interpretive action of the Rebol language and is used internally within many other functions such as <tt>if, case, while, loop, repeat, foreach</tt>, and others.
It performs the fundamental interpretive action of the Rebol language and is used internally within many other functions such as <tt>if, case, while, loop, repeat, foreach</tt>, and others.
<lang rebol>a: -5
<syntaxhighlight lang="rebol">a: -5
b: 7
b: 7
answer: do [abs a * b] ; => 35</lang>
answer: do [abs a * b] ; => 35</syntaxhighlight>


=={{header|REXX}}==
=={{header|REXX}}==
Line 1,530: Line 1,709:
:::* &nbsp; &nbsp; run-time evaluation of an internal expression, &nbsp; and
:::* &nbsp; &nbsp; run-time evaluation of an internal expression, &nbsp; and
:::* &nbsp; &nbsp; run-time evaluation of a user-prompted expression.
:::* &nbsp; &nbsp; run-time evaluation of a user-prompted expression.
<lang rexx>/*REXX program illustrates the ability to execute code entered at runtime (from C.L.)*/
<syntaxhighlight lang="rexx">/*REXX program illustrates the ability to execute code entered at runtime (from C.L.)*/
numeric digits 10000000 /*ten million digits should do it. */
numeric digits 10000000 /*ten million digits should do it. */
bee=51
bee=51
Line 1,549: Line 1,728:
say 'length of result='length(?)
say 'length of result='length(?)
say ' left 50 bytes of result='left(?,50)"···"
say ' left 50 bytes of result='left(?,50)"···"
say 'right 50 bytes of result=···'right(?, 50) /*stick a fork in it, we're all done. */</lang>
say 'right 50 bytes of result=···'right(?, 50) /*stick a fork in it, we're all done. */</syntaxhighlight>
'''output''' &nbsp; when using the input: <tt> 2**44497 - 1 </tt>
'''output''' &nbsp; when using the input: <tt> 2**44497 - 1 </tt>
<br>which happens to be the 27th Mersenne prime.
<br>which happens to be the 27th Mersenne prime.
Line 1,568: Line 1,747:


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
Eval("nOutput = 5+2*5 " )
Eval("nOutput = 5+2*5 " )
See "5+2*5 = " + nOutput + nl
See "5+2*5 = " + nOutput + nl
Line 1,574: Line 1,753:
Eval("func test see 'message from test!' ")
Eval("func test see 'message from test!' ")
test()
test()
</syntaxhighlight>
</lang>
Output :
Output :
<lang ring>
<syntaxhighlight lang="ring">
5+2*5 = 15
5+2*5 = 15
1
1
Line 1,589: Line 1,768:
10
10
message from test!
message from test!
</syntaxhighlight>
</lang>


We can create simple interactive programming environment using the next program
We can create simple interactive programming environment using the next program
<lang ring>
<syntaxhighlight lang="ring">
while true
while true
see nl + "code:> "
see nl + "code:> "
Line 1,602: Line 1,781:
done
done
end
end
</syntaxhighlight>
</lang>


Output
Output
<lang ring>
<syntaxhighlight lang="ring">
code:> see "hello world"
code:> see "hello world"
hello world
hello world
Line 1,626: Line 1,805:


code:> bye
code:> bye
</syntaxhighlight>
</lang>


=={{header|Ruby}}==
=={{header|Ruby}}==


The <tt>eval</tt> method evaluates a string as code and returns the resulting object. With one argument, it evaluates in the current context:
The <tt>eval</tt> method evaluates a string as code and returns the resulting object. With one argument, it evaluates in the current context:
<lang ruby>a, b = 5, -7
<syntaxhighlight lang="ruby">a, b = 5, -7
ans = eval "(a * b).abs" # => 35</lang>
ans = eval "(a * b).abs" # => 35</syntaxhighlight>


With two arguments, <tt>eval</tt> runs in the given <tt>Binding</tt> or <tt>Proc</tt> context:
With two arguments, <tt>eval</tt> runs in the given <tt>Binding</tt> or <tt>Proc</tt> context:
<lang ruby>def first(main_var, main_binding)
<syntaxhighlight lang="ruby">def first(main_var, main_binding)
foo = 42
foo = 42
second [[main_var, main_binding], ["foo", binding]]
second [[main_var, main_binding], ["foo", binding]]
Line 1,652: Line 1,831:


hello = "world"
hello = "world"
first "hello", binding</lang>
first "hello", binding</syntaxhighlight>
<pre>value of hello is world
<pre>value of hello is world
value of foo is 42
value of foo is 42
Line 1,660: Line 1,839:
In Scheme, the expression passed to eval is evaluated in the current interaction environment, unless otherwise specified. The result is read back as a Scheme value.
In Scheme, the expression passed to eval is evaluated in the current interaction environment, unless otherwise specified. The result is read back as a Scheme value.


<lang scheme>> (define x 37)
<syntaxhighlight lang="scheme">> (define x 37)
> (eval '(+ x 5))
> (eval '(+ x 5))
42
42
Line 1,671: Line 1,850:
> (display (eval (read)))
> (display (eval (read)))
(+ 4 5) ;; this is input from the user.
(+ 4 5) ;; this is input from the user.
9</lang>
9</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
The eval method evaluates a string as code and returns the resulting object.
The eval method evaluates a string as code and returns the resulting object.


<lang ruby>var (a, b) = (-5, 7);
<syntaxhighlight lang="ruby">var (a, b) = (-5, 7);
say eval '(a * b).abs'; # => 35
say eval '(a * b).abs'; # => 35
say (a * b -> abs); # => 35</lang>
say (a * b -> abs); # => 35</syntaxhighlight>


=={{header|Slate}}==
=={{header|Slate}}==


In Slate, programs are represented as Syntax Node trees, with methods defined on the various syntactic types. The backtick syntax provides a convenient quoting mechanism, and as objects, they have convenient methods defined for evaluation or evaluation within a specific environment:
In Slate, programs are represented as Syntax Node trees, with methods defined on the various syntactic types. The backtick syntax provides a convenient quoting mechanism, and as objects, they have convenient methods defined for evaluation or evaluation within a specific environment:
<lang slate>`(4 + 5) evaluate.
<syntaxhighlight lang="slate">`(4 + 5) evaluate.
`(4 + 5) evaluateIn: prototypes.</lang>
`(4 + 5) evaluateIn: prototypes.</syntaxhighlight>


You can also explicitly invoke the Parser on a String, to convert it into syntactic objects:
You can also explicitly invoke the Parser on a String, to convert it into syntactic objects:
<lang slate>(Syntax Parser newOn: '4 + 5') upToEnd do: [| :each | print: each evaluate]</lang>
<syntaxhighlight lang="slate">(Syntax Parser newOn: '4 + 5') upToEnd do: [| :each | print: each evaluate]</syntaxhighlight>


You can construct a program using externally-specified values using <tt>`unquote</tt> within a quoted expression:
You can construct a program using externally-specified values using <tt>`unquote</tt> within a quoted expression:
<lang slate>define: #x -> 4.
<syntaxhighlight lang="slate">define: #x -> 4.
`(x `unquote + 5) evaluate.</lang>
`(x `unquote + 5) evaluate.</syntaxhighlight>


Or you can obviously construct a string:
Or you can obviously construct a string:
<lang slate>define: #x -> 4.
<syntaxhighlight lang="slate">define: #x -> 4.
(Syntax Parser newOn: x printString ; ' + 5')</lang>
(Syntax Parser newOn: x printString ; ' + 5')</syntaxhighlight>


The <tt>evaluate</tt> method also takes into consideration the current lexical scope, unless another environment is specified. The following returns 10, no matter what binding <tt>x</tt> has in the local namespace:
The <tt>evaluate</tt> method also takes into consideration the current lexical scope, unless another environment is specified. The following returns 10, no matter what binding <tt>x</tt> has in the local namespace:
<lang slate>define: #x -> 4.
<syntaxhighlight lang="slate">define: #x -> 4.
[| x | x: 5. `(x `unquote + 5) evaluate] do.</lang>
[| x | x: 5. `(x `unquote + 5) evaluate] do.</syntaxhighlight>


Slate can sandbox via constructing a fresh namespace and evaluating within it, but this mechanism is not strongly secure yet.
Slate can sandbox via constructing a fresh namespace and evaluating within it, but this mechanism is not strongly secure yet.

=={{header|Slope}}==
You can create a list via quoted symbols and then evaluate:
<syntaxhighlight lang="slope">(eval (list '+ 1 2 3 4 5))</syntaxhighlight>

Or, you can evaluate a string as code:
<syntaxhighlight lang="slope">(eval "(+ 1 2 3 4 5)" #t)</syntaxhighlight>


=={{header|Smalltalk}}==
=={{header|Smalltalk}}==
<lang smalltalk>[ 4 + 5 ] value.</lang>
<syntaxhighlight lang="smalltalk">[ 4 + 5 ] value.</syntaxhighlight>
Evaluating an expression without bindings:
Evaluating an expression without bindings:
<lang smalltalk>e := ' 123 degreesToRadians sin '.
<syntaxhighlight lang="smalltalk">e := ' 123 degreesToRadians sin '.
Transcript show: (Compiler evaluate: e) .</lang>
Transcript show: (Compiler evaluate: e) .</syntaxhighlight>
To get local bindings (x, y),
To get local bindings (x, y),
evaluate an expression which yields a block given as a string, then call the resulting block:
evaluate an expression which yields a block given as a string, then call the resulting block:
<lang smalltalk>e := '[ :x :y | (x*x + (y*y)) sqrt ]'.
<syntaxhighlight lang="smalltalk">e := '[ :x :y | (x*x + (y*y)) sqrt ]'.
Transcript show: ((Compiler evaluate: e) value: 3 value: 4).</lang>
Transcript show: ((Compiler evaluate: e) value: 3 value: 4).</syntaxhighlight>
this could be wrapped into a utility, which expects the names to bind as argument, if required.
this could be wrapped into a utility, which expects the names to bind as argument, if required.


Line 1,718: Line 1,904:
The built in function eval() evaluates SNOBOL4 expressions and returns the value. The expression is evaluated in the current environment and has access to then-current variables.
The built in function eval() evaluates SNOBOL4 expressions and returns the value. The expression is evaluated in the current environment and has access to then-current variables.


<lang snobol4> expression = "' page ' (i + 1)"
<syntaxhighlight lang="snobol4"> expression = "' page ' (i + 1)"
i = 7
i = 7
output = eval(expression)
output = eval(expression)
end</lang>
end</syntaxhighlight>


{{out}}
{{out}}
Line 1,731: Line 1,917:
Programs of type CODE are executed by a variant of the goto clause:
Programs of type CODE are executed by a variant of the goto clause:


<lang SNOBOL4> compiled = code(' output = "Hello, world."') :s<compiled>
<syntaxhighlight lang="snobol4"> compiled = code(' output = "Hello, world."') :s<compiled>
end</lang>
end</syntaxhighlight>


When passing programs to code(), semicolons are used to separate lines.
When passing programs to code(), semicolons are used to separate lines.
Line 1,749: Line 1,935:
===Evaluating expressions===
===Evaluating expressions===
====Simple====
====Simple====
<lang sparkling>let fn = exprtofn("13 + 37");
<syntaxhighlight lang="sparkling">let fn = exprtofn("13 + 37");
fn() // -> 50</lang>
fn() // -> 50</syntaxhighlight>


====With arguments====
====With arguments====
<lang sparkling>let fn = exprtofn("#0 * #1");
<syntaxhighlight lang="sparkling">let fn = exprtofn("#0 * #1");
fn(3, 4) // -> 12</lang>
fn(3, 4) // -> 12</syntaxhighlight>


===Evaluating statements===
===Evaluating statements===
<lang sparkling>let fn = compile("for (var i = 0; i < 10; i++) { print(i); }");
<syntaxhighlight lang="sparkling">let fn = compile("for (var i = 0; i < 10; i++) { print(i); }");
fn(); // result: 0 1 2 3 4 5 6 7 8 9</lang>
fn(); // result: 0 1 2 3 4 5 6 7 8 9</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
===Simple Evaluation===
===Simple Evaluation===
Evaluation in the current interpreter:
Evaluation in the current interpreter:
<lang tcl>set four 4
<syntaxhighlight lang="tcl">set four 4
set result1 [eval "expr {$four + 5}"] ;# string input
set result1 [eval "expr {$four + 5}"] ;# string input


set result2 [eval [list expr [list $four + 5]]] ;# list input</lang>
set result2 [eval [list expr [list $four + 5]]] ;# list input</syntaxhighlight>


===Evaluation in a restricted context===
===Evaluation in a restricted context===
Tcl handles sandboxing by creating new interpreters. Each interpreter is strongly isolated from all other interpreters except in that the interpreter that creates a sub-interpreter retains management control over that “slave” interpreter. The exact capabilities exposed in the slave are controlled by what commands exist in it; commands in the slave may be aliases for other commands in the master interpreter, which allows for trapping into a more highly authorized context (which can be considered analogous to a system call to an OS kernel).
Tcl handles sandboxing by creating new interpreters. Each interpreter is strongly isolated from all other interpreters except in that the interpreter that creates a sub-interpreter retains management control over that “slave” interpreter. The exact capabilities exposed in the slave are controlled by what commands exist in it; commands in the slave may be aliases for other commands in the master interpreter, which allows for trapping into a more highly authorized context (which can be considered analogous to a system call to an OS kernel).
<lang tcl># Create an interpreter with a default set of restrictions
<syntaxhighlight lang="tcl"># Create an interpreter with a default set of restrictions
interp create -safe restrictedContext
interp create -safe restrictedContext


Line 1,790: Line 1,976:
return "there are [doubleSecret] words in the secret: the magic number is [expr {4 + 5}]"
return "there are [doubleSecret] words in the secret: the magic number is [expr {4 + 5}]"
}]; # --> there are 2 words in the secret: the magic number is 9
}]; # --> there are 2 words in the secret: the magic number is 9
puts $v; # --> secret secret</lang>
puts $v; # --> secret secret</syntaxhighlight>
As can be seen, the result of the overall evaluation is the same as the result of the evaluation in the slave.
As can be seen, the result of the overall evaluation is the same as the result of the evaluation in the slave.


Line 1,799: Line 1,985:
Even stronger protection of the master interpreter is available from Tcl 8.5 onwards through the setting of resource limits on the slaves.
Even stronger protection of the master interpreter is available from Tcl 8.5 onwards through the setting of resource limits on the slaves.
These allow the master to prevent the evaluated script from going berserk:
These allow the master to prevent the evaluated script from going berserk:
<lang tcl>set i [interp create]
<syntaxhighlight lang="tcl">set i [interp create]
interp limit $i commands -value [expr [$i eval info cmdcount]+20] -granularity 1
interp limit $i commands -value [expr [$i eval info cmdcount]+20] -granularity 1
interp eval $i {
interp eval $i {
Line 1,806: Line 1,992:
puts "Counting up... [incr x]"
puts "Counting up... [incr x]"
}
}
}</lang>
}</syntaxhighlight>
{{out}} (the last line is an error message):
{{out}} (the last line is an error message):
<pre>Counting up... 1
<pre>Counting up... 1
Line 1,827: Line 2,013:


TODO: Is there a way to execute statements as well as evaluate expressions? [[Category:TI-89 BASIC examples needing attention]]
TODO: Is there a way to execute statements as well as evaluate expressions? [[Category:TI-89 BASIC examples needing attention]]

=={{header|Transd}}==
<syntaxhighlight lang="scheme">#lang transd

MainModule : {
str: "(textout \"eval output: \" (+ 1 1))",

_start: (λ
(eval str)
)
}</syntaxhighlight>
{{out}}
<pre>
eval output: 2
</pre>


=={{header|UNIX Shell}}==
=={{header|UNIX Shell}}==
<tt>eval</tt> is the command to use:
<tt>eval</tt> is the command to use:
<lang bash>$ a=42
<syntaxhighlight lang="bash">$ a=42
$ b=a
$ b=a
$ eval "echo \$$b"
$ eval "echo \$$b"
42</lang>
42</syntaxhighlight>


=={{header|Ursa}}==
=={{header|Ursa}}==
The eval statement in Ursa takes a string and evaluates it as a command, redirecting the console to the specified I/O device.
The eval statement in Ursa takes a string and evaluates it as a command, redirecting the console to the specified I/O device.
<lang ursa># writes hello world to the console
<syntaxhighlight lang="ursa"># writes hello world to the console
eval "out \"hello world\" endl console" console
eval "out \"hello world\" endl console" console
</syntaxhighlight>
</lang>


=={{header|Wren}}==
=={{header|Wren}}==
Line 1,852: Line 2,053:
$ wren-cli
$ wren-cli
\\/"-
\\/"-
\_/ wren v0.3.0
\_/ wren v0.4.0
> 20 + 22
> 20 + 22
42
42
Line 1,864: Line 2,065:


Secondly, Wren has the ''Meta.eval'' method which can be used from within a script to execute any valid Wren code (presented to it in string form) at runtime. The string could be constructed within the script, obtained from a file or input by the user. Here's a very simple example:
Secondly, Wren has the ''Meta.eval'' method which can be used from within a script to execute any valid Wren code (presented to it in string form) at runtime. The string could be constructed within the script, obtained from a file or input by the user. Here's a very simple example:
<lang ecmascript>import "meta" for Meta
<syntaxhighlight lang="wren">import "meta" for Meta


var s = "for (i in 0..4) System.print(i)"
var s = "for (i in 0..4) System.print(i)"
Meta.eval(s)</lang>
Meta.eval(s)</syntaxhighlight>


{{out}}
{{out}}
Line 1,879: Line 2,080:


=={{header|zkl}}==
=={{header|zkl}}==
In zkl, the compiler is part of the language and compiling a chunk of code returns an executable (which how the REPL works), so <lang zkl>Compiler.Compiler.compileText(
In zkl, the compiler is part of the language and compiling a chunk of code returns an executable (which how the REPL works), so <syntaxhighlight lang="zkl">Compiler.Compiler.compileText(
"fcn f(text){text.len()}").f("foobar")
"fcn f(text){text.len()}").f("foobar")
//-->6</lang>
//-->6</syntaxhighlight>
All language constructs are allowed, the only sand boxing is the new code can only touch global resources or items explicitly passed in ("foobar" in the example).
All language constructs are allowed, the only sand boxing is the new code can only touch global resources or items explicitly passed in ("foobar" in the example).



Latest revision as of 20:14, 3 February 2024

Task
Runtime evaluation
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Demonstrate a language's ability for programs to execute code written in the language provided at runtime.

Show what kind of program fragments are permitted (e.g. expressions vs. statements), and how to get values in and out (e.g. environments, arguments, return values), if applicable what lexical/static environment the program is evaluated in, and what facilities for restricting (e.g. sandboxes, resource limits) or customizing (e.g. debugging facilities) the execution.

You may not invoke a separate evaluator program, or invoke a compiler and then its output, unless the interface of that program, and the syntax and means of executing it, are considered part of your language/library/platform.

For a more constrained task giving a specific program fragment to evaluate, see Eval in environment.

6502 Assembly

The 6502 can execute code at runtime through the use of self-modifying code, provided that the code runs in RAM. For programs that are defined in ROM, the code can be copied to RAM and executed from RAM. If you have a way to type numeric values into your program and save them in a contiguous section of memory, and those values are stored as numbers and not ASCII, a JMP to their storage location can be used to execute arbitrary code.

This example runs on the Commodore 64 and prints the letter A using a crude "eval":

;Init Routine
*=$0801
	db $0E,$08,$0A,$00,$9E,$20,$28,$32,$30,$36,$34,$29,$00,$00,$00  
*=$0810	;Start at $0810

	
	LDA #$A9		;opcode for LDA immediate
	STA smc_test
	
	LDA #'A'
	STA smc_test+1
	
	lda #$20		;opcode for JSR
	STA smc_test+2
	
	lda #<CHROUT
	STA smc_test+3
	
	lda #>CHROUT
	STA smc_test+4
	
	
smc_test:
	nop				;gets overwritten with LDA
	nop				;gets overwritten with #$41
	nop				;gets overwritten with JSR
	nop				;gets overwritten with <CHROUT
	nop				;gets overwritten with >CHROUT
	

	rts				;return to basic
Output:
LOAD"*",8,1

SEARCHING FOR *
LOADING
READY.
RUN
A
READY.

ALGOL 68

Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386 - this implementation is an interpretor, and evaluate is an extension to the standard

Variable names are generally not visible at run time with classic compilers. However ALGOL 68G is an interpretor and it retains this ability.

print(evaluate("4.0*arctan(1.0)"))
Output:
+3.14159265358979e  +0

This example demonstrates the use of variables and that the Algol 68G evaluate uses the normal Algol 68 scoping rules:

Works with: ALGOL 68G version tested with release 2.8.win32
# procedure to call the Algol 68G evaluate procedure                    #
# the environment of the evaluation will be the caller's environment    #
# with "code", "x" and "y" defined as the procedure parameters          #
PROC ev = ( STRING code, INT x, INT y )STRING: evaluate( code );

BEGIN

    INT  i := 1;
    INT  j := 2;
    REAL x := 4.2;
    REAL y := 0.7164;

    # evaluates "i + j" in the current environment                       #
    print( ( evaluate( "i + j" ), newline ) );

    # evaluates "x + y" in the environment of the procedure body of ev   #
    print( ( ev( "x + y", i, j ), newline ) );

    # evaluates "x + y" in the current environment, so shows a different #
    # result to the previous call                                        #
    print( ( evaluate( "x + y" ), newline ) );

    # prints "code" because code is defined in the environment of the    #
    # call to evaluate (in ev) although it is not defined in this        #
    # environment                                                        #
    print( ( ev( "code", 1, 2 ), newline ) );

    # prints "code + codecode + code" - see above                        #
    print( ( ev( "code + code", 1, 2 ), newline ) )

END

# if this next call was executed, a runtime error would occur as x and y #
# do not exist anymore                                                   #
# ;print( ( evaluate( "x + y" ), newline ) ) #
Output:
         +3
         +3
+4.91640000000000e  +0
code
code + codecode + code

Arturo

a: {print ["The result is:" 2+3]}
do a

userCode: input "Give me some code: "
do userCode
Output:
The result is: 5 
Give me some code: print "Hello world!"
Hello world!

AutoHotkey

Works with: AutoHotkey_H

function addScript can be used to dynamically add lines of code to a running script.

; requires AutoHotkey_H or AutoHotkey.dll
msgbox % eval("3 + 4")
msgbox % eval("4 + 4")
return


eval(expression)
{
global script
script = 
(
    expression(){
    return %expression%
  }
)
renameFunction("expression", "")  ; remove any previous expressions
gosub load ; cannot use addScript inside a function yet
exp := "expression"
return %exp%()
}

load:
DllCall(A_AhkPath "\addScript","Str",script,"Uchar",0,"Cdecl UInt")
return

renameFunction(funcName, newname){
static         
x%newname% := newname   ; store newname in a static variable so its memory is not freed
strput(newname, &x%newname%, strlen(newname) + 1)
if fnp := FindFunc(funcName)
  numput(&x%newname%, fnp+0, 0, "uint")
}

BASIC

Works with: Beta BASIC version 3.0


Works with: SAM BASIC

Evaluating expressions

VAL() function converts string into numeric value. On many Basic implementations, VAL only accepts simple numeric values. However, Sinclair Basic and its derivates such as Beta Basic and SAM Basic accept any expression that evaluates to numeric value.

The following example shows a functon that plots graph of any function f(x). The function is passed in string parameter f$.

100 DEF PROC graph f$
110   LOCAL x,y
120   PLOT 0,90
130   FOR x = -2 TO 2 STEP 0.02
140     LET y = VAL(f$)
150     DRAW TO x*50+100, y*50+90
160   NEXT x
170 END PROC

Usage example:

500 graph "SIN(x) + SIN(x*3)/3"

Executing code

The KEYIN statement available on Beta Basic and SAM Basic executes a string as if it had been entered from keyboard in command mode. It can execute commands directly, or add (or replace) lines in the program while the program is executing. This allows creating self-modifying programs.

The function do_with_x in the following example loops variable x from 1 to 10 and within the loop executes any code passed to function in parameter p$.

100 DEF PROC do_with_x p$
110   LOCAL x
130   FOR x = 1 TO 10
140     KEYIN p$
160   NEXT x
170 END PROC

The usage example below creates a multiplication table by executing inner loop for y:

500 LET y$ = "FOR y=1 TO 10: PRINT AT y, x*3; x*y: NEXT y"
510 do_with_x y$

VAL and KEYIN execute code in the environment they are called from. In the above examples, VAL and KEYIN both see the local variable x. There is no sandbox functionality in Bata BASIC or SAM BASIC.

Works with: ZX Spectrum Basic

In ZX Spectrum Basic, loading a new program will replace the existing program. The new program will sutomatically run, if it was saved to do so by using SAVE together with LINE:

10 REM load the next program
20 LOAD "PROG2"

You can also include code in a text string as follows:

10 LET f$=CHR$ 187+"(x)+"+CHR$ 178+"(x*3)/2": REM LET f$="SQR (x)+SIN (x*3)/2"
20 FOR x=0 TO 2 STEP 0.2
30 LET y=VAL f$
40 PRINT y
50 NEXT x

CHR$ 178 is the token of function SQR, and CHR$ 178 is the token of function SIN.

In 48 k mode, you can also write this:

10 LET f= SQR (x)+SIN (x*3)/2

Then the type of the variable is changed and the formula is enclosed in quotation marks:

10 LET f$=" SQR (x)+SIN (x*3)/2"

BBC BASIC

Expressions

Expressions can be evaluated using the EVAL function:

      expr$ = "PI^2 + 1"
      PRINT EVAL(expr$)
Output:
10.8696044

Statements

Statements can be executed by being tokenised and then written to a temporary file:

      exec$ = "PRINT ""Hello world!"""
      bbc$ = FNtokenise(exec$)
      
      tmpfile$ = @tmp$+"temp.bbc"
      tmpfile% = OPENOUT(tmpfile$)
      BPUT#tmpfile%, bbc$+CHR$0
      CLOSE #tmpfile%
      
      CALL tmpfile$
      END
      
      DEF FNtokenise(A$)
      LOCAL A%
      A% = EVAL("0:"+A$)
      A$ = $(!332+2)
      = CHR$(LENA$+4) + CHR$0 + CHR$0 + A$ + CHR$13
Output:
Hello world!

Burlesque

In Burlesque "Code" is actually just a list of identifiers. It is therefore possible to create and manipulate code at runtime. Evaluating a block:

blsq ) {5 5 .+}e!
10

Creating code at runtime (changing map (+5) to map (+6) at runtime):

blsq ) 1 10r@{5.+}m[
{6 7 8 9 10 11 12 13 14 15}
blsq ) 1 10r@{5.+}6 0sam[
{7 8 9 10 11 12 13 14 15 16}

Code from string at runtime:

blsq ) 1 10r@"5.+"psm[
{6 7 8 9 10 11 12 13 14 15}

Evaluating strings at runtime (reverse is just for demonstration):

blsq ) "[m}+.5{@r01 1"<-pe
{6 7 8 9 10 11 12 13 14 15}

Injecting other functions into code:

blsq ) {3 2}(?*)[+e!
6

Identifiers not contained in a block require to be quoted to push them to the stack. Note the difference:

blsq ) ?+
ERROR: Burlesque: (.+) Invalid arguments!
blsq ) ?+to
"Error"
blsq ) (?+)
?+
blsq ) (?+)to
"Ident"

(also note the fallback to .+ from ?+).

Caché ObjectScript

The 'XECUTE' command performs substantially the same operation as the '$XECUTE' function, except the latter must specify a return value.

Examples:
USER>Set cmd="Write ""Hello, World!"""
USER>Xecute cmd
Hello, World!

USER>Set fnc="(num1, num2) Set res=num1+num2 Quit res"
USER>Write $Xecute(fnc, 2, 3)
5

Common Lisp

Brief eval tutorial

The eval function evaluates Lisp code at runtime.

(eval '(+ 4 5)) ; returns 9

In Common Lisp, programs are represented as trees (s-expressions). Therefore, it is easily possible to construct a program which includes externally specified values, particularly using backquote template syntax:

(defun add-four-complicated (a-number)
  (eval `(+ 4 ',a-number)))

Or you can construct a function and then call it. (If the function is used more than once, it would be good to use compile instead of eval, which compiles the code before returning the function. eval is permitted to compile as well, but compile requires it.)

(defun add-four-by-function (a-number)
  (funcall (eval '(lambda (n) (+ 4 n)))) a-number)

If your program came from a file or user input, then you have it as a string, and read or read-from-string will convert it to s-expression form:

(eval (read-from-string "(+ 4 5)"))

Common Lisp has lexical scope, but eval always evaluates “in the null lexical environment”. In particular, eval does not inherit the lexical variables from the enclosing code. (Note that eval is an ordinary function and as such does not have access to that environment anyway.)

(let ((x 11) (y 22))
  ;; This is an error!  Inside the eval, x and y are unbound!
  (format t "~%x + y = ~a" (eval '(+ x y))))

One way to fix the error is to (declare (special x y)) for dynamic variables; but the easier and shorter way is to insert the values of x and y with the backquote template syntax.

(let ((x 11) (y 22))
  (format t "~%x + y = ~a" (eval `(+ ,x ,y))))

Sandboxing Discussion

Sandboxing in Common Lisp can be approached in a variety of ways, none of which are standardized.

One approach to define a sublanguage and validate expressions before passing them to compile or eval. Of course, a whole different language entirely can be defined, and translated to Lisp. This is essentially the classic "trusted compiler generating safe code in an untrusted target language" approach.

One way to simplify the validator is to use the package system to create a sandbox. This is done by defining a package arbitrarily called sandbox. The validator then simply has to make sure that all symbols used in the expression are restricted to those which are visible inside the sandbox package. Inside sandbox, we include only those functions, operators, variables and other symbols from system packages that are safe: materials which don't allow sandboxed code to do anything harmful from within the sandbox, or to escape from the sandbox. For instance, suppose that some package system has a function called run-shell-command. We do not import run-shell-command into the sandbox package, and our validator will reject code which has references such as

(system:run-shell-command ...)

. Therefore, the sandboxed code has no direct way to run that function. To gain access to it, it must exploit some flaw in the sandbox. One flaw in the sandbox would be the inclusion of certain package-related functions like find-symbol. The expression

(find-symbol "FOO" "BAR")

will retrieve symbol foo::bar if it exists. The validator will not find this code because it has no embedded symbolic references to package foo; they are disguised as character string. A cautious approach to the sandbox should be taken: include less rather than more, and consider each expansion of the sandbox with meticulous care.

Debugging Notes

There are no standardized debugging facilities specific to the eval operation itself, but code evaluted may be affected by the current global declarations, particularly the optimize declaration's debug and safety qualities.

Déjà Vu

The compiler, module system and interactive interpreter are all implemented in Déjà Vu itself, and the first two are part of the standard library.

Each compiled fragment is considered to be a single "file", and cannot access any local variables from outside of itself.

!run-blob !compile-string "(fake filename)" "!print \qHello world\q"
Output:
Hello world

E

In E, eval is a method of expression ASTs (EExprs). (Other types of program fragment ASTs such as methods and patterns may not be directly evaluated, and must be inserted into an expression.)

The lexical environment is provided as a parameter and cannot be omitted. The evaluated program has no access to anything but the provided environment.

? e`1 + 1`.eval(safeScope)
# value: 2

eval returns the value of the expression. evalToPair also returns the modified environment for use with further evaluation, e.g. for implementing a REPL.

? def [value, env] := e`def x := 1 + 1`.evalToPair(safeScope)
# value: [2, ...]

? e`x`.eval(env)
# value: 2

Eval from a string may be done by invoking the parser.

? def prog := <elang:syntax.makeEParser>.run("1 + 1")
# value: e`1.add(1)`

? prog.eval(safeScope)
# value: 2

EchoLisp

eval : The evaluation of the eval argument must give a symbolic expression, which is in turn evaluated. Alternatively, read-from-string produces a s-expression - any kind of program - from a string.

(eval (list * 6 7))
    42
(eval '(* 6 7)) ;; quoted argument
    42
(eval (read-from-string "(* 6 7)"))
    42

Elena

ELENA 6.x: Using ELENA Script engine:

import extensions'scripting;

public program()
{
   lscript.interpretLine("system'console.writeLine(""Hello World"")");
}
Output:
Hello World

Elixir

iex(1)> Code.eval_string("x + 4 * Enum.sum([1,2,3,4])", [x: 17])
{57, [x: 17]}
iex(2)> Code.eval_string("c = a + b", [a: 1, b: 2])
{3, [a: 1, b: 2, c: 3]} 
iex(3)> Code.eval_string("a = a + b", [a: 1, b: 2])
{3, [a: 3, b: 2]}

Erlang

Erlang eval is a bit complex/verbose and requires the interaction of 3 modules: erl_scan (tokenizes), erl_parse (returns an abstract form) and erl_eval (variable binding, evaluate abstract form, etc).

1> {ok, Tokens, _} = erl_scan:string("X + 4 * lists:sum([1,2,3,4]).").
...
2> {ok, [Form]} = erl_parse:parse_exprs(Tokens).
...
3> Bindings = erl_eval:add_binding('X', 17, erl_eval:new_bindings()).
[{'X',17}]
4> {value, Value, _} = erl_eval:expr(Form, Bindings).                 
{value,57,[{'X',17}]}
5> Value.
57

Factor

Arbitrary strings can be eval'd, but you must provide their stack effect.

IN: scratchpad "\"Hello, World!\" print" ( -- ) eval
Hello, World!
IN: scratchpad  4 5 "+" ( a b -- c ) eval
9

You can use the infer word to infer a quotation's stack effect. You can combine infer with parse-string to eval an arbitrary string without writing the stack effect yourself.

( scratchpad ) "USE: math 8 9 +" dup parse-string
"USE: math 8 9 +"
[ 8 9 + ] 
( scratchpad ) infer
"USE: math 8 9 +"
( x x -- x )
( scratchpad ) eval
17

Forth

EVALUATE invokes the interpreter on a string of Forth code, using and modifying the current dictionary and stack state.

s" variable foo   1e fatan 4e f*" evaluate

f.      \ 3.14159...
1 foo !

Sandboxing can be achieved in general by using MARKER, which defines a checkpoint for the dictionary state which can later be restored.

unused .    \ show how much dictionary space is available
marker restore

create foo 30 allot
: my-def 30 0 do cr i . ." test" loop ;

unused .    \ lower than before

restore
unused .    \ same as first unused;  restore, foo, and my-def no longer defined

FreeBASIC

#macro assign(sym, expr)
    __fb_unquote__(__fb_eval__("#undef " + sym))
    __fb_unquote__(__fb_eval__("#define " + sym + " " + __fb_quote__(__fb_eval__(expr))))
#endmacro

#define a, b, x

assign("a", 8)
assign("b", 7)
assign("x", Sqr(a) + (Sin(b*3)/2))
Print x

assign("x", "goodbye")
Print x

Sleep
Output:
 3.246754944014219
goodby

Frink

The eval[] function can be used to evaluate arbitrary Frink code in the current environment, or in a new context.

eval["length = 1234 feet + 2 inches"]

There is also a two-argument version, eval[expression, rethrows] where the rethrows argument is a boolean flag indicating if we want evaluation errors to be thrown or just suppressed and undef returned. If it is true, errors will be rethrown as Java exceptions, otherwise an error returns undef.

There is also a three-argument version, eval[expression, rethrows, hidesLocals] where the hidesLocal argument is a boolean flag indicating if we want to hide local variables (that is, create a new context) before evaluation.

Frink has an extensive security manager which allows the eval statement to prevent unsecure operations such as reading or writing a file or URL, creating new functions or classes, altering systemwide flags, evaluate arbitrary Java code, and so on. If code needs to evaluate unsecure statments, you can use the intentionally frighteningly-named unsafeEval[str] (which may itself be disallowed in secure contexts.)

Go

As a compiled, strongly typed language, eval() is not the strong suit of Go. Nevertheless, an eval package exists that does that. Just don't expect it to be as easy or efficient as in interpreted languages. The eval package was originally part of the Go standard library but is now hosted and maintained externally.

package main
import (
	"fmt"
	"bitbucket.org/binet/go-eval/pkg/eval"
	"go/token"
)

func main() {
	w := eval.NewWorld();
	fset := token.NewFileSet();

	code, err := w.Compile(fset, "1 + 2")
	if err != nil {
		fmt.Println("Compile error");
		return
	}

	val, err := code.Run();
	if err != nil {
		fmt.Println("Run time error");
		return;
	}
	fmt.Println("Return value:", val) //prints, well, 3

}

Groovy

Each of these solutions evaluates a Groovy script based on some variation of the solution to the "Yuletide Holiday" task.
Each variation has been verified to give the same output:

[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]

Simple evaluation

The GroovyShell class allows the evaluation of a string or of the text contents of a File or InputStream as a Groovy script. A script is a either a set of statements to be executed in order, or a Groovy class with a main() method, or a Groovy Thread subclass or Runnable implementation. The return value is the value of the last statement executed, or the value of an explicit return statement (if any).

def years1 = new GroovyShell().evaluate('''
(2008..2121).findAll {
    Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
}
''')

println years1

The last expression evaluated in the script, a list of years found, is the return value of the evaluate() method.

Evaluation with variables

There are several approaches to evaluating a script with variables:

  • GString embedded values
  • Binding variables
  • Eval shortcut

GString embedded values
Setting up the script as a GString with embedded value parsing is a "natural" ad hoc solution for Groovy programmers, but there are possible pitfalls if the script itself contains GStrings.

def startYear = 2008
def endYear = 2121
def years2 = new GroovyShell().evaluate("""
(${startYear}..${endYear}).findAll {
    Date.parse("yyyy-MM-dd", "\${it}-12-25").format("EEE") == "Sun"
}
""")

println years2

The variables "startYear" and "endYear" are dynamically pulled into the script GString as embedded values before the script itself ever executes.

Notice that in the script the embedded value "${it}" must be quoted with backslash (\) to prevent parsing as a part of the script GString. However, it is still correctly parsed within the internal GString when the script is run.

Binding variables
GroovyShell uses a Binding object to pass variable values to a script. This is the only way to pass variables if the script comes from a File or InputStream, but even if the script is a string Binding avoids the nested quoting issue caused by the ad hoc use of GString.

def context = new Binding()
context.startYear = 2008
context.endYear = 2121
def years3 = new GroovyShell(context).evaluate('''
(startYear..endYear).findAll {
    Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
}
''')

We may instantiate Binding with the variables as named parameters, allowing a more terse syntax:

def years4 = new GroovyShell( new Binding(startYear: 2008, endYear: 2121) ).evaluate('''
(startYear..endYear).findAll {
    Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
}
''')

println years4

We may also access the Binding object after script evaluation to extract values of any global variables set during the evaluation:

def binding = new Binding(startYear: 2008, endYear: 2121)
new GroovyShell( binding ).evaluate('''
yearList = (startYear..endYear).findAll {
    Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
}
''')

println binding.yearList

Eval shortcut
For simple evaluation of string-based scripts with only a few variables (like this one), the Eval class has static shortcut methods that do the Binding setup and GroovyShell evaluation under the surface. Eval.me(script) evaluates a script with no variables. Eval.x(x,script), Eval.xy(x,y,script), or Eval.xyz(x,y,z,script) each evaluates a script with 1, 2, or 3 variables, respectively. Here is an example with start and end years as script variables x and y.

def years5 = Eval.xy(2008, 2121, '''
(x..y).findAll {
    Date.parse("yyyy-MM-dd", "${it}-12-25").format("EEE") == "Sun"
}
''')

println years5

GW-BASIC

10 LINE INPUT "Type an expression: ",A$
20 OPEN "CHAIN.TMP" FOR OUTPUT AS #1
30 PRINT #1, "70 LET Y=("+A$+")"
40 CLOSE #1
50 CHAIN MERGE "CHAIN.TMP",60,ALL
60 FOR X=0 TO 5
70 REM
80 PRINT X,Y
90 NEXT X
100 GOTO 10

Harbour

Procedure Main()
   local bAdd := {|Label,n1,n2| Qout( Label ), QQout( n1 + n2 )}
   Eval( bAdd, "5+5 = ", 5, 5 )
   Eval( bAdd, "5-5 = ", 5, -5 )
   return

Upon execution you see: 
5+5 = 10
5-5 =  0

HicEst

XEQ invokes the interpreter on a string of HicEst code, but keeps the current dictionary and stack state. Blocks of expressions are not possible.

value = XEQ( " temp = 1 + 2 + 3 ") ! value is assigned 6
! temp is undefined outside XEQ, if it was not defined before.

XEQ(" WRITE(Messagebox) 'Hello World !' ")

OPEN(FIle="my_file.txt")
READ(FIle="my_file.txt", Row=6) string
XEQ( string ) ! executes row 6 of my_file.txt

Insitux

All valid Insitux code can be evaluated at runtime using eval, including function definitions which remain in global scope, with access to global scope but not local.

(var x 123)
[
  (eval "(var y 100) (+ x y)")
  y
]
Output:
[223 100]

Error messages differ between normal code and evaluated code.

Normal invocation error output:

1:6     (let time 1)
Parse Error: "time" cannot be redefined: already exists.

eval invocation error output:

1:2     (eval "(let time 1)")
Eval Error: error within evaluated code.
Parse Error: 1695133413649 eval line 1 col 6: "time" cannot be redefined: already exists

J

Use monadic ". (Do) to execute a string.

". 'a =: +/ 1 2 3' NB. execute a string to sum 1, 2 and 3 and assign to noun a

Only J expressions are allowed in strings used as as arguments for ". (control words and blocks of expressions are not allowed).

Alterntively, you can use the conjunction : (Explicit Definition) to create various kinds of functions and evaluate them. Arguments have names, such as "y", which are specified by the language definition. For example:

monad :'+/y' 1 2 3

Rules of scope for such functions match those described on the Scope modifiers page. Also, control words (like if. or for. or while.) and blocks of expressions are allowed in strings which are evaluated in this fashion.

The context for these evaluations will always be the current locale (which might typically be the current object [or class]). If only expressions are allowed, then local variables will be local to the current explicit definition. Otherwise a new local context will be created for the evaluation (and this will be discarded when evaluation has completed). Local contexts are lexical while locales may also be manipulated programatically.

Debugging facilities [currently] require that the operation be given a name.

J relies on the OS for sandboxing and does not offer any additional resource constraints.

Java

You can kind-of do this in Java. The compiler has the relevant APIs, so it is "considered part of your language/library/platform". You have to get a compiler (which may fail), make a pseudo-file-system, compile your class, and make a class loader that will load it. Then you can use regular Java reflection to make an instance and call methods on it.

Longest "Hello world" program ever?

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;

public class Evaluator{
    public static void main(String[] args){
        new Evaluator().eval(
            "SayHello",
            "public class SayHello{public void speak(){System.out.println(\"Hello world\");}}",
            "speak"
        );
    }

    void eval(String className, String classCode, String methodName){
        Map<String, ByteArrayOutputStream> classCache = new HashMap<>();
        JavaCompiler                       compiler   = ToolProvider.getSystemJavaCompiler();

        if ( null == compiler )
            throw new RuntimeException("Could not get a compiler.");

        StandardJavaFileManager                            sfm  = compiler.getStandardFileManager(null, null, null);
        ForwardingJavaFileManager<StandardJavaFileManager> fjfm = new ForwardingJavaFileManager<StandardJavaFileManager>(sfm){
            @Override
            public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling)
                    throws IOException{
                if (StandardLocation.CLASS_OUTPUT == location && JavaFileObject.Kind.CLASS == kind)
                    return new SimpleJavaFileObject(URI.create("mem:///" + className + ".class"), JavaFileObject.Kind.CLASS){
                        @Override
                        public OutputStream openOutputStream()
                                throws IOException{
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            classCache.put(className, baos);
                            return baos;
                        }
                    };
                else
                    throw new IllegalArgumentException("Unexpected output file requested: " + location + ", " + className + ", " + kind);
            }
        };
        List<JavaFileObject> files = new LinkedList<JavaFileObject>(){{
            add(
                new SimpleJavaFileObject(URI.create("string:///" + className + ".java"), JavaFileObject.Kind.SOURCE){
                    @Override
                    public CharSequence getCharContent(boolean ignoreEncodingErrors){
                        return classCode;
                    }
                }
            );
        }};

        // Now we can compile!
        compiler.getTask(null, fjfm, null, null, null, files).call();

        try{
            Class<?> clarse = new ClassLoader(){
                @Override
                public Class<?> findClass(String name){
                    if (! name.startsWith(className))
                        throw new IllegalArgumentException("This class loader is for " + className + " - could not handle \"" + name + '"');
                    byte[] bytes = classCache.get(name).toByteArray();
                    return defineClass(name, bytes, 0, bytes.length);
                }
            }.loadClass(className);

            // Invoke a method on the thing we compiled
            clarse.getMethod(methodName).invoke(clarse.newInstance());

        }catch(ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException x){
            throw new RuntimeException("Run failed: " + x, x);
        }
    }
}
Output:
Hello world

If you have a JRE and not a JDK, there is no compiler, so this doesn't work.

Exception in thread "main" java.lang.RuntimeException: Could not get a compiler.
        at Evaluator.eval(Evaluator.java:33)
        at Evaluator.main(Evaluator.java:21)

Java REPL

Java has a REPL called jshell which can be used for runtime evaluation. It is started by entering the jshell command from the command line. Here is a typical session:

C:\Program Files\JDK\bin> .\jshell
|  Welcome to JShell -- Version 20
|  For an introduction type: /help intro

jshell> double value = 12.0
value ==> 12.0

jshell> value * 3
$2 ==> 36.0

jshell> List<Integer> items = List.of( 1, 2, 3 )
items ==> [1, 2, 3]

jshell> for ( int item : items ) { System.out.print(item * item + " "); }
1 4 9

jshell> void helloWorld() { System.out.println("Hello World"); }
|   created method helloWorld()

jshell> helloWorld()
Hello World

jshell> /exit
|   Goodbye

JavaScript

The eval method handles statements and expressions well:

var foo = eval('{value: 42}');
eval('var bar = "Hello, world!";');

typeof foo; // 'object'
typeof bar; // 'string'

Jsish

From Javascript entry.

/* Runtime evaluation, in Jsish */
var foo = eval('{value: 42}');
eval('var bar = "Hello, world!";');

;typeof foo;
;foo.value;
;typeof bar;
;bar;

/*
=!EXPECTSTART!=
typeof foo ==> object
foo.value ==> 42
typeof bar ==> string
bar ==> Hello, world!
=!EXPECTEND!=
*/
Output:
prompt$ jsish --U runtimeEvaluation.jsi
typeof foo ==> object
foo.value ==> 42
typeof bar ==> string
bar ==> Hello, world!

Julia

Works with: Julia version 0.6

To run an entire script in the current env:

include("myfile.jl")

To run a string in the current env:

include_string("""
    x = sum([1, 2, 3])
    @show x
    """)

@show typeof(x) # Int64

Kotlin

Kotlin has a REPL which is started from the command line by running the compiler without any parameters.

Any valid Kotlin code can then be entered and immediately evaluated.

Below is a sample session.

$ kotlinc
Welcome to Kotlin version 1.2.31 (JRE 1.8.0_162-8u162-b12-0ubuntu0.16.04.2-b12)
Type :help for help, :quit for quit
>>> 20 + 22
42
>>> 5 * Math.sqrt(81.0)
45.0
>>> fun triple(x: Int) = x * 3
>>> triple(16)
48
>>> :quit

Lang

# Simple assignements are used so that rvalues are parsed as TEXT values
$code=fn.println(Hello World!)
# Returns VOID unless return or throw is explicitly used
fn.exec($code)

$code=return Hello World!
fn.println(fn.exec($code))

$code=throw $LANG_ERROR_DIV_BY_ZERO
# Will print "Dividing by 0" in the Standard Lang implementation (Error texts are not standardized)
fn.println(fn.errorText(fn.exec($code)))

$code=parser.op(20//0)
# Will return VOID because no error was thrown explicitly
fn.println(fn.exec($code))

This is the output for the Standard Lang implementation.

Output:
Hello World!
Hello World!
An error occured [error output: redacted]
Dividing by 0
An error occured [error output: redacted]

Lasso

"Sourcefile" when executed has access to all variables and other data that would be available in scope to an included file.

This means thread vars ($) and types/methods already defined will be accessible.

Types, methods, traits and thread vars created or modified will maintain state subsequently - i.e. if a type is defined in code executed in a sourcefile context then that type will be available after execution. if a thread var is modified in the sourcefile executed code then the var will maintain that value after execution.

Local variables (#) maintain scope behaviour as normal.

Output is governed by the "autocollect" boolean, the third parameter in the sourcefile invocation.

//code, fragment name, autocollect, inplaintext
local(mycode = "'Hello world, it is '+date")
sourcefile('['+#mycode+']','arbritraty_name', true, true)->invoke

'\r'


var(x = 100)
local(mycode = "Outside Lasso\r['Hello world, var x is '+var(x)]")
// autocollect (3rd param): return any output generated
// inplaintext (4th param): if true, assumes this is mixed Lasso and plain text, 
//		requires Lasso code to be in square brackets or other supported code block demarkation. 
sourcefile(#mycode,'arbritraty_name', true, true)->invoke

'\r'

var(y = 2)
local(mycode = "'Hello world, is there output?\r'
var(x) *= var(y)")
// autocollect (3rd param): as false, no output returned
// inplaintext (4th param): as false, assumes this is Lasso code, no mixed-mode Lasso and text.
sourcefile(#mycode,'arbritraty_name', false, false)->invoke
'var x is now: '+$x

'\r'

var(z = 3)
local(mycode = "var(x) *= var(z)")
sourcefile(#mycode,'arbritraty_name', false, false)->invoke
'var x is now: '+$x
Output:
Hello world, it is 2013-11-10 15:54:19
Outside Lasso
Hello world, var x is 100
var x is now: 200
var x is now: 600

Liberty BASIC

Liberty BASIC has the ability to evaluate arrays using a string for the array name and a variable for the element.

'Dimension a numerical and string array
Dim myArray(5)
Dim myStringArray$(5)

'Fill both arrays with the appropriate data
For i = 0 To 5
    myArray(i) = i
    myStringArray$(i) = "String - " + str$(i)
Next i

'Set two variables with the names of each array
numArrayName$ = "myArray"
strArrayName$ = "myStringArray"

'Retrieve the array data by evaluating a string
'that correlates to the array
For i = 0 To 5
    Print Eval$(numArrayName$ + "(" + str$(i) + ")")
    Print Eval$(strArrayName$ + "$(" + str$(i) + ")")
Next i

An example using a struct and a pointer.

Struct myStruct, value  As long, _
                 string As ptr
myStruct.value.struct = 10
myStruct.string.struct = "Hello World!"

structName$ = "myStruct"
numElement$ = "value"
strElement$ = "string"

Print Eval$(structName$ + "." + numElement$ + "." + "struct")

'Pay close attention that this is EVAL() because we are
'retrieving the PTR to the string which is essentially a ulong
Print Winstring(Eval(structName$ + "." + strElement$ + "." + "struct"))

Lua

f = loadstring(s) -- load a string as a function. Returns a function.

one = loadstring"return 1" -- one() returns 1

two = loadstring"return ..." -- two() returns the arguments passed to it

In Lua 5.2 the loadstring function is superseded by the more general load function, which can be used in a compatible way. Nevertheless, loadstring is still available.

Works with: Lua version 5.2
f = load("return 42")
f() --> returns 42

In Lua 5.3+ (5.3, 5.4) loadstring is no longer available, use load instead.

> f = load("return 42")
> f()
42
> n = load("return 42")()
> n
42

M2000 Interpreter

Module checkit {
      Module dummy {
            i++
            Print Number
      }
      \\ using Stack New { } we open a new stack for values, and old one connected back at the end
      \\ using block For This {} we erase any new definition, so we erase i (which Local make a new one)
      a$={
            Stack New {
                  For this {
                        Local i
                        for i=1 to 10 : print i : next i
                  }
            }
            If valid(k) then print k
      }
      i=500
      k=600
      Push 1000
      inline a$
      Print i=500
      Print Number=1000
      \\ eval an expression
      Print Eval("i+k")
      \\ eval a function
      Print Function("{read x : = x**2}", 2)=4
      Dim k(10)=123
      \\ eval array only
      Print array("k()", 2)=123
      Push 10, 10
      \\ call a module by make it inline first
      inline code dummy, dummy
      Print i=502
}
CheckIt

Mathematica/Wolfram Language

Mathematica's ToExpression evaluates an expression string as if it were placed directly in the code. Statements are just CompoundExpressions, so they also work. Any evaluation can be limited with TimeConstrained and MemoryConstrained.

Print[ToExpression["1 + 1"]];
Print[ToExpression["Print[\"Hello, world!\"]; 10!"]];
x = 5;
Print[ToExpression["x!"]];
Print[ToExpression["Module[{x = 8}, x!]"]];
Print[MemoryConstrained[ToExpression["Range[5]"], 10000, {}]];
Print[MemoryConstrained[ToExpression["Range[10^5]"], 10000, {}]];
Print[TimeConstrained[ToExpression["Pause[1]; True"], 2, False]];
Print[TimeConstrained[ToExpression["Pause[60]; True"], 2, False]];
Output:
2
Hello, world!
3628800
120
40320
{1, 2, 3, 4, 5}
{}
True
False

MATLAB

The eval and evalin functions handles any kind of code. It can handle multi-line code, although it needs the lines to be separated by the newline character. It can even allow you to program at runtime, as illustrated in the last example in the code and output below. Errors can occur when mixing eval statements with regular code, especially "compile-time" errors if the code appears to be missing key elements (ending brackets or end statements, etc). Some of these are also demonstrated.

function testEval
    fprintf('Expressions:\n')
    x = eval('5+10^2')
    eval('y = (x-100).*[1 2 3]')
    eval('z = strcat(''my'', '' string'')')
    try
        w eval(' = 45')
    catch
        fprintf('Runtime error: interpretation of w is a function\n\n')
    end
    % eval('v') = 5
    % Invalid at compile-time as MATLAB interprets as using eval as a variable
    
    fprintf('Other Statements:\n')
    nl = sprintf('\n');
    eval(['for k = 1:20' nl ...
              'fprintf(''%.3f\n'', k)' nl ...
              'if k == 3' nl ...
                  'break' nl ...
              'end' nl ...
          'end'])
    true == eval('1')
    try
        true eval(' == 1')
    catch
        fprintf('Runtime error: interpretation of == 1 is of input to true\n\n')
    end
    
    fprintf('Programming on the fly:\n')
    userIn = true;
    codeBlock = '';
    while userIn
        userIn = input('Enter next line of code: ', 's');
        codeBlock = [codeBlock nl userIn];
    end
    eval(codeBlock)
end
Output:
Expressions:

x =

   105


y =

     5    10    15


z =

my string

Runtime error: interpretation of w is a function

Other Statements:
1.000
2.000
3.000

ans =

     1

Runtime error: interpretation of == 1 is of input to true

Programming on the fly:
Enter next line of code: fprintf('Goodbye, World!\n')
Enter next line of code: str = 'Ice and Fire';
Enter next line of code: words = textscan(str, '%s');
Enter next line of code: fprintf('%s ', words{1}{end:-1:1})
Enter next line of code: 
Goodbye, World!
Fire and Ice

Maxima

/* Here is how to create a function and return a value at runtime. In the first example,
the function is made global, i.e. it still exists after the statement is run. In the second example, the function
is declared local. The evaluated string may read or write any variable defined before eval_string is run. */

kill(f)$

eval_string("block(f(x) := x^2 + 1, f(2))");
5

fundef(f);
/* f(x) := x^2 + 1 */

eval_string("block([f], local(f), f(x) := x^3 + 1, f(2))");
9

fundef(f);
/* f(x) := x^2 + 1 */

Nanoquery

The exec() function runs code contained within a string as if it were being read from a file, so any valid code may be run.

exec("println \"hello, world\"")
exec("a = 1\nif a = 1\nprintln \"a is 1\"\nend\nprintln \"test\"")
Output:
hello, world
a is 1
test

Nim

File: runtime_eval.nim

import ../compiler/[nimeval, llstream, ast], strformat, os

let std = findNimStdLibCompileTime()
let modules = [std, std / "pure", std / "std", std / "core"]
var intr = createInterpreter("script", modules)

#dynamic variable
let varname = commandLineParams()[0]
let expr = commandLineParams()[1]

#wrap the naked variable name and expression in a definition and proc,respectively to create valid code
#for simplicity, the variable will always be an int, but one could of course define the type at runtime
#globals and procs must be exported with * to be accessable
#we also need to import any modules needed by the runtime code
intr.evalScript(llStreamOpen(&"import math,sugar; var {varname}*:int; proc output*():auto = {expr}"))

for i in 0..2:
  #set 'varname' to a value
  intr.getGlobalValue(intr.selectUniqueSymbol(varname)).intval = i
  #evaluate the expression and get the result
  let output = intr.callRoutine(intr.selectRoutine("output"), [])
  #depending on the expression, the result could be any type
  #as an example, here we check for int,float,or string
  case output.kind
  of nkIntLit:
    echo expr, " = ", output.intval
  of nkFloatLit:
    echo expr, " = ", output.floatval
  of nkStrLit:
    echo expr, " = ", output.strval
  else:
    discard

destroyInterpreter(intr)

Usage

nim c runtime_eval.nim
./runtime_eval bar 'exp(bar.float)'
./runtime_eval foo 'sum(collect(for i in 1..foo+1: i*i))'
./runtime_eval baz '["hello","dynamic","world"][baz]'
Output:

The second example works only with development version 1.5.x. Other examples work with version 1.4.x.

exp(bar.float) = 1.0
exp(bar.float) = 2.718281828459045
exp(bar.float) = 7.38905609893065
sum(collect(for i in 1..foo+1: i*i)) = 1
sum(collect(for i in 1..foo+1: i*i)) = 5
sum(collect(for i in 1..foo+1: i*i)) = 14
["hello","dynamic","world"][baz] = hello
["hello","dynamic","world"][baz] = dynamic
["hello","dynamic","world"][baz] = world

Oforth

Oforth can evaluate strings at runtime.

In order to restrict evaluation, perform is used on strings. With perform, only objects can be evaluated. If a function or a method is included into the string an exception is raised and the function is not evaluated.

"[ [ $a, 12], [$b, 1.2], [ $c, [ $aaa, $bbb, $ccc ] ], [ $torun, #first ] ]" perform .s
[1] (List) [[a, 12], [b, 1.2], [c, [aaa, bbb, ccc]], [torun, #first]]

"12 13 +" perform
[1:interpreter] ExCompiler : Can't evaluate <+>


In order to evaluate any Oforth code, eval can be used. This method should not be used on unsafe strings.

"12 13 + println" eval
25
": newFunction(a)  a + ; 12 10 newFunction println" eval
22

ooRexx

The ooRexx INTERPRET instruction allows execution of dynamically constructed code. Almost any well-formed code can be executed dynamically, including multiple instructions at a time. The instructions are executed in the local context where the interpret instruction executes, so full access to the current variable context is available. For example:

   a = .array~of(1, 2, 3)
   ins = "loop num over a; say num; end"
   interpret ins

Executes the LOOP instruction, displaying the contents of the array pointed to by variable A.

OxygenBasic

Runtime (secondary) compiling is possible, with some restrictions. For instance, static variables may not be created by the compiled code, but parental variables are visible to it. This demo produces tables of Y values, given a formula, and a range of X values to step through.

  function ExecSeries(string s,double b,e,i) as string
  '===================================================
  '
  sys a,p
  string v,u,tab,cr,er
  '
  'PREPARE OUTPUT BUFFER
  '
  p=1
  cr=chr(13) chr(10)
  tab=chr(9)
  v=nuls 4096
  mid v,p,s+cr+cr
  p+=4+len s
  '
  double x,y,z 'shared variables
  '
  'COMPILE
  '
  a=compile s
  er=error
  if er then
    print "runtime error: "  er : exit function
  end if
  '
  'EXECUTE
  '
  for x=b to e step i
    if p+128>=len v then
      v+=nuls len(v) 'extend buffer
    end if
    call a
    u=str(x) tab str(y) cr
    mid v,p,u : p+=len u
  next
  '
  freememory a 'release compiled code
  '
  return left v,p-1 'results
  '
  end function

  '=====
  'TESTS
  '=====

  'Expression, StartVal, EndVal stepVal, Increment

  print ExecSeries "y=x*x*x", 1, 10, 1
  print ExecSeries "y=sqrt x",1, 9 , 1

Oz

declare
  %% simplest case: just evaluate expressions without bindings
  R1 = {Compiler.virtualStringToValue "{Abs ~42}"}
  {Show R1}

  %% eval expressions with additional bindings and
  %% the possibility to kill the evaluation by calling KillProc
  KillProc
  R2 = {Compiler.evalExpression "{Abs A}" unit('A':~42) ?KillProc}
  {Show R2}

  %% full control: add and remove bindings, eval expressions or
  %% statements, set compiler switches etc.
  Engine = {New Compiler.engine init}
  {Engine enqueue(setSwitch(expression false))} %% statements instead of expr.
  {Engine enqueue(mergeEnv(env('A':42 'System':System)))}
  {Engine enqueue(feedVirtualString("{System.show A}"))}

By restricting the environment it is possible to restrict what kind of programs can be run.

PARI/GP

Since GP is usually run from the REPL gp, it is trivial to evaluate programs at runtime (most are run this way). Slightly less trivial is passing code around as a first-class object:

runme(f)={
  f()
};

runme( ()->print("Hello world!") )

One facility designed for restricting such embedded programs is default(secure,1) which denies scripts the ability to run system and extern. This cannot be turned off except interactively.

Perl

The eval function accepts a block or a string as its argument. The difference is that a block is parsed at compile-time, whereas a string is parsed at runtime. The block or string may represent any valid Perl program, including a single expression. The subprogram executes in the same lexical and dynamic scope as the surrounding code. The return value of a call to eval depends on how the subprogram terminates:

  • If control reaches the end of the subprogram, eval returns the value of the last expression evaluated.
  • If the subprogram uses an explicit return, eval returns the given value.
  • If the subprogram throws an exception, eval returns undef. The text of the exception is assigned to $@. (When the subprogram terminates without an exception, $@ is set to the null string instead.)
my ($a, $b) = (-5, 7);
$ans = eval 'abs($a * $b)';  # => 35

Phix

The eval() function can be used to run fragments of code. The code is run in a brand new context and hence must be valid in a standalone sense, and cannot directly reference any external identifiers. Any existing data that needs to be accessed must be provided via the ival and/or iset parameters, and any results must be explicitly requested via the rset parameter, and any updates applied/extracted once eval() returns. Passing large tables into and out of the eval context is actually quite efficient, though some careful refcount management may improve performance, as detailed in the docs.

-- demo\rosetta\Runtime_evaluation.exw
without javascript_semantics
requires("1.0.1")
include eval.e  -- (not an autoinclude, pulls in around 90% of the interpreter/compiler proper)

string code = """
integer i = 0
bool r_init = false
sequence r
if not r_init then r = {} end if
for k=1 to 4 do
    i += k
    r &= k
end for
"""
?eval(code,{"i","r"})                           -- prints {10,{1,2,3,4}}
?eval(code,{"r"},{{"r_init",true},{"r",{5}}})   -- prints {5,1,2,3,4}
?eval(code,{"i"},{{"i",15}})                    -- prints {25}
{} = eval(`puts(1,"Hello World\n")`)            -- prints Hello World
Output:
{10,{1,2,3,4}}
{{5,1,2,3,4}}
{25}
Hello World

Evaluating expressions

Just as a bare (say) "3+4" in a normal source code file would trigger a syntax error, so too would passing that directly to the eval() function. However it is of course trivial to assign the result of an expression to a (newly declared) variable and return that:

function eval_expression(string expr)
    object {res} = eval(sprintf("object x = %s",{expr}),{"x"})
    return res
end function
?eval_expression("3+4") -- prints 7

Sandboxing

It is perfectly possible to add a "with safe_mode" prefix to the code passed to eval(), however any runtime error message generated appears to use the wrong symbol table, and therefore is largely gibberish, but at least it blocks dangerous things properly. Slightly better or more readable error messages may be produced by compiling the program, as in the one that invokes eval(), instead of interpreting it.

PHP

The eval construct allow string evaluation as PHP code. Opening and closing tags are not required. Return statements immediatly terminates evaluation . Eval returns NULL, unless return is called in evalued code.

<?php
  $code = 'echo "hello world"';
  eval($code);
  $code = 'return "hello world"';
  print eval($code);

PicoLisp

In PicoLisp there is a formal equivalence of code and data. Almost any piece of data is potentially executable. PicoLisp has three internal data types: Numbers, symbols and lists. Though in certain contexts (e.g. GUI objects) also atomic data (numbers and symbols) are evaluated as code entities, a typical executable item is a list.

The PicoLisp reference distinguishes between two terms: An 'exe' (expression) is an executable list, with a function as the first element, followed by arguments. A 'prg' (program) is a list of 'exe's, to be executed sequentially.

'exe's and 'prg's are implicit in the whole runtime system. For example, the body of a function is a 'prg', the "true" branch of an 'if' call is an 'exe', while the "false" branch again is a 'prg'.

For explicit execution, an 'exe' can be evaluated by passing it to the function 'eval', while a 'prg' can be handled by 'run'.

As PicoLisp uses exclusively dynamic binding, any 'exe' or 'prg' can be executed in arbitrary contexts. The environmet can be controlled in any conceivable way, through implicit function parameter bindings, or explicitly with the aid of functions like 'bind', 'let' or 'job'.

Pike

Pike provides compile_string() and compile_file() which can compile code into a class that can be instantiated:

program demo = compile_string(#"
    string name=\"demo\";
    string hello()
    { 
       return(\"hello, i am \"+name); 
    }");

demo()->hello();
Result: "hello, i am demo"

an actual application of this is shown in Simple database.

PowerShell

Evaluate an expression:

$test2plus2 = '2 + 2 -eq 4'
Invoke-Expression $test2plus2
Output:
True

Evaluate a [scriptblock] (a statement or group of statements) with code surrounded by curly braces using the & (call) operator:

$say = {"Hello, world!"}
& $say
Output:
Hello, world!

Scriptblocks behave just as functions so they may have parameters:

$say = {param ([string]$Subject) "Hello, $Subject!"}
& $say -Subject "my friend"
Output:
Hello, my friend!

A slightly more complex example:

$say = {param ([string]$Exclamation, [string]$Subject) "$Exclamation, $Subject!"}
& $say -Exclamation "Goodbye" -Subject "cruel world"
Output:
Goodbye, cruel world!

To reverse the normal behaviour of a [scriptblock] use the GetNewClosure method. This makes the scriptblock self-contained or closed; ie, the variable will only be read when the scriptblock is initialised:

$title = "Dong Work For Yuda"
$scriptblock = {$title}
$closedScriptblock = $scriptblock.GetNewClosure()

& $scriptblock
& $closedScriptblock
Output:
Dong Work For Yuda
Dong Work For Yuda

Change the variable and execute the scriptblock, the closed version will not reflect the change:

$title = "I'm Too Sexy"
& $scriptblock
& $closedScriptblock
Output:
I'm Too Sexy
Dong Work For Yuda

Since the [scriptblock] type is an anonymous function, the Begin {}, Process {} and End {} blocks may be added to a scriptblock, just like any function.

Python

Works with: Python version 2.x

The exec statement allows the optional passing in of global and local names via mappings (See the link for full syntax). The example below shows exec being used to parse and execute a string containing two statements:

>>> exec '''
x = sum([1,2,3,4])
print x
'''
10
Works with: Python version 3.x

Note that in Python 3.x exec is a function:

>>> exec('''
x = sum([1,2,3,4])
print(x)
''')
10

Quackery

Quackery includes the word build which takes a string of Quackery code and returns evaluable code, which can be evaluated with do. These two functionalities are combined in the word quackery, defined as [ build do ] is quackery, neatly summarising the way Quackery works.

Any Quackery code fragment can be passed as a string to quackery, with parameters and results being passed via the stack. In the sample code, the string "1 swap times [ i 1+ * ]", when compiled and evaluated by quackery, will take the 10 placed on the stack beforehand, compute its factorial and leave the result on the stack for echo to echo to the screen.

10 $ "1 swap times [ i 1+ * ]" quackery echo
Output:
3628800

R

In R, expressions may be manipulated directly as abstract syntax trees, and evaluated within environments.

quote() captures the abstract syntax tree of an expression. parse() does the same starting from a string. call() constructs an evaluable parse tree. Thus all these three are equivalent.

expr1 <- quote(a+b*c)
expr2 <- parse(text="a+b*c")[[1]]
expr3 <- call("+", quote(`a`), call("*", quote(`b`), quote(`c`)))

eval() evaluates a quoted expression. evalq() is a version of eval() which quotes its first argument.

> a <- 1; b <- 2; c <- 3
> eval(expr1)
[1] 7

eval() has an optional second environment which is the lexical environment to evaluate in.

> env <- as.environment(list(a=1, b=3, c=2))
> evalq(a, env)
[1] 1
> eval(expr1, env) #this fails; env has only emptyenv() as a parent so can't find "+"
Error in eval(expr, envir, enclos) : could not find function "+"
> parent.env(env) <- sys.frame()
> eval(expr1, env) # eval in env, enclosed in the current context
[1] 7
> assign("b", 5, env) # assign() can assign into environments
> eval(expr1, env)
[1] 11

Racket

Racket has the usual eval that is demonstrated here, and in addition, it has a sandbox environment that provides a safe evaluator that is restricted from accessing files, network, etc.

#lang racket
(require racket/sandbox)
(define e (make-evaluator 'racket))
(e '(define + *))
(e '(+ 10 20))
(+ 10 20)
;; (e '(delete-file "/etc/passwd"))
;; --> delete-file: `delete' access denied for /etc/passwd

And, of course, both of these methods can use Racket's multilingual capabilities and evaluate the code in a language with different semantics.

Raku

(formerly Perl 6) Any syntactically valid sequence of statements may be run, and the snippet to be run can see its outer lexical scope at the point of the eval:

use MONKEY-SEE-NO-EVAL;

my ($a, $b) = (-5, 7);
my $ans = EVAL 'abs($a * $b)';  # => 35

Unlike in Perl 5, eval in Raku only compiles and executes the string, but does not trap exceptions. You must say try eval to get that behavior (or supply a CATCH block within the text to be evaluated).

REBOL

The do function evaluates a script file or a series of expressions and returns a result.

It performs the fundamental interpretive action of the Rebol language and is used internally within many other functions such as if, case, while, loop, repeat, foreach, and others.

a: -5
b: 7
answer: do [abs a * b]     ; => 35

REXX

This REXX program does a:

  •     run-time evaluation of an internal expression,   and
  •     run-time evaluation of a user-prompted expression.
/*REXX program illustrates the ability to  execute code  entered  at runtime (from C.L.)*/
numeric digits 10000000                          /*ten million digits should do it.     */
bee=51
stuff= 'bee=min(-2,44);  say 13*2 "[from inside the box.]";  abc=abs(bee)'
interpret stuff
say 'bee='  bee
say 'abc='  abc
say
                                                 /* [↓]  now, we hear from the user.    */
say 'enter an expression:'
pull expression
say
say 'expression entered is:'  expression
say

interpret '?='expression

say 'length of result='length(?)
say ' left 50 bytes of result='left(?,50)"···"
say 'right 50 bytes of result=···'right(?, 50)   /*stick a fork in it,  we're all done. */

output   when using the input: 2**44497 - 1
which happens to be the 27th Mersenne prime.

26 [from inside the box.]
bee= -2
abc= 2

enter an expression:
2**44497 - 1

expression entered is: 2**44497 - 1

length of result=13395
 left 50 bytes of result=85450982430363380319330070531840303650990159130402···
right 50 bytes of result=···22977396345497637789562340536844867686961011228671

Ring

Eval("nOutput = 5+2*5 " )
See "5+2*5 = " + nOutput + nl
Eval("for x = 1 to 10 see x + nl next")
Eval("func test see 'message from test!' ")
test()

Output :

5+2*5 = 15
1
2
3
4
5
6
7
8
9
10
message from test!

We can create simple interactive programming environment using the next program

while true
        see nl + "code:> "
        give cCode
        try
                eval(cCode)
        catch
                see cCatchError
        done
end

Output

code:> see "hello world"
hello world
code:> for x = 1 to 10 see x + nl next
1
2
3
4
5
6
7
8
9
10

code:> func test see "Hello from test" + nl

code:> test()
Hello from test

code:> bye

Ruby

The eval method evaluates a string as code and returns the resulting object. With one argument, it evaluates in the current context:

a, b = 5, -7
ans = eval "(a * b).abs"  # => 35

With two arguments, eval runs in the given Binding or Proc context:

def first(main_var, main_binding)
  foo = 42
  second [[main_var, main_binding], ["foo", binding]]
end

def second(args)
  sqr = lambda {|x| x**2}
  deref(args << ["sqr", binding])
end

def deref(stuff)
  stuff.each do |varname, context|
    puts "value of #{varname} is #{eval varname, context}"
  end
end

hello = "world"
first "hello", binding
value of hello is world
value of foo is 42
value of sqr is #<Proc:0x1002ef6c@eval.rb:7>

Scheme

In Scheme, the expression passed to eval is evaluated in the current interaction environment, unless otherwise specified. The result is read back as a Scheme value.

> (define x 37)
> (eval '(+ x 5))
42
> (eval '(+ x 5) (interaction-environment))
42
> (eval '(+ x 5) (scheme-report-environment 5)) ;; provides R5RS definitions

Error: identifier not visible x.
Type (debug) to enter the debugger.
> (display (eval (read)))
(+ 4 5) ;; this is input from the user.
9

Sidef

The eval method evaluates a string as code and returns the resulting object.

var (a, b) = (-5, 7);
say eval '(a * b).abs';  # => 35
say (a * b -> abs);      # => 35

Slate

In Slate, programs are represented as Syntax Node trees, with methods defined on the various syntactic types. The backtick syntax provides a convenient quoting mechanism, and as objects, they have convenient methods defined for evaluation or evaluation within a specific environment:

`(4 + 5) evaluate.
`(4 + 5) evaluateIn: prototypes.

You can also explicitly invoke the Parser on a String, to convert it into syntactic objects:

(Syntax Parser newOn: '4 + 5') upToEnd do: [| :each | print: each evaluate]

You can construct a program using externally-specified values using `unquote within a quoted expression:

define: #x -> 4.
`(x `unquote + 5) evaluate.

Or you can obviously construct a string:

define: #x -> 4.
(Syntax Parser newOn: x printString ; ' + 5')

The evaluate method also takes into consideration the current lexical scope, unless another environment is specified. The following returns 10, no matter what binding x has in the local namespace:

define: #x -> 4.
[| x | x: 5. `(x `unquote + 5) evaluate] do.

Slate can sandbox via constructing a fresh namespace and evaluating within it, but this mechanism is not strongly secure yet.

Slope

You can create a list via quoted symbols and then evaluate:

(eval (list '+ 1 2 3 4 5))

Or, you can evaluate a string as code:

(eval "(+ 1 2 3 4 5)" #t)

Smalltalk

[ 4 + 5 ] value.

Evaluating an expression without bindings:

e := ' 123 degreesToRadians sin '.
Transcript show: (Compiler evaluate: e) .

To get local bindings (x, y), evaluate an expression which yields a block given as a string, then call the resulting block:

e := '[ :x :y | (x*x + (y*y)) sqrt ]'.
Transcript show: ((Compiler evaluate: e) value: 3 value: 4).

this could be wrapped into a utility, which expects the names to bind as argument, if required.

SNOBOL4

The built in function eval() evaluates SNOBOL4 expressions and returns the value. The expression is evaluated in the current environment and has access to then-current variables.

     expression = "' page ' (i + 1)"
     i = 7
     output = eval(expression)
end
Output:
 page 8

The built in function code() compiles complete SNOBOL4 source statements, or even complete programs. The compiled program is returned (as a value of type CODE), and when executed the program is executed in the then-current environment and has access to the then-current variables. Labels in the compiled program are added to the current program. Programs of type CODE are executed by a variant of the goto clause:

     compiled = code(' output = "Hello, world."')  :s<compiled>
end

When passing programs to code(), semicolons are used to separate lines.

The calling (already-compiled) program can call, for example, functions that are defined in the code compiled at runtime, and can include gotos to labels only defined in the code compiled at runtime. Likewise, the code compiled at runtime has access to not just variables, but also files, functions, etc., that are in the already-compiled program.

Sparkling

In Sparkling, the standard library provides functions to compile expressions and statements into functions. Each such function is considered a different top-level program, running in the execution context of it's "parent" program (i. e. the piece of code from within which it was created). Consequently, functions compiled at runtime share their environment (e. g. all globals) with their parent program.

Compiled expressions and statements can take arbitrary arguments and return values to the caller. As with any function, the expression or statement being compiled can refer to its arguments using the # prefix operator.

An expression always "returns" a value (i. e. evaluates to one) to the caller. Basically, compiling an expression is semantically (and syntactically) equivalent with creating a function with no declared arguments of which the body consists of a single return statement, returning the expression.

Evaluating expressions

Simple

let fn = exprtofn("13 + 37");
fn() // -> 50

With arguments

let fn = exprtofn("#0 * #1");
fn(3, 4) // -> 12

Evaluating statements

let fn = compile("for (var i = 0; i < 10; i++) { print(i); }");
fn(); // result: 0 1 2 3 4 5 6 7 8 9

Tcl

Simple Evaluation

Evaluation in the current interpreter:

set four 4
set result1 [eval "expr {$four + 5}"]           ;# string input

set result2 [eval [list expr [list $four + 5]]] ;# list input

Evaluation in a restricted context

Tcl handles sandboxing by creating new interpreters. Each interpreter is strongly isolated from all other interpreters except in that the interpreter that creates a sub-interpreter retains management control over that “slave” interpreter. The exact capabilities exposed in the slave are controlled by what commands exist in it; commands in the slave may be aliases for other commands in the master interpreter, which allows for trapping into a more highly authorized context (which can be considered analogous to a system call to an OS kernel).

# Create an interpreter with a default set of restrictions
interp create -safe restrictedContext

# Our secret variable
set v "secret"

# Allow some guarded access to the secret from the restricted context.
interp alias restrictedContext doubleSecret {} example
proc example {} {
    global v
    lappend v $v
    return [llength $v]
}

# Evaluate a script in the restricted context
puts [restrictedContext eval {
    append v " has been leaked"
    catch {file delete yourCriticalFile.txt} ;# Will be denied!
    return "there are [doubleSecret] words in the secret: the magic number is [expr {4 + 5}]"
}];       # --> there are 2 words in the secret: the magic number is 9
puts $v;  # --> secret secret

As can be seen, the result of the overall evaluation is the same as the result of the evaluation in the slave.

Note that with providing values to the restricted context, it is normal to do this by providing an alias/trap command in the restricted context to allow the script to pick up the value when it wants it. Although the value could also have been provided by setting a variable in the restricted context, this is fairly unusual in practice. The example above shows how this might be done with the result of the doubleSecret command.

Evaluation within limits

Works with: Tcl version 8.5

Even stronger protection of the master interpreter is available from Tcl 8.5 onwards through the setting of resource limits on the slaves. These allow the master to prevent the evaluated script from going berserk:

set i [interp create]
interp limit $i commands -value [expr [$i eval info cmdcount]+20] -granularity 1
interp eval $i {
    set x 0
    while {1} { # Infinite loop! Bwahahahaha!
        puts "Counting up... [incr x]"
    }
}
Output:

(the last line is an error message)

Counting up... 1
Counting up... 2
Counting up... 3
Counting up... 4
Counting up... 5
Counting up... 6
Counting up... 7
Counting up... 8
Counting up... 9
Counting up... 10
command count limit exceeded

TI-89 BASIC

The function expr(string) evaluates the string as an expression. It is evaluated in the environment of the calling program (it can see local variables).

The Exec string, args... statement executes arbitrary 68k machine code (and is thus entirely unsafe).

TODO: Is there a way to execute statements as well as evaluate expressions?

Transd

#lang transd

MainModule : {
    str: "(textout \"eval output: \" (+ 1 1))",

    _start: (λ 
        (eval str)
    )
}
Output:
eval output: 2

UNIX Shell

eval is the command to use:

$ a=42
$ b=a
$ eval "echo \$$b"
42

Ursa

The eval statement in Ursa takes a string and evaluates it as a command, redirecting the console to the specified I/O device.

# writes hello world to the console
eval "out \"hello world\" endl console" console

Wren

Firstly, Wren has a REPL which is started from the command line by running Wren-cli without any parameters.

Any valid Wren code can then be entered and immediately evaluated.

To quit the REPL just type Ctrl-C or Ctrl-D.

The examples in the Kotlin entry would look like this in the Wren REPL:

$ wren-cli
\\/"-
 \_/   wren v0.4.0
> 20 + 22
42
> 5 * 81.sqrt
45
> var triple = Fn.new { |x| x * 3 }
> triple.call(16)
48
> 

Secondly, Wren has the Meta.eval method which can be used from within a script to execute any valid Wren code (presented to it in string form) at runtime. The string could be constructed within the script, obtained from a file or input by the user. Here's a very simple example:

import "meta" for Meta

var s = "for (i in 0..4) System.print(i)" 
Meta.eval(s)
Output:
0
1
2
3
4

zkl

In zkl, the compiler is part of the language and compiling a chunk of code returns an executable (which how the REPL works), so

Compiler.Compiler.compileText(
     "fcn f(text){text.len()}").f("foobar")
//-->6

All language constructs are allowed, the only sand boxing is the new code can only touch global resources or items explicitly passed in ("foobar" in the example).