Skip to content

Commit 5a288a2

Browse files
committed
Merge branch 'main' into node_categories
2 parents 3683cf5 + 8592e8d commit 5a288a2

File tree

12 files changed

+185
-33
lines changed

12 files changed

+185
-33
lines changed

cmd/docgen/docs/base_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func TestGenerateDocs(t *testing.T) {
4343
context := completion["context"].(map[string]any)
4444
functions := completion["functions"].([]any)
4545

46-
assert.Equal(t, 89, len(functions))
46+
assert.Equal(t, 90, len(functions))
4747

4848
types := context["types"].([]any)
4949
assert.Equal(t, 21, len(types))

excellent/functions/builtin.go

+49-25
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,15 @@ func init() {
103103
"time_from_parts": ThreeIntegerFunction(TimeFromParts),
104104

105105
// array functions
106-
"contains": TwoArgFunction(Contains),
107-
"join": TwoArgFunction(Join),
106+
"slice": InitialArrayFunction(1, 2, Slice),
107+
"contains": InitialArrayFunction(1, 1, Contains),
108+
"join": InitialArrayFunction(1, 1, Join),
108109
"reverse": OneArrayFunction(Reverse),
109110
"sort": OneArrayFunction(Sort),
110111
"sum": OneArrayFunction(Sum),
111112
"unique": OneArrayFunction(Unique),
112113
"concat": TwoArrayFunction(Concat),
113-
"filter": TwoArgFunction(Filter),
114+
"filter": InitialArrayFunction(1, 1, Filter),
114115

115116
// encoded text functions
116117
"urn_parts": OneTextFunction(URNParts),
@@ -1518,23 +1519,55 @@ func TimeFromParts(env envs.Environment, hour, minute, second int) types.XValue
15181519
// Array Functions
15191520
//------------------------------------------------------------------------------------------
15201521

1522+
// Slice extracts a sub-sequence of items from `array`.
1523+
//
1524+
// The returned items are those from `start` up to but not-including `end`. Indexes start at zero and a negative
1525+
// end value counts back from the end.
1526+
//
1527+
// @(slice(array("a", "b", "c"), 0, 2)) -> [a, b]
1528+
// @(slice(array("a", "b", "c"), 1, 3)) -> [b, c]
1529+
// @(slice(array("a", "b", "c"), 0, -1)) -> [a, b]
1530+
// @(slice(array("a", "b", "c"), 1)) -> [b, c]
1531+
// @(slice(array("a", "b", "c"), 10)) -> []
1532+
//
1533+
// @function slice(array, start, [,end])
1534+
func Slice(env envs.Environment, array *types.XArray, args ...types.XValue) types.XValue {
1535+
start, xerr := types.ToInteger(env, args[0])
1536+
if xerr != nil {
1537+
return xerr
1538+
}
1539+
if start < 0 {
1540+
return types.NewXErrorf("must start with a positive index")
1541+
}
1542+
1543+
end := array.Count()
1544+
if len(args) == 2 {
1545+
if end, xerr = types.ToInteger(env, args[1]); xerr != nil {
1546+
return xerr
1547+
}
1548+
}
1549+
1550+
start = min(start, array.Count())
1551+
if end < 0 {
1552+
end = max(start, array.Count()+end)
1553+
}
1554+
1555+
return array.Slice(start, end)
1556+
}
1557+
15211558
// Contains returns whether `array` contains `value`.
15221559
//
15231560
// @(contains(array("a", "b", "c"), "a")) -> true
15241561
// @(contains(array(1, 2, 3), 4)) -> false
15251562
//
15261563
// @function contains(array, value)
1527-
func Contains(env envs.Environment, arg1 types.XValue, value types.XValue) types.XValue {
1528-
array, xerr := types.ToXArray(env, arg1)
1529-
if xerr != nil {
1530-
return xerr
1531-
}
1532-
if types.IsXError(value) {
1533-
return value
1564+
func Contains(env envs.Environment, array *types.XArray, args ...types.XValue) types.XValue {
1565+
if types.IsXError(args[0]) {
1566+
return args[0]
15341567
}
15351568

1536-
for i := 0; i < array.Count(); i++ {
1537-
if types.Equals(array.Get(i), value) {
1569+
for i := range array.Count() {
1570+
if types.Equals(array.Get(i), args[0]) {
15381571
return types.XBooleanTrue
15391572
}
15401573
}
@@ -1548,13 +1581,8 @@ func Contains(env envs.Environment, arg1 types.XValue, value types.XValue) types
15481581
// @(join(split("a.b.c", "."), " ")) -> a b c
15491582
//
15501583
// @function join(array, separator)
1551-
func Join(env envs.Environment, arg1 types.XValue, arg2 types.XValue) types.XValue {
1552-
array, xerr := types.ToXArray(env, arg1)
1553-
if xerr != nil {
1554-
return xerr
1555-
}
1556-
1557-
separator, xerr := types.ToXText(env, arg2)
1584+
func Join(env envs.Environment, array *types.XArray, args ...types.XValue) types.XValue {
1585+
separator, xerr := types.ToXText(env, args[0])
15581586
if xerr != nil {
15591587
return xerr
15601588
}
@@ -1700,12 +1728,8 @@ func Concat(env envs.Environment, array1 *types.XArray, array2 *types.XArray) ty
17001728
// @(filter(array("a", "b", "c"), (x) => x != "c")) -> [a, b]
17011729
//
17021730
// @function filter(array, func)
1703-
func Filter(env envs.Environment, arg1 types.XValue, arg2 types.XValue) types.XValue {
1704-
array, xerr := types.ToXArray(env, arg1)
1705-
if xerr != nil {
1706-
return xerr
1707-
}
1708-
function, xerr := types.ToXFunction(arg2)
1731+
func Filter(env envs.Environment, array *types.XArray, args ...types.XValue) types.XValue {
1732+
function, xerr := types.ToXFunction(args[0])
17091733
if xerr != nil {
17101734
return xerr
17111735
}

excellent/functions/builtin_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,14 @@ func TestFunctions(t *testing.T) {
586586
{"round_up", dmy, []types.XValue{xs("not_num")}, ERROR},
587587
{"round_up", dmy, []types.XValue{}, ERROR},
588588

589+
{"slice", dmy, []types.XValue{xa(xs("a"), xs("b"), xs("c")), xi(0), xi(2)}, xa(xs("a"), xs("b"))},
590+
{"slice", dmy, []types.XValue{xa(xs("a"), xs("b"), xs("c")), xi(1), xi(3)}, xa(xs("b"), xs("c"))},
591+
{"slice", dmy, []types.XValue{xa(xs("a"), xs("b"), xs("c")), xi(1)}, xa(xs("b"), xs("c"))},
592+
{"slice", dmy, []types.XValue{xa(xs("a"), xs("b"), xs("c")), xi(0), xi(-1)}, xa(xs("a"), xs("b"))},
593+
{"slice", dmy, []types.XValue{xa(xs("a"), xs("b"), xs("c")), xi(10)}, xa()},
594+
{"slice", dmy, []types.XValue{xa(xs("a"), xs("b"), xs("c")), xi(0), xi(-10)}, xa()},
595+
{"slice", dmy, []types.XValue{xa(xs("a"), xs("b"), xs("c")), xi(-1)}, ERROR},
596+
589597
{"sort", dmy, []types.XValue{xa()}, xa()},
590598
{"sort", dmy, []types.XValue{xa(xn("3"))}, xa(xn("3"))},
591599
{"sort", dmy, []types.XValue{xa(xn("3"), xn("1"), xn("2"))}, xa(xn("1"), xn("2"), xn("3"))},

excellent/functions/wrappers.go

+11
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,17 @@ func InitialTextFunction(minOtherArgs int, maxOtherArgs int, f func(envs.Environ
192192
})
193193
}
194194

195+
// InitialArrayFunction creates an XFunc from a function that takes an initial array arg followed by other args
196+
func InitialArrayFunction(minOtherArgs int, maxOtherArgs int, f func(envs.Environment, *types.XArray, ...types.XValue) types.XValue) types.XFunc {
197+
return MinAndMaxArgsCheck(minOtherArgs+1, maxOtherArgs+1, func(env envs.Environment, args ...types.XValue) types.XValue {
198+
arr, xerr := types.ToXArray(env, args[0])
199+
if xerr != nil {
200+
return xerr
201+
}
202+
return f(env, arr, args[1:]...)
203+
})
204+
}
205+
195206
// OneNumberFunction creates an XFunc from a single number function
196207
func OneNumberFunction(f func(envs.Environment, *types.XNumber) types.XValue) types.XFunc {
197208
return NumArgsCheck(1, func(env envs.Environment, args ...types.XValue) types.XValue {

excellent/types/array.go

+5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ func (x *XArray) Get(index int) XValue {
4444
return x.values()[index]
4545
}
4646

47+
// Get is called when this object is indexed
48+
func (x *XArray) Slice(start, end int) *XArray {
49+
return NewXArray(x.values()[start:end]...)
50+
}
51+
4752
// Count is called when the length of this object is requested in an expression
4853
func (x *XArray) Count() int {
4954
return len(x.values())

locale/cs/flows.po

+19-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#, fuzzy
77
msgid ""
88
msgstr ""
9-
"POT-Creation-Date: 2025-04-02 15:22-0500\n"
9+
"POT-Creation-Date: 2025-04-03 14:28-0500\n"
1010
"Last-Translator: trendspotter <[email protected]>, 2021\n"
1111
"Language-Team: Czech (https://www.transifex.com/rapidpro/teams/226/cs/)\n"
1212
"Language: cs\n"
@@ -69,6 +69,11 @@ msgstr ""
6969
msgid "Encodes `text` for use as a URL parameter."
7070
msgstr "Zakóduje `text` pro použití jako parametr URL."
7171

72+
#, fuzzy
73+
#| msgid "Extracts a sub-sequence of words from `text`."
74+
msgid "Extracts a sub-sequence of items from `array`."
75+
msgstr "Extrahuje dílčí posloupnost slov z `text`."
76+
7277
msgid "Extracts a sub-sequence of words from `text`."
7378
msgstr "Extrahuje dílčí posloupnost slov z `text`."
7479

@@ -344,6 +349,9 @@ msgstr "Vrátí nové pole s hodnotami `array` seřazenými."
344349
msgid "Returns a new datetime with the time part replaced by the `time`."
345350
msgstr "Vrátí nový datetime s časovou částí nahrazenou hodnotou `time`."
346351

352+
msgid "Returns a pre-defined LLM prompt."
353+
msgstr ""
354+
347355
msgid "Returns a single random number between [0.0-1.0)."
348356
msgstr "Vrátí jedno náhodné číslo v rozsahu [0.0-1.0)."
349357

@@ -594,6 +602,16 @@ msgid ""
594602
"and 1 if `text1` comes after `text2`."
595603
msgstr "Návratová hodnota bude -1, pokud je `text1` před `text2`, 0, pokud jsou stejné, a 1, pokud je `text1` za `text2`."
596604

605+
#, fuzzy
606+
#| msgid ""
607+
#| "The returned words are those from `start` up to but not-including `end`. Indexes start at zero and a negative\n"
608+
#| "end value means that all words after the start should be returned. There is an optional final parameter `delimiters`\n"
609+
#| "which is string of characters used to split the text into words."
610+
msgid ""
611+
"The returned items are those from `start` up to but not-including `end`. Indexes start at zero and a negative\n"
612+
"end value counts back from the end."
613+
msgstr "Vrácená slova jsou slova od `start` až po `end`, ale bez něj. Indexy začínají nulou a záporná hodnota konce znamená, že by měla být vrácena všechna slova po začátku. K dispozici je nepovinný koncový parametr `delimiters`, což je řetězec znaků použitý k rozdělení textu na slova."
614+
597615
msgid "The returned number can contain fractional seconds."
598616
msgstr "Vrácené číslo může obsahovat zlomky sekund."
599617

locale/en_US/flows.po

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#, fuzzy
44
msgid ""
55
msgstr ""
6-
"POT-Creation-Date: 2025-04-02 15:22-0500\n"
6+
"POT-Creation-Date: 2025-04-03 14:28-0500\n"
77
"Language: en_US\n"
88
"MIME-Version: 1.0\n"
99
"Content-Type: text/plain; charset=UTF-8\n"
@@ -61,6 +61,9 @@ msgstr ""
6161
msgid "Encodes `text` for use as a URL parameter."
6262
msgstr ""
6363

64+
msgid "Extracts a sub-sequence of items from `array`."
65+
msgstr ""
66+
6467
msgid "Extracts a sub-sequence of words from `text`."
6568
msgstr ""
6669

@@ -272,6 +275,9 @@ msgstr ""
272275
msgid "Returns a new datetime with the time part replaced by the `time`."
273276
msgstr ""
274277

278+
msgid "Returns a pre-defined LLM prompt."
279+
msgstr ""
280+
275281
msgid "Returns a single random number between [0.0-1.0)."
276282
msgstr ""
277283

@@ -467,6 +473,11 @@ msgid ""
467473
"and 1 if `text1` comes after `text2`."
468474
msgstr ""
469475

476+
msgid ""
477+
"The returned items are those from `start` up to but not-including `end`. Indexes start at zero and a negative\n"
478+
"end value counts back from the end."
479+
msgstr ""
480+
470481
msgid "The returned number can contain fractional seconds."
471482
msgstr ""
472483

locale/es/flows.po

+22-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#, fuzzy
99
msgid ""
1010
msgstr ""
11-
"POT-Creation-Date: 2025-04-02 15:22-0500\n"
11+
"POT-Creation-Date: 2025-04-03 14:28-0500\n"
1212
"Last-Translator: Rowan Seymour <[email protected]>, 2022\n"
1313
"Language-Team: Spanish (https://www.transifex.com/rapidpro/teams/226/es/)\n"
1414
"Language: es\n"
@@ -71,6 +71,11 @@ msgstr ""
7171
msgid "Encodes `text` for use as a URL parameter."
7272
msgstr "Codifica `text` para utilizarlo como parámetro de URL."
7373

74+
#, fuzzy
75+
#| msgid "Extracts a sub-sequence of words from `text`."
76+
msgid "Extracts a sub-sequence of items from `array`."
77+
msgstr "Extrae una subsecuencia de palabras de `text`."
78+
7479
msgid "Extracts a sub-sequence of words from `text`."
7580
msgstr "Extrae una subsecuencia de palabras de `text`."
7681

@@ -360,6 +365,9 @@ msgstr "Devuelve un nuevo array de los valores de `array` ordenados."
360365
msgid "Returns a new datetime with the time part replaced by the `time`."
361366
msgstr "Devuelve una nueva fecha y hora con la parte de la hora reemplazada por `hour`."
362367

368+
msgid "Returns a pre-defined LLM prompt."
369+
msgstr ""
370+
363371
msgid "Returns a single random number between [0.0-1.0)."
364372
msgstr "Devuelve un solo número aleatorio entre [0.0-1.0)."
365373

@@ -619,6 +627,19 @@ msgstr ""
619627
"El valor de retorno será -1 si `text1` viene antes de` text2`, 0 si son iguales\n"
620628
"y 1 si `text1` viene después de` text2`."
621629

630+
#, fuzzy
631+
#| msgid ""
632+
#| "The returned words are those from `start` up to but not-including `end`. Indexes start at zero and a negative\n"
633+
#| "end value means that all words after the start should be returned. There is an optional final parameter `delimiters`\n"
634+
#| "which is string of characters used to split the text into words."
635+
msgid ""
636+
"The returned items are those from `start` up to but not-including `end`. Indexes start at zero and a negative\n"
637+
"end value counts back from the end."
638+
msgstr ""
639+
"Las palabras devueltas son las que van desde `start` hasta `end`, pero sin incluirlas. Los índices comienzan en cero y en negativo.\n"
640+
"valor final significa que se deben devolver todas las palabras después del inicio. Hay un parámetro final opcional `delimiters`\n"
641+
"que es una cadena de caracteres utilizada para dividir el texto en palabras."
642+
622643
msgid "The returned number can contain fractional seconds."
623644
msgstr "El número devuelto puede contener fracciones de segundo."
624645

locale/fr/flows.po

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#, fuzzy
44
msgid ""
55
msgstr ""
6-
"POT-Creation-Date: 2025-04-02 15:22-0500\n"
6+
"POT-Creation-Date: 2025-04-03 14:28-0500\n"
77
"Language-Team: French (https://www.transifex.com/rapidpro/teams/226/fr/)\n"
88
"Language: fr\n"
99
"MIME-Version: 1.0\n"
@@ -63,6 +63,9 @@ msgstr ""
6363
msgid "Encodes `text` for use as a URL parameter."
6464
msgstr ""
6565

66+
msgid "Extracts a sub-sequence of items from `array`."
67+
msgstr ""
68+
6669
msgid "Extracts a sub-sequence of words from `text`."
6770
msgstr ""
6871

@@ -274,6 +277,9 @@ msgstr ""
274277
msgid "Returns a new datetime with the time part replaced by the `time`."
275278
msgstr ""
276279

280+
msgid "Returns a pre-defined LLM prompt."
281+
msgstr ""
282+
277283
msgid "Returns a single random number between [0.0-1.0)."
278284
msgstr ""
279285

@@ -469,6 +475,11 @@ msgid ""
469475
"and 1 if `text1` comes after `text2`."
470476
msgstr ""
471477

478+
msgid ""
479+
"The returned items are those from `start` up to but not-including `end`. Indexes start at zero and a negative\n"
480+
"end value counts back from the end."
481+
msgstr ""
482+
472483
msgid "The returned number can contain fractional seconds."
473484
msgstr ""
474485

locale/mn/flows.po

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#, fuzzy
44
msgid ""
55
msgstr ""
6-
"POT-Creation-Date: 2025-04-02 15:22-0500\n"
6+
"POT-Creation-Date: 2025-04-03 14:28-0500\n"
77
"Language-Team: Mongolian (https://www.transifex.com/rapidpro/teams/226/mn/)\n"
88
"Language: mn\n"
99
"MIME-Version: 1.0\n"
@@ -63,6 +63,9 @@ msgstr ""
6363
msgid "Encodes `text` for use as a URL parameter."
6464
msgstr ""
6565

66+
msgid "Extracts a sub-sequence of items from `array`."
67+
msgstr ""
68+
6669
msgid "Extracts a sub-sequence of words from `text`."
6770
msgstr ""
6871

@@ -274,6 +277,9 @@ msgstr ""
274277
msgid "Returns a new datetime with the time part replaced by the `time`."
275278
msgstr ""
276279

280+
msgid "Returns a pre-defined LLM prompt."
281+
msgstr ""
282+
277283
msgid "Returns a single random number between [0.0-1.0)."
278284
msgstr ""
279285

@@ -469,6 +475,11 @@ msgid ""
469475
"and 1 if `text1` comes after `text2`."
470476
msgstr ""
471477

478+
msgid ""
479+
"The returned items are those from `start` up to but not-including `end`. Indexes start at zero and a negative\n"
480+
"end value counts back from the end."
481+
msgstr ""
482+
472483
msgid "The returned number can contain fractional seconds."
473484
msgstr ""
474485

0 commit comments

Comments
 (0)