diff --git a/env/env.go b/env/env.go index f2023c25..c1f35f1e 100755 --- a/env/env.go +++ b/env/env.go @@ -390,7 +390,7 @@ type LiveEnv struct { func NewLiveEnv() *LiveEnv { watcher, err := fsnotify.NewWatcher() if err != nil { - fmt.Println("Error creating watcher:", err) + // fmt.Println("Error creating watcher:", err) return nil } // defer watcher.Close() diff --git a/evaldo/builtins.go b/evaldo/builtins.go index b805d511..ed6ba338 100644 --- a/evaldo/builtins.go +++ b/evaldo/builtins.go @@ -2422,6 +2422,34 @@ var builtins = map[string]*env.Builtin{ }, }, + "do\\par": { // ** + Argsn: 2, + Doc: "Takes a Context and a Block. It Does a block in current context but with parent a given Context.", + Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { + switch ctx := arg0.(type) { + case env.RyeCtx: + switch bloc := arg1.(type) { + case env.Block: + ser := ps.Ser + ps.Ser = bloc.Series + temp := ps.Ctx.Parent + ps.Ctx.Parent = &ctx + EvalBlock(ps) + ps.Ctx.Parent = temp + ps.Ser = ser + return ps.Res + default: + ps.ErrorFlag = true + return MakeArgError(ps, 2, []env.Type{env.BlockType}, "do-in") + } + default: + ps.ErrorFlag = true + return MakeArgError(ps, 1, []env.Type{env.CtxType}, "do-in") + } + + }, + }, + "capture-stdout": { // ** Argsn: 1, Doc: "Takes a block of code and does (runs) it.", @@ -2705,7 +2733,7 @@ var builtins = map[string]*env.Builtin{ // CONTEXT - "current-ctx": { // ** + "current-ctx": { // ** deprecated ... current from now on Argsn: 0, Doc: "Returns current context.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { @@ -2713,7 +2741,7 @@ var builtins = map[string]*env.Builtin{ }, }, - "current-ctx!!": { // ** + "current": { // ** Argsn: 0, Doc: "Returns current context.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { @@ -2721,7 +2749,7 @@ var builtins = map[string]*env.Builtin{ }, }, - "parent-ctx": { // ** + "parent": { // ** Argsn: 0, Doc: "Returns parent context of the current context.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { @@ -2934,7 +2962,7 @@ var builtins = map[string]*env.Builtin{ }, }, - "extend": { // ** exclamation mark, because it as it is now extends/changes the source context too .. in place + "extends": { // ** add one with exclamation mark, which it as it is now extends/changes the source context too .. in place Argsn: 2, Doc: "Extends a context with a new context in place and returns it.", Pure: false, @@ -2946,7 +2974,8 @@ var builtins = map[string]*env.Builtin{ ser := ps.Ser ctx := ps.Ctx ps.Ser = bloc.Series - ps.Ctx = ctx0.Copy() // make new context with no parent + // ps.Ctx = ctx0.Copy() // make new context with no parent + ps.Ctx = env.NewEnv(&ctx0) // make new context with no parent EvalBlock(ps) rctx := ps.Ctx ps.Ctx = ctx diff --git a/evaldo/builtins_math.go b/evaldo/builtins_math.go index c6a8b001..6d1afe3d 100644 --- a/evaldo/builtins_math.go +++ b/evaldo/builtins_math.go @@ -114,6 +114,17 @@ var Builtins_math = map[string]*env.Builtin{ return *env.NewDecimal(math.Mod(fa, fb)) }, }, + "pow": { + Argsn: 2, + Doc: "Return the power of", + Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { + fa, fb, errPos := assureFloats(arg0, arg1) + if errPos > 0 { + return MakeArgError(ps, errPos, []env.Type{env.IntegerType, env.BlockType}, "mod") + } + return *env.NewDecimal(math.Pow(fa, fb)) + }, + }, "log2": { Argsn: 1, Doc: "Return binary logarithm of x", @@ -128,6 +139,20 @@ var Builtins_math = map[string]*env.Builtin{ } }, }, + "sq": { + Argsn: 1, + Doc: "Return the sine of the radian argument.", + Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { + switch val := arg0.(type) { + case env.Integer: + return *env.NewDecimal(math.Pow(float64(val.Value), 2.0)) + case env.Decimal: + return *env.NewDecimal(math.Pow(val.Value, 2.0)) + default: + return MakeArgError(ps, 2, []env.Type{env.IntegerType, env.BlockType}, "mod") + } + }, + }, "sin": { Argsn: 1, Doc: "Return the sine of the radian argument.", @@ -398,6 +423,36 @@ var Builtins_math = map[string]*env.Builtin{ } }, }, + "round\\to": { + Argsn: 2, + Doc: "Round to a number of digits.", + Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { + switch val := arg0.(type) { + case env.Decimal: + switch precision := arg1.(type) { + case env.Integer: + ratio := math.Pow(10, float64(precision.Value)) + return env.NewDecimal(math.Round(val.Value*ratio) / ratio) + default: + return MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "dim") + } + default: + return MakeArgError(ps, 1, []env.Type{env.DecimalType}, "dim") + } + }, + }, + "round": { + Argsn: 1, + Doc: "Round to nearest integer.", + Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { + switch val := arg0.(type) { + case env.Decimal: + return env.NewDecimal(math.Round(val.Value)) + default: + return MakeArgError(ps, 1, []env.Type{env.DecimalType}, "dim") + } + }, + }, "erf": { Argsn: 1, Doc: "Returns the error function of value.", diff --git a/evaldo/builtins_spreadsheet.go b/evaldo/builtins_spreadsheet.go index 58c78f8a..2629628b 100644 --- a/evaldo/builtins_spreadsheet.go +++ b/evaldo/builtins_spreadsheet.go @@ -840,13 +840,25 @@ func GenerateColumn(ps *env.ProgramState, s env.Spreadsheet, name env.Word, extr switch w := word.(type) { case env.Word: val, er := s.GetRowValue(ps.Idx.GetWord(w.Index), row) + if val == nil { + val = "" + } + // fmt.Println(val) if er != nil { return nil } if firstVal == nil { - firstVal = val.(env.Object) + var ok bool + firstVal, ok = val.(env.Object) + if !ok { + firstVal = *env.NewString(val.(string)) + } + } + val1, ok := val.(env.Object) + if !ok { + val1 = *env.NewString(val.(string)) } - ctx.Set(w.Index, val.(env.Object)) + ctx.Set(w.Index, val1) } } // execute the block of code injected with first value diff --git a/evaldo/repl.go b/evaldo/repl.go index fcc1d269..2ef70b0a 100644 --- a/evaldo/repl.go +++ b/evaldo/repl.go @@ -214,6 +214,25 @@ func DoRyeRepl(es *env.ProgramState, dialect string, showResults bool) { // here EvalBlockInj(es, prevResult, true) } else if dialect == "eyr" { Eyr_EvalBlock(es, stack, true) + } else if dialect == "math" { + idxx, _ := es.Idx.GetIndex("math") + s1, ok := es.Ctx.Get(idxx) + if ok { + switch ss := s1.(type) { + case env.RyeCtx: /* */ + es.Ctx = &ss + // return s1 + } + } + res := DialectMath(es, block1) + switch block := res.(type) { + case env.Block: + stack := NewEyrStack() + ser := es.Ser + es.Ser = block.Series + Eyr_EvalBlock(es, stack, false) + es.Ser = ser + } } MaybeDisplayFailureOrError(es, genv)