diff --git a/Cargo.toml b/Cargo.toml index a600ae0..b43823e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" authors = ["Moritz Hölting "] categories = ["compilers"] -description = "ShulkerScript language implementation with compiler" +description = "Shulkerscript language implementation with compiler" repository = "https://github.com/moritz-hoelting/shulkerscript-lang" readme = "README.md" license = "MIT" @@ -13,11 +13,12 @@ license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = ["fs_access", "lua", "shulkerbox"] +default = ["fs_access", "lua", "shulkerbox", "zip"] fs_access = ["shulkerbox?/fs_access"] lua = ["dep:mlua"] serde = ["dep:serde", "shulkerbox?/serde"] shulkerbox = ["dep:shulkerbox"] +zip = ["shulkerbox?/zip"] [target.'cfg(target_arch = "wasm32")'.dependencies] path-absolutize = { version = "3.1.1", features = ["use_unix_paths_on_wasm"] } @@ -25,7 +26,7 @@ path-absolutize = { version = "3.1.1", features = ["use_unix_paths_on_wasm"] } [dependencies] chksum-md5 = "0.0.0" colored = "2.1.0" -derive_more = { version = "0.99.17", default-features = false, features = ["deref", "from", "deref_mut"] } +derive_more = { version = "1.0.0", default-features = false, features = ["deref", "deref_mut", "from"] } enum-as-inner = "0.6.0" getset = "0.1.2" itertools = "0.13.0" @@ -33,9 +34,9 @@ mlua = { version = "0.9.7", features = ["lua54", "vendored"], optional = true } path-absolutize = "3.1.1" pathdiff = "0.2.1" serde = { version = "1.0.197", features = ["derive", "rc"], optional = true } -shulkerbox = { git = "https://github.com/moritz-hoelting/shulkerbox", default-features = false, optional = true, rev = "60458e6b2d719278c4fe090cb2759e123a3f86d2" } +shulkerbox = { git = "https://github.com/moritz-hoelting/shulkerbox", default-features = false, optional = true, rev = "a16f1ce105959b37bd5776476352b92905ff12d1" } strsim = "0.11.1" strum = { version = "0.26.2", features = ["derive"] } -strum_macros = "0.26.2" +strum_macros = "0.26.4" thiserror = "1.0.58" tracing = "0.1.40" diff --git a/README.md b/README.md index b4a0156..cbd219e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# ShulkerScript Language +# Shulkerscript Language -ShulkerScript is a simple, easy-to-use scripting language for Minecraft datapacks. It is designed to be easy to learn and use, while still being powerful enough to create complex scripts, while not being hindered by Minecraft command limitations. +Shulkerscript is a simple, easy-to-use scripting language for Minecraft datapacks. It is designed to be easy to learn and use, while still being powerful enough to create complex scripts, while not being hindered by Minecraft command limitations. ## Usage diff --git a/grammar.md b/grammar.md index 38f6694..0419177 100644 --- a/grammar.md +++ b/grammar.md @@ -1,4 +1,4 @@ -# Grammar of the ShulkerScript language +# Grammar of the Shulkerscript language ## Table of contents diff --git a/src/base/file_provider.rs b/src/base/file_provider.rs index 6e704c8..40c1cd1 100644 --- a/src/base/file_provider.rs +++ b/src/base/file_provider.rs @@ -82,11 +82,11 @@ pub struct Error { } impl Error { - /// Creates a new [`FileProviderError`] from a known kind of error as well as an + /// Creates a new [`Error`] from a known kind of error as well as an /// arbitrary error payload. /// /// The `error` argument is an arbitrary - /// payload which will be contained in this [`FileProviderError`]. + /// payload which will be contained in this [`Error`]. /// /// Note that this function allocates memory on the heap. /// If no extra payload is required, use the `From` conversion from @@ -101,9 +101,9 @@ impl Error { } } - /// Creates a new [`FileProviderError`] from an arbitrary error payload. + /// Creates a new [`Error`] from an arbitrary error payload. /// - /// It is a shortcut for [`FileProviderError::new`] + /// It is a shortcut for [`Error::new`] /// with [`std::io::ErrorKind::Other`]. pub fn other(error: E) -> Self where @@ -114,14 +114,14 @@ impl Error { /// Returns a reference to the inner error wrapped by this error (if any). /// - /// If this [`FileProviderError`] was constructed via [`Self::new`] then this function will + /// If this [`Error`] was constructed via [`Self::new`] then this function will /// return [`Some`], otherwise it will return [`None`]. #[must_use] pub fn get_ref(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)> { return self.error.as_deref(); } - /// Consumes the [`FileProviderError`], returning its inner error (if any). + /// Consumes the [`Error`], returning its inner error (if any). /// /// If this [`Error`] was constructed via [`Self::new`] then this function will /// return [`Some`], otherwise it will return [`None`]. diff --git a/src/base/mod.rs b/src/base/mod.rs index 5e2fd1f..7aab2e6 100644 --- a/src/base/mod.rs +++ b/src/base/mod.rs @@ -1,4 +1,4 @@ -//! The base module contains the core functionality of the `ShulkerScript` language. +//! The base module contains the core functionality of the `Shulkerscript` language. pub mod source_file; diff --git a/src/base/source_file.rs b/src/base/source_file.rs index 9de2123..369e210 100644 --- a/src/base/source_file.rs +++ b/src/base/source_file.rs @@ -86,7 +86,7 @@ impl SourceFile { /// Load the source file from the given file path. /// /// # Errors - /// - [`Error::IoError`]: Error occurred when reading the file contents. + /// - [`Error::FileProviderError`]: Error occurred when reading the file contents. pub fn load( path: &Path, identifier: String, diff --git a/src/lib.rs b/src/lib.rs index bd76d66..ec35d2d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ -//! The `ShulkerScript` language. +//! The `Shulkerscript` language. //! -//! `ShulkerScript` is a simple, imperative scripting language for creating Minecraft data packs. +//! `Shulkerscript` is a simple, imperative scripting language for creating Minecraft data packs. #![deny( missing_debug_implementations, @@ -29,7 +29,9 @@ use shulkerbox::{datapack::Datapack, virtual_fs::VFolder}; use crate::lexical::token_stream::TokenStream; -/// The version of the `ShulkerScript` language. +/// The version of the `Shulkerscript` language. +/// +/// Matches the version of this [`crate`]. pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Converts the given source code to tokens and returns a token stream. diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 84ceb17..5e26778 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -1,4 +1,4 @@ -//! This module contains the syntax tree and parser for the `ShulkerScript` language. +//! This module contains the syntax tree and parser for the `Shulkerscript` language. pub mod error; pub mod parser; diff --git a/src/syntax/syntax_tree/condition.rs b/src/syntax/syntax_tree/condition.rs index 49d51ad..84632f8 100644 --- a/src/syntax/syntax_tree/condition.rs +++ b/src/syntax/syntax_tree/condition.rs @@ -23,11 +23,13 @@ use crate::{ }, }; +/// Condition that is viewed as a single entity during precedence parsing. +/// /// Syntax Synopsis: /// /// ``` ebnf /// PrimaryCondition: -/// ConditionalPrefix +/// UnaryCondition /// | ParenthesizedCondition /// | StringLiteral /// ``` @@ -35,7 +37,7 @@ use crate::{ #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, EnumAsInner)] pub enum PrimaryCondition { - Prefix(ConditionalPrefix), + Unary(UnaryCondition), Parenthesized(ParenthesizedCondition), StringLiteral(StringLiteral), } @@ -43,13 +45,15 @@ pub enum PrimaryCondition { impl SourceElement for PrimaryCondition { fn span(&self) -> Span { match self { - Self::Prefix(prefix) => prefix.span(), + Self::Unary(unary) => unary.span(), Self::Parenthesized(parenthesized) => parenthesized.span(), Self::StringLiteral(literal) => literal.span(), } } } +/// Condition that is composed of two conditions and a binary operator. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -88,6 +92,8 @@ impl BinaryCondition { } } +/// Operator that is used to combine two conditions. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -128,6 +134,8 @@ impl SourceElement for ConditionalBinaryOperator { } } +/// Condition that is enclosed in parentheses. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -165,6 +173,8 @@ impl SourceElement for ParenthesizedCondition { } } +/// Operator that is used to prefix a condition. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -185,16 +195,18 @@ impl SourceElement for ConditionalPrefixOperator { } } +/// Condition that is prefixed by an operator. +/// /// Syntax Synopsis: /// /// ```ebnf -/// ConditionalPrefix: +/// UnaryCondition: /// ConditionalPrefixOperator PrimaryCondition /// ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] -pub struct ConditionalPrefix { +pub struct UnaryCondition { /// The operator of the prefix. #[get = "pub"] operator: ConditionalPrefixOperator, @@ -203,12 +215,12 @@ pub struct ConditionalPrefix { operand: Box, } -impl SourceElement for ConditionalPrefix { +impl SourceElement for UnaryCondition { fn span(&self) -> Span { self.operator.span().join(&self.operand.span()).unwrap() } } -impl ConditionalPrefix { +impl UnaryCondition { /// Dissolves the conditional prefix into its components #[must_use] pub fn dissolve(self) -> (ConditionalPrefixOperator, PrimaryCondition) { @@ -216,6 +228,8 @@ impl ConditionalPrefix { } } +/// Represents a condition in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -331,7 +345,7 @@ impl<'a> Parser<'a> { let operand = Box::new(self.parse_primary_condition(handler)?); - Ok(PrimaryCondition::Prefix(ConditionalPrefix { + Ok(PrimaryCondition::Unary(UnaryCondition { operator, operand, })) diff --git a/src/syntax/syntax_tree/declaration.rs b/src/syntax/syntax_tree/declaration.rs index a7e0c22..e507bdc 100644 --- a/src/syntax/syntax_tree/declaration.rs +++ b/src/syntax/syntax_tree/declaration.rs @@ -22,6 +22,8 @@ use crate::{ use super::{statement::Block, ConnectedList, DelimitedList}; +/// Represents a declaration in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -47,6 +49,8 @@ impl SourceElement for Declaration { } } } +/// Represents an Annotation with optional value. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -99,6 +103,8 @@ impl SourceElement for Annotation { } } +/// Represents a function declaration in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -176,6 +182,8 @@ impl SourceElement for Function { } } +/// Represents an import declaration in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -198,6 +206,7 @@ pub struct Import { semicolon: Punctuation, } +/// Items to import. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum ImportItems { @@ -228,6 +237,8 @@ impl SourceElement for Import { } } +/// Represents a tag declaration in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf diff --git a/src/syntax/syntax_tree/expression.rs b/src/syntax/syntax_tree/expression.rs index 1db61bf..707dff7 100644 --- a/src/syntax/syntax_tree/expression.rs +++ b/src/syntax/syntax_tree/expression.rs @@ -22,6 +22,8 @@ use crate::{ use super::ConnectedList; +/// Represents an expression in the syntax tree. +/// /// Syntax Synopsis: /// /// ```ebnf @@ -43,6 +45,8 @@ impl SourceElement for Expression { } } +/// Represents a primary expression in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -68,6 +72,8 @@ impl SourceElement for Primary { } } +/// Represents a function call in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -101,6 +107,8 @@ impl SourceElement for FunctionCall { } } +/// Represents a lua code block in the syntax tree. +/// /// Syntax Synopsis: /// /// ```ebnf diff --git a/src/syntax/syntax_tree/statement.rs b/src/syntax/syntax_tree/statement.rs index 412fd40..63398f0 100644 --- a/src/syntax/syntax_tree/statement.rs +++ b/src/syntax/syntax_tree/statement.rs @@ -25,6 +25,8 @@ use self::execute_block::ExecuteBlock; use super::expression::Expression; +/// Represents a statement in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -65,6 +67,8 @@ impl SourceElement for Statement { } } +/// Represents a block in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -103,6 +107,8 @@ impl SourceElement for Block { } } +/// Represents a run statement in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -141,6 +147,8 @@ impl Run { } } +/// Represents a grouping statement in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -176,6 +184,8 @@ impl SourceElement for Grouping { } } +/// Represents a statement that ends with a semicolon in the syntax tree. +/// /// Syntax Synopsis: /// ``` ebnf /// Semicolon: diff --git a/src/syntax/syntax_tree/statement/execute_block.rs b/src/syntax/syntax_tree/statement/execute_block.rs index d579526..302ea5d 100644 --- a/src/syntax/syntax_tree/statement/execute_block.rs +++ b/src/syntax/syntax_tree/statement/execute_block.rs @@ -23,6 +23,8 @@ use crate::{ use super::Block; +/// Represents an execute block statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// ExecuteBlock: @@ -51,11 +53,25 @@ impl SourceElement for ExecuteBlock { } } +/// Represents the head of an execute block statement. +/// /// Syntax Synopsis: +/// /// ```ebnf /// ExecuteBlockHead: /// Conditional +/// | Align +/// | Anchored /// | As +/// | AsAt +/// | At +/// | Facing +/// | In +/// | On +/// | Positioned +/// | Rotated +/// | Store +/// | Summon /// ; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, EnumAsInner, From)] @@ -96,6 +112,8 @@ impl SourceElement for ExecuteBlockHead { } } +/// Represents the tail of an execute block statement. +/// /// Syntax Synopsis: /// ```ebnf /// ExecuteBlockTail: @@ -122,6 +140,8 @@ impl SourceElement for ExecuteBlockTail { } } +/// Represents an conditional `if` statement in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -157,6 +177,8 @@ impl SourceElement for Conditional { } } +/// Represents an `else` block in the syntax tree. +/// /// Syntax Synopsis: /// /// ``` ebnf @@ -189,6 +211,8 @@ impl SourceElement for Else { } } +/// Represents an `as` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// /// ```ebnf @@ -234,6 +258,8 @@ impl As { } } +/// Represents an `align` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// Align: @@ -278,6 +304,8 @@ impl Align { } } +/// Represents an `anchored` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// Anchored: @@ -321,6 +349,8 @@ impl Anchored { } } +/// Represents an `asat` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// AsAt: @@ -364,6 +394,8 @@ impl AsAt { } } +/// Represents an `at` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// At: @@ -407,6 +439,8 @@ impl At { } } +/// Represents a `facing` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// Facing: @@ -450,6 +484,8 @@ impl Facing { } } +/// Represents an `in` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// In: @@ -493,6 +529,8 @@ impl In { } } +/// Represents an `on` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// On: @@ -536,6 +574,8 @@ impl On { } } +/// Represents a `positioned` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// Positioned: @@ -579,6 +619,8 @@ impl Positioned { } } +/// Represents a `rotated` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// Rotated: @@ -622,6 +664,8 @@ impl Rotated { } } +/// Represents a `store` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// Store: @@ -665,6 +709,8 @@ impl Store { } } +/// Represents a `summon` execute statement in the syntax tree. +/// /// Syntax Synopsis: /// ```ebnf /// Summon: diff --git a/src/transpile/conversions.rs b/src/transpile/conversions.rs index 3ead89d..6478113 100644 --- a/src/transpile/conversions.rs +++ b/src/transpile/conversions.rs @@ -23,7 +23,7 @@ impl From for DpCondition { Self::Atom(literal.str_content().to_string()) } PrimaryCondition::Parenthesized(cond) => cond.dissolve().1.into(), - PrimaryCondition::Prefix(prefix) => match prefix.operator() { + PrimaryCondition::Unary(prefix) => match prefix.operator() { ConditionalPrefixOperator::LogicalNot(_) => { Self::Not(Box::new(prefix.dissolve().1.into())) } diff --git a/src/transpile/transpiler.rs b/src/transpile/transpiler.rs index 388b5fc..6292d55 100644 --- a/src/transpile/transpiler.rs +++ b/src/transpile/transpiler.rs @@ -1,4 +1,4 @@ -//! Transpiler for `ShulkerScript` +//! Transpiler for `Shulkerscript` use chksum_md5 as md5; use std::{ @@ -29,7 +29,7 @@ use crate::{ use super::error::{TranspileError, TranspileResult, UnexpectedExpression}; -/// A transpiler for `ShulkerScript`. +/// A transpiler for `Shulkerscript`. #[derive(Debug)] pub struct Transpiler { datapack: shulkerbox::datapack::Datapack, @@ -282,7 +282,7 @@ impl Transpiler { || { let hash_data = program_identifier.to_string() + "\0" + identifier_span.str(); - Some("shu/".to_string() + &md5::hash(hash_data).to_hex_lowercase()[..16]) + Some("shu/".to_string() + &md5::hash(hash_data).to_hex_lowercase()) }, Clone::clone, )