From 49fe4555c60b67eb2d48a710c84828da75239c41 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 26 Jun 2024 11:35:39 -0400 Subject: [PATCH] Clean up --- .../src/abstract_tree/built_in_function.rs | 23 +++- dust-lang/src/abstract_tree/expression.rs | 6 - dust-lang/src/abstract_tree/function_call.rs | 129 ++++++++++++------ dust-lang/src/abstract_tree/type.rs | 8 +- dust-lang/src/value.rs | 14 +- examples/type_inference.ds | 6 +- 6 files changed, 123 insertions(+), 63 deletions(-) diff --git a/dust-lang/src/abstract_tree/built_in_function.rs b/dust-lang/src/abstract_tree/built_in_function.rs index 7a156d6..ae6200a 100644 --- a/dust-lang/src/abstract_tree/built_in_function.rs +++ b/dust-lang/src/abstract_tree/built_in_function.rs @@ -1,4 +1,10 @@ -use std::{fs::read_to_string, io::stdin, thread::sleep, time::Duration}; +use std::{ + fmt::{self, Display, Formatter}, + fs::read_to_string, + io::stdin, + thread::sleep, + time::Duration, +}; use serde::{Deserialize, Serialize}; use serde_json::from_str; @@ -51,6 +57,21 @@ impl BuiltInFunction { } } +impl Display for BuiltInFunction { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let display = match self { + BuiltInFunction::Length => "__LENGTH__", + BuiltInFunction::ReadLine => "__READ_LINE__", + BuiltInFunction::ReadFile => "__READ_FILE__", + BuiltInFunction::Sleep => "__SLEEP__", + BuiltInFunction::WriteLine => "__WRITE_LINE__", + BuiltInFunction::JsonParse => "__JSON_PARSE__", + }; + + write!(f, "{display}") + } +} + trait FunctionLogic { fn r#type() -> Type; fn call(context: &Context, manage_memory: bool) -> Result, RuntimeError>; diff --git a/dust-lang/src/abstract_tree/expression.rs b/dust-lang/src/abstract_tree/expression.rs index 91f4444..66dc594 100644 --- a/dust-lang/src/abstract_tree/expression.rs +++ b/dust-lang/src/abstract_tree/expression.rs @@ -40,8 +40,6 @@ impl Expression { impl AbstractNode for Expression { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { - log::trace!("Defining types for expression at {}", self.position()); - match self { Expression::As(inner) => inner.node.define_types(_context), Expression::FunctionCall(inner) => inner.node.define_types(_context), @@ -55,8 +53,6 @@ impl AbstractNode for Expression { } fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> { - log::trace!("Validating expression at {}", self.position()); - match self { Expression::As(r#as) => r#as.node.validate(context, manage_memory), Expression::FunctionCall(function_call) => { @@ -87,8 +83,6 @@ impl AbstractNode for Expression { context: &Context, manage_memory: bool, ) -> Result, RuntimeError> { - log::trace!("Evaluating expression at {}", self.position()); - match self { Expression::As(r#as) => r#as.node.evaluate(context, manage_memory), Expression::FunctionCall(function_call) => { diff --git a/dust-lang/src/abstract_tree/function_call.rs b/dust-lang/src/abstract_tree/function_call.rs index 9ae6547..4c1da92 100644 --- a/dust-lang/src/abstract_tree/function_call.rs +++ b/dust-lang/src/abstract_tree/function_call.rs @@ -8,7 +8,7 @@ use crate::{ value::ValueInner, }; -use super::{AbstractNode, Evaluation, Expression, Type, TypeConstructor, ValueNode, WithPosition}; +use super::{AbstractNode, Evaluation, Expression, Type, TypeConstructor}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FunctionCall { @@ -143,16 +143,6 @@ 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 { @@ -162,48 +152,101 @@ impl AbstractNode for FunctionCall { ValidationError::ExpectedExpression(function_position), )); }; - let function = if let ValueInner::Function(function) = value.inner().as_ref() { - function.clone() - } else { - return Err(RuntimeError::ValidationFailure( - ValidationError::ExpectedFunction { - actual: value.r#type(context)?, - position: function_position, - }, - )); - }; - if let (Some(type_parameters), Some(type_arguments)) = - (function.type_parameters(), self.type_arguments) - { - for (identifier, constructor) in - type_parameters.into_iter().zip(type_arguments.into_iter()) + if let ValueInner::Function(function) = value.inner().as_ref() { + if let (Some(type_parameters), Some(type_arguments)) = + (function.type_parameters(), self.type_arguments) { - let r#type = constructor.construct(context)?; + for (identifier, constructor) in + type_parameters.into_iter().zip(type_arguments.into_iter()) + { + let r#type = constructor.construct(context)?; - self.context.set_type(identifier.clone(), r#type)?; + self.context.set_type(identifier.clone(), r#type)?; + } } + + if let (Some(parameters), Some(arguments)) = + (function.value_parameters(), self.value_arguments) + { + for ((identifier, _), expression) in + parameters.into_iter().zip(arguments.into_iter()) + { + let position = expression.position(); + let evaluation = expression.evaluate(context, manage_memory)?; + let value = if let Some(Evaluation::Return(value)) = evaluation { + value + } else { + return Err(RuntimeError::ValidationFailure( + ValidationError::ExpectedValue(position), + )); + }; + + self.context.set_value(identifier.clone(), value)?; + } + } + + return function.clone().call(&self.context, manage_memory); } - if let (Some(parameters), Some(arguments)) = - (function.value_parameters(), self.value_arguments) - { - for ((identifier, _), expression) in parameters.into_iter().zip(arguments.into_iter()) { - let position = expression.position(); - let evaluation = expression.evaluate(context, manage_memory)?; - let value = if let Some(Evaluation::Return(value)) = evaluation { - value - } else { - return Err(RuntimeError::ValidationFailure( - ValidationError::ExpectedValue(position), - )); - }; + if let ValueInner::BuiltInFunction(function) = value.inner().as_ref() { + let (type_parameters, value_parameters, _) = if let Type::Function { + type_parameters, + value_parameters, + return_type, + } = function.r#type() + { + (type_parameters, value_parameters, return_type) + } else { + return Err(RuntimeError::ValidationFailure( + ValidationError::ExpectedFunction { + actual: function.r#type(), + position: function_position, + }, + )); + }; - self.context.set_value(identifier.clone(), value)?; + if let (Some(type_parameters), Some(type_arguments)) = + (type_parameters, self.type_arguments) + { + for (identifier, constructor) in + type_parameters.into_iter().zip(type_arguments.into_iter()) + { + let r#type = constructor.construct(context)?; + + self.context.set_type(identifier.clone(), r#type)?; + } } + + if let (Some(parameters), Some(arguments)) = (value_parameters, self.value_arguments) { + for ((identifier, _), expression) in + parameters.into_iter().zip(arguments.into_iter()) + { + let position = expression.position(); + let evaluation = expression.evaluate(context, manage_memory)?; + let value = if let Some(Evaluation::Return(value)) = evaluation { + value + } else { + return Err(RuntimeError::ValidationFailure( + ValidationError::ExpectedValue(position), + )); + }; + + self.context.set_value(identifier.clone(), value)?; + } + } + + return function + .call(&self.context, manage_memory) + .map(|option| option.map(|value| Evaluation::Return(value))); } - function.call(&self.context, manage_memory) + return Err(RuntimeError::ValidationFailure( + ValidationError::ExpectedFunction { + actual: value.r#type(context)?, + position: function_position, + }, + )); } fn expected_type(&self, context: &Context) -> Result, ValidationError> { diff --git a/dust-lang/src/abstract_tree/type.rs b/dust-lang/src/abstract_tree/type.rs index c39c75c..d05af8e 100644 --- a/dust-lang/src/abstract_tree/type.rs +++ b/dust-lang/src/abstract_tree/type.rs @@ -235,10 +235,10 @@ impl Display for Type { } Type::Float => write!(f, "float"), Type::Generic { concrete_type, .. } => { - if let Some(r#type) = concrete_type { - write!(f, "implied to be {}", r#type) - } else { - write!(f, "unknown") + match concrete_type.clone().map(|r#box| *r#box) { + Some(Type::Generic { identifier, .. }) => write!(f, "{identifier}"), + Some(concrete_type) => write!(f, "implied to be {concrete_type}"), + None => write!(f, "unknown"), } } Type::Integer => write!(f, "int"), diff --git a/dust-lang/src/value.rs b/dust-lang/src/value.rs index f36f7c1..ed410df 100644 --- a/dust-lang/src/value.rs +++ b/dust-lang/src/value.rs @@ -169,7 +169,7 @@ impl Display for Value { write!(f, "{{ ")?; for (index, (key, value)) in map.into_iter().enumerate() { - write!(f, "{key} = {value}")?; + write!(f, "{key} = {value:?}")?; if index != map.len() - 1 { write!(f, ", ")?; @@ -178,7 +178,7 @@ impl Display for Value { write!(f, " }}") } - ValueInner::Range(_) => todo!(), + ValueInner::Range(range) => write!(f, "{}..{}", range.start, range.end), ValueInner::String(string) => write!(f, "{string}"), ValueInner::Function(Function { type_parameters, @@ -187,14 +187,16 @@ impl Display for Value { body, .. }) => { + write!(f, "fn ")?; + if let Some(type_parameters) = type_parameters { write!(f, "(")?; - for (index, r#type) in type_parameters.into_iter().enumerate() { + for (index, identifier) in type_parameters.into_iter().enumerate() { if index == type_parameters.len() - 1 { - write!(f, "{}", r#type)?; + write!(f, "{}", identifier)?; } else { - write!(f, "{} ", r#type)?; + write!(f, "{} ", identifier)?; } } @@ -226,7 +228,7 @@ impl Display for Value { write!(f, "}}") } - ValueInner::BuiltInFunction(_) => todo!(), + ValueInner::BuiltInFunction(built_in_function) => write!(f, "{built_in_function}"), } } } diff --git a/examples/type_inference.ds b/examples/type_inference.ds index 0ebc58e..db30012 100644 --- a/examples/type_inference.ds +++ b/examples/type_inference.ds @@ -1,8 +1,8 @@ // This function returns its argument. -foo = fn |T| (x: T) -> T { x } +foo = fn (x: T) -> T { x } // Use turbofish to supply type information. -bar = foo::(str)::("hi") +bar = foo::("hi") // Use type annotation baz: str = foo("hi") @@ -10,7 +10,7 @@ baz: str = foo("hi") // The `json.parse` function takes a string and returns the specified type // Use turbofish -x = json.parse::(int)::("1") +x = json.parse::("1") // Use type annotation x: int = json.parse("1")