Execution Model in AVAP
4.1. Structure of a Program
A program in AVAP is built from code blocks that execute linearly. A block is a section of the AVAP program text that executes as a unit. Code blocks in AVAP include:

A script file.
The body of a function.
An import statement for additional files.
Each line of code in AVAP is considered a block and executes sequentially. There is no interactive execution, deferred execution, or object classes.

4.2. Names and Bindings
4.2.1. Name Binding
Names in AVAP refer to values and are introduced through name binding operations. The following constructs bind names:

Formal parameters of functions.
Function definitions.
Assignment expressions.
Name binding is performed using the addVar(value, variable) function, which assigns the value to the specified variable. There are no class declarations or complex targets in AVAP. Only functions and direct assignments to variables are valid code blocks.

4.2.2. Name Resolution
A scope defines the visibility of a name in a code block. In AVAP, if a variable is defined in a code block, its scope includes that block. The scope of a variable within a function extends to the entire function block.

When a name is used in a code block, it is resolved using the nearest enclosing scope. If the name is not found in the current scope, a NameError exception is raised.

If a name binding operation occurs anywhere within a code block, all uses of the name within that block are treated as references to the current block. This means that variables must be defined before their use within the same block.

In AVAP, there are no global or nonlocal declarations. All names are resolved within the scope in which they are defined. There is no dynamic code execution with eval or exec, so all bindings must be static and known at code writing time.

4.3. Importing Files
In AVAP, it is possible to import the contents of other code files. The import file.avap statement inserts the contents of the specified file at the exact point where the import statement appears. This process is linear and sequential, meaning that the imported content is executed as if it were part of the original file.

It is crucial that the necessary functions are defined before they are called. If a function is not defined before its call, a NameError exception will be raised.

Example of import usage:

avap

// Content of the file main.avap 
addVar(x, 10) 
include functions.avap 
myFunction(x)

// Content of the file functions.avap
function myFunction(y){
    addVar(result, y + 5)
    addResult(result)
}
4.4. Exceptions
Exceptions in AVAP allow for the handling of errors or exceptional conditions. An exception is raised when an error is detected; it can be handled by the surrounding code block or by any code block that directly or indirectly invoked the block where the error occurred.

The AVAP interpreter raises an exception when it detects a runtime error. An AVAP program can also explicitly raise an exception using the raise statement. Exception handlers are specified with the try ... except statement.

Example of exception handling:

try() 
    addVar(10 / 0, result)
except() 
    addResult("Cannot divide by zero.")
end()
In this example, if a division by zero occurs, a ZeroDivisionError exception is raised and handled by the except block.

This structure ensures that AVAP programs execute in a sequential and predictable manner, without advanced dynamic or deferred execution features, maintaining simplicity and clarity in name binding and import handling.

5. The Import System in AVAP
AVAP code in one file gains access to code in another file through the import process. The import statement is the only way to invoke the import machinery in AVAP.

The include statement inserts the contents of the specified file at the exact point where the import statement appears in the original file. There are no other ways to invoke the import system in AVAP.

When an include statement is executed, the contents of the imported file are processed as if they were part of the original file, ensuring that all functions and variables from the imported file are available in the context of the original file. If the specified file is not found, a FileNotFoundError is raised.

Example of using the include statement in AVAP:

Content of file main.avap 
addVar(x,10) 
include functions.avap 
myFunction(x)

Content of file functions.avap 
function myFunction(y){ 
    addVar(result, y + 5) 
    addResult(result)
}
In this example, the content of functions.avap is inserted into main.avap at the point of the import statement, ensuring that myFunction is defined before being called.

5.1. Import Rules
Position of Import: The include statement must be placed at the exact location where the content of the imported file is to be included. The content of the imported file is executed linearly along with the original file.
Import Error: If the file specified in the include statement is not found, a FileNotFoundError is raised.
Scope of Imports: The functions and variables from the imported file are added to the local scope of the original file at the point of import. This means they can be accessed as if they were defined in the same file.
5.2. Limitations and Considerations
No Packages: Unlike other languages, AVAP does not have a hierarchical package system. Each file is imported independently and treated as an autonomous unit.
Sequential Execution: Execution in AVAP is sequential and does not allow lazy or deferred execution. Therefore, all functions and variables must be defined before use, and the content of imported files must be in the correct order.
No Conditional Import: The import statement in AVAP does not support conditions. The specified file will always be imported at the point of the statement, regardless of any conditions.
5.3. Advanced Example
Consider the following example where multiple files are imported:

Content of the file main.avap
addVar(5, a) 
include utilities.avap 
include operations.avap

addVar(b, increment(a))
addVar( c, multiply(b, 2))
addResult(c)

Content of the file utilities.avap
function increment(x){
    return(x + 1)
}
Content of the file operations.avap
function multiply(x, y){ 
    return(x * y)
}
In this example, utilities.avap and operations.avap are imported into main.avap at the specified points, allowing the increment and multiply functions to be used in main.avap.