You need to include module /pliant/language/compiler.pli when using Expression data type.
See pliant computing mechanism for a general introduction on meta-programming

Some of the methods are defined in expression.c and others are defined in expression1.pli, expression2.pli and expression3.pli

Fields in the Expression data type:
Field name Type Content
value Arrow Points to the content of the expression provided by the parser. If you see the expressions tree as a graph, this is the label of the node.
arguments Array Pointers to the sub expressions
module Link Module Points to the module which the expression belongs to (the module defines the context in which the expression is going to be compiled)
position Str A string describing where the expression is in the source code (name of the module plus line and column number)
instructions List The list of instructions generated by the compiling mechanism
result Link Argument Points to the argument that contains the expression result when the instructions have been executed
access Int The access rights on the result
cast_level Int The number of successive casting that have been performed to the result to get a result with the requested type
Do not use
operator ParserOperator used by the parser to store the operator that will fold the expression at the end of the parsing process
Do not use
close_operator_name Str used by the parser to check that operators such as () or {} are nested properly
Do not use
error_message Str Used to keep an error message that has been cleared, in order to pick it back at the end if the function fails to compile
Do not use


method e ident -> id
  arg Expression e ; arg Str id

If the expression value is an identifier, then the identifier is returned, converted to string, elsewhere an empty string is returned.

method e is_pure_ident -> id
  arg Expression e ; arg CBool id

Returns true if the expression value is an identifier and the expression as no subexpressions (arguments field size is 0).

method e is_compiled -> c
  arg Expression e ; arg CBool 

Test if the expression has already been compiled.

method e compile
  arg Expression e

Asks Pliant engine to compile the expression if it is not done yet.

method e compile_as e2 -> success
  arg_rw Expression e e2 ; arg CBool success

'e2' is considered as a rewritten version of 'e', so tries to compile 'e2' and if success, then use the instructions and result as the way to compile 'e' (for more details, see example at the end of this document)

there are more complicated versions available

method e constant wished_type -> address
  arg Expression e ; arg Type wished_type ; arg address address

First attempts to compile the expression if not done yet, then attempt to cast the result to the desired type. If the result is a constant then return it's address, elsewhere returns null.

method e execute
  arg Expression e

Attempts to compile, then generate code, and finally execute the code.

method e evaluate value
  arg Expression e ; arg address value

Attempts to compile, then generate code, and finally execute the code. On return, 'value' points to a constant which is the computed result.


method e cast wished_type -> success
  arg Expression e ; arg Type wished_type ; arg CBool success

First attempts to compile the expression if not done yet, then attempt to cast the result to the desired type.
Common mistake: Casting an expression will often add instructions to the instructions list, so if you intend to suckup the expression, then you have to ask for the cast before calling suckup method.

method e explicit_cast t -> success
  arg_rw Expression e ; arg Type t ; arg CBool success

Try to cast the expression to type t
Please read Pliant casting mechanism for a general introduction on Pliant casting rules

there is also a more complicated versions available

method e add i
  arg_rw Expression e ; arg Instruction i

add instruction 'i' at the end of the instructions list of 'e'.

method e suckup sub
  arg_rw Expression e ; arg Expression sub

add all instructions in the 'sub' instructions list at the end of the instructions list of 'e'.

method e set_void_result
  arg_rw Expression e

Defines that the expression is an instruction (it as no result, which is meant by attaching the constant of type Void as the result)

method e set_result result access_rights
  arg_rw Expression e ; arg Argument result ; arg Int access_rights

Attaches the 'result' to the expression.
For the 'access_rights' argument, use either access_read or access_read_write.

An expression is considered to be successfully compiled when a result as been attached to it. So the basic way to compile an expression is to call method add or suckup several times to attach the various instructions, then either call set_result or

extra compiling methods that you will probably never need to use

method e size -> s
  arg Expression e ; arg_C Int s

Returns the number of sub expressions in the expression
This is not the prototype of a real methods but indicates that you can also use size method to change the number of sub expressions in the expression just like you can use size method to resize a variable size array.

method e 'i -> ei
  arg Expression e ; arg Int i ; arg_C Expression ei

Selects one of the subexpressions.


function duplicate e -> e2
  arg Expression e ; arg_RW Expression e2

Duplicates the expression and it's sub expressions and returns a pointer to the copy.

function expression ... -> e
  arg_RW Expression e

Builds a new expression.
This are the various parameters that may appear in an 'expression' function:

duplicate original

The original expression will be copyed and used as the basis for the new one.

map existing

The existing expression will be modifyed by subsequent parameters and a pointer on it will be return.

immediat body

The body expression will be copyed and used as the basis for the new expression. The 'body' parameter is not evaluated: the raw expression provided by the parser is used.

auto_rename

All identifiers in the expression that end with a '_' will be renamed in order to be unique. This is mainly used when the expression is constructed using the 'immediat' parameter.
You can find an example in each.pli

ident str

Sets the 'value' field of the expression (see at the beginning of the page) to an identifier 'str' provided as a string.

constant value

Sets the 'value' field of the expression (see at the beginning of the page) to the provided value.

near existing

All the subexpressions that are currently not linked to a module will be linked to the module to which existing is linked.

subexpressions parameters

All the remaining parameters are specifying the subexpressions of the new expression.each parameter can be either:
  • another expression
  • a subset of the subexpressions of an expression.
    The subset is extracted using the method with the prototype given just under this table.

substitute identifier expression

All the occurrences of the identifier will be replaced by a copy of the expression.The 'expression' may also be several sub-expressions specifyed using the method with the prototype given just under this table.
Be awarded: only the occurrences of the identifier that are not yet linked to a module will be substituted, so if you used 'near' as a previous parameter the expression will not be modifyed !
Now, the expression you provide for substitution, and all it's sub expressions must be already linked to a module.
These constraints are expressed in order to avoid name clashes when several substitutions are performed. Moreover, they also apply for the 'insert' and 'remove' parameter listed below.

insert identifier expression

A copy of 'expression' will be inserted in front of each of the occurrences of the identifier.
Be awarded: only the occurrences of the identifier that are not yet linked to a module will considered, and the inserted expression(s) must be fully linked to some modules.

remove identifier

All the occurrences of the identifier will be removed.
Be awarded: only the occurrences of the identifier that are not yet linked to a module will be removed.

function 'e base nb -> range
  arg Expression e ; arg Int base nb ; arg ExpressionRange range

There are mainly three ways of building an expression: This is an example taken from the user forum:

module "/pliant/v1.pli"
module "/pliant/meta.pli"

constant use_method 2

meta foo e
  if e:size<>3
    return
  if use_method=1
    var Link:Expression call_titi :> expression ident "titi" subexpressions (duplicate e:0)
    var Link:Expression call_toto :> expression ident "toto" subexpressions call_titi
    var Link:Expression call_tutu :> expression ident "tutu" subexpressions (e 0 3)
    var Link:Expression all :> expression ident "{}" subexpressions call_toto call_tutu
    e compile_as all
  eif use_method=2
    e compile_as (expression immediat { toto titi:x ; tutu x y z } substitute x e:0 substitute y e:1 substitute z e:2)

# sample usage

function toto x
  arg Int x
  console x eol

function titi x -> y
  arg Int x y
  y := x*x

function tutu x y z -> t
  arg Int x y z t
  t := x+y+z

console (foo 2 5 10) eol


You can find an example of building a new expression in setfield.pli module which does the following:

Each time an expression such as:

a size := 12

is found, then it attempts to compile it as:

a 'size :=' 12

function parse string -> e
  arg Str string ; arg Link:Expression Expression e

The 'string' will be submitted to the parser and returned as an expression.


method e 'ident :=' id
  arg_rw Expression e ; arg Str id

method e near original
  arg_rw Expression e ; arg Expression original

method e auto_rename
  arg_rw Expression e

method e substitute id value -> newone
  arg_rw Expression e ; arg Str id ; arg Expression value ; arg_RW Expression newone

method e substitute id values
  arg_rw Expression e ; arg Str id ; arg ExpressionRange values

method e insert id value
  arg_rw Expression e ; arg Str id ; arg Expression value

method e remove id
  arg_rw Expression e ; arg Str id

All these methods are called in order to modify the expression when you use the 'expression' function.

named_expression label
  body

is roughly equivalent to

var constant Expression label (expression immediat body)

but a more convenient notation for multi lines immediat expressions.