add boolean type

master
Jordan Orelli 10 years ago
parent 37feb9336a
commit 9da5f572ee

@ -24,6 +24,15 @@ The following is taken to be the contents of a file named ex.moon:
first_name: jordan first_name: jordan
last_name: orelli last_name: orelli
# the bare strings true and false are boolean values
bool_true: true
bool_false: false
# the quoted strings "true" and "false" are string values. In the unlikely
# event you need literal true and false strings, quote them.
string_true: "true"
string_false: "false"
# lists of things should be supported # lists of things should be supported
items: [ items: [
one one
@ -66,7 +75,6 @@ The following is taken to be the contents of a file named ex.moon:
people: [@person_one @person_two] people: [@person_one @person_two]
Subcommands Subcommands
check: used to syntax check a given file. To check a given file, in this case ex.moon, to see if it is syntactically valid, one would invoke the following command: check: used to syntax check a given file. To check a given file, in this case ex.moon, to see if it is syntactically valid, one would invoke the following command:

@ -12,6 +12,15 @@
first_name: jordan first_name: jordan
last_name: orelli last_name: orelli
# the bare strings true and false are boolean values
bool_true: true
bool_false: false
# the quoted strings "true" and "false" are string values. In the unlikely
# event you need literal true and false strings, quote them.
string_true: "true"
string_false: "false"
# lists of things should be supported # lists of things should be supported
items: [ items: [
one one

@ -89,28 +89,7 @@ func setValue(dest, src reflect.Value) error {
dest.Set(src) dest.Set(src)
return nil return nil
} }
switch dest.Kind() { return fmt.Errorf("src and destination are not of same type. src type: %s, dest type: %s", src.Type().Name(), dest.Type().Name())
case reflect.Bool:
setBoolValue(dest, src)
return nil
default:
return fmt.Errorf("src and destination are not of same type. src type: %s, dest type: %s", src.Type().Name(), dest.Type().Name())
}
}
func setBoolValue(dest, src reflect.Value) error {
switch src.Kind() {
case reflect.String:
s := src.String()
if s == "false" { // lol
dest.Set(reflect.ValueOf(false))
return nil
}
dest.Set(reflect.ValueOf(true))
return nil
default:
return fmt.Errorf("dunno how to set a bool with that damned value")
}
} }
// Fill takes the raw values from the moon document and assigns them to the // Fill takes the raw values from the moon document and assigns them to the
@ -165,6 +144,8 @@ func (d *Doc) Fill(dest interface{}) error {
return nil return nil
} }
// NoValue is the error type returned when attempting to get a value from a
// moon doc that isn't found.
type NoValue struct { type NoValue struct {
fullpath string fullpath string
relpath string relpath string

@ -41,6 +41,8 @@ func (t tokenType) String() string {
return "t_imaginary_number" return "t_imaginary_number"
case t_variable: case t_variable:
return "t_variable" return "t_variable"
case t_bool:
return "t_bool"
default: default:
panic(fmt.Sprintf("unknown token type: %v", t)) panic(fmt.Sprintf("unknown token type: %v", t))
} }
@ -49,7 +51,8 @@ func (t tokenType) String() string {
const ( const (
t_error tokenType = iota // a stored lex error t_error tokenType = iota // a stored lex error
t_eof // end of file token t_eof // end of file token
t_string // a string literal t_string // a bare string
t_string_quoted // a quoted string
t_name // a name t_name // a name
t_comment // a comment t_comment // a comment
t_list_start // [ t_list_start // [
@ -60,6 +63,7 @@ const (
t_real_number // a number t_real_number // a number
t_imaginary_number // an imaginary number t_imaginary_number // an imaginary number
t_variable // e.g. @var_name, a variable name. t_variable // e.g. @var_name, a variable name.
t_bool // a boolean token (true|false)
) )
type stateFn func(*lexer) stateFn type stateFn func(*lexer) stateFn
@ -143,6 +147,13 @@ func (l *lexer) emit(t tokenType) {
msg := fmt.Sprintf(`invalid name: "%s" (names cannot contain spaces)`, string(l.buf)) msg := fmt.Sprintf(`invalid name: "%s" (names cannot contain spaces)`, string(l.buf))
l.out <- token{t_error, msg} l.out <- token{t_error, msg}
return return
case t_string:
switch string(l.buf) {
case "true", "false":
t = t_bool
}
case t_string_quoted:
t = t_string
} }
l.out <- token{t, string(l.buf)} l.out <- token{t, string(l.buf)}
l.buf = l.buf[0:0] l.buf = l.buf[0:0]
@ -292,7 +303,7 @@ func lexQuotedString(delim rune) stateFn {
return func(l *lexer) stateFn { return func(l *lexer) stateFn {
switch r := l.next(); r { switch r := l.next(); r {
case delim: case delim:
l.emit(t_string) l.emit(t_string_quoted)
return lexRoot return lexRoot
case '\\': case '\\':
switch r := l.next(); r { switch r := l.next(); r {

@ -22,6 +22,7 @@ const (
n_list n_list
n_object n_object
n_variable n_variable
n_bool
) )
var indent = " " var indent = " "
@ -476,3 +477,34 @@ func (v *variableNode) eval(ctx *context) (interface{}, error) {
} }
return value, nil return value, nil
} }
type boolNode bool
func (b *boolNode) Type() nodeType {
return n_bool
}
func (b *boolNode) parse(p *parser) error {
t := p.next()
if t.t != t_bool {
return fmt.Errorf("unexpected %s token while parsing bool", t.t)
}
switch t.s {
case "true":
*b = true
case "false":
default:
return fmt.Errorf("illegal lexeme for bool token: %s", t.s)
}
return nil
}
func (b *boolNode) pretty(w io.Writer, prefix string) error {
fmt.Fprintf(w, "%sbool:\n", prefix)
fmt.Fprintf(w, "%s%t\n", prefix+indent, *b)
return nil
}
func (b *boolNode) eval(ctx *context) (interface{}, error) {
return bool(*b), nil
}

@ -153,6 +153,12 @@ func (p *parser) parseValue() (node, error) {
return nil, err return nil, err
} }
return n, nil return n, nil
case t_bool:
n := new(boolNode)
if err := n.parse(p); err != nil {
return nil, err
}
return n, nil
default: default:
return nil, fmt.Errorf("parse error: unexpected %v token while looking for value", t.t) return nil, fmt.Errorf("parse error: unexpected %v token while looking for value", t.t)
} }

@ -0,0 +1,4 @@
true
false
"true"
"false"

@ -0,0 +1,4 @@
{t_bool true}
{t_bool false}
{t_string true}
{t_string false}

@ -0,0 +1,4 @@
b_t: true
b_f: false
s_t: "true"
s_f: "false"

@ -0,0 +1,25 @@
root:
assign:
name:
b_t
value:
bool:
true
assign:
name:
b_f
value:
bool:
false
assign:
name:
s_t
value:
string:
true
assign:
name:
s_f
value:
string:
false
Loading…
Cancel
Save