Refactor Purity enum and NativeFunction struct
Move `Purity` enum definition from `optimizer.rs` to `types.rs` and create a `NativeFunction` struct to hold the function and its purity. Update `Value::Function` to store `Rc<NativeFunction>` and `Value::make_function` helper to simplify creation. This change allows tracking the purity of native functions, which is useful for optimization and static analysis.
This commit is contained in:
+19
-20
@@ -1,5 +1,4 @@
|
||||
use crate::ast::types::{StaticType, Value};
|
||||
use std::rc::Rc;
|
||||
use crate::ast::types::{Purity, StaticType, Value};
|
||||
|
||||
/// Looks up a specialized intrinsic function for the given operator and argument types.
|
||||
/// Returns (Executable Value, Return Type) if a fast-path exists.
|
||||
@@ -7,29 +6,29 @@ pub fn lookup(name: &str, args: &[StaticType]) -> Option<(Value, StaticType)> {
|
||||
match (name, args) {
|
||||
// --- Integer Arithmetic ---
|
||||
("+", [StaticType::Int, StaticType::Int]) => Some((
|
||||
Value::Function(Rc::new(|args| {
|
||||
Value::make_function(Purity::Pure, |args| {
|
||||
if let (Value::Int(a), Value::Int(b)) = (&args[0], &args[1]) {
|
||||
Value::Int(a + b)
|
||||
} else {
|
||||
Value::Int(0) // Should not happen if type checker works
|
||||
}
|
||||
})),
|
||||
}),
|
||||
StaticType::Int,
|
||||
)),
|
||||
("-", [StaticType::Int, StaticType::Int]) => Some((
|
||||
Value::Function(Rc::new(|args| {
|
||||
Value::make_function(Purity::Pure, |args| {
|
||||
if let (Value::Int(a), Value::Int(b)) = (&args[0], &args[1]) {
|
||||
Value::Int(a - b)
|
||||
} else {
|
||||
Value::Int(0)
|
||||
}
|
||||
})),
|
||||
}),
|
||||
StaticType::Int,
|
||||
)),
|
||||
("-", [StaticType::Int, StaticType::Int, StaticType::Int]) => Some((
|
||||
// Variadic optimization for 3 args (common in some Lisp dialects, though - usually is binary/unary)
|
||||
// MyC's core.rs supports variadic subtraction.
|
||||
Value::Function(Rc::new(|args| {
|
||||
Value::make_function(Purity::Pure, |args| {
|
||||
let a = match args[0] {
|
||||
Value::Int(i) => i,
|
||||
_ => 0,
|
||||
@@ -43,69 +42,69 @@ pub fn lookup(name: &str, args: &[StaticType]) -> Option<(Value, StaticType)> {
|
||||
_ => 0,
|
||||
};
|
||||
Value::Int(a - b - c)
|
||||
})),
|
||||
}),
|
||||
StaticType::Int,
|
||||
)),
|
||||
("*", [StaticType::Int, StaticType::Int]) => Some((
|
||||
Value::Function(Rc::new(|args| {
|
||||
Value::make_function(Purity::Pure, |args| {
|
||||
if let (Value::Int(a), Value::Int(b)) = (&args[0], &args[1]) {
|
||||
Value::Int(a * b)
|
||||
} else {
|
||||
Value::Int(0)
|
||||
}
|
||||
})),
|
||||
}),
|
||||
StaticType::Int,
|
||||
)),
|
||||
|
||||
// --- Integer Comparison ---
|
||||
("<=", [StaticType::Int, StaticType::Int]) => Some((
|
||||
Value::Function(Rc::new(|args| {
|
||||
Value::make_function(Purity::Pure, |args| {
|
||||
if let (Value::Int(a), Value::Int(b)) = (&args[0], &args[1]) {
|
||||
Value::Bool(a <= b)
|
||||
} else {
|
||||
Value::Bool(false)
|
||||
}
|
||||
})),
|
||||
}),
|
||||
StaticType::Bool,
|
||||
)),
|
||||
("<", [StaticType::Int, StaticType::Int]) => Some((
|
||||
Value::Function(Rc::new(|args| {
|
||||
Value::make_function(Purity::Pure, |args| {
|
||||
if let (Value::Int(a), Value::Int(b)) = (&args[0], &args[1]) {
|
||||
Value::Bool(a < b)
|
||||
} else {
|
||||
Value::Bool(false)
|
||||
}
|
||||
})),
|
||||
}),
|
||||
StaticType::Bool,
|
||||
)),
|
||||
(">", [StaticType::Int, StaticType::Int]) => Some((
|
||||
Value::Function(Rc::new(|args| {
|
||||
Value::make_function(Purity::Pure, |args| {
|
||||
if let (Value::Int(a), Value::Int(b)) = (&args[0], &args[1]) {
|
||||
Value::Bool(a > b)
|
||||
} else {
|
||||
Value::Bool(false)
|
||||
}
|
||||
})),
|
||||
}),
|
||||
StaticType::Bool,
|
||||
)),
|
||||
(">=", [StaticType::Int, StaticType::Int]) => Some((
|
||||
Value::Function(Rc::new(|args| {
|
||||
Value::make_function(Purity::Pure, |args| {
|
||||
if let (Value::Int(a), Value::Int(b)) = (&args[0], &args[1]) {
|
||||
Value::Bool(a >= b)
|
||||
} else {
|
||||
Value::Bool(false)
|
||||
}
|
||||
})),
|
||||
}),
|
||||
StaticType::Bool,
|
||||
)),
|
||||
("=", [StaticType::Int, StaticType::Int]) => Some((
|
||||
Value::Function(Rc::new(|args| {
|
||||
Value::make_function(Purity::Pure, |args| {
|
||||
if let (Value::Int(a), Value::Int(b)) = (&args[0], &args[1]) {
|
||||
Value::Bool(a == b)
|
||||
} else {
|
||||
Value::Bool(false)
|
||||
}
|
||||
})),
|
||||
}),
|
||||
StaticType::Bool,
|
||||
)),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user