diff --git a/dust-lang/src/abstract_tree/built_in_function.rs b/dust-lang/src/abstract_tree/built_in_function.rs index d6d6a37..49ef105 100644 --- a/dust-lang/src/abstract_tree/built_in_function.rs +++ b/dust-lang/src/abstract_tree/built_in_function.rs @@ -155,7 +155,24 @@ impl FunctionLogic for WriteLine { } fn call(context: &Context, manage_memory: bool) -> Result, RuntimeError> { - todo!() + let value = if let Some(value) = context.get_value(&Identifier::new("output"))? { + value + } else { + return Err(RuntimeError::ValidationFailure( + ValidationError::BuiltInFunctionFailure("output does not exist"), + )); + }; + let input = if let ValueInner::String(string) = value.inner().as_ref() { + string + } else { + return Err(RuntimeError::ValidationFailure( + ValidationError::BuiltInFunctionFailure("output is not a string"), + )); + }; + + println!("{input}"); + + Ok(None) } } diff --git a/dust-lang/src/abstract_tree/function_call.rs b/dust-lang/src/abstract_tree/function_call.rs index 5d91caf..d8a7e02 100644 --- a/dust-lang/src/abstract_tree/function_call.rs +++ b/dust-lang/src/abstract_tree/function_call.rs @@ -104,6 +104,16 @@ impl AbstractNode for FunctionCall { context: &Context, manage_memory: bool, ) -> Result, RuntimeError> { + if let Expression::Value(WithPosition { + node: ValueNode::BuiltInFunction(function), + .. + }) = *self.function_expression + { + return function + .call(context, manage_memory) + .map(|value_option| value_option.map(|value| Evaluation::Return(value))); + } + let function_position = self.function_expression.position(); let evaluation = self.function_expression.evaluate(context, manage_memory)?; let value = if let Some(Evaluation::Return(value)) = evaluation { diff --git a/dust-lang/src/abstract_tree/value_node.rs b/dust-lang/src/abstract_tree/value_node.rs index 1a93570..50591bd 100644 --- a/dust-lang/src/abstract_tree/value_node.rs +++ b/dust-lang/src/abstract_tree/value_node.rs @@ -173,8 +173,6 @@ impl AbstractNode for ValueNode { { body.node.validate(&context_template, _manage_memory)?; - println!("beep"); - let ((expected_return, expected_position), actual_return) = match (return_type, body.node.expected_type(&context_template)?) { (Some(constructor), Some(r#type)) => ( @@ -373,11 +371,7 @@ impl AbstractNode for ValueNode { Value::structure(name, fields) } - ValueNode::BuiltInFunction(built_in_function) => { - return built_in_function - .call(context, manage_memory) - .map(|value_option| value_option.map(|value| Evaluation::Return(value))); - } + ValueNode::BuiltInFunction(function) => Value::built_in_function(function), }; Ok(Some(Evaluation::Return(value))) diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index d431b85..a1089da 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -13,7 +13,7 @@ use std::{ }; use abstract_tree::{AbstractTree, Type}; -use ariadne::{Color, Config, Fmt, Label, Report, ReportKind}; +use ariadne::{Color, Fmt, Label, Report, ReportKind}; use chumsky::prelude::*; use context::Context; use error::{DustError, RuntimeError, TypeConflict, ValidationError}; @@ -307,13 +307,12 @@ impl InterpreterError { .with_label( Label::new((self.source_id.clone(), position.0..position.1)).with_message("Error occured here.") ), - - if let RuntimeError::ValidationFailure(validation_error) = error { - Some(validation_error) - } else { - None - }, - ) + if let RuntimeError::ValidationFailure(validation_error) = error { + Some(validation_error) + } else { + None + }, + ) } }; @@ -432,7 +431,14 @@ impl InterpreterError { Label::new((self.source_id.clone(), position.0..position.1)) .with_message("Expected a statement that ends in an expression."), ), - ValidationError::ExpectedFunction { .. } => todo!(), + ValidationError::ExpectedFunction { actual, position } => builder.add_label( + Label::new((self.source_id.clone(), position.0..position.1)).with_message( + format!( + "Expected a function value but got {}.", + actual.fg(type_color) + ), + ), + ), ValidationError::ExpectedValue(_) => todo!(), ValidationError::FieldNotFound { identifier, @@ -481,12 +487,11 @@ impl InterpreterError { } ValidationError::EnumVariantNotFound { .. } => todo!(), ValidationError::ExpectedList { .. } => todo!(), - ValidationError::BuiltInFunctionFailure(_) => todo!(), + ValidationError::BuiltInFunctionFailure(reason) => builder + .add_label(Label::new((self.source_id.clone(), 0..0)).with_message(reason)), } } - builder = builder.with_config(Config::default().with_multiline_arrows(false)); - let report = builder.finish(); reports.push(report); diff --git a/dust-lang/src/value.rs b/dust-lang/src/value.rs index e37d393..d35d936 100644 --- a/dust-lang/src/value.rs +++ b/dust-lang/src/value.rs @@ -32,6 +32,10 @@ impl Value { Value(Arc::new(ValueInner::Boolean(boolean))) } + pub fn built_in_function(function: BuiltInFunction) -> Self { + Value(Arc::new(ValueInner::BuiltInFunction(function))) + } + pub fn enum_instance( type_name: Identifier, variant: Identifier, @@ -631,7 +635,7 @@ impl ValueInner { }); } } - ValueInner::BuiltInFunction(_) => todo!(), + ValueInner::BuiltInFunction(function) => function.r#type(), }; Ok(r#type)