Fix REPL context handling

This commit is contained in:
Alexander Luzgarev 2020-07-16 11:50:19 +02:00
parent 2f04f86af3
commit 5e9111a085
4 changed files with 16 additions and 32 deletions

View File

@ -21,7 +21,7 @@ namespace Parser
return Binder.BindProgram(_syntaxTree);
}
public EvaluationResult Evaluate(CompilationContext context)
public EvaluationResult Evaluate(CompilationContext context, bool inRepl)
{
var program = GetBoundProgram();
if (program.Diagnostics.Length > 0)
@ -29,7 +29,7 @@ namespace Parser
return new EvaluationResult(null, program.Diagnostics);
}
var evaluator = new Evaluator(program, context);
var evaluator = new Evaluator(program, context, inRepl);
return evaluator.Evaluate();
}
}

View File

@ -13,15 +13,16 @@ namespace Parser
private readonly BoundProgram _program;
private readonly CompilationContext _context;
private readonly DiagnosticsBag _diagnostics = new DiagnosticsBag();
private bool _insideFunction = false;
private bool _inRepl = false;
private readonly Stack<EvaluationScope> _scopeStack = new Stack<EvaluationScope>();
public Evaluator(BoundProgram program, CompilationContext context)
public Evaluator(BoundProgram program, CompilationContext context, bool inRepl)
{
_program = program;
_context = context;
var outerScope = new EvaluationScope();
_scopeStack.Push(outerScope);
_inRepl = inRepl;
}
internal EvaluationResult Evaluate()
@ -33,7 +34,7 @@ namespace Parser
_diagnostics.ReportNotEnoughInputs(
new TextSpan(mainFunction.Declaration.Position, mainFunction.Declaration.Position + mainFunction.Declaration.FullWidth),
mainFunction.Name);
return new EvaluationResult(null, _diagnostics.ToImmutableArray());
return new EvaluationResult(null, _diagnostics.ToImmutableArray());
}
else
{
@ -458,44 +459,27 @@ namespace Parser
private MObject? GetVariableValue(string name)
{
if (_insideFunction)
if (_inRepl)
{
if (_context.Variables.TryGetValue(name, out var globalValue))
{
return globalValue;
}
var currentScope = _scopeStack.Peek();
return currentScope.Variables.TryGetValue(name, out var localValue) ? globalValue : null;
return _context.Variables.TryGetValue(name, out var globalValue) ? globalValue : null;
}
else
{
if (_context.Variables.TryGetValue(name, out var globalValue))
{
return globalValue;
}
return null;
var currentScope = _scopeStack.Peek();
return currentScope.Variables.TryGetValue(name, out var localValue) ? localValue : null;
}
}
private void SetVariableValue(string name, MObject value)
{
if (_insideFunction)
if (_inRepl)
{
if (_context.Variables.ContainsKey(name))
{
_context.Variables[name] = value;
}
else
{
var currentScope = _scopeStack.Peek();
currentScope.Variables[name] = value;
}
_context.Variables[name] = value;
}
else
{
_context.Variables[name] = value;
var currentScope = _scopeStack.Peek();
currentScope.Variables[name] = value;
}
}

View File

@ -65,7 +65,7 @@ namespace Repl
TreeRenderer.RenderTree(tree);
var compilation = Compilation.Create(tree);
var evaluationResult = compilation.Evaluate(_context);
var evaluationResult = compilation.Evaluate(_context, inRepl: true);
foreach (var diagnostic in evaluationResult.Diagnostics)
{

View File

@ -36,7 +36,7 @@ namespace cmi
}
var context = new CompilationContext();
var evaluationResult = compilation.Evaluate(context);
var evaluationResult = compilation.Evaluate(context, inRepl: false);
foreach (var diagnostic in evaluationResult.Diagnostics)
{