Skip to content

Commit

Permalink
start varaible block parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
jmoiron committed May 20, 2014
1 parent 50f1b98 commit 3353349
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 20 deletions.
20 changes: 20 additions & 0 deletions neo/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Node interface {
const (
NodeList NodeType = iota
NodeText
NodeVar
)

// ListNode holds a sequence of nodes.
Expand Down Expand Up @@ -82,3 +83,22 @@ func (t *TextNode) String() string {
func (t *TextNode) Copy() Node {
return &TextNode{NodeType: NodeText, Text: append([]byte{}, t.Text...)}
}

// VarNode represents a var print expr, ie {{ ... }}.
type VarNode struct {
NodeType
Pos
Expr Node // The expression node within this one
}

func newVar(pos Pos) *VarNode {
return &VarNode{NodeType: NodeVar, Pos: pos}
}

func (v *VarNode) String() string {
return fmt.Sprintf("{{ %s }}", v.Expr)
}

func (v *VarNode) Copy() Node {
return &VarNode{NodeType: NodeVar, Expr: v.Expr.Copy()}
}
77 changes: 67 additions & 10 deletions neo/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ func (t *Tree) peekNonSpace() (token item) {
return token
}

// expect peeks at the next non-space token, and if it is not itemType
// fails with an error. If it is, that item is returned and consumed.
func (t *Tree) expect(i itemType) (token item) {
token = t.peekNonSpace()
if token.typ != i {
t.unexpected(token, fmt.Sprint(i))
}
return t.nextNonSpace()
}

// Parsing.

// New allocates a new parse tree with the given name.
Expand Down Expand Up @@ -195,13 +205,10 @@ func (t *Tree) parse() (next Node) {
// the start of a {% .. %} tag block.
fmt.Println("Got BlockBegin")
continue
// delim := t.next()

case tokenVariableBegin:
// the start of a {{ .. }} variable print block.
fmt.Println("Got VariableBegin")
continue
// delim := t.next()
n = t.parseVar()

case tokenCommentBegin:
t.skipComment()
Expand Down Expand Up @@ -247,14 +254,11 @@ func (t *Tree) parseText() Node {
return nil
}

// Skips over a comment; commends are not represented in the final AST.
// Skips over a comment; comments are not represented in the final AST.
func (t *Tree) skipComment() {
token := t.next()
if token.typ != tokenCommentBegin {
t.unexpected(token, "begin comment")
}
t.expect(tokenCommentBegin)
for {
token = t.nextNonSpace()
token := t.nextNonSpace()
switch token.typ {
case tokenText:
continue
Expand All @@ -265,3 +269,56 @@ func (t *Tree) skipComment() {
break
}
}

// Parse a variable print expression, from tokenVariableBegin to tokenVariableEnd
func (t *Tree) parseVar() Node {
token := t.expect(tokenVariableBegin)
n := newVar(token.pos)
exprList := newList(token.pos)
for {
token := t.peekNonSpace()
switch token.typ {
case tokenName:
exprList.append(t.varExpr())
continue
case tokenLparen:
exprList.append(t.parenExpr())
continue
case tokenLbrace:
exprList.append(t.mapExpr())
continue
case tokenLbracket:
exprList.append(t.listExpr())
continue
case tokenGt, tokenGteq, tokenLt, tokenLteq, tokenEqEq:
t.unexpected(token, "unexpected boolean operator in var block")
case tokenVariableEnd:
t.nextNonSpace()
default:
t.unexpected(token, "end variable")
}
break
}
n.Expr = exprList
return n
}

func (t *Tree) varExpr() Node {
t.next()
return nil
}

func (t *Tree) parenExpr() Node {
t.next()
return nil
}

func (t *Tree) mapExpr() Node {
t.next()
return nil
}

func (t *Tree) listExpr() Node {
t.next()
return nil
}
48 changes: 38 additions & 10 deletions neo/parse_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
package jigo

import (
"fmt"
"testing"
)
import "testing"

func (n NodeType) String() string {
switch n {
case NodeList:
return "NodeList"
case NodeText:
return "NodeText"
case NodeVar:
return "NodeVar"
default:
return "Unknown Type"
}
}

type parseTest struct {
isError bool
output string
isError bool
nodeTypes []NodeType
}

type parsetest struct {
Expand Down Expand Up @@ -42,16 +52,34 @@ func (p *parsetest) Test(input string, test parseTest) {
t.Errorf("Unexpected error: %s\n", err)
}

fmt.Printf("Tree: %#v\n", tree.Root)
fmt.Printf("Tree: %s\n", tree.Root)
if len(test.nodeTypes) != len(tree.Root.Nodes) {
t.Errorf("Wrong number of nodes in %s\n", tree.Root)
t.Fatalf("Was expecting %d top level nodes, found %d", len(tree.Root.Nodes), len(test.nodeTypes))
}

for i, nt := range test.nodeTypes {
rnt := tree.Root.Nodes[i].Type()
if nt != rnt {
t.Errorf("Type mismatch: expecting %dth to be %s, but was %s", i, nt, rnt)
}
}
}

func TestParser(t *testing.T) {
tester := parsetest{t}
fmt.Println(tester)

tester.Test(
`Hello, World`,
parseTest{nodeTypes: []NodeType{NodeText}},
)

tester.Test(
`Hello, {# comment #}World`,
parseTest{isError: false},
parseTest{nodeTypes: []NodeType{NodeText, NodeText}},
)

tester.Test(
`Hello {{ name }}`,
parseTest{nodeTypes: []NodeType{NodeText, NodeVar}},
)
}

0 comments on commit 3353349

Please sign in to comment.