From 0ab2106660280050f5b527ca58c5d673a43980d6 Mon Sep 17 00:00:00 2001 From: romir kulshrestha Date: Wed, 4 Mar 2026 19:02:53 +0100 Subject: idio(ma)tic --- oryxc/src/compiler.rs | 193 ++++++++++++++++++++++---------------------------- oryxc/src/main.rs | 4 +- 2 files changed, 87 insertions(+), 110 deletions(-) (limited to 'oryxc') diff --git a/oryxc/src/compiler.rs b/oryxc/src/compiler.rs index 8fdd53f..355b496 100644 --- a/oryxc/src/compiler.rs +++ b/oryxc/src/compiler.rs @@ -3,20 +3,17 @@ use std::io::{ self, Write, }; -use std::iter::{ - self, - IntoIterator, -}; -use std::mem::MaybeUninit; -use std::sync::Arc; +use std::iter::once; use std::sync::atomic::{ AtomicUsize, Ordering, }; -use std::vec::Vec; +use std::sync::{ + Arc, + OnceLock, +}; use std::{ fs, - panic, process, thread, }; @@ -44,11 +41,11 @@ use crate::{ pub struct FileId(usize); pub struct FileData { - name: Arc, - buffer: Arc, - tokens: Arc>>, - ast: Arc>>, - extra_data: Arc>>, + pub name: OsString, + pub buffer: String, + pub tokens: OnceLock>, + pub ast: OnceLock>, + pub extra_data: OnceLock>, } impl FileData { @@ -58,26 +55,27 @@ impl FileData { // Append extra data to the end so that we can safely read past // instead of branching on length let mut buffer = fs::read_to_string(&name)?; - buffer.push_str(unsafe { str::from_utf8_unchecked(&PAD) }); - - return Ok(Self { - name: name.into(), - buffer: buffer.into(), - tokens: Arc::new_uninit(), - ast: Arc::new_uninit(), - extra_data: Arc::new_uninit(), - }); + buffer.push_str(unsafe { std::str::from_utf8_unchecked(&PAD) }); + + Ok(Self { + name, + buffer, + tokens: OnceLock::new(), + ast: OnceLock::new(), + extra_data: OnceLock::new(), + }) } } +#[allow(dead_code)] pub enum Job { - Lex { file: FileId }, - Parse { file: FileId }, - ResolveSymbols { file: FileId }, + Lex { file: FileId, fdata: Arc }, + Parse { file: FileId, fdata: Arc }, + ResolveSymbols { file: FileId, fdata: Arc }, } pub struct CompilerState { - pub files: DashMap, + pub files: DashMap>, pub globalq: Injector, pub njobs: AtomicUsize, pub flags: Flags, @@ -95,13 +93,13 @@ where }); for (i, path) in paths.into_iter().enumerate() { let id = FileId(i); - let data = match FileData::new(path.clone().into()) { - Ok(x) => x, - Err(e) => err!(e, "{}", path.display()), - }; - state.files.insert(id, data); + let fdata = Arc::new( + FileData::new(path.clone().into()) + .unwrap_or_else(|e| err!(e, "{}", path.display())), + ); + state.files.insert(id, Arc::clone(&fdata)); state.njobs.fetch_add(1, Ordering::Relaxed); - state.globalq.push(Job::Lex { file: id }); + state.globalq.push(Job::Lex { file: id, fdata }); } let mut workers = Vec::with_capacity(flags.threads); @@ -119,48 +117,28 @@ where let stealer_view = Arc::clone(&stealer_view); let state = Arc::clone(&state); threads.push(thread::spawn(move || { - worker_loop(id, state, w, stealer_view); + worker_loop(id, state, w, stealer_view) })); } for t in threads { - t.join().unwrap_or_else(|e| panic::resume_unwind(e)); - } -} - -macro_rules! fdata_read { - ($state:expr, $file:expr, $($field:ident),+ $(,)?) => { - #[allow(unused_parens)] - let ($($field),+) = { - let fdata = $state.files.get(&$file).unwrap(); - ($(fdata.$field.clone()),+) - }; - }; -} - -macro_rules! fdata_write { - ($state:expr, $file:expr, $($field:ident),+ $(,)?) => { - { - let mut fdata = $state.files.get_mut(&$file).unwrap(); - $( - fdata.$field = Arc::from(MaybeUninit::new($field)); - )+ + if let Err(e) = t.join() { + std::panic::resume_unwind(e) } - }; + } } -fn emit_errors(state: Arc, file: FileId, errors: T) +fn emit_errors(fdata: &FileData, errors: T) where T: IntoIterator, { - fdata_read!(state, file, name, buffer); - for e in errors.into_iter() { - e.report(name.as_ref(), buffer.as_ref()); + for e in errors { + e.report(&fdata.name, &fdata.buffer); } } fn worker_loop( - id: usize, + _id: usize, state: Arc, queue: Worker, stealers: Arc<[Stealer]>, @@ -170,62 +148,61 @@ fn worker_loop( break; } - let job = find_task(&queue, &state.globalq, &stealers); - if let Some(job) = job { - match job { - Job::Lex { file } => { - fdata_read!(state, file, buffer); - let tokens = match lexer::tokenize(buffer.as_ref()) { - Ok(xs) => xs, - Err(e) => { - emit_errors(state.clone(), file, iter::once(e)); - process::exit(1); - }, - }; + let Some(job) = find_task(&queue, &state.globalq, &stealers) else { + thread::yield_now(); + continue; + }; - if state.flags.debug_lexer { - let mut handle = io::stderr().lock(); - for t in tokens.iter() { - let _ = write!(handle, "{t:?}\n"); - } + match job { + Job::Lex { file, fdata } => { + let tokens = match lexer::tokenize(&fdata.buffer) { + Ok(xs) => xs, + Err(e) => { + emit_errors(&fdata, once(e)); + process::exit(1) + }, + }; + + if state.flags.debug_lexer { + let mut handle = io::stderr().lock(); + for t in tokens.iter() { + let _ = write!(handle, "{t:?}\n"); } - - fdata_write!(state, file, tokens); - state.njobs.fetch_add(1, Ordering::Relaxed); - queue.push(Job::Parse { file }); - }, - Job::Parse { file } => { - fdata_read!(state, file, tokens); - let (ast, extra_data) = match parser::parse( - unsafe { tokens.assume_init() }.as_ref(), - ) { + } + + fdata.tokens.set(tokens).unwrap(); + state.njobs.fetch_add(1, Ordering::Relaxed); + queue.push(Job::Parse { file, fdata }); + }, + Job::Parse { file, fdata } => { + let (ast, extra_data) = + match parser::parse(fdata.tokens.get().unwrap()) { Ok(xs) => xs, Err(errs) => { - emit_errors(state.clone(), file, errs); - process::exit(1); + emit_errors(&fdata, errs); + process::exit(1) }, }; - if state.flags.debug_parser { - let mut handle = io::stderr().lock(); - for n in ast.iter() { - let _ = write!(handle, "{n:?}\n"); - } + if state.flags.debug_parser { + let mut handle = io::stderr().lock(); + for n in ast.iter() { + let _ = write!(handle, "{n:?}\n"); } - - fdata_write!(state, file, ast, extra_data); - state.njobs.fetch_add(1, Ordering::Relaxed); - queue.push(Job::ResolveSymbols { file }); - }, - Job::ResolveSymbols { file } => { - err!("not implemented"); - }, - } - - state.njobs.fetch_sub(1, Ordering::Relaxed); - } else { - thread::yield_now(); + } + + fdata.ast.set(ast).unwrap(); + fdata.extra_data.set(extra_data).unwrap(); + state.njobs.fetch_add(1, Ordering::Relaxed); + queue.push(Job::ResolveSymbols { file, fdata }); + }, + Job::ResolveSymbols { file: _, fdata: _ } => { + err!("not implemented"); + // unimplemented!() + }, } + + state.njobs.fetch_sub(1, Ordering::Relaxed); } } @@ -256,5 +233,5 @@ fn find_task( } } - return None; + None } diff --git a/oryxc/src/main.rs b/oryxc/src/main.rs index ed7c550..b5c63cf 100644 --- a/oryxc/src/main.rs +++ b/oryxc/src/main.rs @@ -55,10 +55,10 @@ fn main() { } let flags = Flags { - debug_lexer: args.debug_lexer, + debug_lexer: args.debug_lexer, debug_parser: args.debug_parser, threads, - error_style: args.error_style, + error_style: args.error_style, }; let _ = errors::ERROR_STYLE.set(flags.error_style); -- cgit v1.2.3