|
|
@@ -5,6 +5,69 @@ import (
|
|
|
"strings"
|
|
|
)
|
|
|
|
|
|
+func wrapList(list []string) []string {
|
|
|
+ return append(append([]string{"["}, list...), "]")
|
|
|
+}
|
|
|
+
|
|
|
+func parseList(s string) []string {
|
|
|
+ if !isList(s) {
|
|
|
+ panic(fmt.Errorf("parselist: %s (%s)", errListExpected, s))
|
|
|
+ }
|
|
|
+ list, bracketCnt, start, resList := strings.Split(s, " "), 0, 1, []string{}
|
|
|
+ for i := 1; i < len(list)-1; i++ {
|
|
|
+ if list[i] == "[" {
|
|
|
+ bracketCnt++
|
|
|
+ }
|
|
|
+ if list[i] == "]" {
|
|
|
+ bracketCnt--
|
|
|
+ }
|
|
|
+ if bracketCnt == 0 {
|
|
|
+ resList = append(resList, strings.Join(list[start:i+1], " "))
|
|
|
+ start = i + 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return resList
|
|
|
+}
|
|
|
+
|
|
|
+func indexOfList(s string, index int) string {
|
|
|
+ if !isList(s) {
|
|
|
+ panic(fmt.Errorf("indexoflist: %s (%s)", errListExpected, s))
|
|
|
+ }
|
|
|
+ list := parseList(s)
|
|
|
+ if index < 0 || index >= len(list) {
|
|
|
+ panic(fmt.Errorf("indexoflist: %s", errIndexOutOfBound))
|
|
|
+ }
|
|
|
+ return list[index]
|
|
|
+}
|
|
|
+
|
|
|
+func rangeOfList(s string, index1, index2 int) string {
|
|
|
+ if !isList(s) {
|
|
|
+ panic(fmt.Errorf("rangeoflist: %s (%s)", errListExpected, s))
|
|
|
+ }
|
|
|
+ list := parseList(s)
|
|
|
+ if index1 < 0 || index1 > len(list) || index2 < 0 || index2 > len(list) {
|
|
|
+ panic(fmt.Errorf("rangeoflist: %s", errIndexOutOfBound))
|
|
|
+ }
|
|
|
+ if index1 > index2 {
|
|
|
+ panic(fmt.Errorf("rangelist: %s", errIllegalRange))
|
|
|
+ }
|
|
|
+ return strings.Join(wrapList(list[index1:index2]), " ")
|
|
|
+}
|
|
|
+
|
|
|
+func spliceList(s string, index int, cnt int, val ...string) string {
|
|
|
+ if !isList(s) {
|
|
|
+ panic(fmt.Errorf("splicelist: %s (%s)", errListExpected, s))
|
|
|
+ }
|
|
|
+ list := parseList(s)
|
|
|
+ if index < 0 || index > len(list) {
|
|
|
+ panic(fmt.Errorf("splicelist: %s", errIndexOutOfBound))
|
|
|
+ }
|
|
|
+ if index+cnt > len(list) {
|
|
|
+ cnt = len(list) - index
|
|
|
+ }
|
|
|
+ return strings.Join(wrapList(append(append(list[:index], val...), list[index+cnt:]...)), " ")
|
|
|
+}
|
|
|
+
|
|
|
func opWord(val1, val2 value) value {
|
|
|
if !isWord(val1.val) {
|
|
|
panic(fmt.Errorf("word: %s (%s)", errWordExpceted, val1.val))
|
|
|
@@ -19,20 +82,25 @@ func opWord(val1, val2 value) value {
|
|
|
}
|
|
|
|
|
|
func opSentence(val1, val2 value) value {
|
|
|
- return value{val: "[ " +
|
|
|
- strings.TrimSuffix(strings.TrimPrefix(val1.val, "[ "), " ]") + " " +
|
|
|
- strings.TrimSuffix(strings.TrimPrefix(val2.val, "[ "), " ]") + " ]"}
|
|
|
+ list1, list2 := []string{val1.val}, []string{val2.val}
|
|
|
+ if isList(val1.val) {
|
|
|
+ list1 = parseList(val1.val)
|
|
|
+ }
|
|
|
+ if isList(val2.val) {
|
|
|
+ list2 = parseList(val2.val)
|
|
|
+ }
|
|
|
+ return value{val: strings.Join(wrapList(append(list1, list2...)), " ")}
|
|
|
}
|
|
|
|
|
|
func opList(val1, val2 value) value {
|
|
|
- return value{val: "[ " + val1.val + " " + val2.val + " ]"}
|
|
|
+ return value{val: strings.Join(wrapList([]string{val1.val, val2.val}), " ")}
|
|
|
}
|
|
|
|
|
|
func opJoin(val1, val2 value) value {
|
|
|
if !isList(val1.val) {
|
|
|
panic(fmt.Errorf("join: %s (%s)", errListExpected, val1.val))
|
|
|
}
|
|
|
- return value{val: strings.TrimSuffix(val1.val, " ]") + " " + val2.val + " ]"}
|
|
|
+ return value{val: strings.Join(wrapList(append(parseList(val1.val), val2.val)), " ")}
|
|
|
}
|
|
|
|
|
|
func opFirst(val1 value) value {
|
|
|
@@ -43,22 +111,13 @@ func opFirst(val1 value) value {
|
|
|
panic(fmt.Errorf("first: %s (%s)", errEmptyWordOrList, val1.val))
|
|
|
}
|
|
|
if isWord(val1.val) {
|
|
|
- return value{val: val1.val[1:2]}
|
|
|
- }
|
|
|
- list1 := strings.Split(val1.val, " ")
|
|
|
- if list1[1] != "[" {
|
|
|
- return value{val: list1[1]}
|
|
|
+ return value{val: val1.val[:2]}
|
|
|
}
|
|
|
- i, bracketCnt := 2, 1
|
|
|
- for ; bracketCnt > 0; i++ {
|
|
|
- if list1[i] == "[" {
|
|
|
- bracketCnt++
|
|
|
- }
|
|
|
- if list1[i] == "]" {
|
|
|
- bracketCnt--
|
|
|
- }
|
|
|
+ list1 := parseList(val1.val)
|
|
|
+ if !isList(list1[0]) {
|
|
|
+ list1[0] = `"` + list1[0]
|
|
|
}
|
|
|
- return value{val: strings.Join(list1[1:i], " ")}
|
|
|
+ return value{val: list1[0]}
|
|
|
}
|
|
|
|
|
|
func opLast(val1 value) value {
|
|
|
@@ -69,22 +128,13 @@ func opLast(val1 value) value {
|
|
|
panic(fmt.Errorf("last: %s (%s)", errEmptyWordOrList, val1.val))
|
|
|
}
|
|
|
if isWord(val1.val) {
|
|
|
- return value{val: val1.val[len(val1.val)-1:]}
|
|
|
- }
|
|
|
- list1 := strings.Split(val1.val, " ")
|
|
|
- if list1[len(list1)-2] != "]" {
|
|
|
- return value{val: list1[len(list1)-2]}
|
|
|
+ return value{val: `"` + val1.val[len(val1.val)-1:]}
|
|
|
}
|
|
|
- i, bracketCnt := len(list1)-3, 1
|
|
|
- for ; bracketCnt > 0; i-- {
|
|
|
- if list1[i] == "]" {
|
|
|
- bracketCnt++
|
|
|
- }
|
|
|
- if list1[i] == "[" {
|
|
|
- bracketCnt--
|
|
|
- }
|
|
|
+ list1 := parseList(val1.val)
|
|
|
+ if !isList(list1[len(list1)-1]) {
|
|
|
+ list1[len(list1)-1] = `"` + list1[len(list1)-1]
|
|
|
}
|
|
|
- return value{val: strings.Join(list1[i+1:len(list1)-1], " ")}
|
|
|
+ return value{val: list1[len(list1)-1]}
|
|
|
}
|
|
|
|
|
|
func opButFirst(val1 value) value {
|
|
|
@@ -97,20 +147,8 @@ func opButFirst(val1 value) value {
|
|
|
if isWord(val1.val) {
|
|
|
return value{val: `"` + val1.val[2:]}
|
|
|
}
|
|
|
- list1 := strings.Split(val1.val, " ")
|
|
|
- if list1[1] != "[" {
|
|
|
- return value{val: "[ " + strings.Join(list1[2:], " ")}
|
|
|
- }
|
|
|
- i, bracketCnt := 2, 1
|
|
|
- for ; bracketCnt > 0; i++ {
|
|
|
- if list1[i] == "[" {
|
|
|
- bracketCnt++
|
|
|
- }
|
|
|
- if list1[i] == "]" {
|
|
|
- bracketCnt--
|
|
|
- }
|
|
|
- }
|
|
|
- return value{val: "[ " + strings.Join(list1[i:], " ")}
|
|
|
+ list1 := parseList(val1.val)
|
|
|
+ return value{val: strings.Join(wrapList(list1[1:]), " ")}
|
|
|
}
|
|
|
|
|
|
func opButLast(val1 value) value {
|
|
|
@@ -123,18 +161,6 @@ func opButLast(val1 value) value {
|
|
|
if isWord(val1.val) {
|
|
|
return value{val: val1.val[:len(val1.val)-1]}
|
|
|
}
|
|
|
- list1 := strings.Split(val1.val, " ")
|
|
|
- if list1[len(list1)-2] != "]" {
|
|
|
- return value{val: strings.Join(list1[:len(list1)-2], " ") + " ]"}
|
|
|
- }
|
|
|
- i, bracketCnt := len(list1)-3, 1
|
|
|
- for ; bracketCnt > 0; i-- {
|
|
|
- if list1[i] == "]" {
|
|
|
- bracketCnt++
|
|
|
- }
|
|
|
- if list1[i] == "[" {
|
|
|
- bracketCnt--
|
|
|
- }
|
|
|
- }
|
|
|
- return value{val: strings.Join(list1[:i+1], " ") + " ]"}
|
|
|
+ list1 := parseList(val1.val)
|
|
|
+ return value{val: strings.Join(wrapList(list1[:len(list1)-1]), " ")}
|
|
|
}
|