aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-03-24 12:59:14 +0000
committers-ol <s+removethis@s-ol.nu>2025-04-07 10:33:17 +0000
commit368ce90c865e648c8070662eecd5f847d9228af1 (patch)
treec359b92dfdc6fa8e710076ab7a96d352acc949a3
parentglsl-view: resolve relative paths for video (diff)
downloadalive-368ce90c865e648c8070662eecd5f847d9228af1.tar.gz
alive-368ce90c865e648c8070662eecd5f847d9228af1.zip
propagate dynamic scope in require/import
-rw-r--r--alv/builtins.moon8
-rw-r--r--alv/copilot/base.moon5
-rw-r--r--alv/module.moon4
3 files changed, 9 insertions, 8 deletions
diff --git a/alv/builtins.moon b/alv/builtins.moon
index 56a6eea..da8570f 100644
--- a/alv/builtins.moon
+++ b/alv/builtins.moon
@@ -96,7 +96,7 @@ require_ = Constant.meta
description: "Load a module and return its scope."
value: class extends Builtin
- eval: (scope, tail) =>
+ eval: (scope, tail) =>
L\trace "evaling #{@}"
assert #tail == 1, "'require' takes exactly one parameter"
@@ -104,7 +104,7 @@ require_ = Constant.meta
name = node\const!\unwrap T.str
L\trace @, "loading module #{name}"
- super COPILOT\require name
+ super COPILOT\require name, scope
import_ = Constant.meta
meta:
@@ -123,7 +123,7 @@ current scope."
children = for i, child in ipairs tail
assert child.__class == Constant, "'import' arguments need to be symbols"
name = child\unwrap T.sym
- with COPILOT\require name
+ with COPILOT\require name, scope
scope\set name, \make_ref!
super RTNode :children
@@ -142,7 +142,7 @@ Requires modules `sym1`, `sym2`, … and merges them into the current scope."
children = for i, child in ipairs tail
assert child.__class == Constant, "'import*' arguments need to be symbols"
- with COPILOT\require child\unwrap T.sym
+ with COPILOT\require (child\unwrap T.sym), scope
scope\use .result\unwrap T.scope
super RTNode :children
diff --git a/alv/copilot/base.moon b/alv/copilot/base.moon
index cb82689..2fb0ebc 100644
--- a/alv/copilot/base.moon
+++ b/alv/copilot/base.moon
@@ -69,8 +69,9 @@ class Copilot
--- require a module.
-- @tparam string name
+ -- @tparam Scope scope
-- @treturn RTNode root
- require: (name) =>
+ require: (name, scope) =>
Error.wrap "loading module '#{name}'", ->
ok, result = pcall require, "alv-lib.#{name}"
if ok
@@ -89,7 +90,7 @@ class Copilot
L\trace "entering module #{mod}"
@modules[name] = mod
@active_module = mod
- ok, err = pcall mod\eval
+ ok, err = pcall mod\eval, scope
L\trace "returning to module #{mod}"
@active_module = last
if ok
diff --git a/alv/module.moon b/alv/module.moon
index 8513192..ab98436 100644
--- a/alv/module.moon
+++ b/alv/module.moon
@@ -37,12 +37,12 @@ class Module
--
-- If the module has already been evaluated this tick, this is a noop.
-- Otherwise, register the module with the `Copilot`. Updates `root`.
- eval: =>
+ eval: (parent_scope) =>
@registry\begin_eval!
@ast = Error.wrap "parsing '#{@name true}'", -> program\match @slurp!
assert @ast, Error 'syntax', "failed to parse"
- scope = Scope builtins!
+ scope = Scope builtins!, parent_scope
@root = Error.wrap "evaluating '#{@name true}'", @ast\eval, scope, @registry
--- rollback the last evaluation cycle.