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. pub fn lookup(name: &str, args: &[StaticType]) -> Option<(Value, StaticType)> { match (name, args) { // --- Integer Arithmetic --- ("+", [StaticType::Int, StaticType::Int]) => Some(( 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::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::make_function(Purity::Pure, |args| { let a = match args[0] { Value::Int(i) => i, _ => 0, }; let b = match args[1] { Value::Int(i) => i, _ => 0, }; let c = match args[2] { Value::Int(i) => i, _ => 0, }; Value::Int(a - b - c) }), StaticType::Int, )), ("*", [StaticType::Int, StaticType::Int]) => Some(( 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::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::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::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::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::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, )), // --- Constant Unary for -1 (decrement optimization) --- // Special case: tak uses (- x 1). The specializer sees Call("-", [Int, Int]). _ => None, } }