Skip to content

Commit 0a40192

Browse files
Parse builtin idents into a new node type
1 parent 4f52ef3 commit 0a40192

13 files changed

+331
-14
lines changed

internal/syntax/ast/ast_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,14 @@ func TestNode(t *testing.T) {
5858
},
5959
{
6060
name: "builtin",
61-
node: ast.Ident{
62-
Name: "test",
63-
Token: token.Token{Kind: token.Ident, Start: 0, End: 4},
64-
Type: ast.KindBuiltin,
61+
node: ast.Builtin{
62+
Name: "test",
63+
Dollar: token.Token{Kind: token.Dollar, Start: 0, End: 1},
64+
Token: token.Token{Kind: token.Ident, Start: 1, End: 4},
65+
Type: ast.KindBuiltin,
6566
},
66-
start: token.Token{Kind: token.Ident, Start: 0, End: 4},
67-
end: token.Token{Kind: token.Ident, Start: 0, End: 4},
67+
start: token.Token{Kind: token.Dollar, Start: 0, End: 1},
68+
end: token.Token{Kind: token.Ident, Start: 1, End: 4},
6869
kind: ast.KindBuiltin,
6970
},
7071
{

internal/syntax/ast/expression.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,24 @@ type Builtin struct {
5151
// Name is the ident's name.
5252
Name string `yaml:"name"`
5353

54+
// Dollar is the [token.Dollar] token marking
55+
// the builtin.
56+
Dollar token.Token `yaml:"dollar"`
57+
5458
// The [token.Ident] token.
5559
Token token.Token `yaml:"token"`
5660

5761
// Type is the kind of ast node, in this case [KindBuiltin].
5862
Type Kind `yaml:"type"`
5963
}
6064

61-
// Start returns the first meaningful token in the Builtin, which is
62-
// the [token.Ident].
65+
// Start returns the first token in the Builtin, which is
66+
// the [token.Dollar] opening it.
6367
func (b Builtin) Start() token.Token {
64-
return b.Token
68+
return b.Dollar
6569
}
6670

67-
// End returns the last token in the Builtin, which is also
71+
// End returns the last token in the Builtin, which is
6872
// the [token.Ident].
6973
func (b Builtin) End() token.Token {
7074
return b.Token

internal/syntax/parser/parser.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,8 @@ func (p *Parser) parseExpression(precedence int) (ast.Expression, error) {
580580
expr, err = p.parseInterpolatedExpression(nil)
581581
case token.Ident:
582582
expr = p.parseIdent()
583+
case token.Dollar:
584+
expr, err = p.parseBuiltin()
583585
case token.Body:
584586
expr, err = p.parseBody()
585587
default:
@@ -740,14 +742,34 @@ func (p *Parser) parseHeader() (ast.Header, error) {
740742
// parseIdent parses an Ident.
741743
func (p *Parser) parseIdent() ast.Ident {
742744
ident := ast.Ident{
743-
Name: strings.TrimSpace(p.text()),
745+
Name: p.text(),
744746
Token: p.current,
745747
Type: ast.KindIdent,
746748
}
747749

748750
return ident
749751
}
750752

753+
// parseBuiltin parses a Builtin identifier.
754+
func (p *Parser) parseBuiltin() (ast.Builtin, error) {
755+
builtin := ast.Builtin{
756+
Dollar: p.current,
757+
Type: ast.KindBuiltin,
758+
}
759+
760+
if err := p.expect(token.Ident); err != nil {
761+
return builtin, err
762+
}
763+
764+
// TODO(@FollowTheProcess): Maybe Ident should be a child node in Builtin then?
765+
766+
// Now effectively just an ident
767+
builtin.Token = p.current
768+
builtin.Name = p.text()
769+
770+
return builtin, nil
771+
}
772+
751773
// parseInterp parses an interpolation expression, i.e.
752774
// '{{' <expr> '}}'.
753775
func (p *Parser) parseInterp() (ast.Interp, error) {
@@ -756,8 +778,7 @@ func (p *Parser) parseInterp() (ast.Interp, error) {
756778
Type: ast.KindInterp,
757779
}
758780

759-
// TODO(@FollowTheProcess): For now we'll assume only idents are allowed here
760-
if err := p.expect(token.Ident); err != nil {
781+
if err := p.expect(token.Ident, token.Dollar); err != nil {
761782
return result, err
762783
}
763784

internal/syntax/parser/parser_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func TestParse(t *testing.T) {
4343
p := parser.New(name, src)
4444

4545
parsed, err := p.Parse()
46+
t.Logf("Diagnostics: %+v\n", p.Diagnostics())
4647
test.Ok(t, err)
4748

4849
snap.Snap(parsed)
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
source: parser_test.go
2+
expression: parsed
3+
---
4+
name: interpolation-builtin-body.http
5+
statements:
6+
- url:
7+
value: https://example.com/123
8+
token:
9+
kind: Text
10+
start: 9
11+
end: 32
12+
type: TextLiteral
13+
body:
14+
left:
15+
value: |-
16+
{
17+
"id": "
18+
token:
19+
kind: Body
20+
start: 65
21+
end: 76
22+
type: Body
23+
right:
24+
value: |-
25+
"
26+
}
27+
token:
28+
kind: Body
29+
start: 87
30+
end: 91
31+
type: Body
32+
interp:
33+
expr:
34+
name: uuid
35+
dollar:
36+
kind: Dollar
37+
start: 79
38+
end: 80
39+
token:
40+
kind: Ident
41+
start: 80
42+
end: 84
43+
type: Builtin
44+
open:
45+
kind: OpenInterp
46+
start: 76
47+
end: 78
48+
close:
49+
kind: CloseInterp
50+
start: 85
51+
end: 87
52+
type: Interp
53+
type: InterpolatedExpression
54+
responseRedirect: null
55+
responseReference: null
56+
httpVersion: null
57+
comment: null
58+
vars: []
59+
prompts: []
60+
headers:
61+
- value:
62+
value: application/json
63+
token:
64+
kind: Text
65+
start: 47
66+
end: 63
67+
type: TextLiteral
68+
key: Content-Type
69+
token:
70+
kind: Header
71+
start: 33
72+
end: 45
73+
type: Header
74+
method:
75+
token:
76+
kind: MethodPost
77+
start: 4
78+
end: 8
79+
type: Method
80+
sep:
81+
kind: Separator
82+
start: 0
83+
end: 3
84+
type: Request
85+
type: File
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
source: parser_test.go
2+
expression: parsed
3+
---
4+
name: interpolation-builtin-global.http
5+
statements:
6+
- value:
7+
left: null
8+
right: null
9+
interp:
10+
expr:
11+
name: uuid
12+
dollar:
13+
kind: Dollar
14+
start: 9
15+
end: 10
16+
token:
17+
kind: Ident
18+
start: 10
19+
end: 14
20+
type: Builtin
21+
open:
22+
kind: OpenInterp
23+
start: 6
24+
end: 8
25+
close:
26+
kind: CloseInterp
27+
start: 15
28+
end: 17
29+
type: Interp
30+
type: InterpolatedExpression
31+
ident:
32+
name: id
33+
token:
34+
kind: Ident
35+
start: 1
36+
end: 3
37+
type: Ident
38+
at:
39+
kind: At
40+
start: 0
41+
end: 1
42+
type: VarStatement
43+
- url:
44+
left:
45+
value: https://example.com/
46+
token:
47+
kind: Text
48+
start: 32
49+
end: 52
50+
type: TextLiteral
51+
right: null
52+
interp:
53+
expr:
54+
name: id
55+
token:
56+
kind: Ident
57+
start: 55
58+
end: 57
59+
type: Ident
60+
open:
61+
kind: OpenInterp
62+
start: 52
63+
end: 54
64+
close:
65+
kind: CloseInterp
66+
start: 58
67+
end: 60
68+
type: Interp
69+
type: InterpolatedExpression
70+
body: null
71+
responseRedirect: null
72+
responseReference: null
73+
httpVersion: null
74+
comment:
75+
text: Test
76+
token:
77+
kind: Comment
78+
start: 23
79+
end: 27
80+
type: Comment
81+
vars: []
82+
prompts: []
83+
headers: []
84+
method:
85+
token:
86+
kind: MethodGet
87+
start: 28
88+
end: 31
89+
type: Method
90+
sep:
91+
kind: Separator
92+
start: 19
93+
end: 22
94+
type: Request
95+
type: File
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
source: parser_test.go
2+
expression: parsed
3+
---
4+
name: interpolation-builtin-inline.http
5+
statements:
6+
- url:
7+
left:
8+
value: https://example.com/
9+
token:
10+
kind: Text
11+
start: 13
12+
end: 33
13+
type: TextLiteral
14+
right: null
15+
interp:
16+
expr:
17+
name: uuid
18+
dollar:
19+
kind: Dollar
20+
start: 36
21+
end: 37
22+
token:
23+
kind: Ident
24+
start: 37
25+
end: 41
26+
type: Builtin
27+
open:
28+
kind: OpenInterp
29+
start: 33
30+
end: 35
31+
close:
32+
kind: CloseInterp
33+
start: 42
34+
end: 44
35+
type: Interp
36+
type: InterpolatedExpression
37+
body: null
38+
responseRedirect: null
39+
responseReference: null
40+
httpVersion: null
41+
comment:
42+
text: Test
43+
token:
44+
kind: Comment
45+
start: 4
46+
end: 8
47+
type: Comment
48+
vars: []
49+
prompts: []
50+
headers: []
51+
method:
52+
token:
53+
kind: MethodGet
54+
start: 9
55+
end: 12
56+
type: Method
57+
sep:
58+
kind: Separator
59+
start: 0
60+
end: 3
61+
type: Request
62+
type: File
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
###
2+
POST https://example.com/123
3+
Content-Type: application/json
4+
5+
{
6+
"id": "{{ $uuid }}"
7+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@id = {{ $uuid }}
2+
3+
### Test
4+
GET https://example.com/{{ id }}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
### Test
2+
GET https://example.com/{{ $uuid }}

0 commit comments

Comments
 (0)