Skip to content
Permalink
Browse files

Take care of some TODOs and intern NullValue into a const

  • Loading branch information
thesephist committed Mar 1, 2020
1 parent a7f50eb commit e91dd54627056751fdc3aa823ee379bd016d5b59
Showing with 35 additions and 34 deletions.
  1. +15 −11 pkg/ink/eval.go
  2. +20 −23 pkg/ink/runtime.go
@@ -24,9 +24,9 @@ type Value interface {
}

func isIntable(n NumberValue) bool {
// XXX: not the most reliable check for int because of int64 range
// limitations, but works for now until we nail down Ink's number
// spec more rigorously
// Note: this returns false for int64 outside of the float64 range,
// but that's ok since isIntable is used to check before ops that will
// convert values to float64's (NumberValues) anyway
return n == NumberValue(int64(n))
}

@@ -83,7 +83,8 @@ type StringValue []byte
func (v StringValue) String() string {
return "'" + strings.ReplaceAll(
strings.ReplaceAll(string(v), "\\", "\\\\"),
"'", "\\'") + "'"
"'", "\\'",
) + "'"
}

func (v StringValue) Equals(other Value) bool {
@@ -123,7 +124,10 @@ func (v BooleanValue) Equals(other Value) bool {

// NullValue is a value that only exists at the type level,
// and is represented by the empty expression list `()`.
type NullValue struct{}
type NullValue byte

// The singleton Null value is interned into a single value
const Null = NullValue(0)

func (v NullValue) String() string {
return "()"
@@ -210,7 +214,7 @@ type FunctionCallThunkValue struct {
}

func (v FunctionCallThunkValue) String() string {
return fmt.Sprintf("Tail Call Thunk of (%s)", v.function)
return fmt.Sprintf("Thunk of (%s)", v.function)
}

func (v FunctionCallThunkValue) Equals(other Value) bool {
@@ -433,7 +437,7 @@ func (n BinaryExprNode) Eval(frame *StackFrame, allowThunk bool) (Value, error)
return v, nil
}

return NullValue{}, nil
return Null, nil
} else if leftString, isString := leftValue.(StringValue); isString {
rightNum, err := strconv.ParseInt(rightValueStr, 10, 64)
if err != nil {
@@ -449,7 +453,7 @@ func (n BinaryExprNode) Eval(frame *StackFrame, allowThunk bool) (Value, error)
return StringValue([]byte{leftString[rn]}), nil
}

return NullValue{}, nil
return Null, nil
} else {
return nil, Err{
ErrRuntime,
@@ -754,14 +758,14 @@ func (n MatchExprNode) Eval(frame *StackFrame, allowThunk bool) (Value, error) {
}
}

return NullValue{}, nil
return Null, nil
}

func (n ExpressionListNode) Eval(frame *StackFrame, allowThunk bool) (Value, error) {
length := len(n.expressions)

if length == 0 {
return NullValue{}, nil
return Null, nil
}

callFrame := &StackFrame{
@@ -870,7 +874,7 @@ func (frame *StackFrame) Get(name string) (Value, bool) {
frame = frame.parent
}

return NullValue{}, false
return Null, false
}

// Set a value to the most recent call stack frame
@@ -172,9 +172,6 @@ func inkIn(ctx *Context, in []Value) (Value, error) {
ctx.ExecListener(func() {
reader := bufio.NewReader(os.Stdin)
for {
// XXX: currently reads after every newline / return
// but should ideally read every character input / keystroke
// that would also require stdlib/scan() to change.
str, err := reader.ReadString('\n')
if err != nil {
// also captures io.EOF
@@ -212,14 +209,14 @@ func inkIn(ctx *Context, in []Value) (Value, error) {
}
})

return NullValue{}, nil
return Null, nil
}

func inkOut(ctx *Context, in []Value) (Value, error) {
if len(in) >= 1 {
if output, ok := in[0].(StringValue); ok {
os.Stdout.Write([]byte(output))
return NullValue{}, nil
return Null, nil
}
}

@@ -300,7 +297,7 @@ func inkDir(ctx *Context, in []Value) (Value, error) {
})
}()

return NullValue{}, nil
return Null, nil
}

func inkMake(ctx *Context, in []Value) (Value, error) {
@@ -362,7 +359,7 @@ func inkMake(ctx *Context, in []Value) (Value, error) {
})
}()

return NullValue{}, nil
return Null, nil
}

func inkStat(ctx *Context, in []Value) (Value, error) {
@@ -419,7 +416,7 @@ func inkStat(ctx *Context, in []Value) (Value, error) {
ctx.ExecListener(func() {
_, err := evalInkFunction(cb, false, CompositeValue{
"type": StringValue("data"),
"data": NullValue{},
"data": Null,
})
cbMaybeErr(err)
})
@@ -448,7 +445,7 @@ func inkStat(ctx *Context, in []Value) (Value, error) {
})
}()

return NullValue{}, nil
return Null, nil
}

func inkRead(ctx *Context, in []Value) (Value, error) {
@@ -546,7 +543,7 @@ func inkRead(ctx *Context, in []Value) (Value, error) {
})
}()

return NullValue{}, nil
return Null, nil
}

func inkWrite(ctx *Context, in []Value) (Value, error) {
@@ -639,7 +636,7 @@ func inkWrite(ctx *Context, in []Value) (Value, error) {
})
}()

return NullValue{}, nil
return Null, nil
}

func inkDelete(ctx *Context, in []Value) (Value, error) {
@@ -702,7 +699,7 @@ func inkDelete(ctx *Context, in []Value) (Value, error) {
})
}()

return NullValue{}, nil
return Null, nil
}

// inkHTTPHandler fulfills the Handler interface for inkListen() to work
@@ -768,7 +765,7 @@ func (h inkHTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
responseEnded = true
responses <- in[0]

return NullValue{}, nil
return Null, nil
}

ctx.ExecListener(func() {
@@ -881,7 +878,7 @@ func inkListen(ctx *Context, in []Value) (Value, error) {
name: "close",
exec: func(ctx *Context, in []Value) (Value, error) {
// fake close callback
return NullValue{}, nil
return Null, nil
},
ctx: ctx,
}, nil
@@ -929,7 +926,7 @@ func inkListen(ctx *Context, in []Value) (Value, error) {
}
}()

return NullValue{}, nil
return Null, nil
}

return NativeFunctionValue{
@@ -962,7 +959,7 @@ func inkReq(ctx *Context, in []Value) (Value, error) {
name: "close",
exec: func(ctx *Context, in []Value) (Value, error) {
// fake close callback
return NullValue{}, nil
return Null, nil
},
ctx: ctx,
}, nil
@@ -978,7 +975,7 @@ func inkReq(ctx *Context, in []Value) (Value, error) {

closer := func(ctx *Context, in []Value) (Value, error) {
reqCancel()
return NullValue{}, nil
return Null, nil
}

sendErr := func(msg string) {
@@ -1128,7 +1125,7 @@ func inkUrand(ctx *Context, in []Value) (Value, error) {
buf := make([]byte, int64(float64(bufLength)))
_, err := crand.Read(buf)
if err != nil {
return NullValue{}, nil
return Null, nil
}

return StringValue(buf), nil
@@ -1178,7 +1175,7 @@ func inkWait(ctx *Context, in []Value) (Value, error) {
})
}()

return NullValue{}, nil
return Null, nil
}

func inkExec(ctx *Context, in []Value) (Value, error) {
@@ -1247,7 +1244,7 @@ func inkExec(ctx *Context, in []Value) (Value, error) {
exec: func(ctx *Context, in []Value) (Value, error) {
// fake close callback
closed = true
return NullValue{}, nil
return Null, nil
},
ctx: ctx,
}, nil
@@ -1336,7 +1333,7 @@ func inkExec(ctx *Context, in []Value) (Value, error) {
exec: func(ctx *Context, in []Value) (Value, error) {
// multiple calls to close() should be idempotent
if closed {
return NullValue{}, nil
return Null, nil
}

neverRun <- true
@@ -1348,7 +1345,7 @@ func inkExec(ctx *Context, in []Value) (Value, error) {
}
cmdMutex.Unlock()

return NullValue{}, nil
return Null, nil
},
ctx: ctx,
}, nil
@@ -1558,7 +1555,7 @@ func inkNumber(ctx *Context, in []Value) (Value, error) {
case StringValue:
f, err := strconv.ParseFloat(string(v), 64)
if err != nil {
return NullValue{}, nil
return Null, nil
}
return NumberValue(f), nil
case NumberValue:

0 comments on commit e91dd54

Please sign in to comment.
You can’t perform that action at this time.