Added support for defining macros in Rust within the macro system

Also fixed a lot of bugs
This commit is contained in:
2025-09-30 21:23:16 +02:00
parent 7971a2b4eb
commit b77653f841
52 changed files with 849 additions and 502 deletions

View File

@@ -10,10 +10,10 @@ use std::rc::Rc;
use async_fn_stream::try_stream;
use camino::Utf8PathBuf;
use clap::{Parser, Subcommand};
use futures::{Stream, TryStreamExt, io};
use futures::{FutureExt, Stream, TryStreamExt, io};
use itertools::Itertools;
use orchid_base::error::Reporter;
use orchid_base::format::{FmtCtxImpl, Format, take_first};
use orchid_base::format::{FmtCtxImpl, Format, fmt, take_first};
use orchid_base::location::SrcRange;
use orchid_base::logging::{LogStrategy, Logger};
use orchid_base::name::{NameLike, VPath};
@@ -29,6 +29,7 @@ use orchid_host::parse::{HostParseCtxImpl, parse_item, parse_items};
use orchid_host::parsed::{Item, ItemKind, ParsTokTree, ParsedMember, ParsedModule};
use orchid_host::subprocess::ext_command;
use orchid_host::system::init_systems;
use orchid_host::tree::{MemberKind, Module, RootData};
use substack::Substack;
use tokio::io::{AsyncBufReadExt, BufReader, stdin};
use tokio::task::{LocalSet, spawn_local};
@@ -61,6 +62,12 @@ pub enum Commands {
file: Utf8PathBuf,
},
Repl,
ModTree {
#[arg(long)]
proj: Option<Utf8PathBuf>,
#[arg(long)]
prefix: Option<String>,
},
Exec {
#[arg(long)]
proj: Option<Utf8PathBuf>,
@@ -226,6 +233,53 @@ async fn main() -> io::Result<ExitCode> {
}
}
},
Commands::ModTree { proj, prefix } => {
let reporter = Reporter::new();
let (mut root, _systems) = init_systems(&args.system, &extensions).await.unwrap();
if let Some(proj_path) = proj {
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) => {
eprintln!("{e}");
*exit_code1.borrow_mut() = ExitCode::FAILURE;
return;
},
}
}
let prefix = match prefix {
Some(pref) => VPath::parse(&pref, i).await,
None => VPath::new([]),
};
let root_data = root.0.read().await;
print_mod(&root_data.root, prefix, &root_data).await;
async fn print_mod(module: &Module, path: VPath, root: &RootData) {
let indent = " ".repeat(path.len());
for (key, tgt) in &module.imports {
match tgt {
Ok(tgt) => println!("{indent}import {key} => {}", tgt.target),
Err(opts) => println!(
"{indent}import {key} conflicts between {}",
opts.iter().map(|i| &i.target).join(" ")
),
}
}
for (key, mem) in &module.members {
let new_path = path.clone().name_with_suffix(key.clone()).to_sym(&root.ctx.i).await;
match mem.kind(root.ctx.clone(), &root.consts).await {
MemberKind::Module(module) => {
println!("{indent}module {key} {{");
print_mod(module, VPath::new(new_path.segs()), root).boxed_local().await;
println!("{indent}}}")
},
MemberKind::Const => {
let value = root.consts.get(&new_path).expect("Missing const!");
println!("{indent}const {key} = {}", fmt(value, &root.ctx.i).await)
},
}
}
}
},
Commands::Exec { proj, code } => {
let reporter = Reporter::new();
let path = sym!(usercode; i).await;