111 lines
2.2 KiB
Rust
111 lines
2.2 KiB
Rust
#![cfg_attr(test, allow(non_snake_case))]
|
|
|
|
use crate::ast::{Name, Program, Term, Unique};
|
|
use std::cell::RefCell;
|
|
use std::collections::HashMap;
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
mod apply;
|
|
mod builtin;
|
|
mod constant;
|
|
mod delay;
|
|
mod error;
|
|
mod force;
|
|
mod lambda;
|
|
mod var;
|
|
|
|
pub use apply::*;
|
|
pub use builtin::*;
|
|
pub use constant::*;
|
|
pub use delay::*;
|
|
pub use error::*;
|
|
pub use force::*;
|
|
pub use lambda::*;
|
|
pub use var::*;
|
|
|
|
pub struct Builder {
|
|
version: (usize, usize, usize),
|
|
term: Term<Name>,
|
|
}
|
|
|
|
struct Context {
|
|
next_unique: isize,
|
|
names: HashMap<String, Unique>,
|
|
}
|
|
|
|
impl Context {
|
|
pub fn new() -> Context {
|
|
Context {
|
|
next_unique: 0,
|
|
names: HashMap::new(),
|
|
}
|
|
}
|
|
|
|
pub fn get_name(&mut self, name_str: &str) -> Name {
|
|
if let Some(unique) = self.names.get(name_str) {
|
|
Name {
|
|
text: name_str.to_string(),
|
|
unique: *unique,
|
|
}
|
|
} else {
|
|
let next_unique = self.next_unique;
|
|
self.next_unique = next_unique + 1;
|
|
let unique = Unique::new(next_unique);
|
|
self.names.insert(name_str.to_string(), unique);
|
|
Name {
|
|
text: name_str.to_string(),
|
|
unique,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct Core {
|
|
version: (usize, usize, usize),
|
|
ctx: RefCell<Context>,
|
|
}
|
|
|
|
pub trait WithTerm
|
|
where
|
|
Self: Sized,
|
|
{
|
|
type Next;
|
|
|
|
fn next(self, term: Term<Name>) -> Self::Next;
|
|
fn get_name(&self, name_str: &str) -> Name;
|
|
}
|
|
|
|
impl WithTerm for Core {
|
|
type Next = Builder;
|
|
fn next(self, term: Term<Name>) -> Self::Next {
|
|
Builder {
|
|
version: self.version,
|
|
term,
|
|
}
|
|
}
|
|
|
|
fn get_name(&self, name_str: &str) -> Name {
|
|
let mut ctx = self.ctx.borrow_mut();
|
|
ctx.get_name(name_str)
|
|
}
|
|
}
|
|
|
|
impl Builder {
|
|
/// Max: `9223372036854775807`
|
|
pub fn start(maj: usize, min: usize, patch: usize) -> Core {
|
|
Core {
|
|
version: (maj, min, patch),
|
|
ctx: RefCell::new(Context::new()),
|
|
}
|
|
}
|
|
|
|
pub fn build_named(&self) -> Program<Name> {
|
|
Program {
|
|
version: self.version,
|
|
term: self.term.clone(),
|
|
}
|
|
}
|
|
}
|