This commit is contained in:
2024-07-18 16:07:36 +02:00
parent 949b3758fd
commit cc3699bbe7
31 changed files with 1021 additions and 312 deletions

View File

@@ -1,6 +1,6 @@
use std::sync::Arc;
use orchid_extension::atom::AtomicFeatures;
use orchid_extension::atom::{AtomDynfo, AtomicFeatures};
use orchid_extension::fs::DeclFs;
use orchid_extension::fun::Fun;
use orchid_extension::system::{System, SystemCard};
@@ -22,16 +22,25 @@ impl SystemCtor for StdSystem {
}
impl SystemCard for StdSystem {
type Ctor = Self;
const ATOM_DEFS: &'static [Option<fn() -> &'static orchid_extension::atom::AtomInfo>] = &[
Some(StringAtom::info)
];
const ATOM_DEFS: &'static [Option<&'static dyn AtomDynfo>] = &[Some(StringAtom::INFO)];
}
impl System for StdSystem {
fn lexers() -> Vec<orchid_extension::lexer::LexerObj> { vec![&StringLexer] }
fn vfs() -> DeclFs { DeclFs::Mod(&[]) }
fn env() -> GenTree {
GenTree::module([("std", GenTree::module([("string", GenTree::module([
("concat", GenTree::cnst(Fun::new(|left: OrcString| Fun::new(move |right: OrcString| StringAtom::new(Arc::new(left.get_string().to_string() + &right.get_string()))))))
]))]))])
GenTree::module([(
"std",
GenTree::module([(
"string",
GenTree::module([(
"concat",
GenTree::cnst(Fun::new(|left: OrcString| {
Fun::new(move |right: OrcString| {
StringAtom::new(Arc::new(left.get_string().to_string() + &right.get_string()))
})
})),
)]),
)]),
)])
}
}

View File

@@ -10,10 +10,10 @@ use orchid_base::interner::{deintern, Tok};
use orchid_base::location::Pos;
use orchid_extension::atom::{Atomic, TypAtom};
use orchid_extension::atom_owned::{OwnedAtom, OwnedVariant};
use orchid_extension::conv::TryFromExpr;
use orchid_extension::error::{ProjectError, ProjectResult};
use orchid_extension::expr::{ExprHandle, OwnedExpr};
use orchid_extension::system::{downcast_atom, SysCtx};
use orchid_extension::conv::TryFromExpr;
pub static STR_REPO: IdStore<Arc<String>> = IdStore::new();
@@ -59,10 +59,12 @@ impl StringAtom {
fn get_value(&self) -> Arc<String> { self.try_local_value().expect("no string found for ID") }
}
impl OwnedAtom for StringAtom {
fn val(&self) -> Cow<'_, Self::Data> { Cow::Owned(match self {
Self::Int(tok) => StringVal::Int(tok.marker()),
Self::Val(id) => StringVal::Val(*id),
}) }
fn val(&self) -> Cow<'_, Self::Data> {
Cow::Owned(match self {
Self::Int(tok) => StringVal::Int(tok.marker()),
Self::Val(id) => StringVal::Val(*id),
})
}
fn same(&self, _ctx: SysCtx, other: &Self) -> bool { self.get_value() == other.get_value() }
fn handle_req(
&self,
@@ -90,9 +92,7 @@ impl OrcString {
pub struct NotString(Pos);
impl ProjectError for NotString {
const DESCRIPTION: &'static str = "A string was expected";
fn one_position(&self) -> Pos {
self.0.clone()
}
fn one_position(&self) -> Pos { self.0.clone() }
}
impl TryFromExpr for OrcString {
fn try_from_expr(expr: ExprHandle) -> ProjectResult<OrcString> {
@@ -101,4 +101,4 @@ impl TryFromExpr for OrcString {
.map_err(|p| NotString(p).pack())
.map(OrcString)
}
}
}

View File

@@ -6,7 +6,7 @@ use orchid_base::vname;
use orchid_extension::atom::AtomicFeatures;
use orchid_extension::error::{ErrorSansOrigin, ProjectErrorObj, ProjectResult};
use orchid_extension::lexer::{LexContext, Lexer};
use orchid_extension::tree::{wrap_tokv, GenTok, GenTokTree};
use orchid_extension::tree::{wrap_tokv, OwnedTok, OwnedTokTree};
use super::str_atom::StringAtom;
@@ -119,15 +119,15 @@ impl Lexer for StringLexer {
fn lex<'a>(
full_string: &'a str,
ctx: &'a LexContext<'a>,
) -> Option<ProjectResult<(&'a str, GenTokTree)>> {
) -> Option<ProjectResult<(&'a str, OwnedTokTree)>> {
full_string.strip_prefix('"').map(|mut tail| {
let mut parts = vec![];
let mut cur = String::new();
let commit_str = |str: &mut String, tail: &str, parts: &mut Vec<GenTokTree>| {
let commit_str = |str: &mut String, tail: &str, parts: &mut Vec<OwnedTokTree>| {
let str_val = parse_string(str)
.inspect_err(|e| ctx.report(e.clone().into_proj(ctx.pos(tail) - str.len() as u32)))
.unwrap_or_default();
let tok = GenTok::Atom(StringAtom::new_int(intern(&str_val)).factory());
let tok = OwnedTok::Atom(StringAtom::new_int(intern(&str_val)).factory());
parts.push(tok.at(ctx.tok_ran(str.len() as u32, tail)));
*str = String::new();
};
@@ -137,8 +137,8 @@ impl Lexer for StringLexer {
return Ok((rest, wrap_tokv(parts, ctx.pos(full_string)..ctx.pos(rest))));
} else if let Some(rest) = tail.strip_prefix('$') {
commit_str(&mut cur, tail, &mut parts);
parts.push(GenTok::Name(VName::literal("++")).at(ctx.tok_ran(1, rest)));
parts.push(GenTok::Name(vname!(std::string::convert)).at(ctx.tok_ran(1, rest)));
parts.push(OwnedTok::Name(VName::literal("++")).at(ctx.tok_ran(1, rest)));
parts.push(OwnedTok::Name(vname!(std::string::convert)).at(ctx.tok_ran(1, rest)));
match ctx.recurse(rest) {
Ok((new_tail, tree)) => {
tail = new_tail;