Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EvalContext discards context on recursion #93

Closed
DeadlySurgeon opened this issue Nov 15, 2023 · 7 comments · Fixed by #96
Closed

EvalContext discards context on recursion #93

DeadlySurgeon opened this issue Nov 15, 2023 · 7 comments · Fixed by #96
Assignees
Labels
bug Something isn't working

Comments

@DeadlySurgeon
Copy link
Contributor

evaluator.EvalContext has some points where it calls Eval, which then just calls EvalContext with a background context, thus dropping the original context passed to it. This should be fixed so it instead calls EvalContext with the provided context.

EG: https://github.com/skx/monkey/blob/master/evaluator/evaluator.go#L56

func EvalContext(ctx context.Context, node ast.Node, env *object.Environment) object.Object {
        ...
	case *ast.ExpressionStatement:
		return Eval(node.Expression, env)
@DeadlySurgeon
Copy link
Contributor Author

DeadlySurgeon commented Nov 15, 2023

This also extends into EvalContext calling evalProgram which then executes Eval, further dropping the context.

@skx skx self-assigned this Nov 15, 2023
@skx skx added the bug Something isn't working label Nov 15, 2023
@skx
Copy link
Owner

skx commented Nov 15, 2023

Now you say it .. yes. This is obviously incorrect! Thank you for the bug-report.

If you want to have a stab at resolving it you're welcome, otherwise I'll look at it over the weekend.

@DeadlySurgeon
Copy link
Contributor Author

I think you should take a swing at it. I recommend just temp removing the Eval function, and then any places that call it that are giving an error should just be changed to EvalContext, and then once that's resolved add it back.

@skx
Copy link
Owner

skx commented Nov 20, 2023

I suspect this solution would get messy quickly, since EvalContext passes to evalBlockStatement, etc, etc.

The better change is to add a call to "SetContext", and use that to update the global context variable - which defaults to context.Background, and only test that. There then wouldn't be any difference between Eval and EvalWithContext.

  • Shuffle the code into eval where it used to live.
    • Add the context-testing at the head of that function, using the global variable.
  • EvalWithContext is then a minimal wrapper which does two things:
    • call SetContext to update the global variable.
    • call Eval(...)

Possibly SetContext and the global variable can be local/package-local, rather than externally accessible. That preserves the current API.

@DeadlySurgeon
Copy link
Contributor Author

DeadlySurgeon commented Nov 20, 2023

I wouldn't have a global variable context, that's pretty bad practice. Changing unexported functions isn't a breaking change.

EDIT:
I just noticed the existing global context, and I'd honestly remove it as it isn't concurrent safe and allows for bad flow control.

Also it looks like SetContext is only used in a test file, removing it wouldn't break any other bits if your code base, you could just change your tests to call EvalContext.

@skx
Copy link
Owner

skx commented Nov 21, 2023

Yeah having the global is not great - the issue with this implemetnation is that everything's global, more or less, there should be a struct to start state of the interpreter and mediate access appropriately.

Still it looks like your PR does all the right things and I'll merge that. Thanks for taking the time to report the issue and resolve it.

@skx skx closed this as completed in #96 Nov 21, 2023
@DeadlySurgeon
Copy link
Contributor Author

NP. I've been trying to complete my own monkey interpreter for a while and kept getting sidetracked, and seeing your repository has helped a lot in my own pursuit, especially around the part where I parse my tokens into the AST for then further execution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants