Compare commits

..

3 Commits

Author SHA1 Message Date
Moritz Hölting 9718763664 change order of serialization of Span by serializing to temporary buffer 2025-02-12 15:18:05 +01:00
Moritz Hölting 7df7061e8e implement custom deserialize
- requires opposite order of data and source_files than what is serialized
2025-02-12 14:37:52 +01:00
Moritz Hölting 8619cac56c implement custom serialize for Span 2025-02-12 14:09:02 +01:00
9 changed files with 48 additions and 1076 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target
/Cargo.lock

View File

@ -11,8 +11,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Option to deduplicate source files during serialization when using `SerdeWrapper`
### Removed
## [0.1.0] - 2024-10-01

1018
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -18,28 +18,28 @@ license = "MIT OR Apache-2.0"
default = ["fs_access", "lua", "shulkerbox", "zip"]
fs_access = ["shulkerbox?/fs_access"]
lua = ["dep:mlua"]
serde = ["dep:serde", "dep:flexbuffers", "shulkerbox?/serde"]
shulkerbox = ["dep:shulkerbox", "dep:chksum-md5"]
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"] }
[dependencies]
chksum-md5 = { version = "0.1.0", optional = true }
colored = "3.0.0"
chksum-md5 = "0.0.0"
colored = "2.1.0"
derive_more = { version = "1.0.0", default-features = false, features = ["deref", "deref_mut", "from"] }
enum-as-inner = "0.6.0"
flexbuffers = { version = "25.2.10", optional = true }
flexbuffers = "25.2.10"
getset = "0.1.2"
itertools = "0.14.0"
mlua = { version = "0.10.2", features = ["lua54", "vendored"], optional = true }
itertools = "0.13.0"
mlua = { version = "0.10.0", features = ["lua54", "vendored"], optional = true }
path-absolutize = "3.1.1"
pathdiff = "0.2.3"
serde = { version = "1.0.217", features = ["derive", "rc"], optional = true }
pathdiff = "0.2.2"
serde = { version = "1.0.214", features = ["derive", "rc"], optional = true }
shulkerbox = { version = "0.1.0", default-features = false, optional = true }
strsim = "0.11.1"
strum = { version = "0.26.2", features = ["derive"] }
strum_macros = "0.26.4"
thiserror = "2.0.11"
tracing = "0.1.41"
thiserror = "1.0.65"
tracing = "0.1.40"

View File

@ -12,7 +12,6 @@
#![warn(missing_docs, clippy::all, clippy::pedantic)]
#![allow(clippy::missing_panics_doc, clippy::missing_const_for_fn)]
#[cfg(feature = "shulkerbox")]
pub use shulkerbox;
pub mod base;

View File

@ -13,7 +13,7 @@ use crate::{
syntax::syntax_tree::expression::Expression,
};
use super::FunctionData;
use super::transpiler::FunctionData;
/// Errors that can occur during transpilation.
#[allow(clippy::module_name_repetitions, missing_docs)]
@ -44,7 +44,6 @@ pub struct MissingFunctionDeclaration {
}
impl MissingFunctionDeclaration {
#[cfg_attr(not(feature = "shulkerbox"), expect(unused))]
pub(super) fn from_context(
identifier_span: Span,
functions: &BTreeMap<(String, String), FunctionData>,

View File

@ -59,8 +59,9 @@ mod enabled {
err
})?;
self.handle_lua_result(lua_result).inspect_err(|err| {
self.handle_lua_result(lua_result).map_err(|err| {
handler.receive(err.clone());
err
})
}

View File

@ -1,14 +1,9 @@
//! The transpile module is responsible for transpiling the abstract syntax tree into a data pack.
use std::collections::HashMap;
use crate::{base::source_file::Span, syntax::syntax_tree::statement::Statement};
#[doc(hidden)]
#[cfg(feature = "shulkerbox")]
pub mod conversions;
mod error;
#[doc(inline)]
#[allow(clippy::module_name_repetitions)]
pub use error::{TranspileError, TranspileResult};
@ -16,18 +11,7 @@ pub use error::{TranspileError, TranspileResult};
pub mod lua;
#[cfg(feature = "shulkerbox")]
mod transpiler;
#[cfg(feature = "shulkerbox")]
#[cfg_attr(feature = "shulkerbox", doc(inline))]
#[doc(inline)]
pub use transpiler::Transpiler;
#[cfg(feature = "shulkerbox")]
mod util;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct FunctionData {
pub(super) namespace: String,
pub(super) identifier_span: Span,
pub(super) statements: Vec<Statement>,
pub(super) public: bool,
pub(super) annotations: HashMap<String, Option<String>>,
}

View File

@ -4,6 +4,7 @@ use chksum_md5 as md5;
use std::{
collections::{BTreeMap, HashMap},
iter,
sync::RwLock,
};
use shulkerbox::datapack::{self, Command, Datapack, Execute};
@ -26,21 +27,25 @@ use crate::{
transpile::error::{ConflictingFunctionNames, MissingFunctionDeclaration},
};
use super::{
error::{TranspileError, TranspileResult, UnexpectedExpression},
FunctionData,
};
use super::error::{TranspileError, TranspileResult, UnexpectedExpression};
/// A transpiler for `Shulkerscript`.
#[derive(Debug)]
pub struct Transpiler {
datapack: shulkerbox::datapack::Datapack,
/// Key: (program identifier, function name)
functions: BTreeMap<(String, String), FunctionData>,
/// Key: (program identifier, function name), Value: (function location, public)
function_locations: HashMap<(String, String), (String, bool)>,
/// Key: alias, Value: target
aliases: HashMap<(String, String), (String, String)>,
functions: RwLock<BTreeMap<(String, String), FunctionData>>,
function_locations: RwLock<HashMap<(String, String), (String, bool)>>,
aliases: RwLock<HashMap<(String, String), (String, String)>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct FunctionData {
pub(super) namespace: String,
pub(super) identifier_span: Span,
pub(super) statements: Vec<Statement>,
pub(super) public: bool,
pub(super) annotations: HashMap<String, Option<String>>,
}
impl Transpiler {
@ -49,9 +54,9 @@ impl Transpiler {
pub fn new(pack_format: u8) -> Self {
Self {
datapack: shulkerbox::datapack::Datapack::new(pack_format),
functions: BTreeMap::new(),
function_locations: HashMap::new(),
aliases: HashMap::new(),
functions: RwLock::new(BTreeMap::new()),
function_locations: RwLock::new(HashMap::new()),
aliases: RwLock::new(HashMap::new()),
}
}
@ -80,7 +85,7 @@ impl Transpiler {
let mut always_transpile_functions = Vec::new();
{
let functions = &mut self.functions;
let functions = self.functions.read().unwrap();
for (_, data) in functions.iter() {
let always_transpile_function = data.annotations.contains_key("tick")
|| data.annotations.contains_key("load")
@ -143,7 +148,7 @@ impl Transpiler {
})
.collect();
#[allow(clippy::significant_drop_tightening)]
self.functions.insert(
self.functions.write().unwrap().insert(
(program_identifier, name),
FunctionData {
namespace: namespace.namespace_name().str_content().to_string(),
@ -159,7 +164,7 @@ impl Transpiler {
let import_identifier =
super::util::calculate_import_identifier(&program_identifier, path);
let aliases = &mut self.aliases;
let mut aliases = self.aliases.write().unwrap();
match import.items() {
ImportItems::All(_) => todo!("Importing all items is not yet supported."),
@ -210,9 +215,12 @@ impl Transpiler {
program_identifier.to_string(),
identifier_span.str().to_string(),
);
let alias_query = self.aliases.get(&program_query).cloned();
let alias_query = {
let aliases = self.aliases.read().unwrap();
aliases.get(&program_query).cloned()
};
let already_transpiled = {
let locations = &self.function_locations;
let locations = self.function_locations.read().unwrap();
locations
.get(&program_query)
.or_else(|| {
@ -226,7 +234,7 @@ impl Transpiler {
tracing::trace!("Function not transpiled yet, transpiling.");
let statements = {
let functions = &self.functions;
let functions = self.functions.read().unwrap();
let function_data = functions
.get(&program_query)
.or_else(|| {
@ -238,7 +246,7 @@ impl Transpiler {
let error = TranspileError::MissingFunctionDeclaration(
MissingFunctionDeclaration::from_context(
identifier_span.clone(),
functions,
&functions,
),
);
handler.receive(error.clone());
@ -248,7 +256,7 @@ impl Transpiler {
};
let commands = self.transpile_function(&statements, program_identifier, handler)?;
let functions = &self.functions;
let functions = self.functions.read().unwrap();
let function_data = functions
.get(&program_query)
.or_else(|| {
@ -260,7 +268,7 @@ impl Transpiler {
let error = TranspileError::MissingFunctionDeclaration(
MissingFunctionDeclaration::from_context(
identifier_span.clone(),
functions,
&functions,
),
);
handler.receive(error.clone());
@ -306,7 +314,7 @@ impl Transpiler {
self.datapack.add_load(&function_location);
}
self.function_locations.insert(
self.function_locations.write().unwrap().insert(
(
program_identifier.to_string(),
identifier_span.str().to_string(),
@ -315,7 +323,7 @@ impl Transpiler {
);
}
let locations = &self.function_locations;
let locations = self.function_locations.read().unwrap();
locations
.get(&program_query)
.or_else(|| alias_query.and_then(|q| locations.get(&q).filter(|(_, p)| *p)))
@ -323,7 +331,7 @@ impl Transpiler {
let error = TranspileError::MissingFunctionDeclaration(
MissingFunctionDeclaration::from_context(
identifier_span.clone(),
&self.functions,
&self.functions.read().unwrap(),
),
);
handler.receive(error.clone());