<- 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.go82
1 files changed, 60 insertions, 22 deletions
diff --git a/subex/parse.go b/subex/parse.go
index d7fe243..619c1c3 100644
--- a/subex/parse.go
+++ b/subex/parse.go
@@ -1,6 +1,7 @@
package subex
import (
+ "fmt"
"main/walk"
"strconv"
"strings"
@@ -115,6 +116,7 @@ func parseScalarLiteral(l RuneReader) (walk.Scalar, bool) {
panic("Invalid literal")
}
default:
+ fmt.Printf("%c\n", r)
panic("Invalid literal")
}
}
@@ -181,7 +183,8 @@ func parseRepeatRange(l RuneReader) (output []ConvexRange) {
return output
}
-func parseValueReplacement(l RuneReader) (output []OutputValueAST) {
+func parseValueReplacement(l RuneReader) (output SubexAST) {
+ output = SubexASTEmpty{}
// TODO escaping
// TODO add arrays, maps and strings
loop: for {
@@ -197,37 +200,67 @@ func parseValueReplacement(l RuneReader) (output []OutputValueAST) {
if slot == eof {
panic("Missing slot character")
}
- output = append(output, OutputValueLoadAST {slot: slot})
+ output = SubexASTConcat {
+ First: output,
+ Second: SubexASTOutputValueLoad {
+ slot: slot,
+ },
+ }
+ // TODO: destructures
+ case '"':
+ output = SubexASTConcat {
+ First: output,
+ Second: SubexASTDestructure {
+ Destructure: NoneStructure,
+ Structure: StringStructure,
+ Content: parseRuneReplacement(l, '"'),
+ },
+ }
default:
l.Rewind()
scalar, ok := parseScalarLiteral(l)
if !ok {
panic("Invalid scalar literal")
}
- output = append(output, OutputValueLiteralAST {scalar})
+ output = SubexASTConcat {
+ First: output,
+ Second: SubexASTOutputValueLiteral {
+ literal: scalar,
+ },
+ }
}
}
return output
}
-func parseRuneReplacement(l RuneReader) (output []OutputRuneAST) {
+func parseRuneReplacement(l RuneReader, end rune) (output SubexAST) {
+ output = SubexASTEmpty{}
// TODO escaping
- // TODO add arrays, maps and strings
loop: for {
r := l.Next()
switch r {
case eof:
panic("Missing closing `")
- case '`':
+ case end:
break loop
case '$':
slot := l.Next()
if slot == eof {
panic("Missing slot character")
}
- output = append(output, OutputRuneLoadAST {slot: slot})
+ output = SubexASTConcat {
+ First: output,
+ Second: SubexASTOutputRuneLoad {
+ slot: slot,
+ },
+ }
default:
- output = append(output, OutputRuneLiteralAST {r})
+ output = SubexASTConcat {
+ First: output,
+ Second: SubexASTOutputRuneLiteral {
+ literal: r,
+ },
+ }
}
}
return output
@@ -394,6 +427,7 @@ func parseDestructure(l RuneReader, destructure Structure, inType Type) (lhs Sub
}
func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType Type) {
+ start:
r := l.Next()
switch r {
case eof:
@@ -467,16 +501,14 @@ func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType
lhs = SubexASTCopyNumber{}
case '`':
outType = inType
- lhs = SubexASTOutputValues {parseValueReplacement(l)}
- // TODO
- // case '_':
- // lhs = SubexASTCopyStringAtom{}
- // case '#':
- // lhs = SubexASTCopyString{}
- // case ',':
- // lhs = SubexASTCopyValue{}
- // case '"':
- // lhs = SubexASTCopyScalar {walk.NewAtomStringTerminal()}
+ lhs = parseValueReplacement(l)
+ case ' ':
+ if inType == RuneType {
+ outType = RuneType
+ lhs = SubexASTCopyRune {' '}
+ } else {
+ goto start
+ }
default:
outType = inType
if inType == RuneType {
@@ -533,10 +565,16 @@ func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType
InnerOutType: outType,
}
} else {
- resolveTypes(inType, ValueType)
- lhs = SubexASTStoreValues {
- Match: lhs,
- Slot: slot,
+ if inType == ValueType {
+ lhs = SubexASTStoreValues {
+ Match: lhs,
+ Slot: slot,
+ }
+ } else {
+ lhs = SubexASTStoreRunes {
+ Match: lhs,
+ Slot: slot,
+ }
}
}
outType = AnyType