Attempt to add JSON parsing
This commit is contained in:
parent
c8dfbda447
commit
f625568ced
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -356,6 +356,8 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1023,18 +1025,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.197"
|
version = "1.0.203"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.197"
|
version = "1.0.203"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1043,9 +1045,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.114"
|
version = "1.0.117"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -17,3 +17,5 @@ env_logger = "0.11.3"
|
|||||||
log = "0.4.21"
|
log = "0.4.21"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
rayon = "1.9.0"
|
rayon = "1.9.0"
|
||||||
|
serde = { version = "1.0.203", features = ["derive"] }
|
||||||
|
serde_json = "1.0.117"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -9,7 +11,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Expression, Type, WithPosition};
|
use super::{AbstractNode, Action, Expression, Type, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct As {
|
pub struct As {
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
r#type: WithPosition<Type>,
|
r#type: WithPosition<Type>,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
identifier::Identifier,
|
identifier::Identifier,
|
||||||
@ -7,7 +9,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Statement, Type, WithPosition};
|
use super::{AbstractNode, Action, Statement, Type, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct Assignment {
|
pub struct Assignment {
|
||||||
identifier: WithPosition<Identifier>,
|
identifier: WithPosition<Identifier>,
|
||||||
r#type: Option<WithPosition<Type>>,
|
r#type: Option<WithPosition<Type>>,
|
||||||
@ -15,7 +17,7 @@ pub struct Assignment {
|
|||||||
statement: Box<Statement>,
|
statement: Box<Statement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum AssignmentOperator {
|
pub enum AssignmentOperator {
|
||||||
Assign,
|
Assign,
|
||||||
AddAssign,
|
AddAssign,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
@ -9,7 +10,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Statement, Type};
|
use super::{AbstractNode, Action, Statement, Type};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct AsyncBlock {
|
pub struct AsyncBlock {
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -5,7 +7,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Statement, Type};
|
use super::{AbstractNode, Action, Statement, Type};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ use std::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
abstract_tree::{Action, Type},
|
abstract_tree::{Action, Type},
|
||||||
context::Context,
|
context::Context,
|
||||||
@ -13,10 +15,12 @@ use crate::{
|
|||||||
Value,
|
Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{AbstractNode, Expression};
|
use super::{AbstractNode, Expression, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum BuiltInFunctionCall {
|
pub enum BuiltInFunctionCall {
|
||||||
|
JsonParse(WithPosition<Type>, Expression),
|
||||||
|
Length(Expression),
|
||||||
ReadFile(Expression),
|
ReadFile(Expression),
|
||||||
ReadLine,
|
ReadLine,
|
||||||
Sleep(Expression),
|
Sleep(Expression),
|
||||||
@ -26,6 +30,8 @@ pub enum BuiltInFunctionCall {
|
|||||||
impl AbstractNode for BuiltInFunctionCall {
|
impl AbstractNode for BuiltInFunctionCall {
|
||||||
fn expected_type(&self, _context: &mut Context) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &mut Context) -> Result<Type, ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
|
BuiltInFunctionCall::JsonParse(r#type, _) => Ok(r#type.item.clone()),
|
||||||
|
BuiltInFunctionCall::Length(_) => Ok(Type::Integer),
|
||||||
BuiltInFunctionCall::ReadFile(_) => Ok(Type::String),
|
BuiltInFunctionCall::ReadFile(_) => Ok(Type::String),
|
||||||
BuiltInFunctionCall::ReadLine => Ok(Type::String),
|
BuiltInFunctionCall::ReadLine => Ok(Type::String),
|
||||||
BuiltInFunctionCall::Sleep(_) => Ok(Type::None),
|
BuiltInFunctionCall::Sleep(_) => Ok(Type::None),
|
||||||
@ -39,6 +45,12 @@ impl AbstractNode for BuiltInFunctionCall {
|
|||||||
_manage_memory: bool,
|
_manage_memory: bool,
|
||||||
) -> Result<(), ValidationError> {
|
) -> Result<(), ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
|
BuiltInFunctionCall::JsonParse(_, expression) => {
|
||||||
|
expression.validate(_context, _manage_memory)
|
||||||
|
}
|
||||||
|
BuiltInFunctionCall::Length(expression) => {
|
||||||
|
expression.validate(_context, _manage_memory)
|
||||||
|
}
|
||||||
BuiltInFunctionCall::ReadFile(expression) => {
|
BuiltInFunctionCall::ReadFile(expression) => {
|
||||||
expression.validate(_context, _manage_memory)
|
expression.validate(_context, _manage_memory)
|
||||||
}
|
}
|
||||||
@ -52,7 +64,7 @@ impl AbstractNode for BuiltInFunctionCall {
|
|||||||
|
|
||||||
fn run(self, context: &mut Context, _manage_memory: bool) -> Result<Action, RuntimeError> {
|
fn run(self, context: &mut Context, _manage_memory: bool) -> Result<Action, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
BuiltInFunctionCall::ReadFile(expression) => {
|
BuiltInFunctionCall::JsonParse(r#type, expression) => {
|
||||||
let action = expression.clone().run(context, _manage_memory)?;
|
let action = expression.clone().run(context, _manage_memory)?;
|
||||||
let value = if let Action::Return(value) = action {
|
let value = if let Action::Return(value) = action {
|
||||||
value
|
value
|
||||||
@ -62,6 +74,45 @@ impl AbstractNode for BuiltInFunctionCall {
|
|||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let ValueInner::String(string) = value.inner().as_ref() {
|
||||||
|
let deserialized = serde_json::from_str(string)?;
|
||||||
|
|
||||||
|
Ok(Action::Return(deserialized))
|
||||||
|
} else {
|
||||||
|
Err(RuntimeError::ValidationFailure(
|
||||||
|
ValidationError::ExpectedString {
|
||||||
|
actual: value.r#type(context)?,
|
||||||
|
position: expression.position(),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BuiltInFunctionCall::Length(expression) => {
|
||||||
|
let action = expression.clone().run(context, _manage_memory)?;
|
||||||
|
let value = if let Action::Return(value) = action {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
return Err(RuntimeError::ValidationFailure(
|
||||||
|
ValidationError::InterpreterExpectedReturn(expression.position()),
|
||||||
|
));
|
||||||
|
};
|
||||||
|
let length = if let ValueInner::List(list) = value.inner().as_ref() {
|
||||||
|
list.len() as i64
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Action::Return(Value::integer(length)))
|
||||||
|
}
|
||||||
|
BuiltInFunctionCall::ReadFile(expression) => {
|
||||||
|
let action = expression.clone().run(context, _manage_memory)?;
|
||||||
|
let value = if let Action::Return(value) = action {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
return Err(RuntimeError::ValidationFailure(
|
||||||
|
ValidationError::InterpreterExpectedReturn(expression.position()),
|
||||||
|
));
|
||||||
|
};
|
||||||
let file_contents = if let ValueInner::String(path) = value.inner().as_ref() {
|
let file_contents = if let ValueInner::String(path) = value.inner().as_ref() {
|
||||||
read_to_string(path)?
|
read_to_string(path)?
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -9,7 +11,7 @@ use super::{
|
|||||||
SourcePosition, Type, ValueNode, WithPosition,
|
SourcePosition, Type, ValueNode, WithPosition,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum Expression {
|
pub enum Expression {
|
||||||
As(WithPosition<Box<As>>),
|
As(WithPosition<Box<As>>),
|
||||||
BuiltInFunctionCall(WithPosition<Box<BuiltInFunctionCall>>),
|
BuiltInFunctionCall(WithPosition<Box<BuiltInFunctionCall>>),
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -6,7 +8,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Expression, Type, WithPosition};
|
use super::{AbstractNode, Action, Expression, Type, WithPosition};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct FunctionCall {
|
pub struct FunctionCall {
|
||||||
function: Box<Expression>,
|
function: Box<Expression>,
|
||||||
type_arguments: Vec<WithPosition<Type>>,
|
type_arguments: Vec<WithPosition<Type>>,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -6,7 +8,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Block, Expression, Type, WithPosition};
|
use super::{AbstractNode, Action, Block, Expression, Type, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct IfElse {
|
pub struct IfElse {
|
||||||
if_expression: Expression,
|
if_expression: Expression,
|
||||||
if_block: WithPosition<Block>,
|
if_block: WithPosition<Block>,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -5,7 +7,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Expression, Type, ValueNode, WithPosition};
|
use super::{AbstractNode, Action, Expression, Type, ValueNode, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct ListIndex {
|
pub struct ListIndex {
|
||||||
left: Expression,
|
left: Expression,
|
||||||
right: Expression,
|
right: Expression,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -7,7 +9,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Expression, Type};
|
use super::{AbstractNode, Action, Expression, Type};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum Logic {
|
pub enum Logic {
|
||||||
Equal(Expression, Expression),
|
Equal(Expression, Expression),
|
||||||
NotEqual(Expression, Expression),
|
NotEqual(Expression, Expression),
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -5,7 +7,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Statement, Type};
|
use super::{AbstractNode, Action, Statement, Type};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct Loop {
|
pub struct Loop {
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -6,7 +8,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Expression, Type, ValueNode, WithPosition};
|
use super::{AbstractNode, Action, Expression, Type, ValueNode, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct MapIndex {
|
pub struct MapIndex {
|
||||||
collection: Expression,
|
collection: Expression,
|
||||||
index: Expression,
|
index: Expression,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -7,7 +9,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Expression, SourcePosition, Type};
|
use super::{AbstractNode, Action, Expression, SourcePosition, Type};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum Math {
|
pub enum Math {
|
||||||
Add(Expression, Expression),
|
Add(Expression, Expression),
|
||||||
Subtract(Expression, Expression),
|
Subtract(Expression, Expression),
|
||||||
|
@ -20,6 +20,7 @@ pub mod r#while;
|
|||||||
use std::{cmp::Ordering, ops::Index};
|
use std::{cmp::Ordering, ops::Index};
|
||||||
|
|
||||||
use chumsky::span::{SimpleSpan, Span};
|
use chumsky::span::{SimpleSpan, Span};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
assignment::{Assignment, AssignmentOperator},
|
assignment::{Assignment, AssignmentOperator},
|
||||||
@ -48,7 +49,7 @@ use crate::{
|
|||||||
Value,
|
Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct WithPosition<T> {
|
pub struct WithPosition<T> {
|
||||||
pub item: T,
|
pub item: T,
|
||||||
pub position: SourcePosition,
|
pub position: SourcePosition,
|
||||||
@ -65,7 +66,7 @@ pub trait WithPos: Sized {
|
|||||||
|
|
||||||
impl<T> WithPos for T {}
|
impl<T> WithPos for T {}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct SourcePosition(pub usize, pub usize);
|
pub struct SourcePosition(pub usize, pub usize);
|
||||||
|
|
||||||
impl From<SimpleSpan> for SourcePosition {
|
impl From<SimpleSpan> for SourcePosition {
|
||||||
@ -87,6 +88,7 @@ pub enum Action {
|
|||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct AbstractTree(Vec<Statement>);
|
pub struct AbstractTree(Vec<Statement>);
|
||||||
|
|
||||||
impl AbstractTree {
|
impl AbstractTree {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -8,7 +10,7 @@ use super::{
|
|||||||
StructureDefinition, Type, While, WithPosition,
|
StructureDefinition, Type, While, WithPosition,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
Assignment(WithPosition<Assignment>),
|
Assignment(WithPosition<Assignment>),
|
||||||
AsyncBlock(WithPosition<AsyncBlock>),
|
AsyncBlock(WithPosition<AsyncBlock>),
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -6,7 +8,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Type, WithPosition};
|
use super::{AbstractNode, Action, Type, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct StructureDefinition {
|
pub struct StructureDefinition {
|
||||||
name: Identifier,
|
name: Identifier,
|
||||||
fields: Vec<(Identifier, WithPosition<Type>)>,
|
fields: Vec<(Identifier, WithPosition<Type>)>,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
use clap::error::Result;
|
use clap::error::Result;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
@ -10,7 +11,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, WithPosition};
|
use super::{AbstractNode, Action, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
Any,
|
Any,
|
||||||
Argument(Identifier),
|
Argument(Identifier),
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::{cmp::Ordering, collections::BTreeMap, ops::Range};
|
use std::{cmp::Ordering, collections::BTreeMap, ops::Range};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -9,7 +11,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Block, Expression, Type, WithPos, WithPosition};
|
use super::{AbstractNode, Action, Block, Expression, Type, WithPos, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum ValueNode {
|
pub enum ValueNode {
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -7,7 +9,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{AbstractNode, Action, Expression, Statement, Type};
|
use super::{AbstractNode, Action, Expression, Statement, Type};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct While {
|
pub struct While {
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
|
@ -55,6 +55,7 @@ pub enum RuntimeError {
|
|||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
RwLockPoison(RwLockPoisonError),
|
RwLockPoison(RwLockPoisonError),
|
||||||
ValidationFailure(ValidationError),
|
ValidationFailure(ValidationError),
|
||||||
|
SerdeJson(serde_json::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RwLockPoisonError> for RuntimeError {
|
impl From<RwLockPoisonError> for RuntimeError {
|
||||||
@ -81,6 +82,12 @@ impl From<io::Error> for RuntimeError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<serde_json::Error> for RuntimeError {
|
||||||
|
fn from(error: serde_json::Error) -> Self {
|
||||||
|
RuntimeError::SerdeJson(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for RuntimeError {
|
impl PartialEq for RuntimeError {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
@ -106,6 +113,10 @@ pub enum ValidationError {
|
|||||||
index_type: Type,
|
index_type: Type,
|
||||||
index_position: SourcePosition,
|
index_position: SourcePosition,
|
||||||
},
|
},
|
||||||
|
ExpectedString {
|
||||||
|
actual: Type,
|
||||||
|
position: SourcePosition,
|
||||||
|
},
|
||||||
ExpectedBoolean {
|
ExpectedBoolean {
|
||||||
actual: Type,
|
actual: Type,
|
||||||
position: SourcePosition,
|
position: SourcePosition,
|
||||||
|
@ -3,6 +3,8 @@ use std::{
|
|||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use serde::{de::Visitor, Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Identifier(Arc<String>);
|
pub struct Identifier(Arc<String>);
|
||||||
|
|
||||||
@ -21,3 +23,33 @@ impl Display for Identifier {
|
|||||||
write!(f, "{}", self.0)
|
write!(f, "{}", self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Serialize for Identifier {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(self.0.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Identifier {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Ok(Identifier(Arc::new(
|
||||||
|
deserializer.deserialize_string(StringVisitor)?,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StringVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for StringVisitor {
|
||||||
|
type Value = String;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("a UTF-8 string")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -48,6 +48,8 @@ pub enum Keyword {
|
|||||||
Fn,
|
Fn,
|
||||||
Int,
|
Int,
|
||||||
If,
|
If,
|
||||||
|
JsonParse,
|
||||||
|
Length,
|
||||||
List,
|
List,
|
||||||
Map,
|
Map,
|
||||||
None,
|
None,
|
||||||
@ -85,6 +87,8 @@ impl Display for Keyword {
|
|||||||
Keyword::Loop => write!(f, "loop"),
|
Keyword::Loop => write!(f, "loop"),
|
||||||
Keyword::While => write!(f, "while"),
|
Keyword::While => write!(f, "while"),
|
||||||
Keyword::Type => write!(f, "type"),
|
Keyword::Type => write!(f, "type"),
|
||||||
|
Keyword::JsonParse => write!(f, "JSON_PARSE"),
|
||||||
|
Keyword::Length => write!(f, "LENGTH"),
|
||||||
Keyword::ReadFile => write!(f, "READ_FILE"),
|
Keyword::ReadFile => write!(f, "READ_FILE"),
|
||||||
Keyword::ReadLine => write!(f, "READ_LINE"),
|
Keyword::ReadLine => write!(f, "READ_LINE"),
|
||||||
Keyword::Sleep => write!(f, "SLEEP"),
|
Keyword::Sleep => write!(f, "SLEEP"),
|
||||||
@ -278,6 +282,8 @@ pub fn lexer<'src>() -> impl Parser<
|
|||||||
"type" => Token::Keyword(Keyword::Type),
|
"type" => Token::Keyword(Keyword::Type),
|
||||||
"loop" => Token::Keyword(Keyword::Loop),
|
"loop" => Token::Keyword(Keyword::Loop),
|
||||||
"while" => Token::Keyword(Keyword::While),
|
"while" => Token::Keyword(Keyword::While),
|
||||||
|
"JSON_PARSE" => Token::Keyword(Keyword::JsonParse),
|
||||||
|
"LENGTH" => Token::Keyword(Keyword::Length),
|
||||||
"READ_FILE" => Token::Keyword(Keyword::ReadFile),
|
"READ_FILE" => Token::Keyword(Keyword::ReadFile),
|
||||||
"READ_LINE" => Token::Keyword(Keyword::ReadLine),
|
"READ_LINE" => Token::Keyword(Keyword::ReadLine),
|
||||||
"SLEEP" => Token::Keyword(Keyword::Sleep),
|
"SLEEP" => Token::Keyword(Keyword::Sleep),
|
||||||
|
@ -17,7 +17,7 @@ use ariadne::{Color, Fmt, Label, Report, ReportKind};
|
|||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
use context::Context;
|
use context::Context;
|
||||||
use error::{Error, RuntimeError, TypeConflict, ValidationError};
|
use error::{Error, RuntimeError, TypeConflict, ValidationError};
|
||||||
use lexer::lex;
|
use lexer::{lex, Token};
|
||||||
use parser::{parse, parser};
|
use parser::{parse, parser};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
pub use value::Value;
|
pub use value::Value;
|
||||||
@ -51,15 +51,47 @@ impl<'a> Interpreter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lex<'source>(
|
||||||
|
&mut self,
|
||||||
|
source_id: Arc<str>,
|
||||||
|
source: &'source str,
|
||||||
|
) -> Result<Vec<Token<'source>>, InterpreterError> {
|
||||||
|
let mut sources = self.sources.write().unwrap();
|
||||||
|
|
||||||
|
sources.clear();
|
||||||
|
sources.push((source_id.clone(), Arc::from(source)));
|
||||||
|
|
||||||
|
lex(source.as_ref())
|
||||||
|
.map(|tokens| tokens.into_iter().map(|(token, _)| token).collect())
|
||||||
|
.map_err(|errors| InterpreterError { source_id, errors })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse<'source>(
|
||||||
|
&mut self,
|
||||||
|
source_id: Arc<str>,
|
||||||
|
source: &'source str,
|
||||||
|
) -> Result<AbstractTree, InterpreterError> {
|
||||||
|
let mut sources = self.sources.write().unwrap();
|
||||||
|
|
||||||
|
sources.clear();
|
||||||
|
sources.push((source_id.clone(), Arc::from(source)));
|
||||||
|
|
||||||
|
parse(&lex(source).map_err(|errors| InterpreterError {
|
||||||
|
source_id: source_id.clone(),
|
||||||
|
errors,
|
||||||
|
})?)
|
||||||
|
.map_err(|errors| InterpreterError { source_id, errors })
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run(
|
pub fn run(
|
||||||
&mut self,
|
&mut self,
|
||||||
source_id: Arc<str>,
|
source_id: Arc<str>,
|
||||||
source: Arc<str>,
|
source: Arc<str>,
|
||||||
) -> Result<Option<Value>, InterpreterError> {
|
) -> Result<Option<Value>, InterpreterError> {
|
||||||
self.sources
|
let mut sources = self.sources.write().unwrap();
|
||||||
.write()
|
|
||||||
.unwrap()
|
sources.clear();
|
||||||
.push((source_id.clone(), source.clone()));
|
sources.push((source_id.clone(), source.clone()));
|
||||||
|
|
||||||
let tokens = lex(source.as_ref()).map_err(|errors| InterpreterError {
|
let tokens = lex(source.as_ref()).map_err(|errors| InterpreterError {
|
||||||
source_id: source_id.clone(),
|
source_id: source_id.clone(),
|
||||||
@ -77,7 +109,11 @@ impl<'a> Interpreter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_std(&mut self) -> Result<(), InterpreterError> {
|
pub fn load_std(&mut self) -> Result<(), InterpreterError> {
|
||||||
let std_sources: [(Arc<str>, Arc<str>); 3] = [
|
let std_sources: [(Arc<str>, Arc<str>); 4] = [
|
||||||
|
(
|
||||||
|
Arc::from("std/core.ds"),
|
||||||
|
Arc::from(include_str!("../../std/core.ds")),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
Arc::from("std/fs.ds"),
|
Arc::from("std/fs.ds"),
|
||||||
Arc::from(include_str!("../../std/fs.ds")),
|
Arc::from(include_str!("../../std/fs.ds")),
|
||||||
@ -363,6 +399,7 @@ impl InterpreterError {
|
|||||||
.with_message(format!("This has type {}.", actual.fg(type_color),)),
|
.with_message(format!("This has type {}.", actual.fg(type_color),)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
ValidationError::ExpectedString { actual, position } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let report = builder.finish();
|
let report = builder.finish();
|
||||||
|
@ -263,6 +263,14 @@ pub fn parser<'src>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let built_in_function_call = choice((
|
let built_in_function_call = choice((
|
||||||
|
just(Token::Keyword(Keyword::Length))
|
||||||
|
.ignore_then(expression.clone())
|
||||||
|
.map_with(|argument, state| {
|
||||||
|
Expression::BuiltInFunctionCall(
|
||||||
|
Box::new(BuiltInFunctionCall::Length(argument))
|
||||||
|
.with_position(state.span()),
|
||||||
|
)
|
||||||
|
}),
|
||||||
just(Token::Keyword(Keyword::ReadFile))
|
just(Token::Keyword(Keyword::ReadFile))
|
||||||
.ignore_then(expression.clone())
|
.ignore_then(expression.clone())
|
||||||
.map_with(|argument, state| {
|
.map_with(|argument, state| {
|
||||||
@ -292,6 +300,15 @@ pub fn parser<'src>(
|
|||||||
.with_position(state.span()),
|
.with_position(state.span()),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
just(Token::Keyword(Keyword::JsonParse))
|
||||||
|
.ignore_then(r#type.clone())
|
||||||
|
.then(expression.clone())
|
||||||
|
.map_with(|(r#type, argument), state| {
|
||||||
|
Expression::BuiltInFunctionCall(
|
||||||
|
Box::new(BuiltInFunctionCall::JsonParse(r#type, argument))
|
||||||
|
.with_position(state.span()),
|
||||||
|
)
|
||||||
|
}),
|
||||||
))
|
))
|
||||||
.try_map_with(move |expression, state| {
|
.try_map_with(move |expression, state| {
|
||||||
if allow_built_ins {
|
if allow_built_ins {
|
||||||
|
@ -6,6 +6,8 @@ use std::{
|
|||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
abstract_tree::{AbstractNode, Action, Block, Type, WithPos, WithPosition},
|
abstract_tree::{AbstractNode, Action, Block, Type, WithPos, WithPosition},
|
||||||
context::Context,
|
context::Context,
|
||||||
@ -181,7 +183,25 @@ impl Ord for Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
impl Serialize for Value {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Value {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum ValueInner {
|
pub enum ValueInner {
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
@ -299,7 +319,7 @@ impl Ord for ValueInner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
type_parameters: Vec<WithPosition<Type>>,
|
type_parameters: Vec<WithPosition<Type>>,
|
||||||
parameters: Vec<(Identifier, WithPosition<Type>)>,
|
parameters: Vec<(Identifier, WithPosition<Type>)>,
|
||||||
|
@ -23,6 +23,14 @@ struct Args {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
command: Option<String>,
|
command: Option<String>,
|
||||||
|
|
||||||
|
// Display lexer tokens of the input source.
|
||||||
|
#[arg(short, long)]
|
||||||
|
lex: bool,
|
||||||
|
|
||||||
|
// Display abstract tree of the input source.
|
||||||
|
#[arg(short, long)]
|
||||||
|
parse: bool,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
no_std: bool,
|
no_std: bool,
|
||||||
|
|
||||||
@ -68,6 +76,36 @@ fn main() {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if args.lex {
|
||||||
|
match interpreter.lex(source_id, source.as_ref()) {
|
||||||
|
Ok(tokens) => println!("{tokens:?}"),
|
||||||
|
Err(error) => {
|
||||||
|
for report in error.build_reports() {
|
||||||
|
report
|
||||||
|
.write_for_stdout(sources(interpreter.sources()), stderr())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.parse {
|
||||||
|
match interpreter.parse(source_id, source.as_ref()) {
|
||||||
|
Ok(abstract_tree) => println!("{abstract_tree:?}"),
|
||||||
|
Err(error) => {
|
||||||
|
for report in error.build_reports() {
|
||||||
|
report
|
||||||
|
.write_for_stdout(sources(interpreter.sources()), stderr())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let run_result = interpreter.run(source_id.clone(), source.clone());
|
let run_result = interpreter.run(source_id.clone(), source.clone());
|
||||||
|
|
||||||
match run_result {
|
match run_result {
|
||||||
|
@ -6,4 +6,4 @@
|
|||||||
input = fs.read_file('examples/assets/data.json')
|
input = fs.read_file('examples/assets/data.json')
|
||||||
data = json.parse(input)
|
data = json.parse(input)
|
||||||
|
|
||||||
list.length(data)
|
length(data)
|
||||||
|
3
std/core.ds
Normal file
3
std/core.ds
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
length = fn (input: list) int {
|
||||||
|
LENGTH input
|
||||||
|
}
|
5
std/json.ds
Normal file
5
std/json.ds
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
json = {
|
||||||
|
parse = fn (T)(input: str) T {
|
||||||
|
JSON_PARSE T input
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user