Continue fixing built-in functions
This commit is contained in:
parent
18859cda77
commit
2e9a523058
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -1,9 +1,9 @@
|
||||
io = {
|
||||
read_line = fn () -> str {
|
||||
__READ_LINE__
|
||||
__READ_LINE__()
|
||||
}
|
||||
|
||||
write_line = fn (output: any) {
|
||||
__WRITE_LINE__ output
|
||||
__WRITE_LINE__(output)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
json = {
|
||||
parse = fn |T| (input: str) -> T {
|
||||
__JSON_PARSE__ T input
|
||||
__JSON_PARSE__::(T)::(input)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
thread = {
|
||||
sleep = fn (milliseconds: int) {
|
||||
__SLEEP__ milliseconds
|
||||
__SLEEP__(milliseconds)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user