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

all: Implement stop #67

Merged
merged 2 commits into from
Feb 8, 2023
Merged

all: Implement stop #67

merged 2 commits into from
Feb 8, 2023

Conversation

juliaogris
Copy link
Member

@juliaogris juliaogris commented Feb 6, 2023

Implement stop in frontend by turning the Run button into a Stop button
during execution. For this we also need an onExit callback into JS from
go when execution finishes so that the button label gets reset.

Additionally we need to occasionally yield to JS event processing via a
time.Sleep in the evaluator code. This operation is abstracted via
the Yielder interface.

Execution is stopped in Eval if the Stopped flag is set, which gets set
on click via the exported Go function stop(). The access to the stop
flag is not synchronised, but as JS is single threaded so we don't need
to worry about it.

In a preparatory commit refactor evaluator and builtins so that there is
a separate NewEvaluator function and e.Run method. This allows for
wasm/main.go to hold an evaluator as global variable on which we set the
evaluator.Stopped flag.

Evy program for testing.

while true 
   rect 10 10
end

another one with sleep:

for i := range 0 100 0.1
  clear
  dot i 50

  sleep 0.01
end

func clear
  color "white"
  move 0 0 
  rect 100 100
end

func dot x:num y:num
  color "red"
  move x y
  circle 10
end

@github-actions
Copy link

github-actions bot commented Feb 6, 2023

firebase-deployment: https://evy-lang--67-4souifjv.web.app (aba3e29)

@juliaogris juliaogris changed the title all: Implement cancel all: Implement stop Feb 8, 2023
@juliaogris juliaogris requested a review from camh- February 8, 2023 00:10
Refactor access to builtin functions and decls so that we can create the
evaluator in wasm main and hold on to it in global state. This will
later be needed so that we can set a cancel flag in the evaluator
during execution in a JS exported function.
Copy link
Contributor

@camh- camh- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥗 LGTM

if e.Stopped {
return ErrStopped
}
e.yield()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a comment here to say why this yield exists?

// Yield to give JavaScript/browser events a chance to run.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

print func(string)
builtins map[string]Builtin

scope *scope // Current top of scope stack
}

type Yielder interface {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a comment perhaps?

// Yielder abstracts the method of yielding the CPU so that JavaScript/browser
// events get a chance to be processed. Currently (Feb 2023) it seems that you
// can only yield to JS by sleeping for at least 1ms but having that delay is
// not ideal. Other methods of yielding can be explored by implementing a
// different Yielder.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice thanks. done.

pkg/wasm/main.go Outdated
@@ -24,6 +27,26 @@ func getSource() string {
return getString(ptr, length)
}

type yielder struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps call this sleepingYielder or something?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Implement stop in frontend by turning the Run button into a Stop button
during execution. For this we also need an onExit callback into JS from
go when execution finishes so that the button label gets reset.

Additionally we need to occasionally yield to JS event processing via a
`time.Sleep` in the evaluator code. This operation is abstracted via
the Yielder interface.

Execution is stopped in Eval if the Stopped flag is set, which gets set
on click via the exported Go function stop(). The access to the stop
flag is not synchronized, but as JS is single threaded so we don't need
to worry about it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants