feat: Initialize compiler GUI project
Sets up the basic structure for the compiler GUI application using eframe. This includes the main application loop, a default UI layout with a source code editor and an output log panel, and the foundational AST (Abstract Syntax Tree) definitions for types, nodes, and an evaluation mechanism.
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
pub mod types;
|
||||
pub mod nodes;
|
||||
|
||||
pub use types::*;
|
||||
pub use nodes::*;
|
||||
@@ -0,0 +1,63 @@
|
||||
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 {
|
||||
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::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::Nil
|
||||
}
|
||||
}
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
||||
/// Shared identity for nodes (Location, etc.)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NodeIdentity {
|
||||
pub line: u32,
|
||||
pub col: u32,
|
||||
}
|
||||
|
||||
pub type Identity = Arc<NodeIdentity>;
|
||||
|
||||
/// Interned string identifier
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Keyword(pub u32);
|
||||
|
||||
/// Core data value in Myc Script (similar to TDataValue)
|
||||
#[derive(Clone)]
|
||||
pub enum Value {
|
||||
Nil,
|
||||
Bool(bool),
|
||||
Int(i64),
|
||||
Float(f64),
|
||||
Text(Arc<str>),
|
||||
Keyword(Keyword),
|
||||
List(Arc<Vec<Value>>),
|
||||
Record(Arc<HashMap<Keyword, Value>>),
|
||||
Function(Arc<dyn Fn(Vec<Value>) -> Value + Send + Sync>),
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn is_truthy(&self) -> bool {
|
||||
match self {
|
||||
Value::Nil => false,
|
||||
Value::Bool(b) => *b,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Value {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Value::Nil => write!(f, "nil"),
|
||||
Value::Bool(b) => write!(f, "{}", b),
|
||||
Value::Int(i) => write!(f, "{}", i),
|
||||
Value::Float(fl) => write!(f, "{}", fl),
|
||||
Value::Text(t) => write!(f, "\"{}\"", t),
|
||||
Value::Keyword(k) => write!(f, ":kw#{}", k.0),
|
||||
Value::List(l) => write!(f, "<list[{}]>", l.len()),
|
||||
Value::Record(r) => write!(f, "<record[{}]>", r.len()),
|
||||
Value::Function(_) => write!(f, "<fn>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Value {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user