<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2024-05-02 21:45:45 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2024-05-02 21:45:45 +0100
commitb434fe4e14f6dcc8d1d7433a29351b8e8ea77d37 (patch)
tree50b7e54713d23c965f6ffc23d9feeecd1dd60301
parent22ccb0c370cf2690f1b1a80fe003e05c6ba5e5ed (diff)
downloadstred-go-main.tar
Add , subex syntax to make FullMerge commands easierHEADmain
-rw-r--r--main/main_test.go15
-rw-r--r--subex/filter.go20
-rw-r--r--subex/parse.go11
-rw-r--r--subex/subexast.go12
4 files changed, 54 insertions, 4 deletions
diff --git a/main/main_test.go b/main/main_test.go
index 3d10c48..076693d 100644
--- a/main/main_test.go
+++ b/main/main_test.go
@@ -6,7 +6,8 @@ import (
)
const miscInput string = `{"something":{"nested":"Here is my test value"},"array":["Hello","world","these","are","values"],"people":[{"first_name":"Charlie","last_name":"Johnson","age":22},{"first_name":"Tom","last_name":"Johnson","age":18},{"first_name":"Charlie","last_name":"Chaplin","age":122},{"first_name":"John","last_name":"Johnson","age":48}]}`
-const mixedArray string = `{"array":["first",{"name":"second"},"third"]}`
+const mixedArray string = `{"array":["first",null,3,{"name":"second"},"third"]}`
+const mixedArray2 string = `{"array":["first",null,3,"second",{"name":"third"}]}`
func TestSpecificCases(t *testing.T) {
type test struct {
@@ -116,7 +117,7 @@ func TestSpecificCases(t *testing.T) {
},
{
name: "Drop last element of array",
- program: `M/#( "people" @( . #()# )@ )#/{ Ed }`,
+ program: `M/#( "people" @( . , )@ )#/{ Ed }`,
input: miscInput,
expected: `{"something":{"nested":"Here is my test value"},"array":["Hello","world","these","are","values"],"people":[{"first_name":"Charlie","last_name":"Johnson","age":22},{"first_name":"Tom","last_name":"Johnson","age":18},{"first_name":"Charlie","last_name":"Chaplin","age":122}]}`,
},
@@ -128,9 +129,15 @@ func TestSpecificCases(t *testing.T) {
},
{
name: "Drop last element of mixed array",
- program: `M/#( "array" @( . (~[.]~|@()@|#()#) )@ )#/{ Ed }`,
+ program: `M/#( "array" @( . , )@ )#/{ Ed }`,
input: mixedArray,
- expected: `{"array":["first",{"name":"second"}]}`,
+ expected: `{"array":["first",null,3,{"name":"second"}]}`,
+ },
+ {
+ name: "Drop last element of mixed array 2",
+ program: `M/#( "array" @( . , )@ )#/{ Ed }`,
+ input: mixedArray2,
+ expected: `{"array":["first",null,3,"second"]}`,
},
{
name: "Prepend to array",
diff --git a/subex/filter.go b/subex/filter.go
index ae4b8ab..309d6c7 100644
--- a/subex/filter.go
+++ b/subex/filter.go
@@ -27,6 +27,26 @@ func (_ anyBoolFilter) valueFilter(value walk.Value) bool {
return isBool
}
+type simpleValueFilter struct {}
+func (_ simpleValueFilter) valueFilter(value walk.Value) bool {
+ switch value := value.(type) {
+ case walk.NullValue:
+ return true
+ case walk.BoolValue:
+ return true
+ case walk.NumberValue:
+ return true
+ case walk.StringValue:
+ return true
+ case walk.ArrayValue:
+ return len(value) == 0
+ case walk.MapValue:
+ return len(value) == 0
+ default:
+ panic("Invalid value type")
+ }
+}
+
type anyValueFilter struct {}
func (_ anyValueFilter) valueFilter(value walk.Value) bool {
return true
diff --git a/subex/parse.go b/subex/parse.go
index 9a7a75c..e91008a 100644
--- a/subex/parse.go
+++ b/subex/parse.go
@@ -520,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{}
diff --git a/subex/subexast.go b/subex/subexast.go
index d08ddac..655a783 100644
--- a/subex/subexast.go
+++ b/subex/subexast.go
@@ -238,6 +238,18 @@ func (ast SubexASTCopyNumber) 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, inType Type, outType Type) SubexState {