<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/subex/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'subex/parse.go')
-rw-r--r--subex/parse.go72
1 files changed, 41 insertions, 31 deletions
diff --git a/subex/parse.go b/subex/parse.go
index b6bf2f6..e91008a 100644
--- a/subex/parse.go
+++ b/subex/parse.go
@@ -55,6 +55,12 @@ func (s Structure) String() string {
}
}
+type DestructureMethod int
+const (
+ Normal DestructureMethod = iota
+ Iterate
+)
+
type RuneReader interface {
Next() rune
Rewind()
@@ -361,8 +367,14 @@ func parseRuneReplacement(l RuneReader, end rune) (output SubexAST) {
// }
func parseDestructure(l RuneReader, destructure Structure, inType Type) (lhs SubexAST, outType Type) {
- if !accept(l, "(") {
- panic("Missing ( after destructure start")
+ var method rune
+ switch l.Next() {
+ case '(':
+ method = ')'
+ case '[':
+ method = ']'
+ default:
+ panic("Missing ( or [ after destructure start")
}
var innerInType Type
@@ -390,8 +402,22 @@ func parseDestructure(l RuneReader, destructure Structure, inType Type) (lhs Sub
resolveTypes(inType, expectedInType)
lhs, innerOutType := parseSubex(l, 0, innerInType)
- if !accept(l, ")") {
- panic("Missing matching )")
+ if !accept(l, string(method)) {
+ panic("Missing matching ) or ]")
+ }
+
+ switch method {
+ case ')':
+ case ']':
+ lhs = SubexASTRepeat {
+ Content: lhs,
+ Acceptable: []ConvexRange{{
+ Start: -1,
+ End: 0,
+ }},
+ }
+ default:
+ panic("Invalid method")
}
var structure Structure
@@ -487,20 +513,6 @@ func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType
case ')', ']', '|', ';', '{', '+', '*', '/', '!', '=', '$':
l.Rewind()
return SubexASTEmpty{}, inType
- // case '=':
- // replacement := parseReplacement(l)
- // lhs = SubexASTOutput{replacement}
- // case '^':
- // replacement := parseReplacement(l)
- // replacement = append(
- // []OutputContentAST{OutputValueLiteralAST {walk.NewAtomStringTerminal()}},
- // replacement...
- // )
- // replacement = append(
- // replacement,
- // OutputValueLiteralAST {walk.NewAtomStringTerminal()},
- // )
- // lhs = SubexASTOutput {replacement}
case '.':
outType = inType
if inType == RuneType {
@@ -508,6 +520,17 @@ func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType
} else {
lhs = SubexASTCopyAnyValue{}
}
+ case ',':
+ switch inType {
+ case ValueType:
+ outType = inType
+ lhs = SubexASTCopyAnySimpleValue{}
+ case RuneType:
+ outType = inType
+ lhs = SubexASTCopyRune{','}
+ default:
+ panic("Invalid inType")
+ }
case '?':
outType = inType
lhs = SubexASTCopyBool{}
@@ -569,14 +592,10 @@ func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType
lhs = SubexASTProduct {lhs}
resolveTypes(inType, ValueType)
outType = resolveTypes(outType, ValueType)
- // case r == '/' && minPower <= 4:
- // lhs = SubexASTReciprocal {lhs}
case r == '!' && minPower <= 4:
lhs = SubexASTNot {lhs}
resolveTypes(inType, ValueType)
outType = resolveTypes(outType, ValueType)
- // case r == '=' && minPower <= 4:
- // lhs = SubexASTEqual {lhs}
case r == '$' && minPower <= 4:
slot := l.Next()
if slot == eof {
@@ -608,15 +627,6 @@ func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType
panic("Missing subex after |")
}
lhs = SubexASTOr{lhs, rhs}
- /*case r == ';' && minPower <= 10:
- rhs := parseSubex(l, 11, inType, outType)
- if rhs == nil {
- panic("Missing subex after ;")
- }
- lhs = SubexASTJoin {
- Content: lhs,
- Delimiter: rhs,
- }*/
default:
l.Rewind()
break loop