Begin implementing async blocks
This commit is contained in:
parent
96afe7d3a3
commit
e29e092875
46
Cargo.lock
generated
46
Cargo.lock
generated
@ -288,6 +288,31 @@ version = "0.8.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossterm"
|
name = "crossterm"
|
||||||
version = "0.27.0"
|
version = "0.27.0"
|
||||||
@ -351,6 +376,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand",
|
||||||
|
"rayon",
|
||||||
"stanza",
|
"stanza",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -883,6 +909,26 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -16,4 +16,5 @@ colored = "2.1.0"
|
|||||||
env_logger = "0.11.3"
|
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"
|
||||||
stanza = "0.5.1"
|
stanza = "0.5.1"
|
||||||
|
56
dust-lang/src/abstract_tree/async_block.rs
Normal file
56
dust-lang/src/abstract_tree/async_block.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
use rayon::prelude::*;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
context::Context,
|
||||||
|
error::{RuntimeError, ValidationError},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{AbstractNode, Action, Statement, Type, WithPosition};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
|
pub struct AsyncBlock {
|
||||||
|
statements: Vec<WithPosition<Statement>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncBlock {
|
||||||
|
pub fn new(statements: Vec<WithPosition<Statement>>) -> Self {
|
||||||
|
Self { statements }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbstractNode for AsyncBlock {
|
||||||
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
|
self.statements.last().unwrap().node.expected_type(_context)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||||
|
for statement in &self.statements {
|
||||||
|
statement.node.validate(_context)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
|
||||||
|
let statement_count = self.statements.len();
|
||||||
|
|
||||||
|
self.statements
|
||||||
|
.into_par_iter()
|
||||||
|
.enumerate()
|
||||||
|
.find_map_any(|(index, statement)| {
|
||||||
|
let result = statement.node.run(_context);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(action) => {
|
||||||
|
if index == statement_count - 1 {
|
||||||
|
Some(Ok(action))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(runtime_error) => Some(Err(runtime_error)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
pub mod assignment;
|
pub mod assignment;
|
||||||
|
pub mod async_block;
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod expression;
|
pub mod expression;
|
||||||
pub mod function_call;
|
pub mod function_call;
|
||||||
@ -21,6 +22,7 @@ use chumsky::span::{SimpleSpan, Span};
|
|||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
assignment::{Assignment, AssignmentOperator},
|
assignment::{Assignment, AssignmentOperator},
|
||||||
|
async_block::AsyncBlock,
|
||||||
block::Block,
|
block::Block,
|
||||||
expression::Expression,
|
expression::Expression,
|
||||||
function_call::FunctionCall,
|
function_call::FunctionCall,
|
||||||
|
@ -4,13 +4,14 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
AbstractNode, Action, Assignment, Block, Expression, IfElse, Loop, StructureDefinition, Type,
|
AbstractNode, Action, Assignment, AsyncBlock, Block, Expression, IfElse, Loop,
|
||||||
While,
|
StructureDefinition, Type, While,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
Assignment(Assignment),
|
Assignment(Assignment),
|
||||||
|
AsyncBlock(AsyncBlock),
|
||||||
Block(Block),
|
Block(Block),
|
||||||
Break,
|
Break,
|
||||||
Expression(Expression),
|
Expression(Expression),
|
||||||
@ -33,6 +34,7 @@ impl AbstractNode for Statement {
|
|||||||
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
Statement::Assignment(assignment) => assignment.expected_type(_context),
|
Statement::Assignment(assignment) => assignment.expected_type(_context),
|
||||||
|
Statement::AsyncBlock(async_block) => async_block.expected_type(_context),
|
||||||
Statement::Block(block) => block.expected_type(_context),
|
Statement::Block(block) => block.expected_type(_context),
|
||||||
Statement::Break => Ok(Type::None),
|
Statement::Break => Ok(Type::None),
|
||||||
Statement::Expression(expression) => expression.expected_type(_context),
|
Statement::Expression(expression) => expression.expected_type(_context),
|
||||||
@ -48,6 +50,7 @@ impl AbstractNode for Statement {
|
|||||||
fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
|
fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
Statement::Assignment(assignment) => assignment.validate(_context),
|
Statement::Assignment(assignment) => assignment.validate(_context),
|
||||||
|
Statement::AsyncBlock(async_block) => async_block.validate(_context),
|
||||||
Statement::Block(block) => block.validate(_context),
|
Statement::Block(block) => block.validate(_context),
|
||||||
Statement::Break => Ok(()),
|
Statement::Break => Ok(()),
|
||||||
Statement::Expression(expression) => expression.validate(_context),
|
Statement::Expression(expression) => expression.validate(_context),
|
||||||
@ -63,6 +66,7 @@ impl AbstractNode for Statement {
|
|||||||
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
|
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
Statement::Assignment(assignment) => assignment.run(_context),
|
Statement::Assignment(assignment) => assignment.run(_context),
|
||||||
|
Statement::AsyncBlock(async_block) => async_block.run(_context),
|
||||||
Statement::Block(block) => block.run(_context),
|
Statement::Block(block) => block.run(_context),
|
||||||
Statement::Break => Ok(Action::Break),
|
Statement::Break => Ok(Action::Break),
|
||||||
Statement::Expression(expression) => expression.run(_context),
|
Statement::Expression(expression) => expression.run(_context),
|
||||||
|
@ -247,6 +247,12 @@ impl From<RwLockPoisonError> for RuntimeError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> From<PoisonError<T>> for RuntimeError {
|
||||||
|
fn from(_: PoisonError<T>) -> Self {
|
||||||
|
RuntimeError::RwLockPoison(RwLockPoisonError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<ValidationError> for RuntimeError {
|
impl From<ValidationError> for RuntimeError {
|
||||||
fn from(error: ValidationError) -> Self {
|
fn from(error: ValidationError) -> Self {
|
||||||
RuntimeError::ValidationFailure(error)
|
RuntimeError::ValidationFailure(error)
|
||||||
|
@ -19,6 +19,7 @@ pub enum Token<'src> {
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub enum Keyword {
|
pub enum Keyword {
|
||||||
Any,
|
Any,
|
||||||
|
Async,
|
||||||
Bool,
|
Bool,
|
||||||
Break,
|
Break,
|
||||||
Else,
|
Else,
|
||||||
@ -39,6 +40,7 @@ impl Display for Keyword {
|
|||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Keyword::Any => write!(f, "any"),
|
Keyword::Any => write!(f, "any"),
|
||||||
|
Keyword::Async => write!(f, "async"),
|
||||||
Keyword::Bool => write!(f, "bool"),
|
Keyword::Bool => write!(f, "bool"),
|
||||||
Keyword::Break => write!(f, "break"),
|
Keyword::Break => write!(f, "break"),
|
||||||
Keyword::Else => write!(f, "else"),
|
Keyword::Else => write!(f, "else"),
|
||||||
@ -255,6 +257,7 @@ pub fn lexer<'src>() -> impl Parser<
|
|||||||
|
|
||||||
let keyword = choice((
|
let keyword = choice((
|
||||||
just("any").to(Keyword::Any),
|
just("any").to(Keyword::Any),
|
||||||
|
just("async").to(Keyword::Async),
|
||||||
just("bool").to(Keyword::Bool),
|
just("bool").to(Keyword::Bool),
|
||||||
just("break").to(Keyword::Break),
|
just("break").to(Keyword::Break),
|
||||||
just("else").to(Keyword::Else),
|
just("else").to(Keyword::Else),
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
extern crate chumsky;
|
|
||||||
|
|
||||||
pub mod abstract_tree;
|
pub mod abstract_tree;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
@ -395,6 +395,21 @@ pub fn parser<'src>() -> impl Parser<
|
|||||||
Statement::Expression(node).with_position(position)
|
Statement::Expression(node).with_position(position)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let async_block = just(Token::Keyword(Keyword::Async))
|
||||||
|
.ignore_then(
|
||||||
|
positioned_statement
|
||||||
|
.clone()
|
||||||
|
.repeated()
|
||||||
|
.collect()
|
||||||
|
.delimited_by(
|
||||||
|
just(Token::Control(Control::CurlyOpen)),
|
||||||
|
just(Token::Control(Control::CurlyClose)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map_with(|statements, state| {
|
||||||
|
Statement::AsyncBlock(AsyncBlock::new(statements)).with_position(state.span())
|
||||||
|
});
|
||||||
|
|
||||||
let r#break = just(Token::Keyword(Keyword::Break))
|
let r#break = just(Token::Keyword(Keyword::Break))
|
||||||
.map_with(|_, state| Statement::Break.with_position(state.span()));
|
.map_with(|_, state| Statement::Break.with_position(state.span()));
|
||||||
|
|
||||||
@ -485,6 +500,7 @@ pub fn parser<'src>() -> impl Parser<
|
|||||||
});
|
});
|
||||||
|
|
||||||
choice((
|
choice((
|
||||||
|
async_block,
|
||||||
structure_definition,
|
structure_definition,
|
||||||
if_else,
|
if_else,
|
||||||
assignment,
|
assignment,
|
||||||
@ -506,6 +522,32 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn async_block() {
|
||||||
|
assert_eq!(
|
||||||
|
parse(
|
||||||
|
&lex("
|
||||||
|
async {
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
}
|
||||||
|
")
|
||||||
|
.unwrap()
|
||||||
|
)
|
||||||
|
.unwrap()[0]
|
||||||
|
.node,
|
||||||
|
Statement::AsyncBlock(AsyncBlock::new(vec![
|
||||||
|
Statement::Expression(Expression::Value(ValueNode::Integer(1)))
|
||||||
|
.with_position((53, 54)),
|
||||||
|
Statement::Expression(Expression::Value(ValueNode::Integer(2)))
|
||||||
|
.with_position((79, 80)),
|
||||||
|
Statement::Expression(Expression::Value(ValueNode::Integer(3)))
|
||||||
|
.with_position((105, 106)),
|
||||||
|
]))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn structure_instance() {
|
fn structure_instance() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
Loading…
Reference in New Issue
Block a user