Skip to content

Commit

Permalink
Merge pull request #372 from refaktor/allin
Browse files Browse the repository at this point in the history
added ref and deref builtins
  • Loading branch information
refaktor authored Oct 7, 2024
2 parents 531fd8f + e7c8a68 commit 2dc5f1e
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 18 deletions.
9 changes: 1 addition & 8 deletions env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package env

import (
"fmt"
"reflect"
"sort"
"strings"
"sync"
Expand All @@ -15,12 +14,6 @@ import (
Set(word int, val Object) Object
} */

// UTIL

func IsPointer(v interface{}) bool {
return reflect.TypeOf(v).Kind() == reflect.Ptr
}

// This is experimental env without map for Functions with up to two variables

type EnvR2 struct {
Expand Down Expand Up @@ -339,7 +332,7 @@ func NewProgramState(ser TSeries, idx *Idxs) *ProgramState {
"",
"",
false,
NewLiveEnv(),
nil, // NewLiveEnv(),
Rye2Dialect,
NewEyrStack(),
}
Expand Down
20 changes: 20 additions & 0 deletions env/envutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package env

import (
"fmt"
"reflect"
"time"
)

Expand Down Expand Up @@ -39,3 +40,22 @@ func ToRyeValue(val any) Object {
return Void{}
}
}

func IsPointer(x any) bool {
return reflect.TypeOf(x).Kind() == reflect.Pointer
}

func IsPointer2(x reflect.Value) bool {
return x.Kind() == reflect.Ptr
}

func DereferenceAny(x any) any {
if reflect.TypeOf(x).Kind() == reflect.Ptr {
return reflect.ValueOf(x).Elem().Interface()
}
return x
}

func ReferenceAny(x any) any {
return &x
}
6 changes: 5 additions & 1 deletion env/spreadsheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,11 @@ func (s SpreadsheetRow) GetKind() int {

// Inspect returns a string
func (s SpreadsheetRow) Inspect(e Idxs) string {
return "[SpreadsheetRow(" + strconv.Itoa(len(s.Values)) + ")" + "]"
p := ""
if IsPointer(s) {
p = "REF:"
}
return "[" + p + "SpreadsheetRow(" + strconv.Itoa(len(s.Values)) + ")" + "]"
}

// Inspect returns a string representation of the Integer.
Expand Down
71 changes: 70 additions & 1 deletion evaldo/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,33 @@ var builtins = map[string]*env.Builtin{
return &sp
case env.Block:
return &sp
case env.Native:
return &sp
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "thaw")
}
},
},

"ref": { // temp duplicate
Argsn: 1,
Doc: "Makes a value (currently only spreadsheets) mutable instead of immutable",
Pure: true,
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch sp := arg0.(type) {
case env.Spreadsheet:
return &sp
case *env.Spreadsheet:
return sp
case env.Dict:
return &sp
case env.List:
return &sp
case env.Block:
return &sp
case env.Native:
sp.Value = env.ReferenceAny(sp.Value)
return &sp
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "thaw")
}
Expand Down Expand Up @@ -863,6 +890,31 @@ var builtins = map[string]*env.Builtin{
},
},

"deref": { // TEMP duplicate
Argsn: 1,
Doc: "Makes a value (currently only spreadsheets) again immutable",
Pure: true,
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch sp := arg0.(type) {
case env.Spreadsheet:
return sp
case *env.Spreadsheet:
return *sp
case *env.Dict:
return *sp
case *env.List:
return *sp
case *env.Block:
return *sp
case *env.Native:
sp.Value = env.DereferenceAny(sp.Value)
return *sp
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "thaw")
}
},
},

"get_": { // *** find a name or decide on order of naming with generic words clashes with
Argsn: 1,
Doc: "Returns value of the word in context",
Expand Down Expand Up @@ -1698,7 +1750,11 @@ var builtins = map[string]*env.Builtin{
Argsn: 1,
Doc: "Prints information about a value.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
fmt.Println(arg0.Inspect(*ps.Idx))
p := ""
if env.IsPointer(arg0) {
p = "REF:"
}
fmt.Println(p + arg0.Inspect(*ps.Idx))
return arg0
},
},
Expand All @@ -1709,6 +1765,19 @@ var builtins = map[string]*env.Builtin{
return *env.NewString(arg0.Inspect(*ps.Idx))
},
},
"is-ref": { // **
Argsn: 1,
Doc: "Prints information about a value.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
// fmt.Println(arg0.Inspect(*ps.Idx))
if env.IsPointer(arg0) {
return env.NewInteger(1)
} else {
return env.NewInteger(0)
}
},
},

"esc": {
Argsn: 1,
Doc: "Creates an escape sequence \033{}",
Expand Down
6 changes: 5 additions & 1 deletion evaldo/repl.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,15 @@ func (r *Repl) evalLine(es *env.ProgramState, code string) string {

if !es.ErrorFlag && es.Res != nil {
r.prevResult = es.Res
p := ""
if env.IsPointer(es.Res) {
p = "Ref"
}
resultStr := es.Res.Inspect(*genv)
if r.dialect == "eyr" {
resultStr = strings.Replace(resultStr, "Block:", "Stack:", 1) // TODO --- temp / hackish way ... make stack display itself or another approach
}
output = fmt.Sprintf("\033[38;5;37m" + resultStr + "\x1b[0m")
output = fmt.Sprintf("\033[38;5;37m" + p + resultStr + "\x1b[0m")
}

es.ReturnFlag = false
Expand Down
19 changes: 12 additions & 7 deletions tests/main.rye
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; Run test cases: ../rye main.rye test
; Generate documentation: ../rye main.rye doc > builtins.html

rye .args\raw :arg
rye .args\raw |load :args
root-ctx: current-ctx

test-framework: context {
Expand Down Expand Up @@ -85,14 +85,19 @@ generate-doc-file: fn { filename menu } {

menu: { "basics" "structures" "validation" "misc" "spreadsheet_mutations" }

switch arg {
"test" {
switch first args {
test {
errors: 0
for menu { + ".rye" |to-file |probe |probe |load |do\in* test-framework |+ errors ::errors }
print "==============="
print "FAILED TESTS: " + errors
either args .length? = 1 {
for menu { + ".rye" |to-file |load |do\in* test-framework |+ errors ::errors }
} {

args .second + ".rye" |to-file |load |do\in* test-framework |+ errors ::errors
}
print "==================="
print " FAILED TESTS: " + errors
}
"doc" {
doc {
for menu { .generate-doc-file menu }
}
_ { print "use test or doc command" }
Expand Down

0 comments on commit 2dc5f1e

Please sign in to comment.