temp commit
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
mod macros;
|
||||
// mod macros;
|
||||
mod std;
|
||||
|
||||
pub use std::number::num_atom::{Float, HomoArray, Int, Num};
|
||||
|
||||
@@ -7,7 +7,9 @@ use orchid_extension::lexer::LexerObj;
|
||||
use orchid_extension::parser::ParserObj;
|
||||
use orchid_extension::system::{System, SystemCard};
|
||||
use orchid_extension::system_ctor::SystemCtor;
|
||||
use orchid_extension::tree::GenItem;
|
||||
use orchid_extension::tree::GenMember;
|
||||
|
||||
use crate::macros::mactree_lexer::MacTreeLexer;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MacroSystem;
|
||||
@@ -26,7 +28,7 @@ impl SystemCard for MacroSystem {
|
||||
impl System for MacroSystem {
|
||||
async fn request(_: ExtReq<'_>, req: Self::Req) -> Receipt<'_> { match req {} }
|
||||
fn vfs() -> orchid_extension::fs::DeclFs { DeclFs::Mod(&[]) }
|
||||
fn lexers() -> Vec<LexerObj> { vec![] }
|
||||
fn lexers() -> Vec<LexerObj> { vec![&MacTreeLexer] }
|
||||
fn parsers() -> Vec<ParserObj> { vec![] }
|
||||
fn env() -> Vec<GenItem> { vec![] }
|
||||
fn env() -> Vec<GenMember> { vec![] }
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Display;
|
||||
use std::rc::Rc;
|
||||
|
||||
use futures::future::join_all;
|
||||
use orchid_api::Paren;
|
||||
use orchid_base::error::OrcErrv;
|
||||
use orchid_base::format::{FmtCtx, FmtUnit, Format, Variants};
|
||||
use orchid_base::interner::Tok;
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::tl_cache;
|
||||
use orchid_base::tree::Ph;
|
||||
use orchid_extension::atom::{Atomic, MethodSetBuilder};
|
||||
use orchid_extension::atom::Atomic;
|
||||
use orchid_extension::atom_owned::{OwnedAtom, OwnedVariant};
|
||||
use orchid_extension::expr::Expr;
|
||||
|
||||
@@ -62,7 +62,7 @@ impl Format for MacTok {
|
||||
},
|
||||
[mtreev_fmt(body, c).await],
|
||||
),
|
||||
Self::Slot => format!("SLOT").into(),
|
||||
Self::Slot => "SLOT".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,3 +73,26 @@ pub async fn mtreev_fmt<'b>(
|
||||
) -> FmtUnit {
|
||||
FmtUnit::sequence(" ", None, join_all(v.into_iter().map(|t| t.print(c))).await)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct Ph {
|
||||
pub name: Tok<String>,
|
||||
pub kind: PhKind,
|
||||
}
|
||||
impl Display for Ph {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self.kind {
|
||||
PhKind::Scalar => write!(f, "${}", self.name),
|
||||
PhKind::Vector { at_least_one: false, priority: 0 } => write!(f, "..${}", self.name),
|
||||
PhKind::Vector { at_least_one: true, priority: 0 } => write!(f, "...${}", self.name),
|
||||
PhKind::Vector { at_least_one: false, priority } => write!(f, "..${}:{priority}", self.name),
|
||||
PhKind::Vector { at_least_one: true, priority } => write!(f, "...${}:{priority}", self.name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub enum PhKind {
|
||||
Scalar,
|
||||
Vector { at_least_one: bool, priority: u8 },
|
||||
}
|
||||
|
||||
@@ -3,13 +3,9 @@ use std::rc::Rc;
|
||||
|
||||
use futures::FutureExt;
|
||||
use orchid_base::error::{OrcRes, mk_errv};
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::parse::name_start;
|
||||
use orchid_base::tokens::PARENS;
|
||||
use orchid_extension::atom::AtomicFeatures;
|
||||
use orchid_extension::gen_expr::atom;
|
||||
use orchid_extension::lexer::{LexContext, Lexer, err_not_applicable};
|
||||
use orchid_extension::tree::{GenTok, GenTokTree};
|
||||
use orchid_extension::tree::{GenTok, GenTokTree, x_tok};
|
||||
|
||||
use crate::macros::mactree::{MacTok, MacTree};
|
||||
|
||||
@@ -17,15 +13,14 @@ use crate::macros::mactree::{MacTok, MacTree};
|
||||
pub struct MacTreeLexer;
|
||||
impl Lexer for MacTreeLexer {
|
||||
const CHAR_FILTER: &'static [RangeInclusive<char>] = &['\''..='\''];
|
||||
async fn lex<'a>(tail: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree<'a>)> {
|
||||
async fn lex<'a>(tail: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree)> {
|
||||
let Some(tail2) = tail.strip_prefix('\'') else {
|
||||
return Err(err_not_applicable(ctx.i).await.into());
|
||||
return Err(err_not_applicable(ctx.i()).await.into());
|
||||
};
|
||||
let tail3 = tail2.trim_start();
|
||||
return match mac_tree(tail3, ctx).await {
|
||||
Ok((tail4, mactree)) =>
|
||||
Ok((tail4, GenTok::X(mactree.factory()).at(ctx.pos(tail)..ctx.pos(tail4)))),
|
||||
Err(e) => Ok((tail2, GenTok::Bottom(e).at(ctx.tok_ran(1, tail2)))),
|
||||
Ok((tail4, mactree)) => Ok((tail4, x_tok(mactree).at(ctx.pos_tt(tail, tail4)))),
|
||||
Err(e) => Ok((tail2, GenTok::Bottom(e).at(ctx.pos_lt(1, tail2)))),
|
||||
};
|
||||
async fn mac_tree<'a>(tail: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, MacTree)> {
|
||||
for (lp, rp, paren) in PARENS {
|
||||
@@ -35,14 +30,14 @@ impl Lexer for MacTreeLexer {
|
||||
let tail2 = body_tail.trim();
|
||||
if let Some(tail3) = tail2.strip_prefix(*rp) {
|
||||
break Ok((tail3, MacTree {
|
||||
pos: Pos::Range(ctx.pos(tail)..ctx.pos(tail3)),
|
||||
pos: ctx.pos_tt(tail, tail3).pos(),
|
||||
tok: Rc::new(MacTok::S(*paren, items)),
|
||||
}));
|
||||
} else if tail2.is_empty() {
|
||||
return Err(mk_errv(
|
||||
ctx.i.i("Unclosed block").await,
|
||||
ctx.i().i("Unclosed block").await,
|
||||
format!("Expected closing {rp}"),
|
||||
[Pos::Range(ctx.tok_ran(1, tail)).into()],
|
||||
[ctx.pos_lt(1, tail)],
|
||||
));
|
||||
}
|
||||
let (new_tail, new_item) = mac_tree(tail2, ctx).boxed_local().await?;
|
||||
@@ -53,11 +48,13 @@ impl Lexer for MacTreeLexer {
|
||||
const INTERPOL: &[&str] = &["$", "..$"];
|
||||
for pref in INTERPOL {
|
||||
let Some(code) = tail.strip_prefix(pref) else { continue };
|
||||
todo!("Register parameter, and push this onto the argument stack held in the atom")
|
||||
}
|
||||
todo!("recursive lexer call");
|
||||
return Err(mk_errv(
|
||||
ctx.i.i("Expected token after '").await,
|
||||
ctx.i().i("Expected token after '").await,
|
||||
format!("Expected a token after ', found {tail:?}"),
|
||||
[Pos::Range(ctx.tok_ran(1, tail)).into()],
|
||||
[ctx.pos_lt(1, tail)],
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use itertools::Itertools;
|
||||
use orchid_api::PhKind;
|
||||
use orchid_base::interner::Tok;
|
||||
use orchid_base::side::Side;
|
||||
use orchid_base::tree::Ph;
|
||||
|
||||
use super::shared::{AnyMatcher, ScalMatcher, VecMatcher};
|
||||
use super::vec_attrs::vec_attrs;
|
||||
use crate::macros::mactree::{Ph, PhKind};
|
||||
use crate::macros::{MacTok, MacTree};
|
||||
|
||||
pub type MaxVecSplit<'a> = (&'a [MacTree], (Tok<String>, u8, bool), &'a [MacTree]);
|
||||
@@ -108,24 +107,22 @@ fn mk_scalar(pattern: &MacTree) -> ScalMatcher {
|
||||
mod test {
|
||||
use std::rc::Rc;
|
||||
|
||||
use orchid_api::PhKind;
|
||||
use orchid_base::interner::Interner;
|
||||
use orchid_base::location::SrcRange;
|
||||
use orchid_base::sym;
|
||||
use orchid_base::tokens::Paren;
|
||||
use orchid_base::tree::Ph;
|
||||
use test_executors::spin_on;
|
||||
|
||||
use super::mk_any;
|
||||
use crate::macros::mactree::{Ph, PhKind};
|
||||
use crate::macros::{MacTok, MacTree};
|
||||
|
||||
#[test]
|
||||
fn test_scan() {
|
||||
spin_on(async {
|
||||
let i = Interner::new_master();
|
||||
let ex = |tok: MacTok| async {
|
||||
MacTree { tok: Rc::new(tok), pos: SrcRange::mock(&i).await.pos() }
|
||||
};
|
||||
let ex =
|
||||
|tok: MacTok| async { MacTree { tok: Rc::new(tok), pos: SrcRange::mock(&i).await.pos() } };
|
||||
let pattern = vec![
|
||||
ex(MacTok::Ph(Ph {
|
||||
kind: PhKind::Vector { priority: 0, at_least_one: false },
|
||||
|
||||
@@ -2,11 +2,9 @@ use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
||||
use itertools::Itertools;
|
||||
use orchid_api::PhKind;
|
||||
use orchid_base::interner::Interner;
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::tree::Ph;
|
||||
|
||||
use super::any_match::any_match;
|
||||
use super::build::{mk_any, mk_vec};
|
||||
@@ -14,6 +12,7 @@ use super::shared::{AnyMatcher, VecMatcher};
|
||||
use super::state::{MatchState, StateEntry};
|
||||
use super::vec_attrs::vec_attrs;
|
||||
use super::vec_match::vec_match;
|
||||
use crate::macros::mactree::{Ph, PhKind};
|
||||
use crate::macros::{MacTok, MacTree};
|
||||
|
||||
pub fn first_is_vec(pattern: &[MacTree]) -> bool { vec_attrs(pattern.first().unwrap()).is_some() }
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use orchid_api::PhKind;
|
||||
use orchid_base::interner::Tok;
|
||||
use orchid_base::tree::Ph;
|
||||
|
||||
use crate::macros::mactree::{Ph, PhKind};
|
||||
use crate::macros::{MacTok, MacTree};
|
||||
|
||||
/// Returns the name, priority and at_least_one of the expression if it is
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
||||
use orchid_extension::entrypoint::ExtensionData;
|
||||
use orchid_extension::tokio::tokio_main;
|
||||
use orchid_std::StdSystem;
|
||||
use tokio::task::{LocalSet, spawn_local};
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn main() { tokio_main(ExtensionData::new("orchid-std::main", &[&StdSystem])).await }
|
||||
|
||||
@@ -2,9 +2,7 @@ use orchid_api_derive::Coding;
|
||||
use orchid_base::error::OrcRes;
|
||||
use orchid_base::format::FmtUnit;
|
||||
use orchid_base::number::Numeric;
|
||||
use orchid_extension::atom::{
|
||||
AtomFactory, Atomic, AtomicFeatures, MethodSetBuilder, ToAtom, TypAtom,
|
||||
};
|
||||
use orchid_extension::atom::{AtomFactory, Atomic, AtomicFeatures, ToAtom, TypAtom};
|
||||
use orchid_extension::atom_thin::{ThinAtom, ThinVariant};
|
||||
use orchid_extension::conv::TryFromExpr;
|
||||
use orchid_extension::expr::Expr;
|
||||
|
||||
@@ -4,7 +4,7 @@ use orchid_base::error::OrcRes;
|
||||
use orchid_base::number::{num_to_err, parse_num};
|
||||
use orchid_extension::atom::ToAtom;
|
||||
use orchid_extension::lexer::{LexContext, Lexer};
|
||||
use orchid_extension::tree::{GenTok, GenTokTree};
|
||||
use orchid_extension::tree::{GenTokTree, x_tok};
|
||||
|
||||
use super::num_atom::Num;
|
||||
|
||||
@@ -12,13 +12,13 @@ use super::num_atom::Num;
|
||||
pub struct NumLexer;
|
||||
impl Lexer for NumLexer {
|
||||
const CHAR_FILTER: &'static [RangeInclusive<char>] = &['0'..='9'];
|
||||
async fn lex<'a>(all: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree<'a>)> {
|
||||
async fn lex<'a>(all: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree)> {
|
||||
let ends_at = all.find(|c: char| !c.is_ascii_hexdigit() && !"xX._pP".contains(c));
|
||||
let (chars, tail) = all.split_at(ends_at.unwrap_or(all.len()));
|
||||
let fac = match parse_num(chars) {
|
||||
Ok(numeric) => Num(numeric).to_atom_factory(),
|
||||
Err(e) => return Err(num_to_err(e, ctx.pos(all), ctx.i).await.into()),
|
||||
Err(e) => return Err(num_to_err(e, ctx.pos(all), &ctx.src, ctx.ctx.i()).await.into()),
|
||||
};
|
||||
Ok((tail, GenTok::X(fac).at(ctx.pos(all)..ctx.pos(tail))))
|
||||
Ok((tail, x_tok(fac).at(ctx.pos_lt(chars.len(), tail))))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use orchid_base::number::Numeric;
|
||||
use orchid_extension::tree::{GenItem, fun, prefix};
|
||||
use orchid_extension::tree::{GenMember, fun, prefix};
|
||||
use ordered_float::NotNan;
|
||||
|
||||
use super::num_atom::{Float, HomoArray, Int, Num};
|
||||
|
||||
pub fn gen_num_lib() -> Vec<GenItem> {
|
||||
pub fn gen_num_lib() -> Vec<GenMember> {
|
||||
prefix("std::number", [
|
||||
fun(true, "add", |a: Num, b: Num| async move {
|
||||
Num(match HomoArray::new([a.0, b.0]) {
|
||||
|
||||
@@ -2,12 +2,12 @@ use never::Never;
|
||||
use orchid_base::reqnot::Receipt;
|
||||
use orchid_extension::atom::{AtomDynfo, AtomicFeatures};
|
||||
use orchid_extension::entrypoint::ExtReq;
|
||||
use orchid_extension::fs::DeclFs;
|
||||
use orchid_extension::fs::DeclVmod;
|
||||
use orchid_extension::lexer::LexerObj;
|
||||
use orchid_extension::parser::ParserObj;
|
||||
use orchid_extension::system::{System, SystemCard};
|
||||
use orchid_extension::system_ctor::SystemCtor;
|
||||
use orchid_extension::tree::{GenItem, merge_trivial};
|
||||
use orchid_extension::tree::{GenMember, merge_trivial};
|
||||
|
||||
use super::number::num_lib::gen_num_lib;
|
||||
use super::string::str_atom::{IntStrAtom, StrAtom};
|
||||
@@ -36,6 +36,6 @@ impl System for StdSystem {
|
||||
async fn request(_: ExtReq<'_>, req: Self::Req) -> Receipt<'_> { match req {} }
|
||||
fn lexers() -> Vec<LexerObj> { vec![&StringLexer, &NumLexer] }
|
||||
fn parsers() -> Vec<ParserObj> { vec![] }
|
||||
fn vfs() -> DeclFs { DeclFs::Mod(&[]) }
|
||||
fn env() -> Vec<GenItem> { merge_trivial([gen_num_lib(), gen_str_lib()]) }
|
||||
fn vfs() -> DeclVmod { DeclVmod::new(&[]) }
|
||||
fn env() -> Vec<GenMember> { merge_trivial([gen_num_lib(), gen_str_lib()]) }
|
||||
}
|
||||
|
||||
@@ -82,17 +82,17 @@ impl OwnedAtom for IntStrAtom {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct OrcString<'a> {
|
||||
kind: OrcStringKind<'a>,
|
||||
pub struct OrcString {
|
||||
kind: OrcStringKind,
|
||||
ctx: SysCtx,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum OrcStringKind<'a> {
|
||||
Val(TypAtom<'a, StrAtom>),
|
||||
Int(TypAtom<'a, IntStrAtom>),
|
||||
pub enum OrcStringKind {
|
||||
Val(TypAtom<StrAtom>),
|
||||
Int(TypAtom<IntStrAtom>),
|
||||
}
|
||||
impl OrcString<'_> {
|
||||
impl OrcString {
|
||||
pub async fn get_string(&self) -> Rc<String> {
|
||||
match &self.kind {
|
||||
OrcStringKind::Int(tok) => self.ctx.i().ex(**tok).await.rc(),
|
||||
@@ -101,8 +101,8 @@ impl OrcString<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFromExpr for OrcString<'static> {
|
||||
async fn try_from_expr(expr: Expr) -> OrcRes<OrcString<'static>> {
|
||||
impl TryFromExpr for OrcString {
|
||||
async fn try_from_expr(expr: Expr) -> OrcRes<OrcString> {
|
||||
if let Ok(v) = TypAtom::<StrAtom>::try_from_expr(expr.clone()).await {
|
||||
return Ok(OrcString { ctx: expr.ctx(), kind: OrcStringKind::Val(v) });
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use itertools::Itertools;
|
||||
use orchid_base::error::{OrcErr, OrcRes, mk_err, mk_errv};
|
||||
use orchid_base::interner::Interner;
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::location::SrcRange;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::sym;
|
||||
use orchid_base::tree::wrap_tokv;
|
||||
use orchid_extension::atom::AtomicFeatures;
|
||||
use orchid_extension::lexer::{LexContext, Lexer, err_not_applicable};
|
||||
use orchid_extension::tree::{GenTok, GenTokTree};
|
||||
use orchid_extension::tree::{GenTokTree, ref_tok, x_tok};
|
||||
|
||||
use super::str_atom::IntStrAtom;
|
||||
|
||||
@@ -32,7 +32,7 @@ struct StringError {
|
||||
|
||||
impl StringError {
|
||||
/// Convert into project error for reporting
|
||||
pub async fn into_proj(self, pos: u32, i: &Interner) -> OrcErr {
|
||||
pub async fn into_proj(self, path: &Sym, pos: u32, i: &Interner) -> OrcErr {
|
||||
let start = pos + self.pos;
|
||||
mk_err(
|
||||
i.i("Failed to parse string").await,
|
||||
@@ -41,7 +41,7 @@ impl StringError {
|
||||
StringErrorKind::BadCodePoint => "The specified number is not a Unicode code point",
|
||||
StringErrorKind::BadEscSeq => "Unrecognized escape sequence",
|
||||
},
|
||||
[Pos::Range(start..start + 1).into()],
|
||||
[SrcRange::new(start..start + 1, path).pos().into()],
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -95,9 +95,9 @@ fn parse_string(str: &str) -> Result<String, StringError> {
|
||||
pub struct StringLexer;
|
||||
impl Lexer for StringLexer {
|
||||
const CHAR_FILTER: &'static [std::ops::RangeInclusive<char>] = &['"'..='"', '`'..='`'];
|
||||
async fn lex<'a>(all: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree<'a>)> {
|
||||
async fn lex<'a>(all: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree)> {
|
||||
let Some(mut tail) = all.strip_prefix('"') else {
|
||||
return Err(err_not_applicable(ctx.i).await.into());
|
||||
return Err(err_not_applicable(ctx.ctx.i()).await.into());
|
||||
};
|
||||
let mut ret = None;
|
||||
let mut cur = String::new();
|
||||
@@ -107,19 +107,19 @@ impl Lexer for StringLexer {
|
||||
tail: &str,
|
||||
err: &mut Vec<OrcErr>,
|
||||
ctx: &'a LexContext<'a>,
|
||||
) -> GenTokTree<'a> {
|
||||
) -> GenTokTree {
|
||||
let str_val_res = parse_string(&str.split_off(0));
|
||||
if let Err(e) = &str_val_res {
|
||||
err.push(e.clone().into_proj(ctx.pos(tail) - str.len() as u32, ctx.i).await);
|
||||
err.push(e.clone().into_proj(&ctx.src, ctx.pos(tail) - str.len() as u32, ctx.i()).await);
|
||||
}
|
||||
let str_val = str_val_res.unwrap_or_default();
|
||||
GenTok::X(IntStrAtom::from(ctx.i.i(&*str_val).await).factory())
|
||||
.at(ctx.tok_ran(str.len() as u32, tail)) as GenTokTree<'a>
|
||||
x_tok(IntStrAtom::from(ctx.i().i(&*str_val).await)).at(ctx.pos_lt(str.len() as u32, tail))
|
||||
as GenTokTree
|
||||
}
|
||||
let add_frag = |prev: Option<GenTokTree<'a>>, new: GenTokTree<'a>| async {
|
||||
let add_frag = |prev: Option<GenTokTree>, new: GenTokTree| async {
|
||||
let Some(prev) = prev else { return new };
|
||||
let concat_fn =
|
||||
GenTok::Reference(sym!(std::string::concat; ctx.i).await).at(prev.sr.start..prev.sr.start);
|
||||
let concat_fn = ref_tok(sym!(std::string::concat; ctx.i()).await)
|
||||
.at(SrcRange::zw(prev.sr.path(), prev.sr.start()));
|
||||
wrap_tokv([concat_fn, prev, new])
|
||||
};
|
||||
loop {
|
||||
@@ -141,9 +141,9 @@ impl Lexer for StringLexer {
|
||||
} else {
|
||||
let range = ctx.pos(all)..ctx.pos("");
|
||||
return Err(mk_errv(
|
||||
ctx.i.i("No string end").await,
|
||||
ctx.i().i("No string end").await,
|
||||
"String never terminated with \"",
|
||||
[Pos::Range(range.clone()).into()],
|
||||
[SrcRange::new(range.clone(), &ctx.src)],
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use orchid_extension::tree::{GenItem, comments, fun, prefix};
|
||||
use orchid_extension::tree::{GenMember, comments, fun, prefix};
|
||||
|
||||
use super::str_atom::StrAtom;
|
||||
use crate::OrcString;
|
||||
|
||||
pub fn gen_str_lib() -> Vec<GenItem> {
|
||||
pub fn gen_str_lib() -> Vec<GenMember> {
|
||||
prefix("std::string", [comments(
|
||||
["Concatenate two strings"],
|
||||
fun(true, "concat", |left: OrcString<'static>, right: OrcString<'static>| async move {
|
||||
fun(true, "concat", |left: OrcString, right: OrcString| async move {
|
||||
StrAtom::new(Rc::new(left.get_string().await.to_string() + &right.get_string().await))
|
||||
}),
|
||||
)])
|
||||
|
||||
Reference in New Issue
Block a user