Runtime evaluation

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

Demonstrate your language's ability for programs to execute code written in the language provided at runtime.
Show us what kind of program fragments are permitted (e.g. expressions vs. statements), how you 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.

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$.

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$.

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.)

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.)

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.

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.

The eval[] function can be used to evaluate aribitrary 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.)

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.

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).

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.

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 variablesGroovyShell 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.

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.

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'123

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.

"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.

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.

/* 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 functionis declared local. The evaluated string may read or write any variable defined before eval_string is run. */

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.

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:

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.

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.)

Unlike in Perl 5, eval in Perl 6 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).

In PicoLisp there is a formal equivalence of code and data. Almost any peace 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'.

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:

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:

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.

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.

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 restrictionsinterp create -safe restrictedContext

# Evaluate a script in the restricted contextputs[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 9puts$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.

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: