lex variables

variables are done with a sigil now.  I picked the @ symbol because I
can find it on the keyboard without looking.  The $ is a little too far
away.  Also php is terrible.
master
Jordan Orelli 10 years ago
parent 9591212531
commit bbc5e45d13

@ -39,6 +39,8 @@ func (t tokenType) String() string {
return "t_real_number" return "t_real_number"
case t_imaginary_number: case t_imaginary_number:
return "t_imaginary_number" return "t_imaginary_number"
case t_variable:
return "t_variable"
default: default:
panic(fmt.Sprintf("unknown token type: %v", t)) panic(fmt.Sprintf("unknown token type: %v", t))
} }
@ -57,6 +59,7 @@ const (
t_object_separator // : t_object_separator // :
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.
) )
type stateFn func(*lexer) stateFn type stateFn func(*lexer) stateFn
@ -217,6 +220,8 @@ func lexRoot(l *lexer) stateFn {
case r == '.': case r == '.':
l.keep(r) l.keep(r)
return lexAfterPeriod return lexAfterPeriod
case r == '@':
return lexVariable
case strings.IndexRune("+-0123456789", r) >= 0: case strings.IndexRune("+-0123456789", r) >= 0:
l.unread(r) l.unread(r)
return lexNumber return lexNumber
@ -283,30 +288,62 @@ func lexQuotedString(delim rune) stateFn {
func lexNameOrString(l *lexer) stateFn { func lexNameOrString(l *lexer) stateFn {
r := l.next() r := l.next()
switch { switch r {
case r == '\n', r == ';': case '\n', ';':
l.emit(t_string) l.emit(t_string)
return lexRoot return lexRoot
case r == ':': case ':':
l.emit(t_name) l.emit(t_name)
l.keep(r) l.keep(r)
l.emit(t_object_separator) l.emit(t_object_separator)
return lexRoot return lexRoot
case r == '\\': case '\\':
rr := l.next() rr := l.next()
if rr == eof { if rr == eof {
return lexErrorf("unexpected eof in string or name") return lexErrorf("unexpected eof in string or name")
} }
l.keep(rr) l.keep(rr)
return lexNameOrString return lexNameOrString
case r == '#': case '#':
return lexComment return lexComment
case eof:
l.emit(t_string)
return nil
default: default:
l.keep(r) l.keep(r)
return lexNameOrString return lexNameOrString
} }
} }
func lexVariable(l *lexer) stateFn {
r := l.next()
switch r {
case '\n', ';':
l.emit(t_variable)
return lexRoot
case ':':
l.emit(t_variable)
l.keep(r)
l.emit(t_object_separator)
return lexRoot
case '\\':
rr := l.next()
if rr == eof {
return lexErrorf("unexpected eof in variable name")
}
l.keep(rr)
return lexVariable
case '#':
return lexComment
case eof:
l.emit(t_variable)
return nil
default:
l.keep(r)
return lexVariable
}
}
func lexNumber(l *lexer) stateFn { func lexNumber(l *lexer) stateFn {
l.accept("+-") l.accept("+-")
digits := "0123456789" digits := "0123456789"

@ -0,0 +1,8 @@
key_one: this is the first value
key_two: @key_one
@variable_key: that key is not exported, it's only valid as a variable inside of moon itself
key_three: @variable_key

@ -0,0 +1,12 @@
{t_name key_one}
{t_object_separator :}
{t_string this is the first value}
{t_name key_two}
{t_object_separator :}
{t_variable key_one}
{t_variable variable_key}
{t_object_separator :}
{t_string that key is not exported, it's only valid as a variable inside of moon itself}
{t_name key_three}
{t_object_separator :}
{t_variable variable_key}
Loading…
Cancel
Save