temp commit

This commit is contained in:
2025-07-12 00:46:10 +02:00
parent 1868f1a506
commit fe89188c4b
60 changed files with 1536 additions and 709 deletions

View File

@@ -1,13 +1,10 @@
use std::cell::RefCell;
use futures::FutureExt;
use futures::future::join_all;
use hashbrown::HashMap;
use itertools::Itertools;
use orchid_base::error::{OrcRes, Reporter, mk_err, mk_errv};
use orchid_base::error::{OrcRes, Reporter, mk_errv};
use orchid_base::format::fmt;
use orchid_base::interner::{Interner, Tok};
use orchid_base::name::Sym;
use orchid_base::name::{Sym, VPath};
use orchid_base::parse::{
Comment, Import, ParseCtx, Parsed, Snippet, expect_end, line_items, parse_multiname,
try_pop_no_fluff,
@@ -17,7 +14,7 @@ use substack::Substack;
use crate::ctx::Ctx;
use crate::expr::{Expr, ExprKind, PathSetBuilder};
use crate::parsed::{Item, ItemKind, ParsTokTree, ParsedMember, ParsedMemberKind, ParsedModule};
use crate::parsed::{Item, ItemKind, ParsedMember, ParsedMemberKind, ParsedModule};
use crate::system::System;
type ParsSnippet<'a> = Snippet<'a, Expr, Expr>;
@@ -27,28 +24,23 @@ pub struct HostParseCtxImpl<'a> {
pub src: Sym,
pub systems: &'a [System],
pub reporter: &'a Reporter,
pub interner: &'a Interner,
pub consts: RefCell<HashMap<Sym, Vec<ParsTokTree>>>,
}
impl ParseCtx for HostParseCtxImpl<'_> {
fn reporter(&self) -> &Reporter { self.reporter }
fn i(&self) -> &Interner { self.interner }
fn i(&self) -> &Interner { &self.ctx.i }
}
impl HostParseCtx for HostParseCtxImpl<'_> {
fn ctx(&self) -> &Ctx { &self.ctx }
fn systems(&self) -> impl Iterator<Item = &System> { self.systems.iter() }
async fn save_const(&self, path: Substack<'_, Tok<String>>, value: Vec<ParsTokTree>) {
let name = Sym::new(path.unreverse(), self.interner).await.unwrap();
self.consts.borrow_mut().insert(name, value);
}
}
pub trait HostParseCtx: ParseCtx {
#[must_use]
fn ctx(&self) -> &Ctx;
#[must_use]
fn systems(&self) -> impl Iterator<Item = &System>;
async fn save_const(&self, path: Substack<'_, Tok<String>>, value: Vec<ParsTokTree>);
}
pub async fn parse_items(
@@ -73,33 +65,10 @@ pub async fn parse_item(
n if *n == ctx.i().i("export").await => match try_pop_no_fluff(ctx, postdisc).await? {
Parsed { output: TokTree { tok: Token::Name(n), .. }, tail } =>
parse_exportable_item(ctx, path, comments, true, n.clone(), tail).await,
Parsed { output: TokTree { tok: Token::S(Paren::Round, body), .. }, tail } => {
expect_end(ctx, tail).await?;
let mut ok = Vec::new();
for tt in body {
let sr = tt.sr.clone();
match &tt.tok {
Token::Name(n) =>
ok.push(Item { comments: comments.clone(), sr, kind: ItemKind::Export(n.clone()) }),
Token::NS(..) => ctx.reporter().report(mk_err(
ctx.i().i("Compound export").await,
"Cannot export compound names (names containing the :: separator)",
[sr.pos().into()],
)),
t => ctx.reporter().report(mk_err(
ctx.i().i("Invalid export").await,
format!("Invalid export target {}", fmt(t, ctx.i()).await),
[sr.pos().into()],
)),
}
}
expect_end(ctx, tail).await?;
Ok(ok)
},
Parsed { output, tail: _ } => Err(mk_errv(
ctx.i().i("Malformed export").await,
"`export` can either prefix other lines or list names inside ( )",
[output.sr.pos().into()],
[output.sr()],
)),
},
n if *n == ctx.i().i("import").await => {
@@ -115,7 +84,7 @@ pub async fn parse_item(
Some(_) => Err(mk_errv(
ctx.i().i("Expected a line type").await,
"All lines must begin with a keyword",
[item.sr().pos().into()],
[item.sr()],
)),
None => unreachable!("These lines are filtered and aggregated in earlier stages"),
}
@@ -138,22 +107,25 @@ pub async fn parse_exportable_item<'a>(
discr: Tok<String>,
tail: ParsSnippet<'a>,
) -> OrcRes<Vec<Item>> {
let path_sym = Sym::new(path.unreverse(), ctx.i()).await.expect("Files should have a namespace");
let kind = if discr == ctx.i().i("mod").await {
let (name, body) = parse_module(ctx, path, tail).await?;
ItemKind::Member(ParsedMember { name, full_name: path_sym, kind: ParsedMemberKind::Mod(body) })
ItemKind::Member(ParsedMember { name, exported, kind: ParsedMemberKind::Mod(body) })
} else if discr == ctx.i().i("const").await {
let name = parse_const(ctx, tail, path.clone()).await?;
ItemKind::Member(ParsedMember { name, full_name: path_sym, kind: ParsedMemberKind::Const })
let (name, expr) = parse_const(ctx, tail, path.clone()).await?;
ItemKind::Member(ParsedMember { name, exported, kind: ParsedMemberKind::ParsedConst(expr) })
} else if let Some(sys) = ctx.systems().find(|s| s.can_parse(discr.clone())) {
let line = sys.parse(path_sym, tail.to_vec(), exported, comments).await?;
return parse_items(ctx, path, Snippet::new(tail.prev(), &line)).await;
return sys
.parse(path, tail.to_vec(), exported, comments, &mut async |stack, lines| {
let source = Snippet::new(lines.first().unwrap(), &lines);
parse_items(ctx, stack, source).await
})
.await;
} else {
let ext_lines = ctx.systems().flat_map(System::line_types).join(", ");
return Err(mk_errv(
ctx.i().i("Unrecognized line type").await,
format!("Line types are: const, mod, macro, grammar, {ext_lines}"),
[tail.prev().sr.pos().into()],
[tail.prev().sr()],
));
};
Ok(vec![Item { comments, sr: tail.sr(), kind }])
@@ -170,7 +142,7 @@ pub async fn parse_module<'a>(
return Err(mk_errv(
ctx.i().i("Missing module name").await,
format!("A name was expected, {} was found", fmt(output, ctx.i()).await),
[output.sr.pos().into()],
[output.sr()],
));
},
};
@@ -180,7 +152,7 @@ pub async fn parse_module<'a>(
return Err(mk_errv(
ctx.i().i("Expected module body").await,
format!("A ( block ) was expected, {} was found", fmt(output, ctx.i()).await),
[output.sr.pos().into()],
[output.sr()],
));
};
let path = path.push(name.clone());
@@ -191,13 +163,13 @@ pub async fn parse_const<'a>(
ctx: &impl HostParseCtx,
tail: ParsSnippet<'a>,
path: Substack<'_, Tok<String>>,
) -> OrcRes<Tok<String>> {
) -> OrcRes<(Tok<String>, Expr)> {
let Parsed { output, tail } = try_pop_no_fluff(ctx, tail).await?;
let Some(name) = output.as_name() else {
return Err(mk_errv(
ctx.i().i("Missing module name").await,
format!("A name was expected, {} was found", fmt(output, ctx.i()).await),
[output.sr.pos().into()],
[output.sr()],
));
};
let Parsed { output, tail } = try_pop_no_fluff(ctx, tail).await?;
@@ -205,12 +177,15 @@ pub async fn parse_const<'a>(
return Err(mk_errv(
ctx.i().i("Missing = separator").await,
format!("Expected = , found {}", fmt(output, ctx.i()).await),
[output.sr.pos().into()],
[output.sr()],
));
}
try_pop_no_fluff(ctx, tail).await?;
ctx.save_const(path, tail[..].to_vec()).await;
Ok(name)
// ctx.save_const(path, tail[..].to_vec()).await;
let final_path =
VPath::new(path.unreverse()).name_with_suffix(name.clone()).to_sym(ctx.i()).await;
let val = parse_expr(ctx, final_path, PathSetBuilder::new(), tail).await?;
Ok((name, val))
}
pub async fn parse_expr(
@@ -223,7 +198,7 @@ pub async fn parse_expr(
.or_else(|| tail.iter().enumerate().rev().find(|(_, tt)| !tt.is_fluff()))
else {
return Err(mk_errv(ctx.i().i("Empty expression").await, "Expression ends abruptly here", [
tail.sr().pos().into(),
tail.sr(),
]));
};
let (function, value) = tail.split_at(last_idx as u32);
@@ -241,7 +216,7 @@ pub async fn parse_expr(
Token::Handle(expr) => Ok(expr.clone()),
Token::NS(n, nametail) => {
let mut nametail = nametail;
let mut segments = path.iter().chain([n]).cloned().collect_vec();
let mut segments = vec![n.clone()];
while let Token::NS(n, newtail) = &nametail.tok {
segments.push(n.clone());
nametail = newtail;
@@ -250,7 +225,7 @@ pub async fn parse_expr(
return Err(mk_errv(
ctx.i().i("Loose namespace prefix in constant").await,
"Namespace prefixes in constants must be followed by names",
[pos.into()],
[pos],
));
};
segments.push(n.clone());
@@ -261,13 +236,27 @@ pub async fn parse_expr(
return Err(mk_errv(
ctx.i().i("Complex lambda binding in constant").await,
"Lambda args in constants must be identified by a single name",
[pos.into()],
[pos],
));
};
let lambda_builder = psb.lambda(arg);
let body = parse_expr(ctx, path.clone(), lambda_builder.stack(), tail).boxed_local().await?;
Ok(ExprKind::Lambda(lambda_builder.collect(), body).at(pos.clone()))
},
_ => todo!("AAAAAA"), // TODO: todo
Token::S(Paren::Round, body) =>
parse_expr(ctx, path, psb, Snippet::new(head, body)).boxed_local().await,
Token::S(..) =>
return Err(mk_errv(
ctx.i().i("Constants may only contain (), not [] or {}").await,
"It seems like you are trying to call a macro. Consider a 'let' line",
[pos],
)),
Token::Name(n) =>
if psb.register_arg(n) {
Ok(ExprKind::Arg.at(pos))
} else {
Ok(ExprKind::Const(Sym::new([n.clone()], ctx.i()).await.unwrap()).at(pos))
},
Token::NewExpr(ex) => Ok(ex.clone()),
}
}