Skip to content

Commit

Permalink
🐞 builtins: Fix rand and sleep functions (#417)
Browse files Browse the repository at this point in the history
Fix `rand` and `sleep` functions to not crash when used with bad
arguments: In the case of rand we ensure the argument is `>= 1`, and in
the case of sleep we ensure we sleep a minimum of 1 millisecond.

Add a minor unrelated typo fix.

This PR has cherry-picked from two other PRs created from forked repo,
which cannot run CI.

This merges the following commits:
* pkg: Fix typo in SVG struct field
* builtins: Fix rand function for bad arg
* builtins: Enforce sleep lower bound in JS runtime

     docs/builtins.md             |  3 +++
     frontend/docs/builtins.html  |  4 ++++
     frontend/docs/builtins.htmlf |  4 ++++
     pkg/cli/svg/runtime.go       |  8 ++++----
     pkg/cli/svg/svg.go           |  2 +-
     pkg/cli/svg/svg_test.go      |  2 +-
     pkg/evaluator/builtin.go     |  4 ++--
     pkg/wasm/imports.go          | 15 ++++++++++-----
     8 files changed, 29 insertions(+), 13 deletions(-)

Related-pull-request: #412
Related-pull-request: #413
Pull-request: #417
  • Loading branch information
juliaogris committed Aug 22, 2024
2 parents b914460 + 5a207f8 commit 7dbd68c
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 13 deletions.
3 changes: 3 additions & 0 deletions docs/builtins.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,9 @@ with `del` while iterating with a `for … range` loop.
`sleep` can be used to create delays in Evy programs. For example, you
could use sleep to create a countdown timer.

In the [browser runtime](spec.md#runtimes) `sleep` pauses a minimum of 1
millisecond.

#### Example

```evy
Expand Down
4 changes: 4 additions & 0 deletions frontend/docs/builtins.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions frontend/docs/builtins.htmlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions pkg/cli/svg/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var (
Stroke: "black",
StrokeWidth: &defaultStrokeWidth,
StrokeLinecap: "round",
StorkeDashArray: "",
StrokeDashArray: "",
}
)

Expand Down Expand Up @@ -105,8 +105,8 @@ func (rt *GraphicsRuntime) nonDefaultAttr() Attr {
if rt.attr.StrokeLinecap == defaultAttr.StrokeLinecap {
attr.StrokeLinecap = ""
}
if rt.attr.StorkeDashArray == defaultAttr.StorkeDashArray {
attr.StorkeDashArray = ""
if rt.attr.StrokeDashArray == defaultAttr.StrokeDashArray {
attr.StrokeDashArray = ""
}
return attr
}
Expand Down Expand Up @@ -327,7 +327,7 @@ func (rt *GraphicsRuntime) Dash(segments []float64) {
for i, segment := range segments {
segmentStrings[i] = ftoa(rt.scale(segment))
}
rt.attr.StorkeDashArray = strings.Join(segmentStrings, " ")
rt.attr.StrokeDashArray = strings.Join(segmentStrings, " ")
}

// Linecap sets the stroke linecap style.
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/svg/svg.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Attr struct {
Stroke string `xml:"stroke,attr,omitempty"`
StrokeWidth *float64 `xml:"stroke-width,attr,omitempty"`
StrokeLinecap string `xml:"stroke-linecap,attr,omitempty"`
StorkeDashArray string `xml:"stroke-dasharray,attr,omitempty"`
StrokeDashArray string `xml:"stroke-dasharray,attr,omitempty"`
}

// TextAttr represents the attributes of text or group SVG elements and
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/svg/svg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestGolden(t *testing.T) {
Stroke: "red",
StrokeWidth: &testStrokeWidth,
StrokeLinecap: "butt",
StorkeDashArray: "3 5",
StrokeDashArray: "3 5",
},
}},
},
Expand Down
4 changes: 2 additions & 2 deletions pkg/evaluator/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,8 +668,8 @@ var randsource = rand.New(rand.NewSource(time.Now().UnixNano())) //nolint:gosec

func randFunc(_ *scope, args []value) (value, error) {
upper := args[0].(*numVal).V
if upper <= 0 || upper > 2147483647 { // [1, 2^31-1]
return nil, fmt.Errorf(`%w: "rand %0.f" not in range 1 to 2147483647`, ErrBadArguments, upper)
if upper < 1 || upper > 2147483647 { // [1, 2^31-1]
return nil, fmt.Errorf(`%w: "rand %v" not in range 1 to 2147483647`, ErrBadArguments, upper)
}
return &numVal{V: float64(randsource.Int31n(int32(upper)))}, nil
}
Expand Down
15 changes: 10 additions & 5 deletions pkg/wasm/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@ func newJSRuntime() *jsRuntime {
return &jsRuntime{yielder: newSleepingYielder()}
}

func (rt *jsRuntime) Yielder() evaluator.Yielder { return rt.yielder }
func (rt *jsRuntime) Print(s string) { jsPrint(s) }
func (rt *jsRuntime) Cls() { jsCls() }
func (rt *jsRuntime) Read() string { return rt.yielder.Read() }
func (rt *jsRuntime) Sleep(dur time.Duration) { rt.yielder.Sleep(dur) }
func (rt *jsRuntime) Yielder() evaluator.Yielder { return rt.yielder }
func (rt *jsRuntime) Print(s string) { jsPrint(s) }
func (rt *jsRuntime) Cls() { jsCls() }
func (rt *jsRuntime) Read() string { return rt.yielder.Read() }

func (rt *jsRuntime) Sleep(dur time.Duration) {
// Enforce a lower bound to stop browser tabs from freezing.
rt.yielder.Sleep(max(minSleepDur, dur))
}

func (rt *jsRuntime) Move(x, y float64) { move(x, y) }
func (rt *jsRuntime) Line(x, y float64) { line(x, y) }
func (rt *jsRuntime) Rect(x, y float64) { rect(x, y) }
Expand Down

0 comments on commit 7dbd68c

Please sign in to comment.