summaryrefslogtreecommitdiff
path: root/src/pkg/exp/template/parse/node.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/exp/template/parse/node.go')
-rw-r--r--src/pkg/exp/template/parse/node.go468
1 files changed, 0 insertions, 468 deletions
diff --git a/src/pkg/exp/template/parse/node.go b/src/pkg/exp/template/parse/node.go
deleted file mode 100644
index 0f77ad850..000000000
--- a/src/pkg/exp/template/parse/node.go
+++ /dev/null
@@ -1,468 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parse nodes.
-
-package parse
-
-import (
- "bytes"
- "fmt"
- "os"
- "strconv"
- "strings"
-)
-
-// A node is an element in the parse tree. The interface is trivial.
-type Node interface {
- Type() NodeType
- String() string
-}
-
-// NodeType identifies the type of a parse tree node.
-type NodeType int
-
-// Type returns itself and provides an easy default implementation
-// for embedding in a Node. Embedded in all non-trivial Nodes.
-func (t NodeType) Type() NodeType {
- return t
-}
-
-const (
- NodeText NodeType = iota // Plain text.
- NodeAction // An simple action such as field evaluation.
- NodeBool // A boolean constant.
- NodeCommand // An element of a pipeline.
- NodeDot // The cursor, dot.
- NodeElse // An else action.
- NodeEnd // An end action.
- NodeField // A field or method name.
- NodeIdentifier // A identifier; always a function name.
- NodeIf // An if action.
- NodeList // A list of Nodes.
- NodeNumber // A numerical constant.
- NodePipe // A pipeline of commands.
- NodeRange // A range action.
- NodeString // A string constant.
- NodeTemplate // A template invocation action.
- NodeVariable // A $ variable.
- NodeWith // A with action.
-)
-
-// Nodes.
-
-// ListNode holds a sequence of nodes.
-type ListNode struct {
- NodeType
- Nodes []Node // The element nodes in lexical order.
-}
-
-func newList() *ListNode {
- return &ListNode{NodeType: NodeList}
-}
-
-func (l *ListNode) append(n Node) {
- l.Nodes = append(l.Nodes, n)
-}
-
-func (l *ListNode) String() string {
- b := new(bytes.Buffer)
- fmt.Fprint(b, "[")
- for _, n := range l.Nodes {
- fmt.Fprint(b, n)
- }
- fmt.Fprint(b, "]")
- return b.String()
-}
-
-// TextNode holds plain text.
-type TextNode struct {
- NodeType
- Text []byte // The text; may span newlines.
-}
-
-func newText(text string) *TextNode {
- return &TextNode{NodeType: NodeText, Text: []byte(text)}
-}
-
-func (t *TextNode) String() string {
- return fmt.Sprintf("(text: %q)", t.Text)
-}
-
-// PipeNode holds a pipeline with optional declaration
-type PipeNode struct {
- NodeType
- Line int // The line number in the input.
- Decl []*VariableNode // Variable declarations in lexical order.
- Cmds []*CommandNode // The commands in lexical order.
-}
-
-func newPipeline(line int, decl []*VariableNode) *PipeNode {
- return &PipeNode{NodeType: NodePipe, Line: line, Decl: decl}
-}
-
-func (p *PipeNode) append(command *CommandNode) {
- p.Cmds = append(p.Cmds, command)
-}
-
-func (p *PipeNode) String() string {
- if p.Decl != nil {
- return fmt.Sprintf("%v := %v", p.Decl, p.Cmds)
- }
- return fmt.Sprintf("%v", p.Cmds)
-}
-
-// ActionNode holds an action (something bounded by delimiters).
-// Control actions have their own nodes; ActionNode represents simple
-// ones such as field evaluations.
-type ActionNode struct {
- NodeType
- Line int // The line number in the input.
- Pipe *PipeNode // The pipeline in the action.
-}
-
-func newAction(line int, pipe *PipeNode) *ActionNode {
- return &ActionNode{NodeType: NodeAction, Line: line, Pipe: pipe}
-}
-
-func (a *ActionNode) String() string {
- return fmt.Sprintf("(action: %v)", a.Pipe)
-}
-
-// CommandNode holds a command (a pipeline inside an evaluating action).
-type CommandNode struct {
- NodeType
- Args []Node // Arguments in lexical order: Identifier, field, or constant.
-}
-
-func newCommand() *CommandNode {
- return &CommandNode{NodeType: NodeCommand}
-}
-
-func (c *CommandNode) append(arg Node) {
- c.Args = append(c.Args, arg)
-}
-
-func (c *CommandNode) String() string {
- return fmt.Sprintf("(command: %v)", c.Args)
-}
-
-// IdentifierNode holds an identifier.
-type IdentifierNode struct {
- NodeType
- Ident string // The identifier's name.
-}
-
-func newIdentifier(ident string) *IdentifierNode {
- return &IdentifierNode{NodeType: NodeIdentifier, Ident: ident}
-}
-
-func (i *IdentifierNode) String() string {
- return fmt.Sprintf("I=%s", i.Ident)
-}
-
-// VariableNode holds a list of variable names. The dollar sign is
-// part of the name.
-type VariableNode struct {
- NodeType
- Ident []string // Variable names in lexical order.
-}
-
-func newVariable(ident string) *VariableNode {
- return &VariableNode{NodeType: NodeVariable, Ident: strings.Split(ident, ".")}
-}
-
-func (v *VariableNode) String() string {
- return fmt.Sprintf("V=%s", v.Ident)
-}
-
-// DotNode holds the special identifier '.'. It is represented by a nil pointer.
-type DotNode bool
-
-func newDot() *DotNode {
- return nil
-}
-
-func (d *DotNode) Type() NodeType {
- return NodeDot
-}
-
-func (d *DotNode) String() string {
- return "{{<.>}}"
-}
-
-// FieldNode holds a field (identifier starting with '.').
-// The names may be chained ('.x.y').
-// The period is dropped from each ident.
-type FieldNode struct {
- NodeType
- Ident []string // The identifiers in lexical order.
-}
-
-func newField(ident string) *FieldNode {
- return &FieldNode{NodeType: NodeField, Ident: strings.Split(ident[1:], ".")} // [1:] to drop leading period
-}
-
-func (f *FieldNode) String() string {
- return fmt.Sprintf("F=%s", f.Ident)
-}
-
-// BoolNode holds a boolean constant.
-type BoolNode struct {
- NodeType
- True bool // The value of the boolean constant.
-}
-
-func newBool(true bool) *BoolNode {
- return &BoolNode{NodeType: NodeBool, True: true}
-}
-
-func (b *BoolNode) String() string {
- return fmt.Sprintf("B=%t", b.True)
-}
-
-// NumberNode holds a number: signed or unsigned integer, float, or complex.
-// The value is parsed and stored under all the types that can represent the value.
-// This simulates in a small amount of code the behavior of Go's ideal constants.
-type NumberNode struct {
- NodeType
- IsInt bool // Number has an integral value.
- IsUint bool // Number has an unsigned integral value.
- IsFloat bool // Number has a floating-point value.
- IsComplex bool // Number is complex.
- Int64 int64 // The signed integer value.
- Uint64 uint64 // The unsigned integer value.
- Float64 float64 // The floating-point value.
- Complex128 complex128 // The complex value.
- Text string // The original textual representation from the input.
-}
-
-func newNumber(text string, typ itemType) (*NumberNode, os.Error) {
- n := &NumberNode{NodeType: NodeNumber, Text: text}
- switch typ {
- case itemCharConstant:
- rune, _, tail, err := strconv.UnquoteChar(text[1:], text[0])
- if err != nil {
- return nil, err
- }
- if tail != "'" {
- return nil, fmt.Errorf("malformed character constant: %s", text)
- }
- n.Int64 = int64(rune)
- n.IsInt = true
- n.Uint64 = uint64(rune)
- n.IsUint = true
- n.Float64 = float64(rune) // odd but those are the rules.
- n.IsFloat = true
- return n, nil
- case itemComplex:
- // fmt.Sscan can parse the pair, so let it do the work.
- if _, err := fmt.Sscan(text, &n.Complex128); err != nil {
- return nil, err
- }
- n.IsComplex = true
- n.simplifyComplex()
- return n, nil
- }
- // Imaginary constants can only be complex unless they are zero.
- if len(text) > 0 && text[len(text)-1] == 'i' {
- f, err := strconv.Atof64(text[:len(text)-1])
- if err == nil {
- n.IsComplex = true
- n.Complex128 = complex(0, f)
- n.simplifyComplex()
- return n, nil
- }
- }
- // Do integer test first so we get 0x123 etc.
- u, err := strconv.Btoui64(text, 0) // will fail for -0; fixed below.
- if err == nil {
- n.IsUint = true
- n.Uint64 = u
- }
- i, err := strconv.Btoi64(text, 0)
- if err == nil {
- n.IsInt = true
- n.Int64 = i
- if i == 0 {
- n.IsUint = true // in case of -0.
- n.Uint64 = u
- }
- }
- // If an integer extraction succeeded, promote the float.
- if n.IsInt {
- n.IsFloat = true
- n.Float64 = float64(n.Int64)
- } else if n.IsUint {
- n.IsFloat = true
- n.Float64 = float64(n.Uint64)
- } else {
- f, err := strconv.Atof64(text)
- if err == nil {
- n.IsFloat = true
- n.Float64 = f
- // If a floating-point extraction succeeded, extract the int if needed.
- if !n.IsInt && float64(int64(f)) == f {
- n.IsInt = true
- n.Int64 = int64(f)
- }
- if !n.IsUint && float64(uint64(f)) == f {
- n.IsUint = true
- n.Uint64 = uint64(f)
- }
- }
- }
- if !n.IsInt && !n.IsUint && !n.IsFloat {
- return nil, fmt.Errorf("illegal number syntax: %q", text)
- }
- return n, nil
-}
-
-// simplifyComplex pulls out any other types that are represented by the complex number.
-// These all require that the imaginary part be zero.
-func (n *NumberNode) simplifyComplex() {
- n.IsFloat = imag(n.Complex128) == 0
- if n.IsFloat {
- n.Float64 = real(n.Complex128)
- n.IsInt = float64(int64(n.Float64)) == n.Float64
- if n.IsInt {
- n.Int64 = int64(n.Float64)
- }
- n.IsUint = float64(uint64(n.Float64)) == n.Float64
- if n.IsUint {
- n.Uint64 = uint64(n.Float64)
- }
- }
-}
-
-func (n *NumberNode) String() string {
- return fmt.Sprintf("N=%s", n.Text)
-}
-
-// StringNode holds a string constant. The value has been "unquoted".
-type StringNode struct {
- NodeType
- Quoted string // The original text of the string, with quotes.
- Text string // The string, after quote processing.
-}
-
-func newString(orig, text string) *StringNode {
- return &StringNode{NodeType: NodeString, Quoted: orig, Text: text}
-}
-
-func (s *StringNode) String() string {
- return fmt.Sprintf("S=%#q", s.Text)
-}
-
-// EndNode represents an {{end}} action. It is represented by a nil pointer.
-type EndNode bool
-
-func newEnd() *EndNode {
- return nil
-}
-
-func (e *EndNode) Type() NodeType {
- return NodeEnd
-}
-
-func (e *EndNode) String() string {
- return "{{end}}"
-}
-
-// ElseNode represents an {{else}} action.
-type ElseNode struct {
- NodeType
- Line int // The line number in the input.
-}
-
-func newElse(line int) *ElseNode {
- return &ElseNode{NodeType: NodeElse, Line: line}
-}
-
-func (e *ElseNode) Type() NodeType {
- return NodeElse
-}
-
-func (e *ElseNode) String() string {
- return "{{else}}"
-}
-
-// IfNode represents an {{if}} action and its commands.
-type IfNode struct {
- NodeType
- Line int // The line number in the input.
- Pipe *PipeNode // The pipeline to be evaluated.
- List *ListNode // What to execute if the value is non-empty.
- ElseList *ListNode // What to execute if the value is empty (nil if absent).
-}
-
-func newIf(line int, pipe *PipeNode, list, elseList *ListNode) *IfNode {
- return &IfNode{NodeType: NodeIf, Line: line, Pipe: pipe, List: list, ElseList: elseList}
-}
-
-func (i *IfNode) String() string {
- if i.ElseList != nil {
- return fmt.Sprintf("({{if %s}} %s {{else}} %s)", i.Pipe, i.List, i.ElseList)
- }
- return fmt.Sprintf("({{if %s}} %s)", i.Pipe, i.List)
-}
-
-// RangeNode represents a {{range}} action and its commands.
-type RangeNode struct {
- NodeType
- Line int // The line number in the input.
- Pipe *PipeNode // The pipeline to be evaluated.
- List *ListNode // What to execute if the value is non-empty.
- ElseList *ListNode // What to execute if the value is empty (nil if absent).
-}
-
-func newRange(line int, pipe *PipeNode, list, elseList *ListNode) *RangeNode {
- return &RangeNode{NodeType: NodeRange, Line: line, Pipe: pipe, List: list, ElseList: elseList}
-}
-
-func (r *RangeNode) String() string {
- if r.ElseList != nil {
- return fmt.Sprintf("({{range %s}} %s {{else}} %s)", r.Pipe, r.List, r.ElseList)
- }
- return fmt.Sprintf("({{range %s}} %s)", r.Pipe, r.List)
-}
-
-// TemplateNode represents a {{template}} action.
-type TemplateNode struct {
- NodeType
- Line int // The line number in the input.
- Name string // The name of the template (unquoted).
- Pipe *PipeNode // The command to evaluate as dot for the template.
-}
-
-func newTemplate(line int, name string, pipe *PipeNode) *TemplateNode {
- return &TemplateNode{NodeType: NodeTemplate, Line: line, Name: name, Pipe: pipe}
-}
-
-func (t *TemplateNode) String() string {
- if t.Pipe == nil {
- return fmt.Sprintf("{{template %q}}", t.Name)
- }
- return fmt.Sprintf("{{template %q %s}}", t.Name, t.Pipe)
-}
-
-// WithNode represents a {{with}} action and its commands.
-type WithNode struct {
- NodeType
- Line int // The line number in the input.
- Pipe *PipeNode // The pipeline to be evaluated.
- List *ListNode // What to execute if the value is non-empty.
- ElseList *ListNode // What to execute if the value is empty (nil if absent).
-}
-
-func newWith(line int, pipe *PipeNode, list, elseList *ListNode) *WithNode {
- return &WithNode{NodeType: NodeWith, Line: line, Pipe: pipe, List: list, ElseList: elseList}
-}
-
-func (w *WithNode) String() string {
- if w.ElseList != nil {
- return fmt.Sprintf("({{with %s}} %s {{else}} %s)", w.Pipe, w.List, w.ElseList)
- }
- return fmt.Sprintf("({{with %s}} %s)", w.Pipe, w.List)
-}