Began implementing fully isomorphic macros

Like Rust's Proc macros. Now we have preprocessor recursion to worry about. I also made a cool macro for enums
This commit is contained in:
2024-10-14 00:13:09 +02:00
parent 84cbcdd4fe
commit 3a3ae98aff
66 changed files with 2302 additions and 1164 deletions

View File

@@ -1,17 +1,21 @@
use std::io::{self, BufRead as _};
use std::io::{self, BufRead as _, Write};
use std::path::PathBuf;
use std::sync::Mutex;
use std::{process, thread};
use orchid_api::ExtensionHeader;
use orchid_api_traits::{Decode, Encode};
use orchid_base::logging::Logger;
use orchid_base::msg::{recv_msg, send_msg};
use crate::api;
use crate::extension::ExtensionPort;
pub struct Subprocess {
child: Mutex<process::Child>,
stdin: Mutex<process::ChildStdin>,
stdout: Mutex<process::ChildStdout>,
header: ExtensionHeader,
}
impl Subprocess {
pub fn new(mut cmd: process::Command, logger: Logger) -> io::Result<Self> {
@@ -22,8 +26,11 @@ impl Subprocess {
.stdout(process::Stdio::piped())
.stderr(process::Stdio::piped())
.spawn()?;
let stdin = child.stdin.take().unwrap();
let stdout = child.stdout.take().unwrap();
let mut stdin = child.stdin.take().unwrap();
api::HostHeader { log_strategy: logger.strat() }.encode(&mut stdin);
stdin.flush()?;
let mut stdout = child.stdout.take().unwrap();
let header = ExtensionHeader::decode(&mut stdout);
let child_stderr = child.stderr.take().unwrap();
thread::Builder::new().name(format!("stderr-fwd:{prog}")).spawn(move || {
let mut reader = io::BufReader::new(child_stderr);
@@ -35,14 +42,25 @@ impl Subprocess {
logger.log(buf);
}
})?;
Ok(Self { child: Mutex::new(child), stdin: Mutex::new(stdin), stdout: Mutex::new(stdout) })
Ok(Self {
child: Mutex::new(child),
stdin: Mutex::new(stdin),
stdout: Mutex::new(stdout),
header,
})
}
}
impl Drop for Subprocess {
fn drop(&mut self) { self.child.lock().unwrap().wait().expect("Extension exited with error"); }
}
impl ExtensionPort for Subprocess {
fn send(&self, msg: &[u8]) { send_msg(&mut *self.stdin.lock().unwrap(), msg).unwrap() }
fn header(&self) -> &orchid_api::ExtensionHeader { &self.header }
fn send(&self, msg: &[u8]) {
if msg.starts_with(&[0, 0, 0, 0x1c]) {
panic!("Received unnecessary prefix");
}
send_msg(&mut *self.stdin.lock().unwrap(), msg).unwrap()
}
fn receive(&self) -> Option<Vec<u8>> {
match recv_msg(&mut *self.stdout.lock().unwrap()) {
Ok(msg) => Some(msg),