Skip to content

Commit

Permalink
add is_even (#2278)
Browse files Browse the repository at this point in the history
  • Loading branch information
srliao authored Nov 22, 2024
1 parent fc2e156 commit fa63444
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
40 changes: 40 additions & 0 deletions pkg/gcs/eval_fn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,43 @@ func TestNestedActions(t *testing.T) {
t.Error(eval.Err())
}
}

func TestIsEven(t *testing.T) {
prog := `is_even(1);`
p := ast.New(prog)
_, gcsl, err := p.Parse()
if err != nil {
t.Fatal(err)
}
fmt.Println("program:")
fmt.Println(gcsl.String())
eval, _ := NewEvaluator(gcsl, nil)
eval.Log = log.Default()
resultChan := make(chan Obj)
go func() {
res, err := eval.Run()
fmt.Printf("done with result: %v, err: %v\n", res, err)
resultChan <- res
}()
for {
eval.Continue()
a, err := eval.NextAction()
if a == nil {
break
}
if err != nil {
t.Fatal(err)
}
}
result := <-resultChan
if result.Typ() != typNum {
t.Errorf("expecting type to return num, got %v", typStrings[result.Typ()])
}
if eval.Err() != nil {
t.Error(eval.Err())
}
val := result.(*number)
if val.ival != 0 {
t.Errorf("expecting result to be 0, got %v", val.ival)
}
}
31 changes: 31 additions & 0 deletions pkg/gcs/sysfunc.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func (e *Eval) initSysFuncs(env *Env) {
e.addSysFunc("cos", e.cos, env)
e.addSysFunc("asin", e.asin, env)
e.addSysFunc("acos", e.acos, env)
e.addSysFunc("is_even", e.isEven, env)

// events
e.addSysFunc("set_on_tick", e.setOnTick, env)
Expand Down Expand Up @@ -495,6 +496,36 @@ func (e *Eval) pickUpCrystallize(c *ast.CallExpr, env *Env) (Obj, error) {
}, nil
}

func (e *Eval) isEven(c *ast.CallExpr, env *Env) (Obj, error) {
// is_even(number goes in here)
if len(c.Args) != 1 {
return nil, fmt.Errorf("invalid number of params for is_even, expected 1 got %v", len(c.Args))
}

// should eval to a number
val, err := e.evalExpr(c.Args[0], env)
if err != nil {
return nil, err
}

n, ok := val.(*number)
if !ok {
return nil, fmt.Errorf("is_even argument should evaluate to a number, got %v", val.Inspect())
}

// if float, floor it
var v int64
v = n.ival
if n.isFloat {
v = int64(n.fval)
}

if v%2 == 0 {
return bton(true), nil
}
return bton(false), nil
}

func (e *Eval) sin(c *ast.CallExpr, env *Env) (Obj, error) {
// sin(number goes in here)
if len(c.Args) != 1 {
Expand Down
12 changes: 12 additions & 0 deletions ui/packages/docs/docs/reference/system_functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,18 @@ pick_up_crystallize(element);
`element` must be a string or an expression that evaluates to a string.
:::

## is_even

```
is_even(arg);
```

`is_even` evaluates if a given number is even or not. If a number is a floating point, the number if floored first.

:::danger
`arg` must be a number or an expression that evaluates to a number.
:::

## sin

```
Expand Down

0 comments on commit fa63444

Please sign in to comment.