here documents

master
Jordan Orelli 10 years ago
parent a100556004
commit edbb412a96

@ -2,6 +2,7 @@ package moon
import ( import (
"bufio" "bufio"
"bytes"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -260,6 +261,12 @@ func lexRoot(l *lexer) stateFn {
case r == '.': case r == '.':
l.keep(r) l.keep(r)
return lexAfterPeriod return lexAfterPeriod
case r == '<':
if l.peek() == '<' {
l.next()
return lexHeredocStart
}
fallthrough
case r == '@': case r == '@':
return lexVariable return lexVariable
case strings.IndexRune("+-0123456789", r) >= 0: case strings.IndexRune("+-0123456789", r) >= 0:
@ -477,6 +484,50 @@ func lexDuration(l *lexer) stateFn {
} }
} }
func lexHeredocStart(l *lexer) stateFn {
r := l.next()
switch {
case r == '\n':
if len(l.buf) == 0 {
return lexErrorf("illegal zero-width heredoc name")
}
label := string(l.buf)
l.buf = l.buf[0:0]
return lexHeredocBody(label)
case unicode.IsUpper(r):
l.keep(r)
return lexHeredocStart
case r == eof:
return lexErrorf("unexpected EOF in lexHeredocStart")
default:
return lexErrorf("unexpected rune in lexHeredocStart: %c (only uppercase letters are ok here)", r)
}
}
func lexHeredocBody(label string) stateFn {
var body bytes.Buffer
line := make([]rune, 0, 128)
return func(l *lexer) stateFn {
for {
r := l.next()
switch r {
case '\n':
if string(line) == label {
l.out <- token{t_string, string(body.Bytes())}
return lexRoot
}
body.WriteString(string(line))
line = line[0:0]
body.WriteRune(r)
case eof:
return lexErrorf("unexpected eof inside of heredoc %s", label)
default:
line = append(line, r)
}
}
}
}
func isAlphaNumeric(r rune) bool { func isAlphaNumeric(r rune) bool {
return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r)
} }

@ -0,0 +1,18 @@
a_doc: <<DOCUMENT
This is a here document!
You should be able to put anything in this at all!
# Even this thing that looks like a comment, it's not a comment!
WHEEEEEEEEEEEEEEEE
Even nested here docs should work!!!
nope: <<DIFFERENT
hahahahhaha
this is still part of the outer one
there is no inner here doc!
lololol
DIFFERENT
ok but we're done now
let's finish up here.
DOCUMENT
foo: bar

@ -0,0 +1,19 @@
{t_name a_doc}
{t_object_separator :}
{t_string This is a here document!
You should be able to put anything in this at all!
# Even this thing that looks like a comment, it's not a comment!
WHEEEEEEEEEEEEEEEE
Even nested here docs should work!!!
nope: <<DIFFERENT
hahahahhaha
this is still part of the outer one
there is no inner here doc!
lololol
DIFFERENT
ok but we're done now
let's finish up here.
}
{t_name foo}
{t_object_separator :}
{t_string bar}
Loading…
Cancel
Save