<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/subex/subexast.go
diff options
context:
space:
mode:
Diffstat (limited to 'subex/subexast.go')
-rw-r--r--subex/subexast.go468
1 files changed, 315 insertions, 153 deletions
diff --git a/subex/subexast.go b/subex/subexast.go
index e02091d..655a783 100644
--- a/subex/subexast.go
+++ b/subex/subexast.go
@@ -7,54 +7,72 @@ import (
// A node in the AST of a subex
type SubexAST interface {
- compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState
+ compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState
}
// Process the first subex, then the second, splitting the input text in two
type SubexASTConcat struct {
First, Second SubexAST
}
-func (ast SubexASTConcat) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- return ast.First.compileWith(ast.Second.compileWith(next, slotMap, runic), slotMap, runic)
+func (ast SubexASTConcat) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ return ast.First.compileWith(
+ ast.Second.compileWith(next, slotMap, inType, outType),
+ slotMap,
+ inType,
+ outType,
+ )
}
func (ast SubexASTConcat) String() string {
return fmt.Sprintf("(%v)(%v)", ast.First, ast.Second)
}
// Processing a subex and storing the output in a slot instead of outputting it
-type SubexASTStore struct {
+type SubexASTStoreValues struct {
Match SubexAST
Slot rune
}
-func (ast SubexASTStore) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTStoreValues) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
id := slotMap.getId(ast.Slot)
newNext := ast.Match.compileWith(&SubexStoreEndState {
slot: id,
next: next,
- }, slotMap, runic)
+ }, slotMap, inType, ValueType)
- if !runic {
- return &SubexCaptureBeginState {
- next: newNext,
- }
- } else {
- return &SubexCaptureRunesBeginState {
- next: newNext,
- }
+ return &SubexCaptureBeginState {
+ next: newNext,
}
}
-func (ast SubexASTStore) String() string {
+func (ast SubexASTStoreValues) String() string {
return fmt.Sprintf("$%c(%v)", ast.Slot, ast.Match)
}
+type SubexASTStoreRunes struct {
+ Match SubexAST
+ Slot rune
+}
+func (ast SubexASTStoreRunes) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ id := slotMap.getRuneId(ast.Slot)
+ newNext := ast.Match.compileWith(&SubexStoreRunesEndState {
+ slot: id,
+ next: next,
+ }, slotMap, inType, RuneType)
+
+ return &SubexCaptureRunesBeginState {
+ next: newNext,
+ }
+}
+func (ast SubexASTStoreRunes) String() string {
+ return fmt.Sprintf("(%v)$%c", ast.Match, ast.Slot)
+}
+
// Try to run the first subex, if it fails then backtrack and use the second
type SubexASTOr struct {
First, Second SubexAST
}
-func (ast SubexASTOr) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTOr) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
return &SubexGroupState {
- ast.First.compileWith(next, slotMap, runic),
- ast.Second.compileWith(next, slotMap, runic),
+ ast.First.compileWith(next, slotMap, inType, outType),
+ ast.Second.compileWith(next, slotMap, inType, outType),
}
}
func (ast SubexASTOr) String() string {
@@ -84,19 +102,24 @@ func (cr ConvexRange) decrement() ConvexRange {
return ConvexRange{cr.Start - 1, cr.End - 1}
}
}
-func (cr ConvexRange) compile(content SubexAST, next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (cr ConvexRange) compile(content SubexAST, next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
min, _ := cr.minmax()
if min != 0 {
- return content.compileWith(cr.decrement().compile(content, next, slotMap, runic), slotMap, runic)
+ return content.compileWith(
+ cr.decrement().compile(content, next, slotMap, inType, outType),
+ slotMap,
+ inType,
+ outType,
+ )
}
if cr.Start == -1 {
state := &SubexGroupState {nil, next}
- state.first = content.compileWith(state, slotMap, runic)
+ state.first = content.compileWith(state, slotMap, inType, outType)
return state
}
if cr.End == -1 {
state := &SubexGroupState {next, nil}
- state.second = content.compileWith(state, slotMap, runic)
+ state.second = content.compileWith(state, slotMap, inType, outType)
return state
}
@@ -104,7 +127,7 @@ func (cr ConvexRange) compile(content SubexAST, next SubexState, slotMap *SlotMa
state := next;
for i := 0; i < cr.Start; i += 1 {
state = &SubexGroupState {
- content.compileWith(state, slotMap, runic),
+ content.compileWith(state, slotMap, inType, outType),
next,
}
}
@@ -114,7 +137,7 @@ func (cr ConvexRange) compile(content SubexAST, next SubexState, slotMap *SlotMa
for i := 0; i < cr.End; i += 1 {
state = &SubexGroupState {
next,
- content.compileWith(state, slotMap, runic),
+ content.compileWith(state, slotMap, inType, outType),
}
}
return state
@@ -127,10 +150,10 @@ type SubexASTRepeat struct {
Content SubexAST
Acceptable []ConvexRange
}
-func (ast SubexASTRepeat) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTRepeat) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
var state SubexState = &SubexDeadState{}
for _, convex := range ast.Acceptable {
- state = &SubexGroupState {state, convex.compile(ast.Content, next, slotMap, runic)}
+ state = &SubexGroupState {state, convex.compile(ast.Content, next, slotMap, inType, outType)}
}
return state
}
@@ -142,7 +165,10 @@ func (ast SubexASTRepeat) String() string {
type SubexASTCopyScalar struct {
Scalar walk.Scalar
}
-func (ast SubexASTCopyScalar) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyScalar) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTCopyScalar")
+ }
return &SubexCopyState{
filter: selectScalarFilter {ast.Scalar},
next: next,
@@ -153,26 +179,41 @@ func (ast SubexASTCopyScalar) String() string {
}
type SubexASTCopyAnyRune struct {}
-func (ast SubexASTCopyAnyRune) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyAnyRune) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != RuneType || outType != RuneType {
+ panic("Invalid types for SubexASTCopyAnyRune")
+ }
return &SubexCopyRuneState {
next: next,
filter: anyRuneFilter{},
}
}
+func (ast SubexASTCopyAnyRune) String() string {
+ return ".RUNE"
+}
type SubexASTCopyRune struct {
rune rune
}
-func (ast SubexASTCopyRune) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyRune) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != RuneType || outType != RuneType {
+ panic("Invalid types for SubexASTCopyRune")
+ }
return &SubexCopyRuneState {
next: next,
filter: selectRuneFilter {ast.rune},
}
}
+func (ast SubexASTCopyRune) String() string {
+ return string(ast.rune)
+}
// Read in a single atom that must be a boolean and output it unchanged
type SubexASTCopyBool struct {}
-func (ast SubexASTCopyBool) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyBool) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTCopyBool")
+ }
return &SubexCopyState {
next: next,
filter: anyBoolFilter{},
@@ -184,7 +225,10 @@ func (ast SubexASTCopyBool) String() string {
// Read in a single atom that must be a number and output it unchanged
type SubexASTCopyNumber struct {}
-func (ast SubexASTCopyNumber) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyNumber) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTCopyNumber")
+ }
return &SubexCopyState {
next: next,
filter: anyNumberFilter{},
@@ -194,34 +238,24 @@ func (ast SubexASTCopyNumber) String() string {
return "%"
}
-// Read in a full string value and copy it out unchanged
-// # is equivalent to "_{-0}"
-// TODO
-// type SubexASTCopyString struct {}
-// func (ast SubexASTCopyString) compileWith(next SubexState, slotMap *SlotMap) SubexState {
-// stringAtomState := &SubexCopyStringAtomState {
-// next: nil,
-// }
-// stringContentState := &SubexGroupState {
-// &SubexCopyScalarState {
-// scalar: walk.NewAtomStringTerminal(),
-// next: next,
-// },
-// stringAtomState,
-// }
-// stringAtomState.next = stringContentState
-// return &SubexCopyScalarState {
-// scalar: walk.NewAtomStringTerminal(),
-// next: stringContentState,
-// }
-// }
-// func (ast SubexASTCopyString) String() string {
-// return "#"
-// }
+// Read in a null, bool, number, string or empty array or map and output it unchanged
+type SubexASTCopyAnySimpleValue struct {}
+func (ast SubexASTCopyAnySimpleValue) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTCopyAnySimpleValue")
+ }
+ return &SubexCopyState {
+ next: next,
+ filter: simpleValueFilter{},
+ }
+}
// Read in any single Atom and output it unchanged
type SubexASTCopyAnyValue struct {}
-func (ast SubexASTCopyAnyValue) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyAnyValue) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTCopyAnyValue")
+ }
return &SubexCopyState {
next: next,
filter: anyValueFilter{},
@@ -231,6 +265,7 @@ func (ast SubexASTCopyAnyValue) String() string {
return "."
}
+/*
type OutputContentAST interface {
compile(slotMap *SlotMap) OutputContent
}
@@ -273,25 +308,58 @@ func (ast SubexASTOutput) compileWith(next SubexState, slotMap *SlotMap, runic b
func (ast SubexASTOutput) String() string {
return "=...="
}
+*/
-// Read in a repeated subex separated by a delimiter. Greedy
-type SubexASTJoin struct {
- Content, Delimiter SubexAST
+type SubexASTOutputValueLiteral struct {
+ literal walk.Scalar
}
-func (ast SubexASTJoin) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- afterContentState := &SubexGroupState {
- nil,
- next,
+func (ast SubexASTOutputValueLiteral) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if outType != ValueType {
+ panic("Invalid outType for SubexASTOutputValueLiteral")
}
- manyContentsState := ast.Content.compileWith(afterContentState, slotMap, runic)
- afterContentState.first = ast.Delimiter.compileWith(manyContentsState, slotMap, runic)
- return &SubexGroupState {
- manyContentsState,
- next,
+ return &SubexOutputValueLiteralState {
+ literal: ast.literal,
+ next: next,
+ }
+}
+
+type SubexASTOutputValueLoad struct {
+ slot rune
+}
+func (ast SubexASTOutputValueLoad) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if outType != ValueType {
+ panic("Invalid outType for SubexASTOutputValueLoad")
+ }
+ return &SubexOutputValueLoadState {
+ slot: slotMap.getId(ast.slot),
+ next: next,
+ }
+}
+
+type SubexASTOutputRuneLiteral struct {
+ literal rune
+}
+func (ast SubexASTOutputRuneLiteral) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if outType != RuneType {
+ panic("Invalid outType for SubexASTOutputRuneLiteral")
+ }
+ return &SubexOutputRuneLiteralState {
+ literal: ast.literal,
+ next: next,
}
}
-func (ast SubexASTJoin) String() string {
- return fmt.Sprintf("(%v);(%v)", ast.Content, ast.Delimiter)
+
+type SubexASTOutputRuneLoad struct {
+ slot rune
+}
+func (ast SubexASTOutputRuneLoad) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if outType != RuneType {
+ panic("Invalid outType for SubexASTOutputRuneLoad")
+ }
+ return &SubexOutputRuneLoadState {
+ slot: slotMap.getRuneId(ast.slot),
+ next: next,
+ }
}
// Run each input Atom through a map to produce an output Atom
@@ -314,12 +382,15 @@ func (ast SubexASTJoin) String() string {
type SubexASTSum struct {
Content SubexAST
}
-func (ast SubexASTSum) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTSum) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTSum")
+ }
return &SubexCaptureBeginState {
next: ast.Content.compileWith(&SubexArithmeticEndState {
next: next,
calculate: sumValues,
- }, slotMap, runic),
+ }, slotMap, inType, outType),
}
}
func (ast SubexASTSum) String() string {
@@ -330,12 +401,15 @@ func (ast SubexASTSum) String() string {
type SubexASTProduct struct {
Content SubexAST
}
-func (ast SubexASTProduct) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTProduct) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTProduct")
+ }
return &SubexCaptureBeginState {
next: ast.Content.compileWith(&SubexArithmeticEndState {
next: next,
calculate: multiplyValues,
- }, slotMap, runic),
+ }, slotMap, inType, outType),
}
}
func (ast SubexASTProduct) String() string {
@@ -347,12 +421,15 @@ func (ast SubexASTProduct) String() string {
type SubexASTNegate struct {
Content SubexAST
}
-func (ast SubexASTNegate) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTNegate) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNegate")
+ }
return &SubexCaptureBeginState {
next: ast.Content.compileWith(&SubexArithmeticEndState {
next: next,
calculate: negateValues,
- }, slotMap, runic),
+ }, slotMap, inType, outType),
}
}
func (ast SubexASTNegate) String() string {
@@ -360,58 +437,29 @@ func (ast SubexASTNegate) String() string {
}
// Runs the content Subex and collects the output
-// If it is a list of atoms castable to numbers, it takes the reciprocal of them all and outputs them
-// Else it rejects
-type SubexASTReciprocal struct {
- Content SubexAST
-}
-func (ast SubexASTReciprocal) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- return &SubexCaptureBeginState {
- next: ast.Content.compileWith(&SubexArithmeticEndState {
- next: next,
- calculate: reciprocalValues,
- }, slotMap, runic),
- }
-}
-func (ast SubexASTReciprocal) String() string {
- return fmt.Sprintf("(%v)/", ast.Content)
-}
-
-// Runs the content Subex and collects the output
// Maps over the values in the output, casting each to a boolean, notting each and then outputs them
// Rejects if it cannot cast to boolean
type SubexASTNot struct {
Content SubexAST
}
-func (ast SubexASTNot) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTNot) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCaptureBeginState {
next: ast.Content.compileWith(&SubexArithmeticEndState {
next: next,
calculate: notValues,
- }, slotMap, runic),
+ }, slotMap, ValueType, ValueType),
}
}
func (ast SubexASTNot) String() string {
return fmt.Sprintf("(%v)!", ast.Content)
}
-// Runs the content Subex and collects the output
-// Replaces it with true if all output values are equal and false otherwise
-type SubexASTEqual struct {
- Content SubexAST
-}
-func (ast SubexASTEqual) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- return &SubexCaptureBeginState {
- next: ast.Content.compileWith(&SubexArithmeticEndState {
- next: next,
- calculate: equalValues,
- }, slotMap, runic),
- }
-}
-
// Does nothing
type SubexASTEmpty struct {}
-func (ast SubexASTEmpty) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTEmpty) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
return next
}
func (ast SubexASTEmpty) String() string {
@@ -421,10 +469,11 @@ func (ast SubexASTEmpty) String() string {
// Discards the output from the content subex
type SubexASTDiscard struct {
Content SubexAST
+ InnerOutType Type
}
-func (ast SubexASTDiscard) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- newNext := ast.Content.compileWith(&SubexDiscardState {next}, slotMap, runic)
- if !runic {
+func (ast SubexASTDiscard) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ newNext := ast.Content.compileWith(&SubexDiscardState {next}, slotMap, inType, ast.InnerOutType)
+ if inType == ValueType {
return &SubexCaptureBeginState {
next: newNext,
}
@@ -438,57 +487,170 @@ func (ast SubexASTDiscard) String() string {
return fmt.Sprintf("(%v)$_", ast.Content)
}
-// Go into an array, pass the content each of the values in the array to eat and then leave the array
-type SubexASTEnterArray struct {
+type SubexASTDestructure struct {
+ Destructure Structure
+ Structure Structure
Content SubexAST
}
-func (ast SubexASTEnterArray) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- return &SubexCaptureBeginState {
- next: &SubexIncrementNestState {
+func (ast SubexASTDestructure) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ var innerOutType Type
+ var construct SubexState
+ switch ast.Structure {
+ case NoneStructure:
+ innerOutType = outType
+ construct = next
+ case StringStructure:
+ innerOutType = RuneType
+ construct = &SubexConstructStringState {
+ next: next,
+ }
+ case ArrayStructure:
+ innerOutType = ValueType
+ construct = &SubexConstructArrayState {
+ next: next,
+ }
+ case ArrayValuesStructure:
+ innerOutType = ValueType
+ construct = &SubexConstructArrayValuesState {
+ next: next,
+ }
+ case MapStructure:
+ innerOutType = ValueType
+ construct = &SubexConstructMapState {
+ next: next,
+ }
+ default:
+ panic("Invalid ast structure")
+ }
+
+ var innerInType Type
+ var destructFooter SubexState
+ switch ast.Destructure {
+ case NoneStructure:
+ innerInType = inType
+ destructFooter = construct
+ case StringStructure:
+ innerInType = RuneType
+ destructFooter = &SubexDiscardTerminalState {
+ terminal: walk.StringEnd,
+ next: &SubexDecrementNestState {
+ next: construct,
+ },
+ }
+ case ArrayStructure:
+ innerInType = ValueType
+ destructFooter = &SubexDiscardTerminalState {
+ terminal: walk.ArrayEnd,
+ next: &SubexDecrementNestState {
+ next: construct,
+ },
+ }
+ case ArrayValuesStructure:
+ innerInType = ValueType
+ destructFooter = &SubexDiscardTerminalState {
+ terminal: walk.ArrayEnd,
+ next: &SubexDecrementNestState {
+ next: construct,
+ },
+ }
+ case MapStructure:
+ innerInType = ValueType
+ destructFooter = &SubexDiscardTerminalState {
+ terminal: walk.MapEnd,
+ next: &SubexDecrementNestState {
+ next: construct,
+ },
+ }
+ default:
+ panic("Invalid ast destructure")
+ }
+
+ inner := ast.Content.compileWith(
+ destructFooter,
+ slotMap,
+ innerInType,
+ innerOutType,
+ )
+
+ var beginConstruct SubexState
+ switch ast.Structure {
+ case NoneStructure:
+ beginConstruct = inner
+ case StringStructure:
+ beginConstruct = &SubexCaptureRunesBeginState {
+ next: inner,
+ }
+ case ArrayStructure:
+ beginConstruct = &SubexCaptureBeginState {
+ next: inner,
+ }
+ case ArrayValuesStructure:
+ beginConstruct = &SubexCaptureBeginState {
+ next: inner,
+ }
+ case MapStructure:
+ beginConstruct = &SubexCaptureBeginState {
+ next: inner,
+ }
+ default:
+ panic("Invalid ast structure")
+ }
+
+ switch ast.Destructure {
+ case NoneStructure:
+ return beginConstruct
+ case StringStructure:
+ return &SubexCaptureBeginState {
+ next: &SubexCopyState {
+ filter: anyStringFilter{},
+ next: &SubexDiscardState {
+ next: &SubexIncrementNestState {
+ keys: true,
+ next: beginConstruct,
+ },
+ },
+ },
+ }
+ case ArrayStructure:
+ return &SubexCaptureBeginState {
next: &SubexCopyState {
filter: anyArrayFilter{},
next: &SubexDiscardState {
- next: &SubexCaptureBeginState {
- next: ast.Content.compileWith(
- &SubexDiscardTerminalState {
- terminal: walk.ArrayEndTerminal{},
- next: &SubexDecrementNestState {
- next: &SubexConstructArrayState {next: next},
- },
- },
- slotMap,
- runic,
- ),
+ next: &SubexIncrementNestState {
+ keys: true,
+ next: beginConstruct,
},
},
},
- },
- }
-}
-
-type SubexASTEnterString struct {
- Content SubexAST
-}
-func (ast SubexASTEnterString) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- return &SubexCaptureBeginState {
- next: &SubexIncrementNestState {
+ }
+ case ArrayValuesStructure:
+ return &SubexCaptureBeginState {
next: &SubexCopyState {
- filter: anyStringFilter{},
+ filter: anyArrayFilter{},
+ next: &SubexDiscardState {
+ next: &SubexIncrementNestState {
+ keys: false,
+ next: beginConstruct,
+ },
+ },
+ },
+ }
+ case MapStructure:
+ return &SubexCaptureBeginState {
+ next: &SubexCopyState {
+ filter: anyMapFilter{},
next: &SubexDiscardState {
- next: &SubexCaptureRunesBeginState {
- next: ast.Content.compileWith(
- &SubexDecrementNestState {
- next: &SubexDiscardTerminalState {
- terminal: walk.StringEndTerminal{},
- next: &SubexConstructStringState {next: next},
- },
- },
- slotMap,
- true,
- ),
+ next: &SubexIncrementNestState {
+ keys: true,
+ next: beginConstruct,
},
},
},
- },
+ }
+ default:
+ panic("Invalid destructure in ast")
}
}
+func (ast SubexASTDestructure) String() string {
+ return fmt.Sprintf("%v(%v)%v", ast.Destructure, ast.Content, ast.Structure)
+}