2023-10-06 17:32:58 +00:00
|
|
|
//! Top-level unit of Dust code.
|
|
|
|
|
2023-10-07 16:37:35 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2023-10-06 17:32:58 +00:00
|
|
|
use tree_sitter::Node;
|
|
|
|
|
|
|
|
use crate::{AbstractTree, Error, Result, Statement, Value, VariableMap};
|
|
|
|
|
|
|
|
/// An abstractiton of an independent unit of source code, or a comment.
|
|
|
|
///
|
|
|
|
/// Items are either comments, which do nothing, or statements, which can be run
|
|
|
|
/// to produce a single value or interact with a context by creating or
|
|
|
|
/// referencing variables.
|
2023-10-07 16:37:35 +00:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
2023-10-06 17:32:58 +00:00
|
|
|
pub enum Item {
|
|
|
|
Comment(String),
|
|
|
|
Statement(Statement),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AbstractTree for Item {
|
|
|
|
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
|
2023-10-07 16:37:35 +00:00
|
|
|
debug_assert_eq!("item", node.kind());
|
|
|
|
|
2023-10-06 17:32:58 +00:00
|
|
|
let child = node.child(0).unwrap();
|
|
|
|
|
|
|
|
if child.kind() == "comment" {
|
|
|
|
let byte_range = child.byte_range();
|
|
|
|
let comment_text = &source[byte_range];
|
|
|
|
|
|
|
|
Ok(Item::Comment(comment_text.to_string()))
|
|
|
|
} else if child.kind() == "statement" {
|
|
|
|
Ok(Item::Statement(Statement::from_syntax_node(child, source)?))
|
|
|
|
} else {
|
|
|
|
Err(Error::UnexpectedSyntax {
|
|
|
|
expected: "comment or statement",
|
|
|
|
actual: child.kind(),
|
|
|
|
location: child.start_position(),
|
|
|
|
relevant_source: source[node.byte_range()].to_string(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run(&self, context: &mut VariableMap) -> Result<Value> {
|
|
|
|
match self {
|
|
|
|
Item::Comment(text) => Ok(Value::String(text.clone())),
|
|
|
|
Item::Statement(statement) => statement.run(context),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|