Compile Time
Compile time is the phase when source code is translated into executable code by a compiler. During this stage, syntax errors, type errors, and other issues that can be detected without running the program are identified and reported.
Note that compile time is the time before compilation is complete.
Run Time
Run time is the phase when a program is executed after it has been successfully compiled. During this stage, the program performs its intended tasks, and errors related to logic, input, or system resources may occur.
Scope
A scope is a region of a program within which a set of identifiers (such as variable names, procedure names, or type names) are visible and accessible. An identifier declared inside a scope is not visible outside of it. Scopes can be nested: code in an inner scope can see identifiers from enclosing outer scopes, but code in an outer scope cannot see identifiers declared in an inner scope.
Top Level Scope
The top level scope (also called the global scope) is the outermost scope of your program. An identifier created at the top level, outside of any { ... } block and lives in this scope and is visible to all code within your application.
File Scope
Given a Jai file, we say that its scope is the collection of identifiers created in the file. A file scope sits underneath the top level scope, meaning code in a file can also see identifiers from the top level scope.
#scope_file
#scope_file is a compile time directive that causes all identifiers declared after it to be private to the current file. These identifiers are placed into the file scope and are not visible to any other file, not via #load, not via #import, and not to other files within the same module. This is the most restrictive visibility level.
#scope_export
#scope_export is a compile time directive that restores the default visibility for identifiers declared after it. These identifiers are exported, they are visible to other files and to code that imports or loads the file. This is the least restrictive visibility level. If no scope directive is specified, #scope_export is the default.
#scope_module
#scope_module is a compile time directive that causes all identifiers declared after it to be visible across all files within the current module, but not to code that imports the module. In a regular application (not inside an imported module), #scope_module behaves the same as #scope_export, because the application itself is the module.
Module
We say that a Jai file is a module when it is written in a way so that all identifiers are in its file scope. A module can also be a folder of files, where the entry point is a file called module.jai. Identifiers within a module have three possible visibility levels, controlled by #scope_export, #scope_module, and #scope_file.
#import
#import "Module_Name"; is a compile time directive that searches the import path for the file module_name.jai or module_name/module.jai. Once found, the file is treated as a module. The module's #scope_export identifiers are made visible to the file scope that the #import exists in, but they are not added to it, they remain in the module's own scope. Identifiers behind #scope_module or #scope_file are not visible to the importer.
The syntax Module_Name :: #import "Module_Name"; binds the module's scope to the identifier Module_Name. The module's exported identifiers are then accessed through it, e.g. Module_Name.some_identifier.
#import
#import "Module_Name"; is a compile time directive that searches the import path for the file module_name.jai or module_name/module.jai. Once found, the file is treated as a module, and only its #scope_export identifiers are pulled into the file scope that the #import exists in. Identifiers behind #scope_module or #scope_file are not visible to the importer.
The syntax Module_Name :: #import "Module_Name";, makes any adds any identifier id to the file scope of the #import.
Import Resolver
The import resolver is the part of the Jai compiler that finds all #import directives, locates the corresponding modules, and makes their identifiers available to the importing code. It also handles module deduplication, which ensures that if multiple files import the same module, the module is only compiled once and the same identifiers are shared, rather than being redefined each time.
#load
#load "file.jai"; is a compile time directive that inserts the contents of the specified file into the current file scope. Only identifiers under #scope_export in the loaded file are brought into the loading file's scope. Identifiers behind #scope_file remain private to the loaded file. Unlike #import, the loaded file does not get its own isolated scope, it shares the same scope as the file that loaded it and can see (and contribute to) identifiers in the top level scope.