config/lang: some hoops to get the types to work
This commit is contained in:
parent
591610deea
commit
6e29ea0366
|
@ -1,6 +1,7 @@
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,3 +27,12 @@ func (n *Concat) Pos() Pos {
|
||||||
func (n *Concat) GoString() string {
|
func (n *Concat) GoString() string {
|
||||||
return fmt.Sprintf("*%#v", *n)
|
return fmt.Sprintf("*%#v", *n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Concat) String() string {
|
||||||
|
var b bytes.Buffer
|
||||||
|
for _, expr := range n.Exprs {
|
||||||
|
b.WriteString(fmt.Sprintf("%s", expr))
|
||||||
|
}
|
||||||
|
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
|
@ -40,6 +40,23 @@ top:
|
||||||
| literalModeTop
|
| literalModeTop
|
||||||
{
|
{
|
||||||
parserResult = $1
|
parserResult = $1
|
||||||
|
|
||||||
|
// We want to make sure that the top value is always a Concat
|
||||||
|
// so that the return value is always a string type from an
|
||||||
|
// interpolation.
|
||||||
|
//
|
||||||
|
// The logic for checking for a LiteralNode is a little annoying
|
||||||
|
// because functionally the AST is the same, but we do that because
|
||||||
|
// it makes for an easy literal check later (to check if a string
|
||||||
|
// has any interpolations).
|
||||||
|
if _, ok := $1.(*ast.Concat); !ok {
|
||||||
|
if n, ok := $1.(*ast.LiteralNode); !ok || n.Type != ast.TypeString {
|
||||||
|
parserResult = &ast.Concat{
|
||||||
|
Exprs: []ast.Node{$1},
|
||||||
|
Posx: $1.Pos(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
literalModeTop:
|
literalModeTop:
|
||||||
|
|
|
@ -149,23 +149,33 @@ func TestParse(t *testing.T) {
|
||||||
{
|
{
|
||||||
"${foo()}",
|
"${foo()}",
|
||||||
false,
|
false,
|
||||||
&ast.Call{
|
&ast.Concat{
|
||||||
Func: "foo",
|
|
||||||
Args: nil,
|
|
||||||
Posx: ast.Pos{Column: 3, Line: 1},
|
Posx: ast.Pos{Column: 3, Line: 1},
|
||||||
|
Exprs: []ast.Node{
|
||||||
|
&ast.Call{
|
||||||
|
Func: "foo",
|
||||||
|
Args: nil,
|
||||||
|
Posx: ast.Pos{Column: 3, Line: 1},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"${foo(bar)}",
|
"${foo(bar)}",
|
||||||
false,
|
false,
|
||||||
&ast.Call{
|
&ast.Concat{
|
||||||
Func: "foo",
|
|
||||||
Posx: ast.Pos{Column: 3, Line: 1},
|
Posx: ast.Pos{Column: 3, Line: 1},
|
||||||
Args: []ast.Node{
|
Exprs: []ast.Node{
|
||||||
&ast.VariableAccess{
|
&ast.Call{
|
||||||
Name: "bar",
|
Func: "foo",
|
||||||
Posx: ast.Pos{Column: 7, Line: 1},
|
Posx: ast.Pos{Column: 3, Line: 1},
|
||||||
|
Args: []ast.Node{
|
||||||
|
&ast.VariableAccess{
|
||||||
|
Name: "bar",
|
||||||
|
Posx: ast.Pos{Column: 7, Line: 1},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -174,17 +184,22 @@ func TestParse(t *testing.T) {
|
||||||
{
|
{
|
||||||
"${foo(bar, baz)}",
|
"${foo(bar, baz)}",
|
||||||
false,
|
false,
|
||||||
&ast.Call{
|
&ast.Concat{
|
||||||
Func: "foo",
|
|
||||||
Posx: ast.Pos{Column: 3, Line: 1},
|
Posx: ast.Pos{Column: 3, Line: 1},
|
||||||
Args: []ast.Node{
|
Exprs: []ast.Node{
|
||||||
&ast.VariableAccess{
|
&ast.Call{
|
||||||
Name: "bar",
|
Func: "foo",
|
||||||
Posx: ast.Pos{Column: 7, Line: 1},
|
Posx: ast.Pos{Column: 3, Line: 1},
|
||||||
},
|
Args: []ast.Node{
|
||||||
&ast.VariableAccess{
|
&ast.VariableAccess{
|
||||||
Name: "baz",
|
Name: "bar",
|
||||||
Posx: ast.Pos{Column: 11, Line: 1},
|
Posx: ast.Pos{Column: 7, Line: 1},
|
||||||
|
},
|
||||||
|
&ast.VariableAccess{
|
||||||
|
Name: "baz",
|
||||||
|
Posx: ast.Pos{Column: 11, Line: 1},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -193,17 +208,22 @@ func TestParse(t *testing.T) {
|
||||||
{
|
{
|
||||||
"${foo(bar(baz))}",
|
"${foo(bar(baz))}",
|
||||||
false,
|
false,
|
||||||
&ast.Call{
|
&ast.Concat{
|
||||||
Func: "foo",
|
|
||||||
Posx: ast.Pos{Column: 3, Line: 1},
|
Posx: ast.Pos{Column: 3, Line: 1},
|
||||||
Args: []ast.Node{
|
Exprs: []ast.Node{
|
||||||
&ast.Call{
|
&ast.Call{
|
||||||
Func: "bar",
|
Func: "foo",
|
||||||
Posx: ast.Pos{Column: 7, Line: 1},
|
Posx: ast.Pos{Column: 3, Line: 1},
|
||||||
Args: []ast.Node{
|
Args: []ast.Node{
|
||||||
&ast.VariableAccess{
|
&ast.Call{
|
||||||
Name: "baz",
|
Func: "bar",
|
||||||
Posx: ast.Pos{Column: 11, Line: 1},
|
Posx: ast.Pos{Column: 7, Line: 1},
|
||||||
|
Args: []ast.Node{
|
||||||
|
&ast.VariableAccess{
|
||||||
|
Name: "baz",
|
||||||
|
Posx: ast.Pos{Column: 11, Line: 1},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -48,7 +48,7 @@ const parserEofCode = 1
|
||||||
const parserErrCode = 2
|
const parserErrCode = 2
|
||||||
const parserMaxDepth = 200
|
const parserMaxDepth = 200
|
||||||
|
|
||||||
//line lang.y:134
|
//line lang.y:151
|
||||||
|
|
||||||
//line yacctab:1
|
//line yacctab:1
|
||||||
var parserExca = []int{
|
var parserExca = []int{
|
||||||
|
@ -354,14 +354,31 @@ parserdefault:
|
||||||
//line lang.y:41
|
//line lang.y:41
|
||||||
{
|
{
|
||||||
parserResult = parserS[parserpt-0].node
|
parserResult = parserS[parserpt-0].node
|
||||||
|
|
||||||
|
// We want to make sure that the top value is always a Concat
|
||||||
|
// so that the return value is always a string type from an
|
||||||
|
// interpolation.
|
||||||
|
//
|
||||||
|
// The logic for checking for a LiteralNode is a little annoying
|
||||||
|
// because functionally the AST is the same, but we do that because
|
||||||
|
// it makes for an easy literal check later (to check if a string
|
||||||
|
// has any interpolations).
|
||||||
|
if _, ok := parserS[parserpt-0].node.(*ast.Concat); !ok {
|
||||||
|
if n, ok := parserS[parserpt-0].node.(*ast.LiteralNode); !ok || n.Type != ast.TypeString {
|
||||||
|
parserResult = &ast.Concat{
|
||||||
|
Exprs: []ast.Node{parserS[parserpt-0].node},
|
||||||
|
Posx: parserS[parserpt-0].node.Pos(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
//line lang.y:47
|
//line lang.y:64
|
||||||
{
|
{
|
||||||
parserVAL.node = parserS[parserpt-0].node
|
parserVAL.node = parserS[parserpt-0].node
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
//line lang.y:51
|
//line lang.y:68
|
||||||
{
|
{
|
||||||
var result []ast.Node
|
var result []ast.Node
|
||||||
if c, ok := parserS[parserpt-1].node.(*ast.Concat); ok {
|
if c, ok := parserS[parserpt-1].node.(*ast.Concat); ok {
|
||||||
|
@ -376,27 +393,27 @@ parserdefault:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 5:
|
case 5:
|
||||||
//line lang.y:67
|
//line lang.y:84
|
||||||
{
|
{
|
||||||
parserVAL.node = parserS[parserpt-0].node
|
parserVAL.node = parserS[parserpt-0].node
|
||||||
}
|
}
|
||||||
case 6:
|
case 6:
|
||||||
//line lang.y:71
|
//line lang.y:88
|
||||||
{
|
{
|
||||||
parserVAL.node = parserS[parserpt-0].node
|
parserVAL.node = parserS[parserpt-0].node
|
||||||
}
|
}
|
||||||
case 7:
|
case 7:
|
||||||
//line lang.y:77
|
//line lang.y:94
|
||||||
{
|
{
|
||||||
parserVAL.node = parserS[parserpt-1].node
|
parserVAL.node = parserS[parserpt-1].node
|
||||||
}
|
}
|
||||||
case 8:
|
case 8:
|
||||||
//line lang.y:83
|
//line lang.y:100
|
||||||
{
|
{
|
||||||
parserVAL.node = parserS[parserpt-0].node
|
parserVAL.node = parserS[parserpt-0].node
|
||||||
}
|
}
|
||||||
case 9:
|
case 9:
|
||||||
//line lang.y:87
|
//line lang.y:104
|
||||||
{
|
{
|
||||||
parserVAL.node = &ast.LiteralNode{
|
parserVAL.node = &ast.LiteralNode{
|
||||||
Value: parserS[parserpt-0].token.Value.(int),
|
Value: parserS[parserpt-0].token.Value.(int),
|
||||||
|
@ -405,7 +422,7 @@ parserdefault:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 10:
|
case 10:
|
||||||
//line lang.y:95
|
//line lang.y:112
|
||||||
{
|
{
|
||||||
parserVAL.node = &ast.LiteralNode{
|
parserVAL.node = &ast.LiteralNode{
|
||||||
Value: parserS[parserpt-0].token.Value.(float64),
|
Value: parserS[parserpt-0].token.Value.(float64),
|
||||||
|
@ -414,32 +431,32 @@ parserdefault:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 11:
|
case 11:
|
||||||
//line lang.y:103
|
//line lang.y:120
|
||||||
{
|
{
|
||||||
parserVAL.node = &ast.VariableAccess{Name: parserS[parserpt-0].token.Value.(string), Posx: parserS[parserpt-0].token.Pos}
|
parserVAL.node = &ast.VariableAccess{Name: parserS[parserpt-0].token.Value.(string), Posx: parserS[parserpt-0].token.Pos}
|
||||||
}
|
}
|
||||||
case 12:
|
case 12:
|
||||||
//line lang.y:107
|
//line lang.y:124
|
||||||
{
|
{
|
||||||
parserVAL.node = &ast.Call{Func: parserS[parserpt-3].token.Value.(string), Args: parserS[parserpt-1].nodeList, Posx: parserS[parserpt-3].token.Pos}
|
parserVAL.node = &ast.Call{Func: parserS[parserpt-3].token.Value.(string), Args: parserS[parserpt-1].nodeList, Posx: parserS[parserpt-3].token.Pos}
|
||||||
}
|
}
|
||||||
case 13:
|
case 13:
|
||||||
//line lang.y:112
|
//line lang.y:129
|
||||||
{
|
{
|
||||||
parserVAL.nodeList = nil
|
parserVAL.nodeList = nil
|
||||||
}
|
}
|
||||||
case 14:
|
case 14:
|
||||||
//line lang.y:116
|
//line lang.y:133
|
||||||
{
|
{
|
||||||
parserVAL.nodeList = append(parserS[parserpt-2].nodeList, parserS[parserpt-0].node)
|
parserVAL.nodeList = append(parserS[parserpt-2].nodeList, parserS[parserpt-0].node)
|
||||||
}
|
}
|
||||||
case 15:
|
case 15:
|
||||||
//line lang.y:120
|
//line lang.y:137
|
||||||
{
|
{
|
||||||
parserVAL.nodeList = append(parserVAL.nodeList, parserS[parserpt-0].node)
|
parserVAL.nodeList = append(parserVAL.nodeList, parserS[parserpt-0].node)
|
||||||
}
|
}
|
||||||
case 16:
|
case 16:
|
||||||
//line lang.y:126
|
//line lang.y:143
|
||||||
{
|
{
|
||||||
parserVAL.node = &ast.LiteralNode{
|
parserVAL.node = &ast.LiteralNode{
|
||||||
Value: parserS[parserpt-0].token.Value.(string),
|
Value: parserS[parserpt-0].token.Value.(string),
|
||||||
|
|
|
@ -35,25 +35,25 @@ state 2
|
||||||
state 3
|
state 3
|
||||||
literalModeTop: literalModeValue. (3)
|
literalModeTop: literalModeValue. (3)
|
||||||
|
|
||||||
. reduce 3 (src line 45)
|
. reduce 3 (src line 62)
|
||||||
|
|
||||||
|
|
||||||
state 4
|
state 4
|
||||||
literalModeValue: literal. (5)
|
literalModeValue: literal. (5)
|
||||||
|
|
||||||
. reduce 5 (src line 65)
|
. reduce 5 (src line 82)
|
||||||
|
|
||||||
|
|
||||||
state 5
|
state 5
|
||||||
literalModeValue: interpolation. (6)
|
literalModeValue: interpolation. (6)
|
||||||
|
|
||||||
. reduce 6 (src line 70)
|
. reduce 6 (src line 87)
|
||||||
|
|
||||||
|
|
||||||
state 6
|
state 6
|
||||||
literal: STRING. (16)
|
literal: STRING. (16)
|
||||||
|
|
||||||
. reduce 16 (src line 124)
|
. reduce 16 (src line 141)
|
||||||
|
|
||||||
|
|
||||||
state 7
|
state 7
|
||||||
|
@ -75,7 +75,7 @@ state 7
|
||||||
state 8
|
state 8
|
||||||
literalModeTop: literalModeTop literalModeValue. (4)
|
literalModeTop: literalModeTop literalModeValue. (4)
|
||||||
|
|
||||||
. reduce 4 (src line 50)
|
. reduce 4 (src line 67)
|
||||||
|
|
||||||
|
|
||||||
state 9
|
state 9
|
||||||
|
@ -91,7 +91,7 @@ state 10
|
||||||
|
|
||||||
PROGRAM_BRACKET_LEFT shift 7
|
PROGRAM_BRACKET_LEFT shift 7
|
||||||
STRING shift 6
|
STRING shift 6
|
||||||
. reduce 8 (src line 81)
|
. reduce 8 (src line 98)
|
||||||
|
|
||||||
interpolation goto 5
|
interpolation goto 5
|
||||||
literal goto 4
|
literal goto 4
|
||||||
|
@ -100,13 +100,13 @@ state 10
|
||||||
state 11
|
state 11
|
||||||
expr: INTEGER. (9)
|
expr: INTEGER. (9)
|
||||||
|
|
||||||
. reduce 9 (src line 86)
|
. reduce 9 (src line 103)
|
||||||
|
|
||||||
|
|
||||||
state 12
|
state 12
|
||||||
expr: FLOAT. (10)
|
expr: FLOAT. (10)
|
||||||
|
|
||||||
. reduce 10 (src line 94)
|
. reduce 10 (src line 111)
|
||||||
|
|
||||||
|
|
||||||
state 13
|
state 13
|
||||||
|
@ -114,13 +114,13 @@ state 13
|
||||||
expr: IDENTIFIER.PAREN_LEFT args PAREN_RIGHT
|
expr: IDENTIFIER.PAREN_LEFT args PAREN_RIGHT
|
||||||
|
|
||||||
PAREN_LEFT shift 15
|
PAREN_LEFT shift 15
|
||||||
. reduce 11 (src line 102)
|
. reduce 11 (src line 119)
|
||||||
|
|
||||||
|
|
||||||
state 14
|
state 14
|
||||||
interpolation: PROGRAM_BRACKET_LEFT expr PROGRAM_BRACKET_RIGHT. (7)
|
interpolation: PROGRAM_BRACKET_LEFT expr PROGRAM_BRACKET_RIGHT. (7)
|
||||||
|
|
||||||
. reduce 7 (src line 75)
|
. reduce 7 (src line 92)
|
||||||
|
|
||||||
|
|
||||||
state 15
|
state 15
|
||||||
|
@ -132,7 +132,7 @@ state 15
|
||||||
INTEGER shift 11
|
INTEGER shift 11
|
||||||
FLOAT shift 12
|
FLOAT shift 12
|
||||||
STRING shift 6
|
STRING shift 6
|
||||||
. reduce 13 (src line 111)
|
. reduce 13 (src line 128)
|
||||||
|
|
||||||
expr goto 17
|
expr goto 17
|
||||||
interpolation goto 5
|
interpolation goto 5
|
||||||
|
@ -153,13 +153,13 @@ state 16
|
||||||
state 17
|
state 17
|
||||||
args: expr. (15)
|
args: expr. (15)
|
||||||
|
|
||||||
. reduce 15 (src line 119)
|
. reduce 15 (src line 136)
|
||||||
|
|
||||||
|
|
||||||
state 18
|
state 18
|
||||||
expr: IDENTIFIER PAREN_LEFT args PAREN_RIGHT. (12)
|
expr: IDENTIFIER PAREN_LEFT args PAREN_RIGHT. (12)
|
||||||
|
|
||||||
. reduce 12 (src line 106)
|
. reduce 12 (src line 123)
|
||||||
|
|
||||||
|
|
||||||
state 19
|
state 19
|
||||||
|
@ -181,7 +181,7 @@ state 19
|
||||||
state 20
|
state 20
|
||||||
args: args COMMA expr. (14)
|
args: args COMMA expr. (14)
|
||||||
|
|
||||||
. reduce 14 (src line 115)
|
. reduce 14 (src line 132)
|
||||||
|
|
||||||
|
|
||||||
14 terminals, 8 nonterminals
|
14 terminals, 8 nonterminals
|
||||||
|
|
Loading…
Reference in New Issue