mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
string concat (WIP)
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
committed by
Anand Krishnamoorthi
parent
e93b33ea05
commit
89e26e37a2
+6
-2
@@ -6,6 +6,7 @@ pub mod arrays;
|
||||
pub mod comparison;
|
||||
pub mod numbers;
|
||||
pub mod sets;
|
||||
pub mod strings;
|
||||
pub mod types;
|
||||
pub mod utils;
|
||||
|
||||
@@ -24,12 +25,15 @@ pub type BuiltinFcn = fn(&Span, &[Expr], &[Value]) -> Result<Value>;
|
||||
lazy_static! {
|
||||
pub static ref BUILTINS: HashMap<&'static str, BuiltinFcn> = {
|
||||
let mut m : HashMap<&'static str, BuiltinFcn> = HashMap::new();
|
||||
|
||||
|
||||
// comparison functions are directly called.
|
||||
numbers::register(&mut m);
|
||||
aggregates::register(&mut m);
|
||||
arrays::register(&mut m);
|
||||
sets::register(&mut m);
|
||||
types::register(&mut m);
|
||||
|
||||
strings::register(&mut m);
|
||||
|
||||
m
|
||||
};
|
||||
}
|
||||
|
||||
+16
-11
@@ -1,19 +1,24 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
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 anyhow::{bail, Result};
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn ensure_numeric(fcn: &str, arg: &Expr, v: &Value) -> Result<Float> {
|
||||
Ok(match &v {
|
||||
Value::Number(n) => n.0 .0,
|
||||
_ => {
|
||||
let span = arg.span();
|
||||
bail!(
|
||||
span.error(format!("`{fcn}` expects numeric argument. Got `{v}` instead").as_str())
|
||||
)
|
||||
}
|
||||
})
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn register(m: &mut HashMap<&'static str, builtins::BuiltinFcn>) {
|
||||
m.insert("concat", concat);
|
||||
}
|
||||
|
||||
fn concat(span: &Span, params: &[Expr], args: &[Value]) -> Result<Value> {
|
||||
let name = "concat";
|
||||
ensure_args_count(span, name, params, args, 2)?;
|
||||
let delimiter = ensure_string(name, ¶ms[0], &args[0])?;
|
||||
let collection = ensure_string_collection(name, ¶ms[1], &args[1])?;
|
||||
Ok(Value::String(collection.join(&delimiter)))
|
||||
}
|
||||
|
||||
@@ -53,6 +53,45 @@ pub fn ensure_string(fcn: &str, arg: &Expr, v: &Value) -> Result<String> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn ensure_string_element<'a>(
|
||||
fcn: &str,
|
||||
arg: &Expr,
|
||||
v: &'a Value,
|
||||
idx: usize,
|
||||
) -> Result<&'a str> {
|
||||
Ok(match &v {
|
||||
Value::String(s) => s.as_str(),
|
||||
_ => {
|
||||
let span = arg.span();
|
||||
bail!(span.error(
|
||||
format!("`{fcn}` expects string collection. Element {idx} is not a string.")
|
||||
.as_str()
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn ensure_string_collection<'a>(fcn: &str, arg: &Expr, v: &'a Value) -> Result<Vec<&'a str>> {
|
||||
let mut collection = vec![];
|
||||
match &v {
|
||||
Value::Array(a) => {
|
||||
for (idx, elem) in a.iter().enumerate() {
|
||||
collection.push(ensure_string_element(fcn, arg, elem, idx)?);
|
||||
}
|
||||
}
|
||||
Value::Set(s) => {
|
||||
for (idx, elem) in s.iter().enumerate() {
|
||||
collection.push(ensure_string_element(fcn, arg, elem, idx)?);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let span = arg.span();
|
||||
bail!(span.error(format!("`{fcn}` expects array/set of strings.").as_str()))
|
||||
}
|
||||
}
|
||||
Ok(collection)
|
||||
}
|
||||
|
||||
pub fn ensure_array(fcn: &str, arg: &Expr, v: Value) -> Result<Rc<Vec<Value>>> {
|
||||
Ok(match v {
|
||||
Value::Array(a) => a,
|
||||
|
||||
Reference in New Issue
Block a user