mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
More string functions
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
committed by
Anand Krishnamoorthi
parent
27c5afd8ee
commit
3c3cd312fc
@@ -5,7 +5,7 @@ use crate::ast::Expr;
|
||||
use crate::builtins;
|
||||
use crate::builtins::utils::{ensure_args_count, ensure_string, ensure_string_collection};
|
||||
use crate::lexer::Span;
|
||||
use crate::value::Value;
|
||||
use crate::value::{Float, Value};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -14,6 +14,12 @@ use anyhow::Result;
|
||||
pub fn register(m: &mut HashMap<&'static str, builtins::BuiltinFcn>) {
|
||||
m.insert("concat", concat);
|
||||
m.insert("contains", contains);
|
||||
m.insert("endswith", endswith);
|
||||
m.insert("indexof", indexof);
|
||||
m.insert("indexof_n", indexof_n);
|
||||
m.insert("lower", lower);
|
||||
m.insert("startswith", startswith);
|
||||
m.insert("upper", upper);
|
||||
}
|
||||
|
||||
fn concat(span: &Span, params: &[Expr], args: &[Value]) -> Result<Value> {
|
||||
@@ -31,3 +37,63 @@ fn contains(span: &Span, params: &[Expr], args: &[Value]) -> Result<Value> {
|
||||
let s2 = ensure_string(name, ¶ms[1], &args[1])?;
|
||||
Ok(Value::Bool(s1.contains(&s2)))
|
||||
}
|
||||
|
||||
fn endswith(span: &Span, params: &[Expr], args: &[Value]) -> Result<Value> {
|
||||
let name = "endswith";
|
||||
ensure_args_count(span, name, params, args, 2)?;
|
||||
let s1 = ensure_string(name, ¶ms[0], &args[0])?;
|
||||
let s2 = ensure_string(name, ¶ms[1], &args[1])?;
|
||||
Ok(Value::Bool(s1.ends_with(&s2)))
|
||||
}
|
||||
|
||||
fn indexof(span: &Span, params: &[Expr], args: &[Value]) -> Result<Value> {
|
||||
let name = "indexof";
|
||||
ensure_args_count(span, name, params, args, 2)?;
|
||||
let s1 = ensure_string(name, ¶ms[0], &args[0])?;
|
||||
let s2 = ensure_string(name, ¶ms[1], &args[1])?;
|
||||
Ok(Value::from_float(match s1.find(&s2) {
|
||||
Some(pos) => pos as i64,
|
||||
_ => -1,
|
||||
} as Float))
|
||||
}
|
||||
|
||||
fn indexof_n(span: &Span, params: &[Expr], args: &[Value]) -> Result<Value> {
|
||||
let name = "indexof_n";
|
||||
ensure_args_count(span, name, params, args, 2)?;
|
||||
let s1 = ensure_string(name, ¶ms[0], &args[0])?;
|
||||
let s2 = ensure_string(name, ¶ms[1], &args[1])?;
|
||||
|
||||
let mut positions = vec![];
|
||||
let mut idx = 0;
|
||||
while idx < s1.len() {
|
||||
if let Some(pos) = s1.find(&s2) {
|
||||
positions.push(Value::from_float(pos as Float));
|
||||
idx = pos + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(Value::from_array(positions))
|
||||
}
|
||||
|
||||
fn lower(span: &Span, params: &[Expr], args: &[Value]) -> Result<Value> {
|
||||
let name = "lower";
|
||||
ensure_args_count(span, name, params, args, 1)?;
|
||||
let s = ensure_string(name, ¶ms[0], &args[0])?;
|
||||
Ok(Value::String(s.to_lowercase()))
|
||||
}
|
||||
|
||||
fn startswith(span: &Span, params: &[Expr], args: &[Value]) -> Result<Value> {
|
||||
let name = "startswith";
|
||||
ensure_args_count(span, name, params, args, 2)?;
|
||||
let s1 = ensure_string(name, ¶ms[0], &args[0])?;
|
||||
let s2 = ensure_string(name, ¶ms[1], &args[1])?;
|
||||
Ok(Value::Bool(s1.starts_with(&s2)))
|
||||
}
|
||||
|
||||
fn upper(span: &Span, params: &[Expr], args: &[Value]) -> Result<Value> {
|
||||
let name = "upper";
|
||||
ensure_args_count(span, name, params, args, 1)?;
|
||||
let s = ensure_string(name, ¶ms[0], &args[0])?;
|
||||
Ok(Value::String(s.to_uppercase()))
|
||||
}
|
||||
|
||||
@@ -9,16 +9,16 @@ cases:
|
||||
package test
|
||||
|
||||
# Arrays
|
||||
a1 = concat(", ", ["Hello", "world"])
|
||||
a1 = concat(", ", ["Hello", "world"])
|
||||
a2 = concat("", ["Hello", "world"]) # empty delimiter
|
||||
a3 = concat(",", []) # empty array
|
||||
a4 = concat("", []) # empty array and delimiter
|
||||
|
||||
a4 = concat("", []) # empty array and delimiter
|
||||
|
||||
# Sets
|
||||
s1 = concat(", ", {"world", "Hello"})
|
||||
s2 = concat("", {"world", "Hello"}) # empty delimiter
|
||||
s3 = concat(",", set()) # empty set
|
||||
s4 = concat("", set()) # empty set and delimiter
|
||||
s4 = concat("", set()) # empty set and delimiter
|
||||
|
||||
query: data.test
|
||||
want_result:
|
||||
@@ -40,7 +40,7 @@ cases:
|
||||
y = concat(x, [])
|
||||
query: data.test
|
||||
want_result: {}
|
||||
|
||||
|
||||
- note: undefined-collection
|
||||
data: {}
|
||||
modules:
|
||||
@@ -50,7 +50,7 @@ cases:
|
||||
y = concat(",", x)
|
||||
query: data.test
|
||||
want_result: {}
|
||||
|
||||
|
||||
- note: invalid-null-delimiter
|
||||
data: {}
|
||||
modules: ["package test\nx=concat(null, [])"]
|
||||
@@ -74,7 +74,7 @@ cases:
|
||||
modules: ["package test\nx=concat([], [])"]
|
||||
query: data.test
|
||||
error: "`concat` expects string argument."
|
||||
|
||||
|
||||
- note: invalid-set-delimiter
|
||||
data: {}
|
||||
modules: ["package test\nx=concat(set(), [])"]
|
||||
@@ -86,4 +86,34 @@ cases:
|
||||
modules: ["package test\nx=concat({}, [])"]
|
||||
query: data.test
|
||||
error: "`concat` expects string argument."
|
||||
|
||||
|
||||
|
||||
- note: invalid-null-collection
|
||||
data: {}
|
||||
modules: ["package test\nx=concat(\"\", null)"]
|
||||
query: data.test
|
||||
error: "`concat` expects array/set of strings."
|
||||
|
||||
- note: invalid-bool-collection
|
||||
data: {}
|
||||
modules: ["package test\nx=concat(\"\", true)"]
|
||||
query: data.test
|
||||
error: "`concat` expects array/set of strings."
|
||||
|
||||
- note: invalid-number-collection
|
||||
data: {}
|
||||
modules: ["package test\nx=concat(\"\", 1)"]
|
||||
query: data.test
|
||||
error: "`concat` expects array/set of strings."
|
||||
|
||||
- note: invalid-string-collection
|
||||
data: {}
|
||||
modules: ["package test\nx=concat(\"\", \"\")"]
|
||||
query: data.test
|
||||
error: "`concat` expects array/set of strings."
|
||||
|
||||
- note: invalid-object-collection
|
||||
data: {}
|
||||
modules: ["package test\nx=concat(\"\", {})"]
|
||||
query: data.test
|
||||
error: "`concat` expects array/set of strings."
|
||||
|
||||
116
tests/interpreter/cases/builtins/strings/endswith.yaml
Normal file
116
tests/interpreter/cases/builtins/strings/endswith.yaml
Normal file
@@ -0,0 +1,116 @@
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
cases:
|
||||
- note: all
|
||||
data: {}
|
||||
modules:
|
||||
- |
|
||||
package test
|
||||
|
||||
v1 = endswith("Hello, world", "ld")
|
||||
v2 = endswith("Hello world", "") # empty substring
|
||||
v3 = endswith("", "ld") # empty string
|
||||
v4 = endswith("", "") # empty substring and string
|
||||
|
||||
query: data.test
|
||||
want_result:
|
||||
v1: true
|
||||
v2: true
|
||||
v3: false
|
||||
v4: true
|
||||
|
||||
- note: undefined-string
|
||||
data: {}
|
||||
modules:
|
||||
- |
|
||||
package test
|
||||
x { false }
|
||||
y = endswith(x, "")
|
||||
query: data.test
|
||||
want_result: {}
|
||||
|
||||
- note: undefined-substring
|
||||
data: {}
|
||||
modules:
|
||||
- |
|
||||
package test
|
||||
x { false }
|
||||
y = endswith(",", x)
|
||||
query: data.test
|
||||
want_result: {}
|
||||
|
||||
- note: invalid-null-string
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(null, ``)"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-bool-string
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(true, ``)"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-number-string
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(1, ``)"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-array-string
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith([], ``)"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-set-string
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(set(), ``)"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-object-string
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith({}, ``)"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
|
||||
|
||||
|
||||
- note: invalid-null-substring
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(``, null)"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-bool-substring
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(``, true)"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-number-substring
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(``, 1)"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-array-substring
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(``, [])"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-set-substring
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(``, set())"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
|
||||
- note: invalid-object-substring
|
||||
data: {}
|
||||
modules: ["package test\nx=endswith(``, {})"]
|
||||
query: data.test
|
||||
error: "`endswith` expects string argument."
|
||||
Reference in New Issue
Block a user