From 1f57ba28dd8f3d57baf1019f30c6e958e672173f Mon Sep 17 00:00:00 2001 From: Celestino Amoroso Date: Sat, 18 Apr 2026 12:21:42 +0200 Subject: [PATCH] Doc: progress about builtin modules --- doc/Expr.adoc | 424 +++++++++++++++++++++++++++++- doc/Expr.html | 709 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 1093 insertions(+), 40 deletions(-) diff --git a/doc/Expr.adoc b/doc/Expr.adoc index fadcf97..facf747 100644 --- a/doc/Expr.adoc +++ b/doc/Expr.adoc @@ -27,6 +27,10 @@ Expressions calculator // Workaround to manage asterisk in back-tick quotes :star: * +:sp:   +:2sp:    +:4sp:      + toc::[] @@ -67,6 +71,37 @@ _Expr_ creates and keeps a inner _global context_ where it stores imported funct Imported functions are registered in the _global context_. When an expression first calls an imported function, that function is linked to the current context; this can be the _main context_ or a _function context_. +===== Inspecting contexts +_Expr_ provides the operator [blue]_$$_ that returns the current context. This can be used to inspect the content of the context, for example to check the value of a variable or to see which functions are currently linked to the context. This operator is primarily intended for debugging purposes. + +An interactive tool could like `dev-expr` (see <<_dev-expr_test_tool>>) can be used to inspect contexts interactively. + + +.Example: inspecting contexts +`>>>` [blue]`$$` + +[green]`{"variables": {"ls": "[10, 20, 30]", "it": "$(#3)", "last": "-1"}, "functions": {"about": "about():string{}", "bin": "bin(value, digits=8):integer{}", "ctrl": "ctrl(prop, value):any{}", "ctrlList": "ctrlList():list-of-strings{}", "envGet": "envGet(name):string{}", "envSet": "envSet(name, value):string{}"}}` + + +`>>>` [gray]_// Let use the *ml* command to activate multi-line output of contexts, which is more readable._ + +`>>>` [blue]`ml` + +`>>>` [blue]`$$` + +[green]`{` + + [green]`{2sp}"variables": {` + + [green]`{4sp}"last": {"variables": {"last": "-1", "ls": "[10, 20, 30]", "it": "$(#3)"}, "functions": {"ctrlList": "ctrlList():list-of-strings{}", "envGet": "envGet(name):string{}", "envSet": "envSet(name, value):string{}", "about": "about():string{}", "bin": "bin(value, digits=8):integer{}", "ctrl": "ctrl(prop, value):any{}"}},` + + [green]`{4sp}"ls": [10, 20, 30],` + + [green]`{4sp}"it": $(#3)` + + [green]`{2sp}},` + + [green]`{2sp}"functions": {` + + [green]`{4sp}"ctrlList": ctrlList():list-of-strings{},` + + [green]`{4sp}"envGet": envGet(name):string{},` + + [green]`{4sp}"envSet": envSet(name, value):string{},` + + [green]`{4sp}"about": about():string{},` + + [green]`{4sp}"bin": bin(value, digits=8):integer{},` + + [green]`{4sp}"ctrl": ctrl(prop, value):any{}` + + [green]`{2sp}}` + +[green]`}` + +In order to inspect the global context issue the [blue]`$$global` operator. + === `dev-expr` test tool Before we begin to describe the syntax of _Expr_, it is worth introducing _dev-expr_ because it will be used to show many examples of expressions. @@ -995,6 +1030,383 @@ The clone modifier can also be used to declare the formal parameters of function [green]`9` ==== +== Builtins +Builtins are collection of function dedicated to specific domains of application. They are defined in Golang source files called _modules_ and compiled within the _Expr_ package. To make builtins available in _Expr_ contextes, it is required to activate the builtin module in which they are defined. + +There are currently several builtin modules. More builtin modules will be added in the future. + +.Available builtin modules +* *base*: Base expression tools like isNil(), int(), etc. +* *fmt*: String and console formatting functions +* *import*: Functions import() and include() +* *iterator*: Iterator helper functions +* *math.arith*: Functions add() and mul() +* *os.file*: Operating system file functions +* *string*: string utilities + +Builtins activation is done by using the [blue]`BUILTIN` operator. All modules except "base" must be explicitly enabled. The syntax is as follows. + +.Builtin activation syntax +==== +*_builtin-activation_* = [blue]`BUILTIN` (_builtin-name_ | _list-of-builtin-names_) + +_builtin-name_ = _string_ + +_list-of-builtin-names_ = **[** _string_ { "**,**" _string_ } **]** +==== + +The following example shows how to activate the builtin module "math.arith" and then use the function add() defined in that module. + +.Example: using built functions +`>>>` [blue]`BUILTIN "math.arith"` + +[green]`1` + +`>>>` [blue]`add(5, 3, -2)` + +[green]`6` + +TIP: To avoid the need to activate builtin modules one by one, it is possible to activate all builtin modules at once by using the [blue]`BUILTIN "*"` syntax. + +=== Builtin modules + +==== Module "base" +The "base" builtin module provides functions for type checking and type conversion. These functions are always available in _Expr_ contexts without the need to activate the "base" module. + +.Checking functions +* <<_isbool,isBool()>> +* <<_isdict,isDict()>> +* <<_isfloat,isFloat()>> +* <<_isfract,isFract()>> +* <<_islist,isList()>> +* <<_isnil,isNil()>> +* <<_isrational,isRational()>> +* <<_isstring,isString()>> + +.Conversion functions +* <<_bool,bool()>> +* <<_int,int()>> +* <<_dec,dec()>> +* <<_string,string()>> +* <<_fract,fract()>> + +.Other functions +* <<_eval,eval()>> +* <<_var,var()>> + + +===== isBool() +Syntax: `isBool() -> bool` + +Returns _true_ if the value type of __ is boolean, false otherwise. + +.Examples +>>> isBool(true) + +true + +>>> isBool(3==2) + +true + +===== isDict() +Syntax: `isDict() -> bool` + +Returns _true_ if the value type of __ is dictionary, false otherwise. + +.Examples +>>> isDict({}) + +true + +>>> isDict({1: "one", 2: "two"}) + +true + +>>> isDict(1:"one") + +Eval Error: denominator must be integer, got string (one) + +===== isFloat() +Syntax: `isFloat() -> bool` + +Returns _true_ if the value type of __ is float, false otherwise. + +.Examples +>>> isFloat(4.) + +true + +>>> isFloat(4) + +false + +>>> isFloat("2.1") + +false + +===== isFract() +Syntax: `isFract() -> bool` + +Returns _true_ if the value type of __ is fraction, false otherwise. + +.Examples +>>> isFract(4.5) + +false + +>>> isFract(4:5) + +true + +>>> isFract(4) + +**false** + +>>> isFract(1.(3)) + +true + +===== isList() +Syntax: `isList() -> bool` + +Returns _true_ if the value type of __ is list, false otherwise. + +.Examples +>>> isList([]) + +true + +>>> isList([1, "2"]) +true +>>> isList(1,2) +Eval Error: isList(): too many params -- expected 1, got 2 + +===== isNil() +Syntax: `isNil() -> bool` + +Returns _true_ if the value type of __ is nil, false otherwise. + +.Examples +>>> isNil(nil) +true +>>> isNil(1) +false + +===== isRational() +Syntax: `isRational() -> bool` + +Returns _true_ if the value type of __ is fraction or int, false otherwise. + +.Examples +>>> isRational(4.5) + +false + +>>> isRational(4:5) + +true + +>>> isRational(4) + +**true** + +>>> isRational(1.(3)) + +true + +===== isString() +Syntax: `isString() -> bool` + +Returns a boolean value , false otherwise. + +.Examples +>>> isString("ciao") + +true + +>>> isString(2) + +false + +>>> isString(2+"2") + +true + +===== bool() +Syntax: `bool() -> bool` + +Returns a _boolean_ value consisent to the value of the expression. + +.Examples +>>> bool(1) +true +>>> bool(0) +false +>>> bool("") +false +>>> bool([]) +false +>>> bool([1]) +true +>>> bool({}) +false +>>> bool({1: "one"}) +true + +===== int() +Syntax: `int() -> int` + +Returns an _integer_ value consistent with the value of the expression. + +.Examples +>>> int(2) + +2 + +>>> int("2") + +2 + +>>> int("0x1") + +Eval Error: strconv.Atoi: parsing "0x1": invalid syntax + +>>> int(0b10) + +2 + +>>> int(0o2) + +2 + +>>> int(0x2) + +2 + +>>> int(1.8) + +1 + +>>> int(5:2) + +2 + +>>> int([]) + +Eval Error: int(): can't convert list to int+ +>>> int(true) + +1 + +>>> int(false) + +0 + + +===== dec() +Syntax: `dec() -> float` + +Returns a _float_ value consistent with the value of the expression. + +.Examples +>>> dec(2) + +2 + +>>> dec(2.1) + +2.1 + +>>> dec(2.3(1)) + +2.311111111111111 + +>>> dec("3.14") + +3.14 + +>>> dec(3:4) + +0.75 + +>>> dec(true) + +1 + +>>> dec(false) + +0 + +===== string() +Syntax: `string() -> string` + +Returns a _string_ value consistent with the value of the expression. + +.Examples +>>> string(2) + +"2" + +>>> string(0.8) + +"0.8" + +>>> string([1,2]) + +"[1, 2]" + +>>> string({1: "one", 2: "two"}) + +"{1: "one", 2: "two"}" + +>>> string(2:5) + +"2:5" + +>>> string(3==2) + +"false" + +===== fract() +Syntax: `fract() -> fraction` + +Returns a _fraction_ value consistent with the value of the expression. + +.Examples +>>> fract(2) + +2:1 + +>>> fract(2.5) + +5:2 + +>>> fract("2.5") + +5:2 + +>>> fract(1.(3)) + +4:3 + +>>> fract([2]) + +Eval Error: fract(): can't convert list to float + +>>> fract(false) + +0:1 + +>>> fract(true) + +1:1 + +===== eval() +Syntax: `eval() -> any` + +Computes and returns the value of the [.underline]#string# expression. + +.Examples +>>> eval( "2 + fract(1.(3))" ) + +10:3 + +===== var() +Syntax: + + `{4sp}var(, ) -> any` + + `{4sp}var() -> any` + +This function allows you to define variables whose names must include special characters. The first form of the function allows you to define a variable with a name specified by the first parameter and assign it the value of the second parameter. The second form only returns the value of the variable with the specified name. + +.Examples +>>> var("$x", 3+9) + +12 + +>>> var("$x") + +12 + +>>> var("gain%", var("$x")) + +12 + +>>> var("gain%", var("$x")+1) + +13 + +==== Module "fmt" + +===== print() + +===== println() + +==== Module "import" +===== _import()_ +[blue]_import([grey]##)_ -- loads the multi-expression contained in the specified source and returns its value. + +===== _importAll()_ + +==== Module "iterator" + +===== run() + +==== Module "math.arith" +Currently, the "math.arith" module provides two functions, add() and mul(), that perform addition and multiplication of an arbitrary number of parameters. More functions will be added in the future. + +===== add() +Syntax: + +`{4sp}add(, , ...) -> any` + +`{4sp}add(]) -> any` + +`{4sp}add() -> any` + +Returns the sum of the values of the parameters. The parameters can be of any numeric type for which the [blue]`+` operator is defined. The result type depends on the types of the parameters. If all parameters are of the same type, the result is of that type. If the parameters are of different types, the result is of the type that can represent all the parameter types without loss of information. For example, if the parameters are a mix of integers and floats, the result is a float. If the parameters are a mix of number types, the result has the type of the most general one. + +.Examples +>>> add(1,2,3) + +6 +>>> add(1.1,2.1,3.1) + +6.300000000000001 + +>>> add("1","2","3") + +Eval Error: add(): param nr 1 (1 in 0) has wrong type string, number expected + +>>> add(1:3, 2:3, 3:3) + +2:1 + +>>> add(1, "2") + +Eval Error: add(): param nr 2 (2 in 0) has wrong type string, number expected + +>>> add([1,2,3]) + +6 + +>>> iterator=$([1,2,3]); add(iterator) + +6 + +>>> add($([1,2,3])) + +6 + +===== mul() +Syntax: + +`{4sp}mul(, , ...) -> any` + +`{4sp}mul(]) -> any` + +`{4sp}mul() -> any` + +Same as add() but returns the product of the values of the parameters. + + +==== Module "os.file" + +===== fileOpen() + +===== fileAppend() + +===== fileCreate() + +===== fileClose() + +===== fileWriteText() + +===== fileReadText() + +===== fileReadTextAll() + + +==== Module "string" + +===== strJoin() + +===== strSub() + +===== strSplit() + +===== strTrim() + +===== strStartsWith() + +===== strEndsWith() + +===== strUpper() + +===== strLower() + == Iterators Iterators are objects that can be used to traverse collections, such as lists and dictionaries. They are created by providing a _data-source_ object, the collection, in a `$()` expression. Once an iterator is created, it can be used to access the elements of the collection one by one. @@ -1044,6 +1456,10 @@ Named operators are operators that are identified by a name instead of a symbol. * *_.next_*: same as [blue]`{plusplus}`. * *_.current_*: same as [blue]`{star}`. * *_.reset_*: resets the state of the iterator to the initial state. +* *_.count_*: returns the number of elements in the iterator, if it can be determined. +* *_.index_*: returns the index of the current element in the iterator. Before the first use of the [blue]`{plusplus}` operator, it returns the error [red]_-1_. + +TIP: Iterators built on custom data-sources can provide additional named operators, depending on the functionality they want to expose. For example, an iterator over a list could provide a named operator called [blue]`.reverse` that returns the next element of the collection in reverse order. .Example: using the named operators `>>>` [blue]`it = $(["one", "two", "three"])` + @@ -1067,14 +1483,6 @@ It is possible to create iterators over custom data-sources by defining a dictio #TODO: custom data-sources# -== Builtins -#TODO: builtins# - -=== Builtin functions - -=== [blue]_import()_ -[blue]_import([grey]##)_ loads the multi-expression contained in the specified source and returns its value. - == Plugins #TODO: plugins# diff --git a/doc/Expr.html b/doc/Expr.html index 658bad0..9b62e0e 100644 --- a/doc/Expr.html +++ b/doc/Expr.html @@ -550,7 +550,11 @@ pre.rouge .ss {
  • 1.2. dev-expr test tool
  • @@ -590,20 +594,87 @@ pre.rouge .ss {
  • 6.4. Function context
  • -
  • 7. Iterators +
  • 7. Builtins +
  • +
  • 8. Iterators
  • 9. Plugins
  • @@ -683,6 +754,43 @@ pre.rouge .ss {

    Imported functions are registered in the global context. When an expression first calls an imported function, that function is linked to the current context; this can be the main context or a function context.

    +
    +
    Inspecting contexts
    +
    +

    Expr provides the operator $$ that returns the current context. This can be used to inspect the content of the context, for example to check the value of a variable or to see which functions are currently linked to the context. This operator is primarily intended for debugging purposes.

    +
    +
    +

    An interactive tool could like dev-expr (see [_dev-expr_test_tool]) can be used to inspect contexts interactively.

    +
    +
    +
    Example: inspecting contexts
    +

    >>> $$
    +{"variables": {"ls": "[10, 20, 30]", "it": "$(#3)", "last": "-1"}, "functions": {"about": "about():string{}", "bin": "bin(value, digits=8):integer{}", "ctrl": "ctrl(prop, value):any{}", "ctrlList": "ctrlList():list-of-strings{}", "envGet": "envGet(name):string{}", "envSet": "envSet(name, value):string{}"}}

    +
    +
    +

    >>> // Let use the ml command to activate multi-line output of contexts, which is more readable.
    +>>> ml
    +>>> $$
    +{
    +   "variables": {
    +     "last": {"variables": {"last": "-1", "ls": "[10, 20, 30]", "it": "$(#3)"}, "functions": {"ctrlList": "ctrlList():list-of-strings{}", "envGet": "envGet(name):string{}", "envSet": "envSet(name, value):string{}", "about": "about():string{}", "bin": "bin(value, digits=8):integer{}", "ctrl": "ctrl(prop, value):any{}"}},
    +     "ls": [10, 20, 30],
    +     "it": $(#3)
    +   },
    +   "functions": {
    +     "ctrlList": ctrlList():list-of-strings{},
    +     "envGet": envGet(name):string{},
    +     "envSet": envSet(name, value):string{},
    +     "about": about():string{},
    +     "bin": bin(value, digits=8):integer{},
    +     "ctrl": ctrl(prop, value):any{}
    +   }
    +}

    +
    +
    +

    In order to inspect the global context issue the $$global operator.

    +
    +
    @@ -2578,7 +2686,544 @@ The clone modifier @ does not make a variable a refere
    -

    7. Iterators

    +

    7. Builtins

    +
    +
    +

    Builtins are collection of function dedicated to specific domains of application. They are defined in Golang source files called modules and compiled within the Expr package. To make builtins available in Expr contextes, it is required to activate the builtin module in which they are defined.

    +
    +
    +

    There are currently several builtin modules. More builtin modules will be added in the future.

    +
    +
    +
    Available builtin modules
    +
      +
    • +

      base: Base expression tools like isNil(), int(), etc.

      +
    • +
    • +

      fmt: String and console formatting functions

      +
    • +
    • +

      import: Functions import() and include()

      +
    • +
    • +

      iterator: Iterator helper functions

      +
    • +
    • +

      math.arith: Functions add() and mul()

      +
    • +
    • +

      os.file: Operating system file functions

      +
    • +
    • +

      string: string utilities

      +
    • +
    +
    +
    +

    Builtins activation is done by using the BUILTIN operator. All modules except "base" must be explicitly enabled. The syntax is as follows.

    +
    +
    +
    Example 16. Builtin activation syntax
    +
    +
    +

    builtin-activation = BUILTIN (builtin-name | list-of-builtin-names)
    +builtin-name = string
    +list-of-builtin-names = [ string { "," string } ]

    +
    +
    +
    +
    +

    The following example shows how to activate the builtin module "math.arith" and then use the function add() defined in that module.

    +
    +
    +
    Example: using built functions
    +

    >>> BUILTIN "math.arith"
    +1
    +>>> add(5, 3, -2)
    +6

    +
    +
    + + + + + +
    + + +To avoid the need to activate builtin modules one by one, it is possible to activate all builtin modules at once by using the BUILTIN "*" syntax. +
    +
    +
    +

    7.1. Builtin modules

    +
    +

    7.1.1. Module "base"

    +
    +

    The "base" builtin module provides functions for type checking and type conversion. These functions are always available in Expr contexts without the need to activate the "base" module.

    +
    +
    +
    Checking functions
    + +
    +
    +
    Conversion functions
    + +
    +
    +
    Other functions
    + +
    +
    +
    isBool()
    +
    +

    Syntax: isBool(<expr>) → bool
    +Returns true if the value type of <expr> is boolean, false otherwise.

    +
    +
    +
    Examples
    +

    >>> isBool(true)
    +true
    +>>> isBool(3==2)
    +true

    +
    +
    +
    +
    isDict()
    +
    +

    Syntax: isDict(<expr>) → bool
    +Returns true if the value type of <expr> is dictionary, false otherwise.

    +
    +
    +
    Examples
    +

    >>> isDict({})
    +true
    +>>> isDict({1: "one", 2: "two"})
    +true
    +>>> isDict(1:"one")
    +Eval Error: denominator must be integer, got string (one)

    +
    +
    +
    +
    isFloat()
    +
    +

    Syntax: isFloat(<expr>) → bool
    +Returns true if the value type of <expr> is float, false otherwise.

    +
    +
    +
    Examples
    +

    >>> isFloat(4.)
    +true
    +>>> isFloat(4)
    +false
    +>>> isFloat("2.1")
    +false

    +
    +
    +
    +
    isFract()
    +
    +

    Syntax: isFract(<expr>) → bool
    +Returns true if the value type of <expr> is fraction, false otherwise.

    +
    +
    +
    Examples
    +

    >>> isFract(4.5)
    +false
    +>>> isFract(4:5)
    +true
    +>>> isFract(4)
    +false
    +>>> isFract(1.(3))
    +true

    +
    +
    +
    +
    isList()
    +
    +

    Syntax: isList(<expr>) → bool
    +Returns true if the value type of <expr> is list, false otherwise.

    +
    +
    +
    Examples
    +

    >>> isList([])
    +true
    +>>> isList([1, "2"]) +true +>>> isList(1,2) +Eval Error: isList(): too many params — expected 1, got 2

    +
    +
    +
    +
    isNil()
    +
    +

    Syntax: isNil(<expr>) → bool
    +Returns true if the value type of <expr> is nil, false otherwise.

    +
    +
    +
    Examples
    +

    >>> isNil(nil) +true +>>> isNil(1) +false

    +
    +
    +
    +
    isRational()
    +
    +

    Syntax: isRational(<expr>) → bool
    +Returns true if the value type of <expr> is fraction or int, false otherwise.

    +
    +
    +
    Examples
    +

    >>> isRational(4.5)
    +false
    +>>> isRational(4:5)
    +true
    +>>> isRational(4)
    +true
    +>>> isRational(1.(3))
    +true

    +
    +
    +
    +
    isString()
    +
    +

    Syntax: isString(<expr>) → bool
    +Returns a boolean value , false otherwise.

    +
    +
    +
    Examples
    +

    >>> isString("ciao")
    +true
    +>>> isString(2)
    +false
    +>>> isString(2+"2")
    +true

    +
    +
    +
    +
    bool()
    +
    +

    Syntax: bool(<expr>) → bool
    +Returns a boolean value consisent to the value of the expression.

    +
    +
    +
    Examples
    +

    >>> bool(1) +true +>>> bool(0) +false +>>> bool("") +false +>>> bool([]) +false +>>> bool([1]) +true +>>> bool({}) +false +>>> bool({1: "one"}) +true

    +
    +
    +
    +
    int()
    +
    +

    Syntax: int(<expr>) → int
    +Returns an integer value consistent with the value of the expression.

    +
    +
    +
    Examples
    +

    >>> int(2)
    +2
    +>>> int("2")
    +2
    +>>> int("0x1")
    +Eval Error: strconv.Atoi: parsing "0x1": invalid syntax
    +>>> int(0b10)
    +2
    +>>> int(0o2)
    +2
    +>>> int(0x2)
    +2
    +>>> int(1.8)
    +1
    +>>> int(5:2)
    +2
    +>>> int([])
    +Eval Error: int(): can’t convert list to int+ +>>> int(true)
    +1
    +>>> int(false)
    +0

    +
    +
    +
    +
    dec()
    +
    +

    Syntax: dec(<expr>) → float
    +Returns a float value consistent with the value of the expression.

    +
    +
    +
    Examples
    +

    >>> dec(2)
    +2
    +>>> dec(2.1)
    +2.1
    +>>> dec(2.3(1))
    +2.311111111111111
    +>>> dec("3.14")
    +3.14
    +>>> dec(3:4)
    +0.75
    +>>> dec(true)
    +1
    +>>> dec(false)
    +0

    +
    +
    +
    +
    string()
    +
    +

    Syntax: string(<expr>) → string
    +Returns a string value consistent with the value of the expression.

    +
    +
    +
    Examples
    +

    >>> string(2)
    +"2"
    +>>> string(0.8)
    +"0.8"
    +>>> string([1,2])
    +"[1, 2]"
    +>>> string({1: "one", 2: "two"})
    +"{1: "one", 2: "two"}"
    +>>> string(2:5)
    +"2:5"
    +>>> string(3==2)
    +"false"

    +
    +
    +
    +
    fract()
    +
    +

    Syntax: fract(<expr>) → fraction
    +Returns a fraction value consistent with the value of the expression.

    +
    +
    +
    Examples
    +

    >>> fract(2)
    +2:1
    +>>> fract(2.5)
    +5:2
    +>>> fract("2.5")
    +5:2
    +>>> fract(1.(3))
    +4:3
    +>>> fract([2])
    +Eval Error: fract(): can’t convert list to float
    +>>> fract(false)
    +0:1
    +>>> fract(true)
    +1:1

    +
    +
    +
    +
    eval()
    +
    +

    Syntax: eval(<string-expr>) → any
    +Computes and returns the value of the string expression.

    +
    +
    +
    Examples
    +

    >>> eval( "2 + fract(1.(3))" )
    +10:3

    +
    +
    +
    +
    var()
    +
    +

    Syntax:
    +     var(<string-expr>, <expr>) → any
    +     var(<string-expr>) → any

    +
    +
    +

    This function allows you to define variables whose names must include special characters. The first form of the function allows you to define a variable with a name specified by the first parameter and assign it the value of the second parameter. The second form only returns the value of the variable with the specified name.

    +
    +
    +
    Examples
    +

    >>> var("$x", 3+9)
    +12
    +>>> var("$x")
    +12
    +>>> var("gain%", var("$x"))
    +12
    +>>> var("gain%", var("$x")+1)
    +13

    +
    +
    +
    + +
    +

    7.1.3. Module "import"

    +
    +
    import()
    +
    +

    import(<source-file>) — loads the multi-expression contained in the specified source and returns its value.

    +
    +
    + +
    + + + + +
    +
    +
    +
    +

    8. Iterators

    Iterators are objects that can be used to traverse collections, such as lists and dictionaries. They are created by providing a data-source object, the collection, in a $(<data-source>) expression. Once an iterator is created, it can be used to access the elements of the collection one by one.

    @@ -2590,7 +3235,7 @@ The clone modifier @ does not make a variable a refere

    Lists and, soon, dictionaries, are implicit data-sources. The syntax for creating an iterator is as follows.

    -
    Example 16. Iterator creation syntax
    +
    Example 17. Iterator creation syntax

    iterator = "$(" data-source ")"
    @@ -2613,7 +3258,7 @@ The clone modifier @ does not make a variable a refere Eval Error: EOF

    -

    7.1. Operators on iterators

    +

    8.1. Operators on iterators

    The above example shows the use of the ++ operator to get the next element of an iterator. The ++ operator is a postfix operator that can be used with iterators. It returns the next element of the collection and updates the state of the iterator. When there are no more elements to iterate over, it returns the error Eval Error: EOF.

    @@ -2632,7 +3277,7 @@ The clone modifier @ does not make a variable a refere "one"

    -

    7.1.1. Named operators

    +

    8.1.1. Named operators

    Named operators are operators that are identified by a name instead of a symbol. They are implicitly defined and can be called using a special syntax. For example, the ++ has the equivalent named operator .next.

    @@ -2648,8 +3293,26 @@ The clone modifier @ does not make a variable a refere
  • .reset: resets the state of the iterator to the initial state.

  • +
  • +

    .count: returns the number of elements in the iterator, if it can be determined.

    +
  • +
  • +

    .index: returns the index of the current element in the iterator. Before the first use of the ++ operator, it returns the error -1.

    +
  • +
    + + + + + +
    + + +Iterators built on custom data-sources can provide additional named operators, depending on the functionality they want to expose. For example, an iterator over a list could provide a named operator called .reverse that returns the next element of the collection in reverse order. +
    +
    Example: using the named operators

    >>> it = $(["one", "two", "three"])
    @@ -2670,7 +3333,7 @@ The clone modifier @ does not make a variable a refere

    -

    7.2. Iterator over custom data-sources

    +

    8.2. Iterator over custom data-sources

    It is possible to create iterators over custom data-sources by defining a dictionary that has the key next whose value is a function that returns the next element of the collection and updates the state of the iterator. The syntax for creating an iterator over a custom data-source is as follows.

    @@ -2681,24 +3344,6 @@ The clone modifier @ does not make a variable a refere
    -

    8. Builtins

    -
    -
    -

    TODO: builtins

    -
    - -
    -

    8.2. import()

    -
    -

    import(<source-file>) loads the multi-expression contained in the specified source and returns its value.

    -
    -
    -
    -
    -

    9. Plugins

    @@ -2709,7 +3354,7 @@ The clone modifier @ does not make a variable a refere