Phased out async-stream in pursuit of compile performance

This commit is contained in:
2025-09-04 15:01:53 +02:00
parent 088cb6a247
commit e339350505
26 changed files with 359 additions and 342 deletions

View File

@@ -6,8 +6,7 @@ edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
async-std = "1.13.0"
async-stream = "0.3.6"
async-fn-stream = { version = "0.1.0", path = "../async-fn-stream" }
camino = "1.1.9"
clap = { version = "4.5.24", features = ["derive", "env"] }
ctrlc = "3.4.5"

View File

@@ -7,9 +7,7 @@ use std::mem;
use std::process::{Command, ExitCode};
use std::rc::Rc;
use async_std::io::stdin;
use async_std::path::PathBuf;
use async_stream::try_stream;
use async_fn_stream::try_stream;
use camino::Utf8PathBuf;
use clap::{Parser, Subcommand};
use futures::{Stream, TryStreamExt, io};
@@ -32,6 +30,7 @@ use orchid_host::parsed::{Item, ItemKind, ParsTokTree, ParsedMember, ParsedModul
use orchid_host::subprocess::ext_command;
use orchid_host::system::init_systems;
use substack::Substack;
use tokio::io::{AsyncBufReadExt, BufReader, stdin};
use tokio::task::{LocalSet, spawn_local};
use crate::parse_folder::parse_folder;
@@ -62,7 +61,7 @@ pub enum Commands {
file: Utf8PathBuf,
},
Repl,
Execute {
Exec {
#[arg(long)]
proj: Option<Utf8PathBuf>,
#[arg()]
@@ -76,19 +75,16 @@ fn get_all_extensions<'a>(
msg_logger: &'a Logger,
ctx: &'a Ctx,
) -> impl Stream<Item = io::Result<Extension>> + 'a {
try_stream! {
try_stream(async |mut cx| {
for ext_path in args.extension.iter() {
let exe = if cfg!(windows) {
ext_path.with_extension("exe")
} else {
ext_path.clone()
};
let init = ext_command(Command::new(exe.as_os_str()), logger.clone(), msg_logger.clone(), ctx.clone()).await
.unwrap();
let ext = Extension::new(init, logger.clone(), msg_logger.clone(), ctx.clone())?;
yield ext
let exe = if cfg!(windows) { ext_path.with_extension("exe") } else { ext_path.clone() };
let init =
ext_command(Command::new(exe.as_os_str()), logger.clone(), msg_logger.clone(), ctx.clone())
.await?;
cx.emit(Extension::new(init, logger.clone(), msg_logger.clone(), ctx.clone())?).await;
}
}
Ok(cx)
})
}
#[tokio::main]
@@ -153,13 +149,14 @@ async fn main() -> io::Result<ExitCode> {
let mut counter = 0;
let mut imports = Vec::new();
let usercode_path = sym!(usercode; i).await;
let mut stdin = BufReader::new(stdin());
loop {
counter += 1;
let (mut root, systems) = init_systems(&args.system, &extensions).await.unwrap();
print!("\\.> ");
std::io::stdout().flush().unwrap();
let mut prompt = String::new();
stdin().read_line(&mut prompt).await.unwrap();
stdin.read_line(&mut prompt).await.unwrap();
let name = i.i(&format!("_{counter}")).await;
let path = usercode_path.suffix([name.clone()], i).await;
let mut lexemes =
@@ -229,13 +226,13 @@ async fn main() -> io::Result<ExitCode> {
}
}
},
Commands::Execute { proj, code } => {
Commands::Exec { proj, code } => {
let reporter = Reporter::new();
let path = sym!(usercode::entrypoint; i).await;
let prefix_sr = SrcRange::zw(path.clone(), 0);
let (mut root, systems) = init_systems(&args.system, &extensions).await.unwrap();
if let Some(proj_path) = proj {
let path = PathBuf::from(proj_path.into_std_path_buf());
let path = proj_path.into_std_path_buf();
match parse_folder(&root, path, sym!(src; i).await, &reporter, ctx.clone()).await {
Ok(r) => root = r,
Err(e) => {

View File

@@ -1,10 +1,6 @@
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use async_std::fs;
use async_std::fs::File;
use async_std::io::ReadExt;
use async_std::path::{Path, PathBuf};
use async_std::stream::StreamExt;
use futures::FutureExt;
use itertools::Itertools;
use orchid_base::error::{OrcRes, Reporter, async_io_err, mk_errv, os_str_to_string};
@@ -17,6 +13,8 @@ use orchid_host::parse::{HostParseCtxImpl, parse_items};
use orchid_host::parsed::ParsedModule;
use orchid_host::tree::Root;
use substack::Substack;
use tokio::fs::{self, File};
use tokio::io::AsyncReadExt;
pub async fn parse_folder(
root: &Root,
@@ -30,7 +28,7 @@ pub async fn parse_folder(
return Ok(root.add_parsed(&parsed_module, ns, rep).await);
async fn recur(path: &Path, ns: Sym, rep: &Reporter, ctx: Ctx) -> OrcRes<Option<ParsedModule>> {
let sr = SrcRange::new(0..0, &ns);
if path.is_dir().await {
if path.is_dir() {
let Some(name_os) = path.file_name() else {
return Err(mk_errv(
ctx.i.i("Could not read directory name").await,
@@ -46,9 +44,10 @@ pub async fn parse_folder(
Err(err) => return Err(async_io_err(err, &ctx.i, [sr]).await),
Ok(s) => s,
};
while let Some(entry_res) = stream.next().await {
let entry = match entry_res {
Ok(ent) => ent,
loop {
let entry = match stream.next_entry().await {
Ok(Some(ent)) => ent,
Ok(None) => break,
Err(err) => {
rep.report(async_io_err(err, &ctx.i, [sr.clone()]).await);
continue;