mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
- Replace std with alloc, core in most places in src Tests, bindings aren't changed. - Introduce BuiltinsMap type alias inplace of HashMap. In no_std case, this could be aliases to BTreeMap - Fix clippy warnings Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
70 lines
2.1 KiB
Rust
70 lines
2.1 KiB
Rust
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
use crate::ast::{Expr, Ref};
|
|
use crate::builtins;
|
|
use crate::builtins::utils::{ensure_args_count, ensure_array, ensure_numeric};
|
|
use crate::lexer::Span;
|
|
use crate::Rc;
|
|
use crate::Value;
|
|
|
|
use anyhow::Result;
|
|
|
|
pub fn register(m: &mut builtins::BuiltinsMap<&'static str, builtins::BuiltinFcn>) {
|
|
m.insert("array.concat", (concat, 2));
|
|
m.insert("array.reverse", (reverse, 1));
|
|
m.insert("array.slice", (slice, 3));
|
|
}
|
|
|
|
fn concat(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> Result<Value> {
|
|
let name = "array.concat";
|
|
ensure_args_count(span, name, params, args, 2)?;
|
|
let mut v1 = ensure_array(name, ¶ms[0], args[0].clone())?;
|
|
let mut v2 = ensure_array(name, ¶ms[1], args[1].clone())?;
|
|
|
|
Rc::make_mut(&mut v1).append(Rc::make_mut(&mut v2));
|
|
Ok(Value::Array(v1))
|
|
}
|
|
|
|
fn reverse(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> Result<Value> {
|
|
let name = "array.reverse";
|
|
ensure_args_count(span, name, params, args, 1)?;
|
|
|
|
let mut v1 = ensure_array(name, ¶ms[0], args[0].clone())?;
|
|
Rc::make_mut(&mut v1).reverse();
|
|
Ok(Value::Array(v1))
|
|
}
|
|
|
|
fn slice(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> Result<Value> {
|
|
let name = "array.slice";
|
|
ensure_args_count(span, name, params, args, 3)?;
|
|
|
|
let array = ensure_array(name, ¶ms[0], args[0].clone())?;
|
|
let start = ensure_numeric(name, ¶ms[1], &args[1].clone())?;
|
|
let stop = ensure_numeric(name, ¶ms[2], &args[2].clone())?;
|
|
|
|
if !start.is_integer() || !stop.is_integer() {
|
|
return Ok(Value::Undefined);
|
|
}
|
|
|
|
let start = match start.as_i64() {
|
|
Some(n) if n < 0 => 0,
|
|
Some(n) => n as usize,
|
|
_ => return Ok(Value::Undefined),
|
|
};
|
|
|
|
let stop = match stop.as_i64() {
|
|
Some(n) if n < 0 => 0,
|
|
Some(n) if n as usize > array.len() => array.len(),
|
|
Some(n) => n as usize,
|
|
_ => return Ok(Value::Undefined),
|
|
};
|
|
|
|
if start >= stop {
|
|
return Ok(Value::new_array());
|
|
}
|
|
|
|
let slice = &array[start..stop];
|
|
Ok(Value::from(slice.to_vec()))
|
|
}
|