Introduce Bool type and Value.Bool method.

The "if" builtin now uses the Value.Bool method to determine trueness.
This commit is contained in:
Cheer Xiao 2015-01-21 23:50:40 +01:00
parent 27a625387e
commit 65e1e19846
3 changed files with 63 additions and 2 deletions

View File

@ -159,7 +159,7 @@ func each(ev *Evaluator, args []Value) Exitus {
}
// if takes a sequence of values and a trailing nullary closure. If all of the
// values are true (= are empty strings), the closure is executed.
// values are true, the closure is executed.
func ifFn(ev *Evaluator, args []Value) Exitus {
if len(args) == 0 {
return argsError
@ -170,7 +170,7 @@ func ifFn(ev *Evaluator, args []Value) Exitus {
return argsError
} else {
for _, a := range args[:len(args)-1] {
if a.String() != "" {
if !a.Bool() {
return success
}
}

View File

@ -52,6 +52,8 @@ func NewEvaluator() *Evaluator {
"env": valuePtr(env),
"pid": valuePtr(pid),
"success": valuePtr(success),
"true": valuePtr(Bool(true)),
"false": valuePtr(Bool(false)),
}
ev := &Evaluator{
Compiler: NewCompiler(),

View File

@ -40,6 +40,17 @@ func (st StringType) String() string {
return "string"
}
type BoolType struct {
}
func (bt BoolType) Default() Value {
return Bool(true)
}
func (bt BoolType) String() string {
return "bool"
}
type ExitusType struct {
}
@ -87,6 +98,7 @@ func (ct ClosureType) String() string {
var typenames = map[string]Type{
"string": StringType{},
"exitus": ExitusType{},
"bool": BoolType{},
"table": TableType{},
"env": EnvType{},
"closure": ClosureType{},
@ -102,6 +114,7 @@ type Value interface {
Type() Type
Repr() string
String() string
Bool() bool
}
func valuePtr(v Value) *Value {
@ -170,6 +183,36 @@ func (s String) String() string {
return string(s)
}
func (s String) Bool() bool {
return true
}
type Bool bool
func (b Bool) Type() Type {
return BoolType{}
}
func (b Bool) Repr() string {
if b {
return "$true"
} else {
return "$false"
}
}
func (b Bool) String() string {
if b {
return "true"
} else {
return "false"
}
}
func (b Bool) Bool() bool {
return bool(b)
}
type Exitus struct {
Success bool
Failure string
@ -201,6 +244,10 @@ func (e Exitus) String() string {
}
}
func (e Exitus) Bool() bool {
return e.Success
}
// Table is a list-dict hybrid.
//
// TODO(xiaq): The dict part use string keys. It should use Value keys instead.
@ -237,6 +284,10 @@ func (t *Table) String() string {
return t.Repr()
}
func (t *Table) Bool() bool {
return t.Bool()
}
func (t *Table) append(vs ...Value) {
t.List = append(t.List, vs...)
}
@ -287,6 +338,10 @@ func (e Env) String() string {
return e.Repr()
}
func (e Env) Bool() bool {
return true
}
// Closure is a closure.
type Closure struct {
ArgNames []string
@ -310,6 +365,10 @@ func (c *Closure) String() string {
return c.Repr()
}
func (c *Closure) Bool() bool {
return true
}
func evalSubscript(ev *Evaluator, left, right Value, lp, rp parse.Pos) Value {
var (
sub String