feat: Enhance #use directive for directories and cwd
The `#use` directive now supports referencing entire directories, automatically including all `.myc` files within them. Additionally, environments are now initialized with the current working directory as a default search path, simplifying module resolution.
This commit is contained in:
@@ -20,20 +20,21 @@ We need a way to explicitly define dependencies *within* a Myc script, ensuring
|
||||
|
||||
## The Solution: `#use` Preprocessor Directives
|
||||
|
||||
We introduce a preprocessor directive `#use` that is evaluated *before* the main parsing phase begins.
|
||||
We introduce a preprocessor directive `#use` that is evaluated *before* the main parsing phase begins. It can target either single files or entire directories.
|
||||
|
||||
### Syntax
|
||||
|
||||
```myc
|
||||
#use math->indicators
|
||||
#use utils
|
||||
#use mylib
|
||||
|
||||
(do
|
||||
;; Actual Myc code begins here
|
||||
(def my_var (indicators.calculate ...))
|
||||
)
|
||||
```
|
||||
*(Here `math->indicators` resolves to `math/indicators.myc` and `utils` resolves to `utils.myc`)*
|
||||
*(Here `math->indicators` resolves to the file `math/indicators.myc`. `utils` resolves to `utils.myc`. If `mylib` is a directory instead of a file, it resolves to all `.myc` files within that directory.)*
|
||||
|
||||
### Implementation Plan
|
||||
|
||||
@@ -41,13 +42,15 @@ We introduce a preprocessor directive `#use` that is evaluated *before* the main
|
||||
The `Environment` will be extended with a `HashSet<PathBuf>` (e.g., `loaded_modules`) to keep track of canonical paths that have already been loaded, ensuring idempotency.
|
||||
|
||||
2. **Pre-Parse Extraction:**
|
||||
Before the AST `Parser` processes a script, a lightweight scraper will read the top lines of the file. It will extract all `#use` paths and stop as soon as it encounters a line that is not empty, not a comment (`;`), and not a `#use` directive.
|
||||
Before the AST `Parser` processes a script, a lightweight scraper will read the top lines of the file. It will extract all `#use` paths and stop as soon as it encounters a line that is not empty, not a comment (`;` or `#`), and not a `#use` directive.
|
||||
|
||||
3. **Recursive Resolution:**
|
||||
- The scraper extracts the module path, replaces `->` with the OS-specific directory separator, and appends `.myc`.
|
||||
- Paths are resolved relative to the file that declares the dependency.
|
||||
- The scraper extracts the module path and replaces `->` with the OS-specific directory separator.
|
||||
- It first checks if `<path>.myc` exists as a file. If it does, it resolves to that single file.
|
||||
- If not, it checks if `<path>` is a directory. If so, it resolves to all `.myc` files inside that directory (sorted alphabetically).
|
||||
- Paths are resolved relative to the file that declares the dependency, with a fallback to the global `--lib` search paths.
|
||||
- If a path is not in `loaded_modules`, it is added to the set.
|
||||
- The file is read, and the extraction process runs recursively on its content.
|
||||
- The files are read, and the extraction process runs recursively on their content.
|
||||
- This creates a flat list of all dependencies in a valid topological order.
|
||||
|
||||
4. **Two-Pass Compilation:**
|
||||
|
||||
Reference in New Issue
Block a user