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

View File

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

View File

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

View File

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