2024-03-27 19:27:11 +01:00
|
|
|
//! The `ShulkerScript` language.
|
|
|
|
//!
|
|
|
|
//! `ShulkerScript` is a simple, imperative scripting language for creating Minecraft data packs.
|
|
|
|
|
|
|
|
#![deny(
|
|
|
|
missing_debug_implementations,
|
|
|
|
missing_copy_implementations,
|
|
|
|
clippy::nursery,
|
|
|
|
rustdoc::broken_intra_doc_links,
|
|
|
|
clippy::missing_errors_doc
|
|
|
|
)]
|
2024-03-27 21:39:56 +01:00
|
|
|
#![warn(missing_docs, clippy::all, clippy::pedantic)]
|
2024-03-27 19:27:11 +01:00
|
|
|
#![allow(clippy::missing_panics_doc, clippy::missing_const_for_fn)]
|
|
|
|
|
2024-04-06 14:42:44 +02:00
|
|
|
pub use shulkerbox;
|
|
|
|
|
2024-03-27 19:27:11 +01:00
|
|
|
pub mod base;
|
|
|
|
pub mod lexical;
|
2024-03-27 21:39:56 +01:00
|
|
|
pub mod syntax;
|
2024-04-03 01:27:02 +02:00
|
|
|
pub mod transpile;
|
2024-03-27 19:27:11 +01:00
|
|
|
|
2024-06-10 08:41:24 +02:00
|
|
|
mod public_helpers;
|
|
|
|
|
2024-04-01 20:42:38 +02:00
|
|
|
use std::{cell::Cell, fmt::Display, path::Path};
|
2024-03-27 19:27:11 +01:00
|
|
|
|
2024-06-10 08:41:24 +02:00
|
|
|
use base::{Handler, Result};
|
2024-04-06 21:49:25 +02:00
|
|
|
use syntax::syntax_tree::program::ProgramFile;
|
2024-04-05 12:59:21 +02:00
|
|
|
|
|
|
|
#[cfg(feature = "shulkerbox")]
|
2024-06-10 08:41:24 +02:00
|
|
|
use shulkerbox::{datapack::Datapack, virtual_fs::VFolder};
|
2024-04-03 00:45:34 +02:00
|
|
|
|
2024-06-10 08:41:24 +02:00
|
|
|
use crate::lexical::token_stream::TokenStream;
|
2024-03-27 19:27:11 +01:00
|
|
|
|
2024-04-01 20:42:38 +02:00
|
|
|
/// Converts the given source code to tokens.
|
|
|
|
///
|
|
|
|
/// # Errors
|
|
|
|
/// - If an error occurs while reading the file.
|
|
|
|
pub fn tokenize(path: &Path) -> Result<TokenStream> {
|
|
|
|
let printer = Printer::new();
|
|
|
|
|
2024-06-10 08:41:24 +02:00
|
|
|
public_helpers::tokenize(&printer, path)
|
2024-04-01 20:42:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Parses the given source code.
|
|
|
|
///
|
|
|
|
/// # Errors
|
|
|
|
/// - If an error occurs while reading the file.
|
|
|
|
/// - If an error occurs while parsing the source code.
|
2024-04-06 21:49:25 +02:00
|
|
|
pub fn parse(path: &Path) -> Result<ProgramFile> {
|
2024-04-01 20:42:38 +02:00
|
|
|
let printer = Printer::new();
|
|
|
|
|
2024-06-10 08:41:24 +02:00
|
|
|
public_helpers::parse(&printer, path)
|
2024-04-01 20:42:38 +02:00
|
|
|
}
|
|
|
|
|
2024-04-03 00:45:34 +02:00
|
|
|
/// Transpiles the given source code into a shulkerbox [`Datapack`].
|
|
|
|
///
|
2024-06-10 08:41:24 +02:00
|
|
|
/// # Parameters:
|
|
|
|
/// - `script_paths`: A list of tuples containing the identifier of the program and the path to the script.
|
|
|
|
///
|
2024-04-03 00:45:34 +02:00
|
|
|
/// # Errors
|
|
|
|
/// - If an error occurs while reading the file.
|
|
|
|
/// - If an error occurs while parsing the source code.
|
|
|
|
/// - If an error occurs while transpiling the source code.
|
|
|
|
#[cfg(feature = "shulkerbox")]
|
2024-06-09 21:22:48 +02:00
|
|
|
pub fn transpile<P>(script_paths: &[(String, P)]) -> Result<Datapack>
|
|
|
|
where
|
|
|
|
P: AsRef<Path>,
|
|
|
|
{
|
2024-04-03 00:45:34 +02:00
|
|
|
let printer = Printer::new();
|
|
|
|
|
2024-06-10 08:41:24 +02:00
|
|
|
public_helpers::transpile(&printer, script_paths)
|
2024-04-03 00:45:34 +02:00
|
|
|
}
|
|
|
|
|
2024-03-27 19:27:11 +01:00
|
|
|
/// Compiles the given source code.
|
|
|
|
///
|
2024-06-10 08:41:24 +02:00
|
|
|
/// # Parameters:
|
|
|
|
/// - `script_paths`: A list of tuples containing the identifier of the program and the path to the script.
|
|
|
|
///
|
2024-03-27 19:27:11 +01:00
|
|
|
/// # Errors
|
|
|
|
/// - If an error occurs while reading the file.
|
2024-04-03 00:45:34 +02:00
|
|
|
/// - If an error occurs while parsing the source code.
|
|
|
|
/// - If an error occurs while transpiling the source code.
|
|
|
|
#[cfg(feature = "shulkerbox")]
|
2024-06-09 21:22:48 +02:00
|
|
|
pub fn compile<P>(script_paths: &[(String, P)]) -> Result<VFolder>
|
|
|
|
where
|
|
|
|
P: AsRef<Path>,
|
|
|
|
{
|
2024-03-27 19:27:11 +01:00
|
|
|
let printer = Printer::new();
|
|
|
|
|
2024-06-10 08:41:24 +02:00
|
|
|
public_helpers::compile(&printer, script_paths)
|
2024-03-27 19:27:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
struct Printer {
|
|
|
|
printed: Cell<bool>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Printer {
|
|
|
|
/// Creates a new [`Printer`].
|
|
|
|
fn new() -> Self {
|
|
|
|
Self {
|
|
|
|
printed: Cell::new(false),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn has_printed(&self) -> bool {
|
|
|
|
self.printed.get()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-21 10:09:30 +02:00
|
|
|
impl<T: Display> Handler<T> for Printer {
|
|
|
|
fn receive<E: Into<T>>(&self, error: E) {
|
|
|
|
eprintln!("{}", error.into());
|
2024-03-27 19:27:11 +01:00
|
|
|
self.printed.set(true);
|
|
|
|
}
|
2024-06-21 10:09:30 +02:00
|
|
|
|
|
|
|
fn has_received(&self) -> bool {
|
|
|
|
self.printed.get()
|
|
|
|
}
|
2024-03-27 19:27:11 +01:00
|
|
|
}
|