summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2026-03-10 17:41:24 +0100
committerThomas Voss <mail@thomasvoss.com> 2026-03-10 17:41:24 +0100
commit4e4232490a56bd573a40c46308e1eec8fdd7c875 (patch)
tree62430501fd65165fd246941badd4d2540698b422
parent81d1341b34bd2a09552a08ffe9a12147c2abb6e4 (diff)
Begin work on symbol collection
-rw-r--r--oryxc/src/compiler.rs72
-rw-r--r--oryxc/src/prelude.rs36
2 files changed, 81 insertions, 27 deletions
diff --git a/oryxc/src/compiler.rs b/oryxc/src/compiler.rs
index a855584..5518b1d 100644
--- a/oryxc/src/compiler.rs
+++ b/oryxc/src/compiler.rs
@@ -34,6 +34,7 @@ use crate::arena::{
LocalArena,
};
use crate::errors::OryxError;
+use crate::hashtrie::HTrie;
use crate::intern::Interner;
use crate::lexer::Token;
use crate::parser::{
@@ -55,6 +56,7 @@ pub struct FileData {
pub buffer: String,
pub tokens: OnceLock<Soa<Token>>,
pub ast: OnceLock<Ast>,
+ pub scopes: OnceLock<HTrie<ScopeId, Scope>>,
}
impl FileData {
@@ -75,6 +77,7 @@ impl FileData {
buffer,
tokens: OnceLock::new(),
ast: OnceLock::new(),
+ scopes: OnceLock::new(),
});
}
}
@@ -89,11 +92,10 @@ pub enum JobType {
file: FileId,
fdata: Arc<FileData>,
},
- FindSymbolsInScope {
- fdata: Arc<FileData>,
- scope: ScopeId,
- block: u32,
- },
+ IndexScopeConstants {
+ fdata: Arc<FileData>,
+ block: u32,
+ parent: ScopeId,
},
ResolveDefBind {
fdata: Arc<FileData>,
@@ -135,12 +137,21 @@ impl<'a> CompilerState<'a> {
}
}
+ /// Generate a new ID for a job, scope, etc.
+ #[inline(always)]
+ fn genid(&self) -> usize {
+ return self.next_id.fetch_add(1, Ordering::Relaxed);
+ }
+
+ /// Build a new job of type KIND.
+ #[inline(always)]
fn job_new(&self, kind: JobType) -> Job {
- let id = self.next_id.fetch_add(1, Ordering::Relaxed);
+ let id = self.genid();
return Job { id, kind };
}
- /// Push a job onto a worker's local queue and wake all threads.
+ /// Push a job onto a worker’s local queue and wake all threads.
+ #[inline(always)]
fn job_push(&self, queue: &Worker<Job>, job: Job) {
self.njobs.fetch_add(1, Ordering::Relaxed);
queue.push(job);
@@ -323,29 +334,33 @@ fn worker_loop(
let root = (ast.nodes.len() - 1) as u32;
fdata.ast.set(ast).unwrap();
+ fdata.scopes.set(HTrie::new()).unwrap();
c_state.job_push(
&queue,
- c_state.job_new(JobType::FindSymbolsInScope {
+ c_state.job_new(JobType::IndexScopeConstants {
fdata,
- scope: ScopeId::GLOBAL,
block: root,
+ parent: ScopeId::INVALID,
}),
);
true
},
- JobType::FindSymbolsInScope {
+ JobType::IndexScopeConstants {
fdata,
- scope,
block,
+ parent,
} => {
let tokens = fdata.tokens.get().unwrap();
let ast = fdata.ast.get().unwrap();
let SubNodes(beg, nstmts) = ast.nodes.sub()[block as usize];
let mut errors = Vec::new();
+ let scope = Scope::new(parent);
+ /* First pass inserts all the symbols in this scope into the
+ * symbol table */
for i in beg..beg + nstmts {
let node = ast.extra[i as usize];
if ast.nodes.kind()[node as usize] != AstType::MultiDefBind
@@ -369,11 +384,10 @@ fn worker_loop(
let sym = Symbol::default();
if let Some(mut sym) =
- fdata.symtab.insert((scope, symid), sym)
+ scope.symtab.insert(symid, sym, &arena)
{
sym.state = ResolutionState::Poisoned;
- fdata.symtab.insert((scope, symid), sym);
-
+ scope.symtab.insert(symid, sym, &arena);
errors.push(OryxError::new(
span,
format!(
@@ -382,17 +396,29 @@ fn worker_loop(
));
}
}
-
- c_state.job_push(
- &queue,
- c_state.job_new(JobType::ResolveDefBind {
- fdata: fdata.clone(),
- scope,
- node: multi_def_bind,
- }),
- );
}
+ let scopeid = if parent == ScopeId::INVALID {
+ ScopeId::GLOBAL
+ } else {
+ ScopeId(c_state.genid())
+ };
+ fdata.scopes.get().unwrap().insert(scopeid, scope, &arena);
+
+ /* Second pass emits jobs to resolve types */
+ for i in beg..beg + nstmts {
+ let node = ast.extra[i as usize];
+ if ast.nodes.kind()[node as usize] != AstType::MultiDefBind
+ {
+ continue;
+ }
+ c_state.job_push(&queue, c_state.job_new(JobType::ResolveDefBind {
+ fdata: fdata.clone(),
+ node,
+ scope: scopeid,
+ }));
+ }
+
let ok = errors.is_empty();
emit_errors(&fdata, errors);
ok
diff --git a/oryxc/src/prelude.rs b/oryxc/src/prelude.rs
index 32a123f..c118c0d 100644
--- a/oryxc/src/prelude.rs
+++ b/oryxc/src/prelude.rs
@@ -4,6 +4,8 @@ use std::fmt::{
Formatter,
};
+use crate::hashtrie::HTrie;
+
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct FileId(pub usize);
@@ -11,14 +13,32 @@ pub struct FileId(pub usize);
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct SymbolId(pub u32);
+#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct ScopeId(pub usize);
impl ScopeId {
pub const GLOBAL: Self = Self(0);
+ pub const INVALID: Self = Self(usize::MAX);
}
-#[derive(Default)]
+#[derive(Debug)]
+pub struct Scope {
+ pub parent: ScopeId,
+ pub symtab: HTrie<SymbolId, Symbol>,
+}
+
+impl Scope {
+ pub fn new(parent: ScopeId) -> Self {
+ return Self {
+ parent,
+ symtab: HTrie::new(),
+ };
+ }
+}
+
+#[repr(u8)]
+#[derive(Debug, Default)]
pub enum ResolutionState {
#[default]
Unresolved,
@@ -27,14 +47,22 @@ pub enum ResolutionState {
Poisoned,
}
-#[derive(Default)]
+#[derive(Debug, Default)]
pub struct Symbol {
- pub state: ResolutionState,
- pub r#type: u32,
+ pub state: ResolutionState,
+ pub kind: u32,
+}
+
+#[repr(u8)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum DeclKind {
+ ConstDef = 0,
+ Param = 1,
}
pub enum OryxType {
Integer { bits: usize, signed: bool },
+ Boolean,
Pointer { base: u32 },
Function { args: Vec<u32>, rets: Vec<u32> },
}