1
0

Continue fixing built-in functions

This commit is contained in:
Jeff 2024-06-24 08:17:06 -04:00
parent 18859cda77
commit 2e9a523058
7 changed files with 46 additions and 27 deletions

View File

@ -35,7 +35,11 @@ impl BuiltInFunction {
}
}
pub fn call(&self, context: &Context, manage_memory: bool) -> Result<Value, RuntimeError> {
pub fn call(
&self,
context: &Context,
manage_memory: bool,
) -> Result<Option<Value>, RuntimeError> {
match self {
BuiltInFunction::Length => Length::call(context, manage_memory),
BuiltInFunction::ReadLine => ReadLine::call(context, manage_memory),
@ -49,7 +53,7 @@ impl BuiltInFunction {
trait FunctionLogic {
fn r#type() -> Type;
fn call(context: &Context, manage_memory: bool) -> Result<Value, RuntimeError>;
fn call(context: &Context, manage_memory: bool) -> Result<Option<Value>, RuntimeError>;
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
@ -67,7 +71,7 @@ impl FunctionLogic for Length {
}
}
fn call(context: &Context, manage_memory: bool) -> Result<Value, RuntimeError> {
fn call(context: &Context, manage_memory: bool) -> Result<Option<Value>, RuntimeError> {
let value = if let Some(value) = context.get_value(&Identifier::new("input"))? {
value
} else {
@ -83,7 +87,7 @@ impl FunctionLogic for Length {
));
};
Ok(Value::integer(list.len() as i64))
Ok(Some(Value::integer(list.len() as i64)))
}
}
@ -95,11 +99,11 @@ impl FunctionLogic for ReadFile {
Type::Function {
type_parameters: None,
value_parameters: None,
return_type: None,
return_type: Some(Box::new(Type::String)),
}
}
fn call(context: &Context, manage_memory: bool) -> Result<Value, RuntimeError> {
fn call(context: &Context, manage_memory: bool) -> Result<Option<Value>, RuntimeError> {
todo!()
}
}
@ -112,11 +116,11 @@ impl FunctionLogic for ReadLine {
Type::Function {
type_parameters: None,
value_parameters: None,
return_type: None,
return_type: Some(Box::new(Type::String)),
}
}
fn call(context: &Context, manage_memory: bool) -> Result<Value, RuntimeError> {
fn call(context: &Context, manage_memory: bool) -> Result<Option<Value>, RuntimeError> {
todo!()
}
}
@ -133,7 +137,7 @@ impl FunctionLogic for Sleep {
}
}
fn call(context: &Context, manage_memory: bool) -> Result<Value, RuntimeError> {
fn call(context: &Context, manage_memory: bool) -> Result<Option<Value>, RuntimeError> {
todo!()
}
}
@ -150,7 +154,7 @@ impl FunctionLogic for WriteLine {
}
}
fn call(context: &Context, manage_memory: bool) -> Result<Value, RuntimeError> {
fn call(context: &Context, manage_memory: bool) -> Result<Option<Value>, RuntimeError> {
todo!()
}
}
@ -163,11 +167,14 @@ impl FunctionLogic for JsonParse {
Type::Function {
type_parameters: None,
value_parameters: None,
return_type: None,
return_type: Some(Box::new(Type::Generic {
identifier: Identifier::new("T"),
concrete_type: None,
})),
}
}
fn call(context: &Context, manage_memory: bool) -> Result<Value, RuntimeError> {
fn call(context: &Context, manage_memory: bool) -> Result<Option<Value>, RuntimeError> {
let target_type = if let Some(r#type) = context.get_type(&Identifier::new("T"))? {
r#type
} else {
@ -216,6 +223,6 @@ impl FunctionLogic for JsonParse {
Ok(value)
}
parse_value(&input, target_type)
parse_value(&input, target_type).map(|value| Some(value))
}
}

View File

@ -6,7 +6,7 @@ use crate::{
value::ValueInner,
};
use super::{AbstractNode, Evaluation, Expression, Type, TypeConstructor};
use super::{AbstractNode, Evaluation, Expression, Type, TypeConstructor, ValueNode, WithPosition};
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct FunctionCall {
@ -47,6 +47,14 @@ impl AbstractNode for FunctionCall {
}
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
if let Expression::Value(WithPosition {
node: ValueNode::BuiltInFunction(_),
..
}) = self.function_expression.as_ref()
{
return Ok(());
}
self.function_expression.validate(context, manage_memory)?;
if let Some(value_arguments) = &self.value_arguments {

View File

@ -173,6 +173,8 @@ 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)) => (
@ -372,7 +374,9 @@ impl AbstractNode for ValueNode {
Value::structure(name, fields)
}
ValueNode::BuiltInFunction(built_in_function) => {
built_in_function.call(context, manage_memory)?
return built_in_function
.call(context, manage_memory)
.map(|value_option| value_option.map(|value| Evaluation::Return(value)));
}
};

View File

@ -109,12 +109,10 @@ impl Interpreter {
}
pub fn load_std(&self) -> Result<(), InterpreterError> {
let std_core_source: (Arc<str>, Arc<str>) = {
(
let std_core_source: (Arc<str>, Arc<str>) = (
Arc::from("std/core.ds"),
Arc::from(include_str!("../../std/core.ds")),
)
};
);
let std_sources: [(Arc<str>, Arc<str>); 4] = [
(
Arc::from("std/fs.ds"),
@ -172,7 +170,6 @@ impl Interpreter {
) -> Result<Option<Value>, InterpreterError> {
let mut sources = self.sources.write().unwrap();
sources.clear();
sources.push((source_id.clone(), source.clone()));
let tokens = lex(source.as_ref()).map_err(|errors| InterpreterError {
@ -431,7 +428,10 @@ impl InterpreterError {
.with_message(format!("This has type {}.", index_type.fg(type_color),)),
])
}
ValidationError::ExpectedExpression(_) => todo!(),
ValidationError::ExpectedExpression(position) => builder.add_label(
Label::new((self.source_id.clone(), position.0..position.1))
.with_message("Expected a statement that ends in an expression."),
),
ValidationError::ExpectedFunction { .. } => todo!(),
ValidationError::ExpectedValue(_) => todo!(),
ValidationError::FieldNotFound {

View File

@ -1,9 +1,9 @@
io = {
read_line = fn () -> str {
__READ_LINE__
__READ_LINE__()
}
write_line = fn (output: any) {
__WRITE_LINE__ output
__WRITE_LINE__(output)
}
}

View File

@ -1,5 +1,5 @@
json = {
parse = fn |T| (input: str) -> T {
__JSON_PARSE__ T input
__JSON_PARSE__::(T)::(input)
}
}

View File

@ -1,5 +1,5 @@
thread = {
sleep = fn (milliseconds: int) {
__SLEEP__ milliseconds
__SLEEP__(milliseconds)
}
}