Skip to content

Commit

Permalink
adding Unwrap on all object types so we can also add sprintf and pass…
Browse files Browse the repository at this point in the history
… the variadic any args to it
  • Loading branch information
ldemailly committed Aug 3, 2024
1 parent d359644 commit 7d759b8
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
10 changes: 10 additions & 0 deletions eval/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,4 +770,14 @@ func TestExtension(t *testing.T) {
input = `round(2.7)`
evaluated = testEval(t, input)
testFloatObject(t, evaluated, 3)
input = `sprintf("%d %s %g", 42, "ab\ncd", pow(2, 43))`
evaluated = testEval(t, input)
expected = "42 ab\ncd 8.796093022208e+12" // might be brittle the %g output of float64.
actual, ok := evaluated.(object.String)
if !ok {
t.Errorf("object is not string. got=%T (%+v)", evaluated, evaluated)
}
if actual.Value != expected {
t.Errorf("object has wrong value. got=%q, want=%q", actual, expected)
}
}
16 changes: 16 additions & 0 deletions extensions/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package extensions

import (
"fmt"
"math"

"grol.io/grol/object"
Expand Down Expand Up @@ -36,6 +37,16 @@ func initInternal() error {
if err != nil {
return err
}
err = object.CreateFunction(object.Extension{
Name: "sprintf",
MinArgs: 1,
MaxArgs: -1,
ArgTypes: []object.Type{object.STRING},
Callback: sprintf,
})
if err != nil {
return err
}
oneFloat := object.Extension{
MinArgs: 1,
MaxArgs: 1,
Expand Down Expand Up @@ -79,3 +90,8 @@ func pow(args []object.Object) object.Object {
result := math.Pow(base, exp)
return object.Float{Value: result}
}

func sprintf(args []object.Object) object.Object {
res := fmt.Sprintf(args[0].(object.String).Value, object.Unwrap(args[1:])...)
return object.String{Value: res}
}
8 changes: 8 additions & 0 deletions object/interp.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,11 @@ func CreateFunction(cmd Extension) error {
func ExtraFunctions() map[string]Extension {
return extraFunctions
}

func Unwrap(objs []Object) []any {
res := make([]any, len(objs))
for i, o := range objs {
res[i] = o.Unwrap()
}
return res
}
44 changes: 39 additions & 5 deletions object/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Type uint8
type Object interface {
Type() Type
Inspect() string
Unwrap() any
}

const (
Expand Down Expand Up @@ -120,6 +121,10 @@ func (i Integer) Inspect() string {
return strconv.FormatInt(i.Value, 10)
}

func (i Integer) Unwrap() any {
return i.Value
}

func (i Integer) Type() Type {
return INTEGER
}
Expand All @@ -128,6 +133,10 @@ type Float struct {
Value float64
}

func (f Float) Unwrap() any {
return f.Value
}

func (f Float) Type() Type {
return FLOAT
}
Expand All @@ -140,6 +149,10 @@ type Boolean struct {
Value bool
}

func (b Boolean) Unwrap() any {
return b.Value
}

func (b Boolean) Type() Type {
return BOOLEAN
}
Expand All @@ -152,6 +165,10 @@ type String struct {
Value string
}

func (s String) Unwrap() any {
return s.Value
}

func (s String) Type() Type {
return STRING
}
Expand All @@ -162,20 +179,24 @@ func (s String) Inspect() string {

type Null struct{}

func (n Null) Unwrap() any { return nil }
func (n Null) Type() Type { return NIL }
func (n Null) Inspect() string { return "nil" }

type Error struct {
Value string // message
}

func (e Error) Unwrap() any { return e }
func (e Error) Error() string { return e.Value }
func (e Error) Type() Type { return ERROR }
func (e Error) Inspect() string { return "<err: " + e.Value + ">" }

type ReturnValue struct {
Value Object
}

func (rv ReturnValue) Unwrap() any { return rv.Value }
func (rv ReturnValue) Type() Type { return RETURN }
func (rv ReturnValue) Inspect() string { return rv.Value.Inspect() }

Expand All @@ -198,7 +219,8 @@ func WriteStrings(out *strings.Builder, list []Object, before, sep, after string
out.WriteString(after)
}

func (f Function) Type() Type { return FUNC }
func (f Function) Unwrap() any { return f }
func (f Function) Type() Type { return FUNC }

// Must be called after the function is fully initialized.
// Whether a function result should be cached doesn't depend on the Name,
Expand Down Expand Up @@ -235,7 +257,8 @@ type Array struct {
Elements []Object
}

func (ao Array) Type() Type { return ARRAY }
func (ao Array) Unwrap() any { return Unwrap(ao.Elements) }
func (ao Array) Type() Type { return ARRAY }
func (ao Array) Inspect() string {
out := strings.Builder{}
WriteStrings(&out, ao.Elements, "[", ",", "]")
Expand Down Expand Up @@ -290,6 +313,14 @@ func (mk MapKeys) Swap(i, j int) {
mk[i], mk[j] = mk[j], mk[i]
}

func (m Map) Unwrap() any {
res := make(map[any]any, len(m))
for k, v := range m {
res[k.Unwrap()] = v.Unwrap()
}
return res
}

func (m Map) Type() Type { return MAP }

func (m Map) Inspect() string {
Expand Down Expand Up @@ -318,7 +349,8 @@ type Quote struct {
Node ast.Node
}

func (q Quote) Type() Type { return QUOTE }
func (q Quote) Unwrap() any { return q.Node }
func (q Quote) Type() Type { return QUOTE }
func (q Quote) Inspect() string {
out := strings.Builder{}
out.WriteString("quote(")
Expand All @@ -333,7 +365,8 @@ type Macro struct {
Env *Environment
}

func (m Macro) Type() Type { return MACRO }
func (m Macro) Unwrap() any { return m }
func (m Macro) Type() Type { return MACRO }
func (m Macro) Inspect() string {
out := strings.Builder{}
out.WriteString("macro(")
Expand Down Expand Up @@ -374,7 +407,8 @@ func (e *Extension) Usage(out *strings.Builder) {
}
}

func (e Extension) Type() Type { return EXTENSION }
func (e Extension) Unwrap() any { return e }
func (e Extension) Type() Type { return EXTENSION }
func (e Extension) Inspect() string {
out := strings.Builder{}
out.WriteString(e.Name)
Expand Down

0 comments on commit 7d759b8

Please sign in to comment.