Refactor: Replace UntypedNode with SyntaxNode

This commit replaces the `UntypedNode` enum with the more accurately
named `SyntaxNode`. This change is primarily for clarity and better
reflects the role of these nodes as representing the structure of the
source code prior to semantic analysis.

The corresponding enum `UntypedKind` has also been renamed to
`SyntaxKind` to maintain consistency.

No functional changes are introduced by this refactoring; it is purely a
renaming and organizational update.
This commit is contained in:
Michael Schimmel
2026-03-13 14:21:28 +01:00
parent 7d72a99fa1
commit 84226f6a16
31 changed files with 8611 additions and 8611 deletions
+176 -176
View File
@@ -1,176 +1,176 @@
use crate::ast::environment::Environment;
use crate::ast::types::{Purity, Signature, StaticType, Value};
use std::f64::consts;
pub fn register(env: &Environment) {
// Constants
env.register_constant("PI", StaticType::Float, Value::Float(consts::PI));
env.register_constant("E", StaticType::Float, Value::Float(consts::E));
// Helper to get f64 from Value (Int or Float)
fn to_f64(v: &Value) -> Option<f64> {
match v {
Value::Float(f) => Some(*f),
Value::Int(i) => Some(*i as f64),
_ => None,
}
}
// Unary functions (float -> float)
let register_unary = |name: &'static str, f: fn(f64) -> f64| {
let ty = StaticType::Function(Box::new(Signature {
params: StaticType::Tuple(vec![StaticType::Float]),
ret: StaticType::Float,
}));
env.register_native_fn(name, ty, Purity::Pure, move |args| {
if let Some(x) = to_f64(&args[0]) {
Value::Float(f(x))
} else {
Value::Void
}
});
};
// Unary functions (float -> int)
let register_to_int = |name: &'static str, f: fn(f64) -> f64| {
let ty = StaticType::Function(Box::new(Signature {
params: StaticType::Tuple(vec![StaticType::Float]),
ret: StaticType::Int,
}));
env.register_native_fn(name, ty, Purity::Pure, move |args| {
if let Some(x) = to_f64(&args[0]) {
Value::Int(f(x) as i64)
} else {
Value::Void
}
});
};
register_unary("sqrt", f64::sqrt);
register_unary("sin", f64::sin);
register_unary("cos", f64::cos);
register_unary("tan", f64::tan);
register_unary("asin", f64::asin);
register_unary("acos", f64::acos);
register_unary("atan", f64::atan);
register_unary("exp", f64::exp);
register_unary("ln", f64::ln);
register_unary("log10", f64::log10);
register_unary("fract", f64::fract);
// Rounding functions returning Int
register_to_int("round", f64::round);
register_to_int("floor", f64::floor);
register_to_int("ceil", f64::ceil);
register_to_int("trunc", f64::trunc);
// Binary functions (float, float -> float)
let register_binary = |name: &'static str, f: fn(f64, f64) -> f64| {
let ty = StaticType::Function(Box::new(Signature {
params: StaticType::Tuple(vec![StaticType::Float, StaticType::Float]),
ret: StaticType::Float,
}));
env.register_native_fn(name, ty, Purity::Pure, move |args| {
if let (Some(a), Some(b)) = (to_f64(&args[0]), to_f64(&args[1])) {
Value::Float(f(a, b))
} else {
Value::Void
}
});
};
register_binary("atan2", f64::atan2);
register_binary("pow", f64::powf);
register_binary("log", f64::log);
// Specialized abs to handle Int -> Int, Float -> Float
let abs_ty = StaticType::Function(Box::new(Signature {
params: StaticType::Tuple(vec![StaticType::Any]),
ret: StaticType::Any,
}));
env.register_native_fn("abs", abs_ty, Purity::Pure, |args| {
if args.len() != 1 {
return Value::Void;
}
match args[0] {
Value::Int(i) => Value::Int(i.abs()),
Value::Float(f) => Value::Float(f.abs()),
_ => Value::Void,
}
});
// Variadic min / max
let variadic_ty = StaticType::Function(Box::new(Signature {
params: StaticType::Any,
ret: StaticType::Any,
}));
env.register_native_fn("min", variadic_ty.clone(), Purity::Pure, |args| {
if args.is_empty() {
return Value::Void;
}
let mut best = args[0].clone();
for arg in &args[1..] {
if let Some(ord) = arg.partial_cmp(&best)
&& ord == std::cmp::Ordering::Less
{
best = arg.clone();
}
}
best
});
env.register_native_fn("max", variadic_ty, Purity::Pure, |args| {
if args.is_empty() {
return Value::Void;
}
let mut best = args[0].clone();
for arg in &args[1..] {
if let Some(ord) = arg.partial_cmp(&best)
&& ord == std::cmp::Ordering::Greater
{
best = arg.clone();
}
}
best
});
// Random generator factory (Closure-based)
let generator_sig = Signature {
params: StaticType::Tuple(vec![]),
ret: StaticType::Float,
};
let make_random_ty = StaticType::FunctionOverloads(vec![
Signature {
params: StaticType::Tuple(vec![]),
ret: StaticType::Function(Box::new(generator_sig.clone())),
},
Signature {
params: StaticType::Tuple(vec![StaticType::Int]),
ret: StaticType::Function(Box::new(generator_sig)),
},
]);
env.register_native_fn(
"make-random",
make_random_ty,
Purity::SideEffectFree,
|args| {
let rng = if args.is_empty() {
fastrand::Rng::new()
} else if let Value::Int(s) = args[0] {
fastrand::Rng::with_seed(s as u64)
} else {
fastrand::Rng::new()
};
let prng = std::rc::Rc::new(std::cell::RefCell::new(rng));
Value::Function(std::rc::Rc::new(crate::ast::types::NativeFunction {
func: std::rc::Rc::new(move |_args| Value::Float(prng.borrow_mut().f64())),
purity: Purity::Impure,
}))
},
);
}
use crate::ast::environment::Environment;
use crate::ast::types::{Purity, Signature, StaticType, Value};
use std::f64::consts;
pub fn register(env: &Environment) {
// Constants
env.register_constant("PI", StaticType::Float, Value::Float(consts::PI));
env.register_constant("E", StaticType::Float, Value::Float(consts::E));
// Helper to get f64 from Value (Int or Float)
fn to_f64(v: &Value) -> Option<f64> {
match v {
Value::Float(f) => Some(*f),
Value::Int(i) => Some(*i as f64),
_ => None,
}
}
// Unary functions (float -> float)
let register_unary = |name: &'static str, f: fn(f64) -> f64| {
let ty = StaticType::Function(Box::new(Signature {
params: StaticType::Tuple(vec![StaticType::Float]),
ret: StaticType::Float,
}));
env.register_native_fn(name, ty, Purity::Pure, move |args| {
if let Some(x) = to_f64(&args[0]) {
Value::Float(f(x))
} else {
Value::Void
}
});
};
// Unary functions (float -> int)
let register_to_int = |name: &'static str, f: fn(f64) -> f64| {
let ty = StaticType::Function(Box::new(Signature {
params: StaticType::Tuple(vec![StaticType::Float]),
ret: StaticType::Int,
}));
env.register_native_fn(name, ty, Purity::Pure, move |args| {
if let Some(x) = to_f64(&args[0]) {
Value::Int(f(x) as i64)
} else {
Value::Void
}
});
};
register_unary("sqrt", f64::sqrt);
register_unary("sin", f64::sin);
register_unary("cos", f64::cos);
register_unary("tan", f64::tan);
register_unary("asin", f64::asin);
register_unary("acos", f64::acos);
register_unary("atan", f64::atan);
register_unary("exp", f64::exp);
register_unary("ln", f64::ln);
register_unary("log10", f64::log10);
register_unary("fract", f64::fract);
// Rounding functions returning Int
register_to_int("round", f64::round);
register_to_int("floor", f64::floor);
register_to_int("ceil", f64::ceil);
register_to_int("trunc", f64::trunc);
// Binary functions (float, float -> float)
let register_binary = |name: &'static str, f: fn(f64, f64) -> f64| {
let ty = StaticType::Function(Box::new(Signature {
params: StaticType::Tuple(vec![StaticType::Float, StaticType::Float]),
ret: StaticType::Float,
}));
env.register_native_fn(name, ty, Purity::Pure, move |args| {
if let (Some(a), Some(b)) = (to_f64(&args[0]), to_f64(&args[1])) {
Value::Float(f(a, b))
} else {
Value::Void
}
});
};
register_binary("atan2", f64::atan2);
register_binary("pow", f64::powf);
register_binary("log", f64::log);
// Specialized abs to handle Int -> Int, Float -> Float
let abs_ty = StaticType::Function(Box::new(Signature {
params: StaticType::Tuple(vec![StaticType::Any]),
ret: StaticType::Any,
}));
env.register_native_fn("abs", abs_ty, Purity::Pure, |args| {
if args.len() != 1 {
return Value::Void;
}
match args[0] {
Value::Int(i) => Value::Int(i.abs()),
Value::Float(f) => Value::Float(f.abs()),
_ => Value::Void,
}
});
// Variadic min / max
let variadic_ty = StaticType::Function(Box::new(Signature {
params: StaticType::Any,
ret: StaticType::Any,
}));
env.register_native_fn("min", variadic_ty.clone(), Purity::Pure, |args| {
if args.is_empty() {
return Value::Void;
}
let mut best = args[0].clone();
for arg in &args[1..] {
if let Some(ord) = arg.partial_cmp(&best)
&& ord == std::cmp::Ordering::Less
{
best = arg.clone();
}
}
best
});
env.register_native_fn("max", variadic_ty, Purity::Pure, |args| {
if args.is_empty() {
return Value::Void;
}
let mut best = args[0].clone();
for arg in &args[1..] {
if let Some(ord) = arg.partial_cmp(&best)
&& ord == std::cmp::Ordering::Greater
{
best = arg.clone();
}
}
best
});
// Random generator factory (Closure-based)
let generator_sig = Signature {
params: StaticType::Tuple(vec![]),
ret: StaticType::Float,
};
let make_random_ty = StaticType::FunctionOverloads(vec![
Signature {
params: StaticType::Tuple(vec![]),
ret: StaticType::Function(Box::new(generator_sig.clone())),
},
Signature {
params: StaticType::Tuple(vec![StaticType::Int]),
ret: StaticType::Function(Box::new(generator_sig)),
},
]);
env.register_native_fn(
"make-random",
make_random_ty,
Purity::SideEffectFree,
|args| {
let rng = if args.is_empty() {
fastrand::Rng::new()
} else if let Value::Int(s) = args[0] {
fastrand::Rng::with_seed(s as u64)
} else {
fastrand::Rng::new()
};
let prng = std::rc::Rc::new(std::cell::RefCell::new(rng));
Value::Function(std::rc::Rc::new(crate::ast::types::NativeFunction {
func: std::rc::Rc::new(move |_args| Value::Float(prng.borrow_mut().f64())),
purity: Purity::Impure,
}))
},
);
}