allow custom handlers instead of only printer
This commit is contained in:
parent
bc25da6f2c
commit
83d5f329f9
|
@ -1,3 +1,5 @@
|
|||
use std::{cell::Cell, fmt::Display};
|
||||
|
||||
/// Represents a trait responsible for handling diagnostics in the interpreter.
|
||||
pub trait Handler<T> {
|
||||
/// Receive an error and handles it.
|
||||
|
@ -6,13 +8,89 @@ pub trait Handler<T> {
|
|||
fn has_received(&self) -> bool;
|
||||
}
|
||||
|
||||
/// Is a struct that implements [`Handler`] trait by doing nothing with the errors.
|
||||
/// Is a struct that implements [`Handler`] trait by doing nothing with the errors and
|
||||
/// never signifying that it has received a message.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct DummyHandler;
|
||||
pub struct VoidHandler;
|
||||
|
||||
impl<T> Handler<T> for DummyHandler {
|
||||
impl<T> Handler<T> for VoidHandler {
|
||||
fn receive<E: Into<T>>(&self, _error: E) {}
|
||||
fn has_received(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// A handler that does not print the error to the standard error stream.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct SilentHandler {
|
||||
received: Cell<bool>,
|
||||
}
|
||||
|
||||
impl SilentHandler {
|
||||
/// Creates a new [`SilentHandler`].
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Handler<T> for SilentHandler {
|
||||
fn receive<E: Into<T>>(&self, _error: E) {
|
||||
self.received.set(true);
|
||||
}
|
||||
|
||||
fn has_received(&self) -> bool {
|
||||
self.received.get()
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple error handler that prints the error to the standard error stream.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct PrintHandler {
|
||||
printed: Cell<bool>,
|
||||
}
|
||||
|
||||
impl PrintHandler {
|
||||
/// Creates a new [`PrintHandler`].
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Display> Handler<T> for PrintHandler {
|
||||
fn receive<E: Into<T>>(&self, error: E) {
|
||||
eprintln!("{}", error.into());
|
||||
self.printed.set(true);
|
||||
}
|
||||
|
||||
fn has_received(&self) -> bool {
|
||||
self.printed.get()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_void_handler() {
|
||||
let handler = VoidHandler;
|
||||
Handler::<&str>::receive(&handler, "error");
|
||||
assert!(!Handler::<&str>::has_received(&handler));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_silent_handler() {
|
||||
let handler = SilentHandler::new();
|
||||
Handler::<&str>::receive(&handler, "error");
|
||||
assert!(Handler::<&str>::has_received(&handler));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_print_handler() {
|
||||
let handler = PrintHandler::new();
|
||||
Handler::<&str>::receive(&handler, "error");
|
||||
assert!(Handler::<&str>::has_received(&handler));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
pub enum Error {
|
||||
#[error("An error occurred while working with Input/Output.")]
|
||||
IoError(String),
|
||||
#[error("An error occurred while lexing the source code.")]
|
||||
LexicalError(#[from] crate::lexical::Error),
|
||||
#[error("An error occured while tokenizing the source code.")]
|
||||
TokenizeError(#[from] crate::lexical::token::TokenizeError),
|
||||
#[error("An error occurred while parsing the source code.")]
|
||||
ParseError(#[from] crate::syntax::error::Error),
|
||||
#[error("An error occurred while transpiling the source code.")]
|
||||
TranspileError(#[from] crate::transpile::error::TranspileError),
|
||||
TranspileError(#[from] crate::transpile::TranspileError),
|
||||
#[error("An error occurred")]
|
||||
Other(&'static str),
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ mod error;
|
|||
pub use error::{Error, Result};
|
||||
|
||||
mod diagnostic;
|
||||
pub use diagnostic::{DummyHandler, Handler};
|
||||
pub use diagnostic::{Handler, PrintHandler, SilentHandler, VoidHandler};
|
||||
|
||||
mod file_provider;
|
||||
pub use file_provider::{FileProvider, FsProvider};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use std::{borrow::Cow, collections::HashMap, fmt::Display, str::FromStr, sync::OnceLock};
|
||||
|
||||
use crate::base::{
|
||||
self,
|
||||
source_file::{SourceElement, SourceIterator, Span},
|
||||
Handler,
|
||||
};
|
||||
|
@ -11,7 +12,7 @@ use enum_as_inner::EnumAsInner;
|
|||
use strum::IntoEnumIterator;
|
||||
use strum_macros::EnumIter;
|
||||
|
||||
use super::{error::UnterminatedDelimitedComment, Error};
|
||||
use super::error::{self, UnterminatedDelimitedComment};
|
||||
|
||||
/// Is an enumeration representing keywords in shulkerscript.
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
|
@ -439,7 +440,7 @@ impl Token {
|
|||
start: usize,
|
||||
character: char,
|
||||
prev_token: Option<&Self>,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Result<Self, TokenizeError> {
|
||||
// Single line comment
|
||||
if let Some((_, '/')) = iter.peek() {
|
||||
|
@ -503,9 +504,9 @@ impl Token {
|
|||
}
|
||||
.into())
|
||||
} else {
|
||||
handler.receive(UnterminatedDelimitedComment {
|
||||
handler.receive(error::Error::from(UnterminatedDelimitedComment {
|
||||
span: Span::new(iter.source_file().clone(), start, start + 2).unwrap(),
|
||||
});
|
||||
}));
|
||||
return Err(TokenizeError::FatalLexicalError);
|
||||
}
|
||||
}
|
||||
|
@ -576,7 +577,7 @@ impl Token {
|
|||
/// - [`TokenizeError::FatalLexicalError`] - A fatal lexical error occurred.
|
||||
pub fn tokenize(
|
||||
iter: &mut SourceIterator,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
prev_token: Option<&Self>,
|
||||
) -> Result<Self, TokenizeError> {
|
||||
// Gets the first character
|
||||
|
|
|
@ -6,6 +6,7 @@ use derive_more::{Deref, From};
|
|||
use enum_as_inner::EnumAsInner;
|
||||
|
||||
use crate::base::{
|
||||
self,
|
||||
source_file::{SourceElement, SourceFile, Span},
|
||||
Handler,
|
||||
};
|
||||
|
@ -46,7 +47,7 @@ impl TokenStream {
|
|||
/// encountered during tokenization.
|
||||
#[must_use]
|
||||
#[tracing::instrument(level = "debug", skip_all, fields(source_file = %source_file.path().display()))]
|
||||
pub fn tokenize(source_file: &Arc<SourceFile>, handler: &impl Handler<error::Error>) -> Self {
|
||||
pub fn tokenize(source_file: &Arc<SourceFile>, handler: &impl Handler<base::Error>) -> Self {
|
||||
// The list of token trees that will be returned.
|
||||
let mut tokens = Vec::new();
|
||||
let mut source_file_iterator = source_file.iter();
|
||||
|
@ -81,7 +82,7 @@ impl TokenStream {
|
|||
/// Handles a token.
|
||||
fn handle_token(
|
||||
tokens: &mut Vec<Token>,
|
||||
handler: &impl Handler<error::Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<TokenTree> {
|
||||
tokens
|
||||
.pop()
|
||||
|
@ -92,7 +93,7 @@ impl TokenStream {
|
|||
fn handle_popped_token(
|
||||
tokens: &mut Vec<Token>,
|
||||
popped_token: Token,
|
||||
handler: &impl Handler<error::Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<TokenTree> {
|
||||
match popped_token {
|
||||
Token::Punctuation(punc) if punc.punctuation == '{' => {
|
||||
|
@ -116,7 +117,7 @@ impl TokenStream {
|
|||
tokens: &mut Vec<Token>,
|
||||
open: Punctuation,
|
||||
delimiter: Delimiter,
|
||||
handler: &impl Handler<error::Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<Delimited> {
|
||||
let mut token_trees = Vec::new();
|
||||
|
||||
|
|
141
src/lib.rs
141
src/lib.rs
|
@ -19,56 +19,77 @@ pub mod lexical;
|
|||
pub mod syntax;
|
||||
pub mod transpile;
|
||||
|
||||
mod public_helpers;
|
||||
use std::path::Path;
|
||||
|
||||
use std::{cell::Cell, fmt::Display, path::Path};
|
||||
|
||||
use base::{FileProvider, Handler, Result};
|
||||
use syntax::syntax_tree::program::ProgramFile;
|
||||
use base::{source_file::SourceFile, Error, FileProvider, Handler, Result};
|
||||
use syntax::{parser::Parser, syntax_tree::program::ProgramFile};
|
||||
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
use shulkerbox::{datapack::Datapack, virtual_fs::VFolder};
|
||||
|
||||
use crate::lexical::token_stream::TokenStream;
|
||||
|
||||
/// Converts the given source code to tokens.
|
||||
/// Converts the given source code to tokens and returns a token stream.
|
||||
///
|
||||
/// # Errors
|
||||
/// - If an error occurs while reading the file.
|
||||
pub fn tokenize<F>(file_provider: &F, path: &Path) -> Result<TokenStream>
|
||||
where
|
||||
F: FileProvider,
|
||||
{
|
||||
let printer = Printer::new();
|
||||
/// - If an error occurs while loading the [`SourceFile`].
|
||||
pub fn tokenize(
|
||||
handler: &impl Handler<base::Error>,
|
||||
file_provider: &impl FileProvider,
|
||||
path: &Path,
|
||||
) -> Result<TokenStream> {
|
||||
tracing::info!("Tokenizing the source code at path: {}", path.display());
|
||||
|
||||
public_helpers::tokenize(&printer, file_provider, path)
|
||||
let source_file = SourceFile::load(path, file_provider)?;
|
||||
|
||||
Ok(TokenStream::tokenize(&source_file, handler))
|
||||
}
|
||||
|
||||
/// Parses the given source code.
|
||||
/// Parses the given source code and returns the AST of the program.
|
||||
///
|
||||
/// # Errors
|
||||
/// - If an error occurs while reading the file.
|
||||
/// - If an error occurs during [`tokenize()`].
|
||||
/// - If an error occurs while parsing the source code.
|
||||
pub fn parse<F>(file_provider: &F, path: &Path) -> Result<ProgramFile>
|
||||
where
|
||||
F: FileProvider,
|
||||
{
|
||||
let printer = Printer::new();
|
||||
pub fn parse(
|
||||
handler: &impl Handler<base::Error>,
|
||||
file_provider: &impl FileProvider,
|
||||
path: &Path,
|
||||
) -> Result<ProgramFile> {
|
||||
let tokens = tokenize(handler, file_provider, path)?;
|
||||
|
||||
public_helpers::parse(&printer, file_provider, path)
|
||||
if handler.has_received() {
|
||||
return Err(Error::Other(
|
||||
"An error occurred while tokenizing the source code.",
|
||||
));
|
||||
}
|
||||
|
||||
tracing::info!("Parsing the source code at path: {}", path.display());
|
||||
|
||||
let mut parser = Parser::new(&tokens);
|
||||
let program = parser.parse_program(handler).ok_or(Error::Other(
|
||||
"An error occured while parsing the source code.",
|
||||
))?;
|
||||
|
||||
if handler.has_received() {
|
||||
return Err(Error::Other(
|
||||
"An error occurred while parsing the source code.",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(program)
|
||||
}
|
||||
|
||||
/// Transpiles the given source code into a shulkerbox [`Datapack`].
|
||||
///
|
||||
/// # Parameters:
|
||||
/// - `script_paths`: A list of tuples containing the identifier of the program and the path to the script.
|
||||
/// - `script_paths`: A list of tuples containing the identifier and the path of each script file.
|
||||
///
|
||||
/// # Errors
|
||||
/// - If an error occurs while reading the file.
|
||||
/// - If an error occurs while parsing the source code.
|
||||
/// - If an error occurs during [`parse()`]
|
||||
/// - If an error occurs while transpiling the source code.
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
pub fn transpile<F, P>(
|
||||
handler: &impl Handler<base::Error>,
|
||||
file_provider: &F,
|
||||
pack_format: u8,
|
||||
script_paths: &[(String, P)],
|
||||
|
@ -77,22 +98,50 @@ where
|
|||
F: FileProvider,
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let printer = Printer::new();
|
||||
use transpile::Transpiler;
|
||||
|
||||
public_helpers::transpile(&printer, file_provider, pack_format, script_paths)
|
||||
let programs = script_paths
|
||||
.iter()
|
||||
.map(|(program_identifier, path)| {
|
||||
let program = parse(handler, file_provider, path.as_ref())?;
|
||||
|
||||
Ok((program_identifier, program))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if programs.iter().any(Result::is_err) {
|
||||
return Err(programs.into_iter().find_map(Result::err).unwrap());
|
||||
}
|
||||
let programs = programs
|
||||
.into_iter()
|
||||
.filter_map(Result::ok)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
tracing::info!("Transpiling the source code.");
|
||||
|
||||
let mut transpiler = Transpiler::new(pack_format);
|
||||
transpiler.transpile(&programs, handler)?;
|
||||
let datapack = transpiler.into_datapack();
|
||||
|
||||
if handler.has_received() {
|
||||
return Err(Error::Other(
|
||||
"An error occurred while transpiling the source code.",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(datapack)
|
||||
}
|
||||
|
||||
/// Compiles the given source code.
|
||||
///
|
||||
/// # Parameters:
|
||||
/// - `script_paths`: A list of tuples containing the identifier of the program and the path to the script.
|
||||
/// - `script_paths`: A list of tuples containing the identifier and the path of each script file.
|
||||
///
|
||||
/// # 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.
|
||||
/// - If an error occurs during [`transpile()`]
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
pub fn compile<F, P>(
|
||||
handler: &impl Handler<base::Error>,
|
||||
file_provider: &F,
|
||||
pack_format: u8,
|
||||
script_paths: &[(String, P)],
|
||||
|
@ -101,35 +150,11 @@ where
|
|||
F: FileProvider,
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let printer = Printer::new();
|
||||
use shulkerbox::prelude::CompileOptions;
|
||||
|
||||
public_helpers::compile(&printer, file_provider, pack_format, script_paths)
|
||||
}
|
||||
let datapack = transpile(handler, file_provider, pack_format, script_paths)?;
|
||||
|
||||
struct Printer {
|
||||
printed: Cell<bool>,
|
||||
}
|
||||
tracing::info!("Compiling the source code.");
|
||||
|
||||
impl Printer {
|
||||
/// Creates a new [`Printer`].
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
printed: Cell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
fn has_printed(&self) -> bool {
|
||||
self.printed.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Display> Handler<T> for Printer {
|
||||
fn receive<E: Into<T>>(&self, error: E) {
|
||||
eprintln!("{}", error.into());
|
||||
self.printed.set(true);
|
||||
}
|
||||
|
||||
fn has_received(&self) -> bool {
|
||||
self.printed.get()
|
||||
}
|
||||
Ok(datapack.compile(&CompileOptions::default()))
|
||||
}
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
use std::path::Path;
|
||||
|
||||
use crate::{
|
||||
base::{source_file::SourceFile, Error, FileProvider, Result},
|
||||
lexical::token_stream::TokenStream,
|
||||
syntax::{parser::Parser, syntax_tree::program::ProgramFile},
|
||||
Printer,
|
||||
};
|
||||
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
use crate::transpile::transpiler::Transpiler;
|
||||
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
use shulkerbox::{datapack::Datapack, util::compile::CompileOptions, virtual_fs::VFolder};
|
||||
|
||||
/// Tokenizes the source code at the given path.
|
||||
pub fn tokenize(
|
||||
printer: &Printer,
|
||||
file_provider: &impl FileProvider,
|
||||
path: &Path,
|
||||
) -> Result<TokenStream> {
|
||||
tracing::info!("Tokenizing the source code at path: {}", path.display());
|
||||
|
||||
let source_file = SourceFile::load(path, file_provider)?;
|
||||
|
||||
Ok(TokenStream::tokenize(&source_file, printer))
|
||||
}
|
||||
|
||||
/// Parses the source code at the given path.
|
||||
pub fn parse(
|
||||
printer: &Printer,
|
||||
file_provider: &impl FileProvider,
|
||||
path: &Path,
|
||||
) -> Result<ProgramFile> {
|
||||
let tokens = tokenize(printer, file_provider, path)?;
|
||||
|
||||
if printer.has_printed() {
|
||||
return Err(Error::Other(
|
||||
"An error occurred while tokenizing the source code.",
|
||||
));
|
||||
}
|
||||
|
||||
tracing::info!("Parsing the source code at path: {}", path.display());
|
||||
|
||||
let mut parser = Parser::new(&tokens);
|
||||
let program = parser.parse_program(printer).ok_or(Error::Other(
|
||||
"An error occured while parsing the source code.",
|
||||
))?;
|
||||
|
||||
if printer.has_printed() {
|
||||
return Err(Error::Other(
|
||||
"An error occurred while parsing the source code.",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(program)
|
||||
}
|
||||
|
||||
/// Transpiles the source code at the given paths into a shulkerbox [`Datapack`].
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
pub fn transpile<F, P>(
|
||||
printer: &Printer,
|
||||
file_provider: &F,
|
||||
pack_format: u8,
|
||||
script_paths: &[(String, P)],
|
||||
) -> Result<Datapack>
|
||||
where
|
||||
F: FileProvider,
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let programs = script_paths
|
||||
.iter()
|
||||
.map(|(program_identifier, path)| {
|
||||
let program = parse(printer, file_provider, path.as_ref())?;
|
||||
|
||||
Ok((program_identifier, program))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if programs.iter().any(Result::is_err) {
|
||||
return Err(programs.into_iter().find_map(Result::err).unwrap());
|
||||
}
|
||||
let programs = programs
|
||||
.into_iter()
|
||||
.filter_map(Result::ok)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
tracing::info!("Transpiling the source code.");
|
||||
|
||||
let mut transpiler = Transpiler::new(pack_format);
|
||||
transpiler.transpile(&programs, printer)?;
|
||||
let datapack = transpiler.into_datapack();
|
||||
|
||||
if printer.has_printed() {
|
||||
return Err(Error::Other(
|
||||
"An error occurred while transpiling the source code.",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(datapack)
|
||||
}
|
||||
|
||||
/// Compiles the source code at the given paths.
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
pub fn compile<F, P>(
|
||||
printer: &Printer,
|
||||
file_provider: &F,
|
||||
pack_format: u8,
|
||||
script_paths: &[(String, P)],
|
||||
) -> Result<VFolder>
|
||||
where
|
||||
F: FileProvider,
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let datapack = transpile(printer, file_provider, pack_format, script_paths)?;
|
||||
|
||||
tracing::info!("Compiling the source code.");
|
||||
|
||||
Ok(datapack.compile(&CompileOptions::default()))
|
||||
}
|
|
@ -4,7 +4,7 @@ use derive_more::{Deref, DerefMut};
|
|||
use enum_as_inner::EnumAsInner;
|
||||
|
||||
use crate::{
|
||||
base::Handler,
|
||||
base::{self, Handler},
|
||||
lexical::{
|
||||
token::{Identifier, Keyword, KeywordKind, Numeric, Punctuation, StringLiteral, Token},
|
||||
token_stream::{Delimited, Delimiter, TokenStream, TokenTree},
|
||||
|
@ -42,7 +42,7 @@ impl<'a> Parser<'a> {
|
|||
&mut self,
|
||||
delimiter: Delimiter,
|
||||
f: impl FnOnce(&mut Self) -> Option<T>,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<DelimitedTree<T>> {
|
||||
self.current_frame.stop_at_significant();
|
||||
let raw_token_tree = self
|
||||
|
@ -363,7 +363,7 @@ impl<'a> Frame<'a> {
|
|||
///
|
||||
/// # Errors
|
||||
/// If the next [`Token`] is not an [`Identifier`].
|
||||
pub fn parse_identifier(&mut self, handler: &impl Handler<Error>) -> Option<Identifier> {
|
||||
pub fn parse_identifier(&mut self, handler: &impl Handler<base::Error>) -> Option<Identifier> {
|
||||
match self.next_significant_token() {
|
||||
Reading::Atomic(Token::Identifier(ident)) => Some(ident),
|
||||
found => {
|
||||
|
@ -397,7 +397,10 @@ impl<'a> Frame<'a> {
|
|||
///
|
||||
/// # Errors
|
||||
/// If the next [`Token`] is not an [`StringLiteral`].
|
||||
pub fn parse_string_literal(&mut self, handler: &impl Handler<Error>) -> Option<StringLiteral> {
|
||||
pub fn parse_string_literal(
|
||||
&mut self,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<StringLiteral> {
|
||||
match self.next_significant_token() {
|
||||
Reading::Atomic(Token::StringLiteral(literal)) => Some(literal),
|
||||
found => {
|
||||
|
@ -417,7 +420,7 @@ impl<'a> Frame<'a> {
|
|||
pub fn parse_keyword(
|
||||
&mut self,
|
||||
expected: KeywordKind,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<Keyword> {
|
||||
match self.next_significant_token() {
|
||||
Reading::Atomic(Token::Keyword(keyword_token)) if keyword_token.keyword == expected => {
|
||||
|
@ -441,7 +444,7 @@ impl<'a> Frame<'a> {
|
|||
&mut self,
|
||||
expected: char,
|
||||
skip_insignificant: bool,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<Punctuation> {
|
||||
match if skip_insignificant {
|
||||
self.next_significant_token()
|
||||
|
|
|
@ -7,8 +7,9 @@ use getset::Getters;
|
|||
|
||||
use crate::{
|
||||
base::{
|
||||
self,
|
||||
source_file::{SourceElement, Span},
|
||||
DummyHandler, Handler,
|
||||
VoidHandler, Handler,
|
||||
},
|
||||
lexical::{
|
||||
token::{Punctuation, StringLiteral, Token},
|
||||
|
@ -240,7 +241,7 @@ impl SourceElement for Condition {
|
|||
|
||||
impl<'a> Parser<'a> {
|
||||
/// Parses a [`Condition`].
|
||||
pub fn parse_condition(&mut self, handler: &impl Handler<Error>) -> Option<Condition> {
|
||||
pub fn parse_condition(&mut self, handler: &impl Handler<base::Error>) -> Option<Condition> {
|
||||
let mut lhs = Condition::Primary(self.parse_primary_condition(handler)?);
|
||||
let mut expressions = VecDeque::new();
|
||||
|
||||
|
@ -305,7 +306,7 @@ impl<'a> Parser<'a> {
|
|||
/// Parses a [`PrimaryCondition`].
|
||||
pub fn parse_primary_condition(
|
||||
&mut self,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<PrimaryCondition> {
|
||||
match self.stop_at_significant() {
|
||||
// prefixed expression
|
||||
|
@ -354,7 +355,7 @@ impl<'a> Parser<'a> {
|
|||
/// Parses a [`ParenthesizedCondition`].
|
||||
pub fn parse_parenthesized_condition(
|
||||
&mut self,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<ParenthesizedCondition> {
|
||||
let token_tree = self.step_into(
|
||||
Delimiter::Parenthesis,
|
||||
|
@ -377,11 +378,11 @@ impl<'a> Parser<'a> {
|
|||
self.try_parse(|parser| match parser.next_significant_token() {
|
||||
Reading::Atomic(Token::Punctuation(punc)) => match punc.punctuation {
|
||||
'&' => {
|
||||
let b = parser.parse_punctuation('&', false, &DummyHandler)?;
|
||||
let b = parser.parse_punctuation('&', false, &VoidHandler)?;
|
||||
Some(ConditionalBinaryOperator::LogicalAnd(punc, b))
|
||||
}
|
||||
'|' => {
|
||||
let b = parser.parse_punctuation('|', false, &DummyHandler)?;
|
||||
let b = parser.parse_punctuation('|', false, &VoidHandler)?;
|
||||
Some(ConditionalBinaryOperator::LogicalOr(punc, b))
|
||||
}
|
||||
_ => None,
|
||||
|
|
|
@ -6,8 +6,9 @@ use getset::Getters;
|
|||
|
||||
use crate::{
|
||||
base::{
|
||||
self,
|
||||
source_file::{SourceElement, Span},
|
||||
DummyHandler, Handler,
|
||||
Handler, VoidHandler,
|
||||
},
|
||||
lexical::{
|
||||
token::{Identifier, Keyword, KeywordKind, Punctuation, StringLiteral, Token},
|
||||
|
@ -226,7 +227,7 @@ impl SourceElement for Import {
|
|||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
pub fn parse_annotation(&mut self, handler: &impl Handler<Error>) -> Option<Annotation> {
|
||||
pub fn parse_annotation(&mut self, handler: &impl Handler<base::Error>) -> Option<Annotation> {
|
||||
match self.stop_at_significant() {
|
||||
Reading::Atomic(Token::Punctuation(punctuation)) if punctuation.punctuation == '#' => {
|
||||
// eat the pound sign
|
||||
|
@ -280,7 +281,10 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip_all)]
|
||||
pub fn parse_declaration(&mut self, handler: &impl Handler<Error>) -> Option<Declaration> {
|
||||
pub fn parse_declaration(
|
||||
&mut self,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<Declaration> {
|
||||
match self.stop_at_significant() {
|
||||
Reading::Atomic(Token::Keyword(function_keyword))
|
||||
if function_keyword.keyword == KeywordKind::Function =>
|
||||
|
@ -355,7 +359,7 @@ impl<'a> Parser<'a> {
|
|||
self.try_parse(|parser| parser
|
||||
.parse_connected_list(
|
||||
',',
|
||||
|parser| parser.parse_identifier(&DummyHandler),
|
||||
|parser| parser.parse_identifier(&VoidHandler),
|
||||
handler,
|
||||
)
|
||||
.map(ImportItems::Named)) // ,
|
||||
|
@ -398,7 +402,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse_function(&mut self, handler: &impl Handler<Error>) -> Option<Function> {
|
||||
pub fn parse_function(&mut self, handler: &impl Handler<base::Error>) -> Option<Function> {
|
||||
if let Reading::Atomic(Token::Keyword(function_keyword)) = self.stop_at_significant() {
|
||||
// eat the function keyword
|
||||
self.forward();
|
||||
|
|
|
@ -5,6 +5,7 @@ use getset::Getters;
|
|||
|
||||
use crate::{
|
||||
base::{
|
||||
self,
|
||||
source_file::{SourceElement, Span},
|
||||
Handler,
|
||||
},
|
||||
|
@ -155,12 +156,12 @@ impl LuaCode {
|
|||
|
||||
impl<'a> Parser<'a> {
|
||||
/// Parses an [`Expression`]
|
||||
pub fn parse_expression(&mut self, handler: &impl Handler<Error>) -> Option<Expression> {
|
||||
pub fn parse_expression(&mut self, handler: &impl Handler<base::Error>) -> Option<Expression> {
|
||||
Some(Expression::Primary(self.parse_primary(handler)?))
|
||||
}
|
||||
|
||||
/// Parses an [`Primary`]
|
||||
pub fn parse_primary(&mut self, handler: &impl Handler<Error>) -> Option<Primary> {
|
||||
pub fn parse_primary(&mut self, handler: &impl Handler<base::Error>) -> Option<Primary> {
|
||||
match self.stop_at_significant() {
|
||||
// identifier expression
|
||||
Reading::Atomic(Token::Identifier(identifier)) => {
|
||||
|
|
|
@ -4,8 +4,9 @@ use getset::Getters;
|
|||
|
||||
use crate::{
|
||||
base::{
|
||||
self,
|
||||
source_file::{SourceElement, Span},
|
||||
DummyHandler, Handler,
|
||||
Handler, VoidHandler,
|
||||
},
|
||||
lexical::{
|
||||
token::{Punctuation, Token},
|
||||
|
@ -14,7 +15,7 @@ use crate::{
|
|||
syntax::parser::Reading,
|
||||
};
|
||||
|
||||
use super::{error::Error, parser::Parser};
|
||||
use super::parser::Parser;
|
||||
|
||||
pub mod condition;
|
||||
pub mod declaration;
|
||||
|
@ -76,7 +77,7 @@ impl<'a> Parser<'a> {
|
|||
delimiter: Delimiter,
|
||||
separator: char,
|
||||
mut f: impl FnMut(&mut Self) -> Option<T>,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<DelimitedList<T>> {
|
||||
fn skip_to_next_separator(this: &mut Parser, separator: char) -> Option<Punctuation> {
|
||||
if let Reading::Atomic(Token::Punctuation(punc)) = this.stop_at(|token| {
|
||||
|
@ -162,14 +163,14 @@ impl<'a> Parser<'a> {
|
|||
&mut self,
|
||||
seperator: char,
|
||||
mut f: impl FnMut(&mut Self) -> Option<T>,
|
||||
_handler: &impl Handler<Error>,
|
||||
_handler: &impl Handler<base::Error>,
|
||||
) -> Option<ConnectedList<T, Punctuation>> {
|
||||
let first = f(self)?;
|
||||
|
||||
let mut rest = Vec::new();
|
||||
|
||||
while let Some(sep) =
|
||||
self.try_parse(|parser| parser.parse_punctuation(seperator, true, &DummyHandler))
|
||||
self.try_parse(|parser| parser.parse_punctuation(seperator, true, &VoidHandler))
|
||||
{
|
||||
if let Some(element) = self.try_parse(&mut f) {
|
||||
rest.push((sep, element));
|
||||
|
|
|
@ -4,12 +4,14 @@ use getset::Getters;
|
|||
|
||||
use crate::{
|
||||
base::{
|
||||
self,
|
||||
source_file::{SourceElement, Span},
|
||||
Handler,
|
||||
},
|
||||
lexical::token::{Keyword, KeywordKind, Punctuation, StringLiteral, Token},
|
||||
syntax::{
|
||||
error::{Error, SyntaxKind, UnexpectedSyntax},
|
||||
self,
|
||||
error::{SyntaxKind, UnexpectedSyntax},
|
||||
parser::{Parser, Reading},
|
||||
},
|
||||
};
|
||||
|
@ -79,7 +81,7 @@ impl Namespace {
|
|||
impl<'a> Parser<'a> {
|
||||
/// Parses a [`ProgramFile`].
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
pub fn parse_program(&mut self, handler: &impl Handler<Error>) -> Option<ProgramFile> {
|
||||
pub fn parse_program(&mut self, handler: &impl Handler<base::Error>) -> Option<ProgramFile> {
|
||||
tracing::debug!("Parsing program");
|
||||
|
||||
let namespace = match self.stop_at_significant() {
|
||||
|
@ -102,10 +104,10 @@ impl<'a> Parser<'a> {
|
|||
})
|
||||
}
|
||||
unexpected => {
|
||||
handler.receive(UnexpectedSyntax {
|
||||
handler.receive(syntax::error::Error::from(UnexpectedSyntax {
|
||||
expected: SyntaxKind::Keyword(KeywordKind::Namespace),
|
||||
found: unexpected.into_token(),
|
||||
});
|
||||
}));
|
||||
None
|
||||
}
|
||||
}?;
|
||||
|
|
|
@ -7,6 +7,7 @@ use getset::Getters;
|
|||
|
||||
use crate::{
|
||||
base::{
|
||||
self,
|
||||
source_file::{SourceElement, Span},
|
||||
Handler,
|
||||
},
|
||||
|
@ -14,10 +15,7 @@ use crate::{
|
|||
token::{CommandLiteral, DocComment, Keyword, KeywordKind, Punctuation, Token},
|
||||
token_stream::Delimiter,
|
||||
},
|
||||
syntax::{
|
||||
error::Error,
|
||||
parser::{Parser, Reading},
|
||||
},
|
||||
syntax::parser::{Parser, Reading},
|
||||
};
|
||||
|
||||
use self::execute_block::ExecuteBlock;
|
||||
|
@ -211,7 +209,7 @@ impl Semicolon {
|
|||
|
||||
impl<'a> Parser<'a> {
|
||||
/// Parses a [`Block`].
|
||||
pub fn parse_block(&mut self, handler: &impl Handler<Error>) -> Option<Block> {
|
||||
pub fn parse_block(&mut self, handler: &impl Handler<base::Error>) -> Option<Block> {
|
||||
let token_tree = self.step_into(
|
||||
Delimiter::Brace,
|
||||
|parser| {
|
||||
|
@ -250,7 +248,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
/// Parses a [`Statement`].
|
||||
#[tracing::instrument(level = "trace", skip_all)]
|
||||
pub fn parse_statement(&mut self, handler: &impl Handler<Error>) -> Option<Statement> {
|
||||
pub fn parse_statement(&mut self, handler: &impl Handler<base::Error>) -> Option<Statement> {
|
||||
match self.stop_at_significant() {
|
||||
// variable declaration
|
||||
Reading::Atomic(Token::CommandLiteral(command)) => {
|
||||
|
|
|
@ -6,15 +6,17 @@ use getset::Getters;
|
|||
|
||||
use crate::{
|
||||
base::{
|
||||
self,
|
||||
source_file::{SourceElement, Span},
|
||||
DummyHandler, Handler,
|
||||
VoidHandler, Handler,
|
||||
},
|
||||
lexical::{
|
||||
token::{Keyword, KeywordKind, Punctuation, StringLiteral, Token},
|
||||
token_stream::Delimiter,
|
||||
},
|
||||
syntax::{
|
||||
error::{Error, SyntaxKind, UnexpectedSyntax},
|
||||
self,
|
||||
error::{SyntaxKind, UnexpectedSyntax},
|
||||
parser::{DelimitedTree, Parser, Reading},
|
||||
syntax_tree::condition::ParenthesizedCondition,
|
||||
},
|
||||
|
@ -711,7 +713,7 @@ impl<'a> Parser<'a> {
|
|||
/// Parses an [`ExecuteBlock`].
|
||||
pub fn parse_execute_block_statement(
|
||||
&mut self,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<ExecuteBlock> {
|
||||
match self.stop_at_significant() {
|
||||
Reading::Atomic(Token::Keyword(if_keyword))
|
||||
|
@ -728,7 +730,7 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
|
||||
let else_tail = self.try_parse(|parser| {
|
||||
let block = parser.parse_block(&DummyHandler)?;
|
||||
let block = parser.parse_block(&VoidHandler)?;
|
||||
let (else_keyword, else_block) = match parser.stop_at_significant() {
|
||||
// else statement
|
||||
Reading::Atomic(Token::Keyword(else_keyword))
|
||||
|
@ -775,10 +777,10 @@ impl<'a> Parser<'a> {
|
|||
handler,
|
||||
),
|
||||
unexpected => {
|
||||
handler.receive(UnexpectedSyntax {
|
||||
handler.receive(syntax::error::Error::from(UnexpectedSyntax {
|
||||
expected: SyntaxKind::Punctuation('('),
|
||||
found: unexpected.into_token(),
|
||||
});
|
||||
}));
|
||||
None
|
||||
}
|
||||
}?;
|
||||
|
@ -792,10 +794,10 @@ impl<'a> Parser<'a> {
|
|||
|
||||
// unexpected
|
||||
unexpected => {
|
||||
handler.receive(UnexpectedSyntax {
|
||||
handler.receive(syntax::error::Error::from(UnexpectedSyntax {
|
||||
expected: SyntaxKind::ExecuteBlock,
|
||||
found: unexpected.into_token(),
|
||||
});
|
||||
}));
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -803,7 +805,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
fn parse_execute_block_tail(
|
||||
&mut self,
|
||||
handler: &impl Handler<Error>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Option<ExecuteBlockTail> {
|
||||
match self.stop_at_significant() {
|
||||
// nested execute block
|
||||
|
@ -827,10 +829,10 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
unexpected => {
|
||||
handler.receive(UnexpectedSyntax {
|
||||
handler.receive(syntax::error::Error::from(UnexpectedSyntax {
|
||||
expected: SyntaxKind::ExecuteBlockTail,
|
||||
found: unexpected.into_token(),
|
||||
});
|
||||
}));
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ mod enabled {
|
|||
use mlua::Lua;
|
||||
|
||||
use crate::{
|
||||
base::{source_file::SourceElement, Handler},
|
||||
base::{self, source_file::SourceElement, Handler},
|
||||
syntax::syntax_tree::expression::LuaCode,
|
||||
transpile::error::{TranspileError, TranspileResult},
|
||||
};
|
||||
|
@ -16,10 +16,7 @@ mod enabled {
|
|||
/// # Errors
|
||||
/// - If Lua code evaluation is disabled.
|
||||
#[tracing::instrument(level = "debug", name = "eval_lua", skip_all, ret)]
|
||||
pub fn eval_string(
|
||||
&self,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
) -> TranspileResult<String> {
|
||||
pub fn eval_string(&self, handler: &impl Handler<base::Error>) -> TranspileResult<String> {
|
||||
tracing::debug!("Evaluating Lua code");
|
||||
|
||||
let lua = Lua::new();
|
||||
|
|
|
@ -3,10 +3,15 @@
|
|||
#[doc(hidden)]
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
pub mod conversions;
|
||||
pub mod error;
|
||||
mod error;
|
||||
#[doc(inline)]
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
pub use error::{TranspileError, TranspileResult};
|
||||
#[doc(hidden)]
|
||||
pub mod lua;
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
pub mod transpiler;
|
||||
mod transpiler;
|
||||
#[doc(inline)]
|
||||
pub use transpiler::Transpiler;
|
||||
|
||||
mod util;
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::{collections::HashMap, iter, sync::RwLock};
|
|||
use shulkerbox::datapack::{self, Command, Datapack, Execute};
|
||||
|
||||
use crate::{
|
||||
base::{source_file::SourceElement, Handler},
|
||||
base::{self, source_file::SourceElement, Handler},
|
||||
syntax::syntax_tree::{
|
||||
declaration::{Declaration, ImportItems},
|
||||
expression::{Expression, FunctionCall, Primary},
|
||||
|
@ -64,7 +64,7 @@ impl Transpiler {
|
|||
pub fn transpile<Ident>(
|
||||
&mut self,
|
||||
programs: &[(Ident, ProgramFile)],
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> Result<(), TranspileError>
|
||||
where
|
||||
Ident: AsRef<str>,
|
||||
|
@ -107,7 +107,7 @@ impl Transpiler {
|
|||
&mut self,
|
||||
program: &ProgramFile,
|
||||
identifier: &str,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) {
|
||||
let namespace = program.namespace();
|
||||
|
||||
|
@ -117,12 +117,13 @@ impl Transpiler {
|
|||
}
|
||||
|
||||
/// Transpiles the given declaration.
|
||||
#[allow(clippy::needless_pass_by_ref_mut)]
|
||||
fn transpile_declaration(
|
||||
&mut self,
|
||||
declaration: &Declaration,
|
||||
namespace: &Namespace,
|
||||
program_identifier: &str,
|
||||
_handler: &impl Handler<TranspileError>,
|
||||
_handler: &impl Handler<base::Error>,
|
||||
) {
|
||||
match declaration {
|
||||
Declaration::Function(function) => {
|
||||
|
@ -184,7 +185,7 @@ impl Transpiler {
|
|||
&mut self,
|
||||
name: &str,
|
||||
program_identifier: &str,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<String> {
|
||||
let program_query = (program_identifier.to_string(), name.to_string());
|
||||
let alias_query = {
|
||||
|
@ -289,7 +290,7 @@ impl Transpiler {
|
|||
&mut self,
|
||||
statements: &[Statement],
|
||||
program_identifier: &str,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Vec<Command>> {
|
||||
let mut errors = Vec::new();
|
||||
let commands = statements
|
||||
|
@ -314,7 +315,7 @@ impl Transpiler {
|
|||
&mut self,
|
||||
statement: &Statement,
|
||||
program_identifier: &str,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Option<Command>> {
|
||||
match statement {
|
||||
Statement::LiteralCommand(literal_command) => {
|
||||
|
@ -381,7 +382,7 @@ impl Transpiler {
|
|||
&mut self,
|
||||
func: &FunctionCall,
|
||||
program_identifier: &str,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Command> {
|
||||
let identifier = func.identifier().span();
|
||||
let identifier_name = identifier.str();
|
||||
|
@ -394,7 +395,7 @@ impl Transpiler {
|
|||
&mut self,
|
||||
execute: &ExecuteBlock,
|
||||
program_identifier: &str,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Option<Command>> {
|
||||
self.transpile_execute_block_internal(execute, program_identifier, handler)
|
||||
.map(|ex| ex.map(Command::Execute))
|
||||
|
@ -404,7 +405,7 @@ impl Transpiler {
|
|||
&mut self,
|
||||
execute: &ExecuteBlock,
|
||||
program_identifier: &str,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Option<Execute>> {
|
||||
match execute {
|
||||
ExecuteBlock::HeadTail(head, tail) => {
|
||||
|
@ -489,7 +490,7 @@ impl Transpiler {
|
|||
then: Execute,
|
||||
el: Option<&Else>,
|
||||
program_identifier: &str,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Option<Execute>> {
|
||||
let (_, cond) = cond.clone().dissolve();
|
||||
let (_, cond, _) = cond.dissolve();
|
||||
|
@ -540,7 +541,7 @@ impl Transpiler {
|
|||
head: &ExecuteBlockHead,
|
||||
tail: Option<Execute>,
|
||||
program_identifier: &str,
|
||||
handler: &impl Handler<TranspileError>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Option<Execute>> {
|
||||
Ok(match head {
|
||||
ExecuteBlockHead::Conditional(cond) => {
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::path::Path;
|
|||
|
||||
use shulkerbox::virtual_fs::{VFile, VFolder};
|
||||
use shulkerscript::{
|
||||
base::source_file::SourceElement,
|
||||
base::{source_file::SourceElement, PrintHandler},
|
||||
syntax::syntax_tree::{declaration::Declaration, statement::Statement},
|
||||
};
|
||||
|
||||
|
@ -12,7 +12,8 @@ fn parsing_test1() {
|
|||
let mut dir = VFolder::new();
|
||||
dir.add_file("test1.shu", VFile::Text(source.to_string()));
|
||||
|
||||
let parsed = shulkerscript::parse(&dir, Path::new("test1.shu")).expect("Failed to parse");
|
||||
let parsed = shulkerscript::parse(&PrintHandler::default(), &dir, Path::new("test1.shu"))
|
||||
.expect("Failed to parse");
|
||||
|
||||
assert_eq!(
|
||||
parsed.namespace().namespace_name().str_content(),
|
||||
|
@ -48,5 +49,6 @@ fn parsing_invalid() {
|
|||
let mut dir = VFolder::new();
|
||||
dir.add_file("invalid.shu", VFile::Text(source.to_string()));
|
||||
|
||||
shulkerscript::parse(&dir, Path::new("invalid.shu")).expect_err("Expecting parsing failure");
|
||||
shulkerscript::parse(&PrintHandler::default(), &dir, Path::new("invalid.shu"))
|
||||
.expect_err("Expecting parsing failure");
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use shulkerbox::{
|
|||
datapack::{Command, Condition, Datapack, Execute},
|
||||
virtual_fs::{VFile, VFolder},
|
||||
};
|
||||
use shulkerscript::base::PrintHandler;
|
||||
|
||||
#[test]
|
||||
fn transpile_test1() {
|
||||
|
@ -9,7 +10,12 @@ fn transpile_test1() {
|
|||
let mut dir = VFolder::new();
|
||||
dir.add_file("test1.shu", VFile::Text(source.to_string()));
|
||||
|
||||
let transpiled = shulkerscript::transpile(&dir, 48, &[("test1".to_string(), "./test1.shu")])
|
||||
let transpiled = shulkerscript::transpile(
|
||||
&PrintHandler::default(),
|
||||
&dir,
|
||||
48,
|
||||
&[("test1".to_string(), "./test1.shu")],
|
||||
)
|
||||
.expect("Failed to transpile");
|
||||
|
||||
let expected = {
|
||||
|
|
Loading…
Reference in New Issue