package main import ( "fmt" "strings" ) func parseList(s string) ([]string, []string) { if !isList(value{word: s}) { panic(fmt.Errorf("list: %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, list } func makeList(list []string) string { return strings.Join(append(append([]string{"["}, list...), "]"), " ") } func indexOfList(list []string, index int) string { if index < 0 || index >= len(list) { panic(fmt.Errorf("list: %s (%d / %d)", errIndexOutOfBound, index, len(list))) } return list[index] } func rangeOfList(list []string, index1, index2 int) string { if index1 < 0 || index1 > len(list) || index2 < 0 || index2 > len(list) { panic(fmt.Errorf("list: %s (%d : %d / %d)", errIndexOutOfBound, index1, index2, len(list))) } if index1 > index2 { panic(fmt.Errorf("list: %s (%d : %d)", errIllegalRange, index1, index2)) } return makeList(list[index1:index2]) } func spliceList(list []string, index int, cnt int, val ...string) string { if index < 0 || index > len(list) { panic(fmt.Errorf("list: %s (%d / %d)", errIndexOutOfBound, index, len(list))) } if index+cnt > len(list) { cnt = len(list) - index } return makeList(append(append(list[:index], val...), list[index+cnt:]...)) } func opWord(val1, val2 value) value { if !isWord(val1) || isList(val2) { panic(fmt.Errorf("word: %s", errWordExpceted)) } return value{tp: typeWord, word: val1.word + toString(val2)} } func opSentence(val1, val2 value) value { list1, list2 := []string{toString(val1)}, []string{toString(val2)} if isList(val1) { list1 = val1.list } if isList(val2) { list2 = val2.list } return value{word: makeList(append(list1, list2...))} } func opList(val1, val2 value) value { return value{word: makeList([]string{toString(val1), toString(val2)})} } func opJoin(val1, val2 value) value { if !isList(val1) { fmt.Println(val1, val2) panic(fmt.Errorf("join: %s", errListExpected)) } return value{word: makeList(append(val1.list, toString(val2)))} } func opFirst(val1 value) value { if !isWord(val1) && !isList(val1) { panic(fmt.Errorf("first: %s", errWordOrListExpected)) } if isEmpty(val1) { panic(fmt.Errorf("first: %s", errEmptyWordOrList)) } if isWord(val1) { return value{word: val1.word[:2]} } val := value{word: val1.list[0]} if !isList(val) { val.word = `"` + val.word } return val } func opLast(val1 value) value { if !isWord(val1) && !isList(val1) { panic(fmt.Errorf("last: %s", errWordOrListExpected)) } if isEmpty(val1) { panic(fmt.Errorf("last: %s", errEmptyWordOrList)) } if isWord(val1) { return value{word: `"` + val1.word[len(val1.word)-1:]} } val := value{word: val1.list[len(val1.list)-1]} if !isList(val) { val.word = `"` + val.word } return val } func opButFirst(val1 value) value { if !isWord(val1) && !isList(val1) { panic(fmt.Errorf("butfirst: %s", errWordOrListExpected)) } if isEmpty(val1) { panic(fmt.Errorf("butfirst: %s", errEmptyWordOrList)) } if isWord(val1) { return value{word: `"` + val1.word[2:]} } return value{word: makeList(val1.list[1:])} } func opButLast(val1 value) value { if !isWord(val1) && !isList(val1) { panic(fmt.Errorf("butlast: %s", errWordOrListExpected)) } if isEmpty(val1) { panic(fmt.Errorf("butlast: %s", errEmptyWordOrList)) } if isWord(val1) { return value{word: val1.word[:len(val1.word)-1]} } return value{word: makeList(val1.list[:len(val1.list)-1])} }