From b9190514c4c573c7c6a8f87888dccc1c56046d6b Mon Sep 17 00:00:00 2001 From: Jeff Date: Sat, 9 Mar 2024 06:55:19 -0500 Subject: [PATCH] Add output function --- src/context.rs | 34 +++++++++++++++++++++++++++------- src/error.rs | 2 +- src/value.rs | 24 ++++++++++++++++++------ 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/context.rs b/src/context.rs index e658073..dd164f2 100644 --- a/src/context.rs +++ b/src/context.rs @@ -6,6 +6,7 @@ use std::{ use crate::{ abstract_tree::{Identifier, Type}, error::RwLockPoisonError, + value::BuiltInFunction, Value, }; @@ -36,23 +37,42 @@ impl Context { &self, identifier: &Identifier, ) -> Result, RwLockPoisonError> { - Ok(self.inner.read()?.get(identifier).cloned()) + if let Some(value_data) = self.inner.read()?.get(identifier) { + return Ok(Some(value_data.clone())); + } + + let value_data = match identifier.as_str() { + "output" => ValueData::Value(BuiltInFunction::output()), + _ => return Ok(None), + }; + + Ok(Some(value_data)) } pub fn get_type(&self, identifier: &Identifier) -> Result, RwLockPoisonError> { if let Some(ValueData::Type(r#type)) = self.inner.read()?.get(identifier) { - Ok(Some(r#type.clone())) - } else { - Ok(None) + return Ok(Some(r#type.clone())); } + + let r#type = match identifier.as_str() { + "output" => BuiltInFunction::Output.r#type(), + _ => return Ok(None), + }; + + Ok(Some(r#type)) } pub fn get_value(&self, identifier: &Identifier) -> Result, RwLockPoisonError> { if let Some(ValueData::Value(value)) = self.inner.read()?.get(identifier) { - Ok(Some(value.clone())) - } else { - Ok(None) + return Ok(Some(value.clone())); } + + let value = match identifier.as_str() { + "output" => BuiltInFunction::output(), + _ => return Ok(None), + }; + + Ok(Some(value)) } pub fn set_type(&self, identifier: Identifier, r#type: Type) -> Result<(), RwLockPoisonError> { diff --git a/src/error.rs b/src/error.rs index c4b553e..fd0cd20 100644 --- a/src/error.rs +++ b/src/error.rs @@ -56,7 +56,7 @@ impl Error { Error::Runtime(_) => todo!(), Error::Validation { error, span } => { let mut report = Report::build( - ReportKind::Custom("Lexing Error", Color::White), + ReportKind::Custom("Validation Error", Color::White), (), span.start, ); diff --git a/src/value.rs b/src/value.rs index 21e6931..427e92c 100644 --- a/src/value.rs +++ b/src/value.rs @@ -87,6 +87,10 @@ impl Value { )))) } + pub fn built_in_function(function: BuiltInFunction) -> Self { + Value(Arc::new(ValueInner::Function(Function::BuiltIn(function)))) + } + pub fn r#type(&self) -> Type { match self.0.as_ref() { ValueInner::Boolean(_) => Type::Boolean, @@ -343,22 +347,30 @@ pub struct ParsedFunction { #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub enum BuiltInFunction { - Output(Value), + Output, } impl BuiltInFunction { - fn r#type(&self, context: &Context) -> Type { + pub fn output() -> Value { + static OUTPUT: OnceLock = OnceLock::new(); + + OUTPUT + .get_or_init(|| Value::built_in_function(BuiltInFunction::Output)) + .clone() + } + + pub fn r#type(&self) -> Type { match self { - BuiltInFunction::Output(_) => Type::Function { + BuiltInFunction::Output => Type::Function { parameter_types: vec![Type::Any], return_type: Box::new(Type::None), }, } } - fn call(self, context: &Context) -> Result { + pub fn call(self, value: Value, _context: &Context) -> Result { match self { - BuiltInFunction::Output(value) => { + BuiltInFunction::Output => { println!("{value}"); Ok(Action::None) @@ -370,7 +382,7 @@ impl BuiltInFunction { impl Display for BuiltInFunction { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - BuiltInFunction::Output(_) => write!(f, "(to_output : any) : none rust_magic();"), + BuiltInFunction::Output => write!(f, "(to_output : any) : none rust_magic();"), } } }