zclwrite: parsing of blocks
There's something a little off here, as illustrated by the failing round trip test. Will figure that out later.
This commit is contained in:
parent
948b2e0b7b
commit
cb768a591a
@ -195,8 +195,7 @@ func parseBodyItem(nativeItem zclsyntax.Node, from inputTokens) (inputTokens, No
|
|||||||
case *zclsyntax.Attribute:
|
case *zclsyntax.Attribute:
|
||||||
item = parseAttribute(tItem, within, leadComments, lineComments, newline)
|
item = parseAttribute(tItem, within, leadComments, lineComments, newline)
|
||||||
case *zclsyntax.Block:
|
case *zclsyntax.Block:
|
||||||
// TODO: implement this
|
item = parseBlock(tItem, within, leadComments, lineComments, newline)
|
||||||
panic("block parsing not yet implemented")
|
|
||||||
default:
|
default:
|
||||||
// should never happen if caller is behaving
|
// should never happen if caller is behaving
|
||||||
panic("unsupported native item type")
|
panic("unsupported native item type")
|
||||||
@ -255,6 +254,78 @@ func parseAttribute(nativeAttr *zclsyntax.Attribute, from, leadComments, lineCom
|
|||||||
return attr
|
return attr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseBlock(nativeBlock *zclsyntax.Block, from, leadComments, lineComments, newline inputTokens) *Block {
|
||||||
|
var allTokens TokenSeq
|
||||||
|
block := &Block{}
|
||||||
|
|
||||||
|
if leadComments.Len() > 0 {
|
||||||
|
block.LeadCommentTokens = leadComments.Seq()
|
||||||
|
allTokens = append(allTokens, block.LeadCommentTokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
before, typeTokens, from := from.Partition(nativeBlock.TypeRange)
|
||||||
|
if before.Len() > 0 {
|
||||||
|
allTokens = append(allTokens, before.Seq())
|
||||||
|
}
|
||||||
|
block.TypeTokens = typeTokens.Seq()
|
||||||
|
allTokens = append(allTokens, block.TypeTokens)
|
||||||
|
|
||||||
|
for _, rng := range nativeBlock.LabelRanges {
|
||||||
|
var labelTokens inputTokens
|
||||||
|
before, labelTokens, from = from.Partition(rng)
|
||||||
|
if before.Len() > 0 {
|
||||||
|
allTokens = append(allTokens, before.Seq())
|
||||||
|
}
|
||||||
|
seq := labelTokens.Seq()
|
||||||
|
block.LabelTokens = append(block.LabelTokens, seq)
|
||||||
|
*(block.LabelTokensFlat) = append(*(block.LabelTokensFlat), seq)
|
||||||
|
allTokens = append(allTokens, seq)
|
||||||
|
}
|
||||||
|
|
||||||
|
before, oBrace, from := from.Partition(nativeBlock.OpenBraceRange)
|
||||||
|
if before.Len() > 0 {
|
||||||
|
allTokens = append(allTokens, before.Seq())
|
||||||
|
}
|
||||||
|
block.OBraceTokens = oBrace.Seq()
|
||||||
|
allTokens = append(allTokens, block.OBraceTokens)
|
||||||
|
|
||||||
|
// We go a bit out of order here: we go hunting for the closing brace
|
||||||
|
// so that we have a delimited body, but then we'll deal with the body
|
||||||
|
// before we actually append the closing brace and any straggling tokens
|
||||||
|
// that appear after it.
|
||||||
|
bodyTokens, cBrace, from := from.Partition(nativeBlock.CloseBraceRange)
|
||||||
|
before, body, after := parseBody(nativeBlock.Body, bodyTokens)
|
||||||
|
|
||||||
|
if before.Len() > 0 {
|
||||||
|
allTokens = append(allTokens, before.Seq())
|
||||||
|
}
|
||||||
|
block.Body = body
|
||||||
|
allTokens = append(allTokens, body.AllTokens)
|
||||||
|
if after.Len() > 0 {
|
||||||
|
allTokens = append(allTokens, after.Seq())
|
||||||
|
}
|
||||||
|
|
||||||
|
block.CBraceTokens = cBrace.Seq()
|
||||||
|
allTokens = append(allTokens, block.CBraceTokens)
|
||||||
|
|
||||||
|
// stragglers
|
||||||
|
if after.Len() > 0 {
|
||||||
|
allTokens = append(allTokens, from.Seq())
|
||||||
|
}
|
||||||
|
if lineComments.Len() > 0 {
|
||||||
|
// blocks don't actually have line comments, so we'll just treat
|
||||||
|
// them as extra stragglers
|
||||||
|
allTokens = append(allTokens, lineComments.Seq())
|
||||||
|
}
|
||||||
|
if newline.Len() > 0 {
|
||||||
|
block.EOLTokens = newline.Seq()
|
||||||
|
allTokens = append(allTokens, block.EOLTokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
block.AllTokens = &allTokens
|
||||||
|
return block
|
||||||
|
}
|
||||||
|
|
||||||
func parseExpression(nativeExpr zclsyntax.Expression, from inputTokens) *Expression {
|
func parseExpression(nativeExpr zclsyntax.Expression, from inputTokens) *Expression {
|
||||||
// TODO: Populate VarRefs by analyzing the result of nativeExpr.Variables()
|
// TODO: Populate VarRefs by analyzing the result of nativeExpr.Variables()
|
||||||
return &Expression{
|
return &Expression{
|
||||||
@ -336,7 +407,7 @@ func partitionTokens(toks zclsyntax.Tokens, rng zcl.Range) (start, end int) {
|
|||||||
return len(toks), len(toks)
|
return len(toks), len(toks)
|
||||||
}
|
}
|
||||||
|
|
||||||
if toks[i].Range.ContainsOffset(rng.Start.Byte) {
|
if toks[i].Range.Start.Byte >= rng.Start.Byte {
|
||||||
start = i
|
start = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -348,8 +419,8 @@ func partitionTokens(toks zclsyntax.Tokens, rng zcl.Range) (start, end int) {
|
|||||||
return start, len(toks)
|
return start, len(toks)
|
||||||
}
|
}
|
||||||
|
|
||||||
if toks[i].Range.End.Byte >= rng.End.Byte {
|
if toks[i].Range.Start.Byte >= rng.End.Byte {
|
||||||
end = i + 1 // end marker is exclusive
|
end = i // end marker is exclusive
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -530,6 +530,468 @@ func TestParse(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"b {}\n",
|
||||||
|
&Body{
|
||||||
|
Items: []Node{
|
||||||
|
&Block{
|
||||||
|
AllTokens: &TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`b`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenOBrace,
|
||||||
|
Bytes: []byte(`{`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
(*TokenSeq)(nil), // the empty body
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenCBrace,
|
||||||
|
Bytes: []byte(`}`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypeTokens: &TokenSeq{Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`b`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
OBraceTokens: &TokenSeq{Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenOBrace,
|
||||||
|
Bytes: []byte(`{`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
Body: &Body{},
|
||||||
|
CBraceTokens: &TokenSeq{Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenCBrace,
|
||||||
|
Bytes: []byte(`}`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
EOLTokens: &TokenSeq{Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AllTokens: &TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`b`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenOBrace,
|
||||||
|
Bytes: []byte(`{`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
(*TokenSeq)(nil), // the empty body
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenCBrace,
|
||||||
|
Bytes: []byte(`}`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"b {\n a = 1\n}\n",
|
||||||
|
&Body{
|
||||||
|
Items: []Node{
|
||||||
|
&Block{
|
||||||
|
AllTokens: &TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`b`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenOBrace,
|
||||||
|
Bytes: []byte(`{`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`a`),
|
||||||
|
SpacesBefore: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenEqual,
|
||||||
|
Bytes: []byte(`=`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNumberLit,
|
||||||
|
Bytes: []byte(`1`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenCBrace,
|
||||||
|
Bytes: []byte(`}`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypeTokens: &TokenSeq{Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`b`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
OBraceTokens: &TokenSeq{Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenOBrace,
|
||||||
|
Bytes: []byte(`{`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
Body: &Body{
|
||||||
|
Items: []Node{
|
||||||
|
&Attribute{
|
||||||
|
AllTokens: &TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`a`),
|
||||||
|
SpacesBefore: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenEqual,
|
||||||
|
Bytes: []byte(`=`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNumberLit,
|
||||||
|
Bytes: []byte(`1`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NameTokens: &TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`a`),
|
||||||
|
SpacesBefore: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
EqualsTokens: &TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenEqual,
|
||||||
|
Bytes: []byte(`=`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Expr: &Expression{
|
||||||
|
AllTokens: &TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNumberLit,
|
||||||
|
Bytes: []byte(`1`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
EOLTokens: &TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AllTokens: &TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`a`),
|
||||||
|
SpacesBefore: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenEqual,
|
||||||
|
Bytes: []byte(`=`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNumberLit,
|
||||||
|
Bytes: []byte(`1`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CBraceTokens: &TokenSeq{Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenCBrace,
|
||||||
|
Bytes: []byte(`}`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
EOLTokens: &TokenSeq{Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AllTokens: &TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`b`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenOBrace,
|
||||||
|
Bytes: []byte(`{`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenIdent,
|
||||||
|
Bytes: []byte(`a`),
|
||||||
|
SpacesBefore: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenEqual,
|
||||||
|
Bytes: []byte(`=`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNumberLit,
|
||||||
|
Bytes: []byte(`1`),
|
||||||
|
SpacesBefore: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenCBrace,
|
||||||
|
Bytes: []byte(`}`),
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&TokenSeq{
|
||||||
|
Tokens{
|
||||||
|
{
|
||||||
|
Type: zclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
SpacesBefore: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
prettyConfig := &pretty.Config{
|
prettyConfig := &pretty.Config{
|
||||||
|
@ -27,6 +27,20 @@ baz = 1
|
|||||||
foobar = 1
|
foobar = 1
|
||||||
baz = 1
|
baz = 1
|
||||||
|
|
||||||
|
block {
|
||||||
|
a = "a"
|
||||||
|
b = "b"
|
||||||
|
c = "c"
|
||||||
|
d = "d"
|
||||||
|
|
||||||
|
subblock {
|
||||||
|
}
|
||||||
|
|
||||||
|
subblock {
|
||||||
|
e = "e"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# and they all lived happily ever after
|
# and they all lived happily ever after
|
||||||
`,
|
`,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user