Reworked modules, they now should bind properly
This commit is contained in:
parent
1caf8320b3
commit
98e5c1c136
|
@ -6,6 +6,7 @@ using Upsilon.BaseTypes;
|
|||
using Upsilon.BaseTypes.Number;
|
||||
using Upsilon.Binder.VariableSymbols;
|
||||
using Upsilon.BoundTypes;
|
||||
using Upsilon.Evaluator;
|
||||
using Upsilon.Parser;
|
||||
using Type = Upsilon.BaseTypes.Type;
|
||||
|
||||
|
@ -15,21 +16,26 @@ namespace Upsilon.Binder
|
|||
{
|
||||
private Diagnostics _diagnostics;
|
||||
public BoundScope Scope { get; private set; }
|
||||
private readonly Script _script;
|
||||
|
||||
private Dictionary<string, UnboundFunctionExpression> _unboundFunctions =
|
||||
new Dictionary<string, UnboundFunctionExpression>();
|
||||
|
||||
public Binder(Diagnostics diagnostics, Dictionary<string, VariableSymbol> variables)
|
||||
public Binder(Diagnostics diagnostics, Dictionary<string, VariableSymbol> variables, Script script)
|
||||
{
|
||||
_diagnostics = diagnostics;
|
||||
_script = script;
|
||||
Scope = new BoundScope(variables, null);
|
||||
}
|
||||
|
||||
private Binder(){}
|
||||
|
||||
internal static Binder CreateWithSetScope(Diagnostics diagnostics, BoundScope scope)
|
||||
private Binder(Script script)
|
||||
{
|
||||
return new Binder {_diagnostics = diagnostics, Scope = scope};
|
||||
_script = script;
|
||||
}
|
||||
|
||||
internal static Binder CreateWithSetScope(Diagnostics diagnostics, BoundScope scope, Script script)
|
||||
{
|
||||
return new Binder(script) {_diagnostics = diagnostics, Scope = scope};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -233,6 +239,24 @@ namespace Upsilon.Binder
|
|||
_unboundFunctions.Remove(scriptFunction.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.Equals(function.Name, "require") && parameters.Count > 0)
|
||||
{
|
||||
var parameter = parameters[0];
|
||||
if (parameter is BoundLiteralExpression be && be.Value.Type == Type.String)
|
||||
{
|
||||
var moduleName = be.Value.ToString();
|
||||
var module = _script.Options.ModuleHandler.GetModule(_script, moduleName);
|
||||
foreach (var moduleVariable in module.Scope.Variables)
|
||||
{
|
||||
if (moduleVariable.Value.Local)
|
||||
continue;
|
||||
Scope.Variables.Add(moduleVariable.Key, moduleVariable.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
returnType = function.ResultType;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Upsilon.Evaluator
|
|||
|
||||
var staticBoundScope = options.OverrideStaticBoundScope ?? StaticScope.BoundScope;
|
||||
var boundScope = BoundScope.WithReadOnlyScope(staticBoundScope);
|
||||
Binder = Upsilon.Binder.Binder.CreateWithSetScope(Diagnostics, boundScope);
|
||||
Binder = Upsilon.Binder.Binder.CreateWithSetScope(Diagnostics, boundScope, this);
|
||||
|
||||
var staticScope = options.OverrideStaticScope ?? StaticScope.Scope;
|
||||
Scope = EvaluationScope.CreateWithGetOnlyParent(staticScope);
|
||||
|
@ -45,7 +45,7 @@ namespace Upsilon.Evaluator
|
|||
_scriptString = scriptString;
|
||||
Diagnostics = new Diagnostics(ScriptString, options.ThrowExceptionOnError);
|
||||
|
||||
Binder = Upsilon.Binder.Binder.CreateWithSetScope(Diagnostics, binder.Scope);
|
||||
Binder = Upsilon.Binder.Binder.CreateWithSetScope(Diagnostics, binder.Scope, this);
|
||||
Evaluator = Evaluator.CreateWithSetScope(Diagnostics, evaluator.Scope, this);
|
||||
Scope = Evaluator.Scope;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ namespace Upsilon.Evaluator
|
|||
_bound = boundScript;
|
||||
Diagnostics = new Diagnostics(ScriptString, options.ThrowExceptionOnError);
|
||||
|
||||
Binder = Upsilon.Binder.Binder.CreateWithSetScope(Diagnostics, binder.Scope);
|
||||
Binder = Upsilon.Binder.Binder.CreateWithSetScope(Diagnostics, binder.Scope, this);
|
||||
Evaluator = Evaluator.CreateWithSetScope(Diagnostics, evaluator.Scope, this);
|
||||
Scope = Evaluator.Scope;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections.Generic;
|
||||
using Upsilon.Binder;
|
||||
using Upsilon.Evaluator;
|
||||
|
||||
namespace Upsilon
|
||||
{
|
||||
public class ModuleHandler
|
||||
{
|
||||
private readonly Dictionary<string, BoundScript> _cachedModules = new Dictionary<string, BoundScript>();
|
||||
|
||||
public virtual BoundScript GetModule(Script script, string name)
|
||||
{
|
||||
if (_cachedModules.TryGetValue(name, out var module))
|
||||
return module;
|
||||
|
||||
var moduleScript = script.Options.ScriptLoader.LoadModule(name);
|
||||
var parsed = Executor.ContinueWith(script, moduleScript);
|
||||
module = parsed.Bind();
|
||||
_cachedModules.Add(name, module);
|
||||
return module;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ namespace Upsilon
|
|||
|
||||
public BoundScope OverrideStaticBoundScope { get; set; } = null;
|
||||
public EvaluationScope OverrideStaticScope { get; set; } = null;
|
||||
public ScriptLoader ScriptLoader { get; set; } = null;
|
||||
public ScriptLoader ScriptLoader { get; set; } = new ScriptLoader();
|
||||
public ModuleHandler ModuleHandler { get; set; } = new ModuleHandler();
|
||||
}
|
||||
}
|
|
@ -41,30 +41,15 @@ namespace Upsilon.StandardLibraries
|
|||
return new PairsScriptIterator(table);
|
||||
}
|
||||
|
||||
private static readonly Dictionary<string, BoundScript> CachedBoundModules = new Dictionary<string, BoundScript>();
|
||||
|
||||
[StandardLibraryScriptFunction("require", "Loads a module from the module path, using the given script loader.",
|
||||
true)]
|
||||
public ScriptType Require(Script script, ScriptString fileName)
|
||||
{
|
||||
var file = fileName.Value;
|
||||
var loader = script.Options.ScriptLoader;
|
||||
if (loader != null)
|
||||
{
|
||||
if (!CachedBoundModules.TryGetValue(file, out var boundScript))
|
||||
{
|
||||
var loadedScript = loader.LoadModule(file);
|
||||
boundScript = Executor.ParseInput(loadedScript).Bind();
|
||||
CachedBoundModules.Add(file, boundScript);
|
||||
}
|
||||
var s = Executor.ContinueWith(script, boundScript);
|
||||
var val = s.Evaluate();
|
||||
if (val != null)
|
||||
{
|
||||
return val.ToScriptType();
|
||||
}
|
||||
}
|
||||
return new ScriptNull();
|
||||
var module = script.Options.ModuleHandler.GetModule(script, file);
|
||||
var s = Executor.ContinueWith(script, module);
|
||||
var val = s.Evaluate();
|
||||
return val != null ? val.ToScriptType() : new ScriptNull();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue