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()
@ -458,32 +459,20 @@ 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;
} }
@ -493,11 +482,6 @@ namespace Parser
currentScope.Variables[name] = value; currentScope.Variables[name] = value;
} }
} }
else
{
_context.Variables[name] = value;
}
}
private MObject? EvaluateLambdaExpression(BoundLambdaExpression node) private MObject? EvaluateLambdaExpression(BoundLambdaExpression node)
{ {

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)
{ {