c05c74bb65
Introduces the lexer and parser modules, enabling the conversion of source code into an Abstract Syntax Tree (AST). This includes: - Defining token kinds and structures. - Implementing lexer logic to tokenize input. - Defining AST node kinds and structures. - Implementing parser logic to construct the AST from tokens. - Adding support for basic expressions, lists, keywords, and identifiers. - Adding the `lazy_static` dependency for keyword interning. - Refactoring `Value::Nil` to `Value::Void`.
67 lines
2.0 KiB
Rust
67 lines
2.0 KiB
Rust
use std::sync::Arc;
|
|
use std::fmt::Debug;
|
|
use crate::ast::types::{Identity, Value};
|
|
|
|
/// A generic AST Node wrapper to preserve identity and metadata
|
|
#[derive(Debug, Clone)]
|
|
pub struct Node<K> {
|
|
pub identity: Identity,
|
|
pub kind: K,
|
|
}
|
|
|
|
/// The base for custom node types (extensions)
|
|
pub trait CustomNode: Debug + Send + Sync {
|
|
fn eval(&self, node: &Node<UntypedKind>, ctx: &mut Context) -> Value;
|
|
fn display_name(&self) -> &'static str;
|
|
}
|
|
|
|
/// Evaluation Context (Scope management)
|
|
pub struct Context {
|
|
// Add variables, scope management here later
|
|
}
|
|
|
|
/// The core AST variant enum for performance and structure
|
|
#[derive(Debug)]
|
|
pub enum UntypedKind {
|
|
/// The "..." placeholder for incomplete code
|
|
Nop,
|
|
Constant(Value),
|
|
Identifier(Arc<str>),
|
|
If {
|
|
cond: Box<Node<UntypedKind>>,
|
|
then_br: Box<Node<UntypedKind>>,
|
|
else_br: Option<Box<Node<UntypedKind>>>,
|
|
},
|
|
Call {
|
|
callee: Box<Node<UntypedKind>>,
|
|
args: Vec<Node<UntypedKind>>,
|
|
},
|
|
/// The "escape hatch" for decentralized node types
|
|
Extension(Box<dyn CustomNode>),
|
|
}
|
|
|
|
impl Node<UntypedKind> {
|
|
pub fn eval(&self, ctx: &mut Context) -> Value {
|
|
match &self.kind {
|
|
UntypedKind::Nop => Value::Void,
|
|
UntypedKind::Constant(v) => v.clone(),
|
|
UntypedKind::Identifier(_) => todo!("Lookup in Context"),
|
|
UntypedKind::If { cond, then_br, else_br } => {
|
|
if cond.eval(ctx).is_truthy() {
|
|
then_br.eval(ctx)
|
|
} else if let Some(eb) = else_br {
|
|
eb.eval(ctx)
|
|
} else {
|
|
Value::Void
|
|
}
|
|
}
|
|
UntypedKind::Call { callee, args } => {
|
|
let _func = callee.eval(ctx);
|
|
let _eval_args: Vec<Value> = args.iter().map(|a| a.eval(ctx)).collect();
|
|
todo!("Execute func with args")
|
|
}
|
|
UntypedKind::Extension(ext) => ext.eval(self, ctx),
|
|
}
|
|
}
|
|
}
|