fix compile errors without shulkerbox feature

This commit is contained in:
Moritz Hölting 2025-03-31 22:47:16 +02:00
parent 32d453ebef
commit f808fef3f1
6 changed files with 84 additions and 25 deletions

View File

@ -20,7 +20,10 @@ use crate::{
AnyStringLiteral, AnyStringLiteral,
}, },
transpile::{ transpile::{
error::{AssignmentError, IllegalIndexing, MismatchedTypes, UnknownIdentifier}, error::{
AssignmentError, IllegalIndexing, IllegalIndexingReason, MismatchedTypes,
UnknownIdentifier,
},
expression::{ExpectedType, ValueType}, expression::{ExpectedType, ValueType},
}, },
}; };
@ -380,10 +383,7 @@ impl Assignment {
if let Some(expected) = valid_index { if let Some(expected) = valid_index {
let err = error::Error::IllegalIndexing(IllegalIndexing { let err = error::Error::IllegalIndexing(IllegalIndexing {
expression: index.span(), expression: index.span(),
reason: reason: IllegalIndexingReason::InvalidComptimeType { expected },
crate::transpile::error::IllegalIndexingReason::InvalidComptimeType {
expected,
},
}); });
handler.receive(err.clone()); handler.receive(err.clone());
return Err(err); return Err(err);
@ -513,6 +513,7 @@ impl Expression {
} }
impl Primary { impl Primary {
#[expect(clippy::too_many_lines)]
fn analyze_semantics( fn analyze_semantics(
&self, &self,
scope: &SemanticScope, scope: &SemanticScope,
@ -545,9 +546,58 @@ impl Primary {
} }
} }
Self::Indexed(indexed) => { Self::Indexed(indexed) => {
// TODO: check if target is indexable and can be indexed with given type if let Self::Identifier(ident) = indexed.object().as_ref() {
indexed.object().analyze_semantics(scope, handler)?; let variable_type = scope.get_variable(ident.span.str());
indexed.index().analyze_semantics(scope, handler) match variable_type {
Some(VariableType::BooleanStorageArray | VariableType::ScoreboardArray) => {
if !indexed
.index()
.can_yield_type_semantics(ValueType::Integer, scope)
{
let err = error::Error::IllegalIndexing(IllegalIndexing {
reason: IllegalIndexingReason::InvalidComptimeType {
expected: ExpectedType::Integer,
},
expression: indexed.index().span(),
});
handler.receive(err.clone());
return Err(err);
}
}
Some(VariableType::Tag | VariableType::Scoreboard) => {
if !indexed
.index()
.can_yield_type_semantics(ValueType::String, scope)
{
let err = error::Error::IllegalIndexing(IllegalIndexing {
reason: IllegalIndexingReason::InvalidComptimeType {
expected: ExpectedType::String,
},
expression: indexed.index().span(),
});
handler.receive(err.clone());
return Err(err);
}
}
_ => {
let err = error::Error::IllegalIndexing(IllegalIndexing {
reason: IllegalIndexingReason::NotIndexable,
expression: indexed.object().span(),
});
handler.receive(err.clone());
return Err(err);
}
}
indexed.object().analyze_semantics(scope, handler)?;
indexed.index().analyze_semantics(scope, handler)
} else {
let err = error::Error::IllegalIndexing(IllegalIndexing {
reason: IllegalIndexingReason::NotIdentifier,
expression: indexed.object().span(),
});
handler.receive(err.clone());
Err(err)
}
} }
Self::Parenthesized(expr) => expr.analyze_semantics(scope, handler), Self::Parenthesized(expr) => expr.analyze_semantics(scope, handler),
Self::Prefix(prefixed) => match prefixed.operator() { Self::Prefix(prefixed) => match prefixed.operator() {
@ -730,10 +780,11 @@ impl Binary {
impl LuaCode { impl LuaCode {
#[expect(clippy::unused_self, clippy::unnecessary_wraps)] #[expect(clippy::unused_self, clippy::unnecessary_wraps)]
#[cfg_attr(feature = "lua", expect(unused_variables))]
fn analyze_semantics( fn analyze_semantics(
&self, &self,
_scope: &SemanticScope, _scope: &SemanticScope,
_handler: &impl Handler<base::Error>, handler: &impl Handler<base::Error>,
) -> Result<(), error::Error> { ) -> Result<(), error::Error> {
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(feature = "lua")] { if #[cfg(feature = "lua")] {

View File

@ -1,15 +1,8 @@
//! The expression transpiler. //! The expression transpiler.
use std::{fmt::Display, string::ToString, sync::Arc}; use std::{fmt::Display, string::ToString};
use super::{util::MacroString, Scope, VariableData}; use super::util::MacroString;
use crate::{
base::{self, Handler, VoidHandler},
lexical::token::MacroStringLiteralPart,
syntax::syntax_tree::expression::{
Binary, BinaryOperator, Expression, PrefixOperator, Primary,
},
};
#[cfg(feature = "shulkerbox")] #[cfg(feature = "shulkerbox")]
use enum_as_inner::EnumAsInner; use enum_as_inner::EnumAsInner;
@ -20,16 +13,22 @@ use shulkerbox::prelude::{Command, Condition, Execute};
#[cfg(feature = "shulkerbox")] #[cfg(feature = "shulkerbox")]
use super::{ use super::{
error::{IllegalIndexing, IllegalIndexingReason, MismatchedTypes, UnknownIdentifier}, error::{IllegalIndexing, IllegalIndexingReason, MismatchedTypes, UnknownIdentifier},
TranspileResult, Transpiler, Scope, TranspileResult, Transpiler, VariableData,
}; };
#[cfg(feature = "shulkerbox")] #[cfg(feature = "shulkerbox")]
use crate::{ use crate::{
base::source_file::SourceElement, base::{self, source_file::SourceElement, Handler, VoidHandler},
lexical::token::MacroStringLiteralPart,
syntax::syntax_tree::expression::{
Binary, BinaryOperator, Expression, PrefixOperator, Primary,
},
transpile::{ transpile::{
error::{FunctionArgumentsNotAllowed, MissingValue}, error::{FunctionArgumentsNotAllowed, MissingValue},
TranspileError, TranspileError,
}, },
}; };
#[cfg(feature = "shulkerbox")]
use std::sync::Arc;
/// Compile-time evaluated value /// Compile-time evaluated value
#[allow(missing_docs)] #[allow(missing_docs)]
@ -227,6 +226,7 @@ pub enum ExtendedCondition {
Comptime(bool), Comptime(bool),
} }
#[cfg(feature = "shulkerbox")]
impl Expression { impl Expression {
/// Returns whether the expression can yield a certain type. /// Returns whether the expression can yield a certain type.
#[must_use] #[must_use]
@ -251,6 +251,7 @@ impl Expression {
} }
} }
#[cfg(feature = "shulkerbox")]
impl Primary { impl Primary {
/// Returns whether the primary can yield a certain type. /// Returns whether the primary can yield a certain type.
#[must_use] #[must_use]
@ -386,6 +387,7 @@ impl Primary {
} }
} }
#[cfg(feature = "shulkerbox")]
impl Binary { impl Binary {
/// Returns whether the binary can yield a certain type. /// Returns whether the binary can yield a certain type.
#[must_use] #[must_use]

View File

@ -1,6 +1,6 @@
//! Executes the Lua code and returns the resulting command. //! Executes the Lua code and returns the resulting command.
#[cfg(feature = "lua")] #[cfg(all(feature = "lua", feature = "shulkerbox"))]
mod enabled { mod enabled {
use std::sync::Arc; use std::sync::Arc;
@ -378,7 +378,7 @@ mod enabled {
} }
} }
#[cfg(not(feature = "lua"))] #[cfg(all(not(feature = "lua"), feature = "shulkerbox"))]
mod disabled { mod disabled {
use std::sync::Arc; use std::sync::Arc;

View File

@ -38,9 +38,12 @@ pub mod internal_functions;
#[doc(hidden)] #[doc(hidden)]
#[cfg(feature = "shulkerbox")] #[cfg(feature = "shulkerbox")]
pub mod function; pub mod function;
#[doc(inline)]
#[cfg(feature = "shulkerbox")]
pub use function::TranspiledFunctionArguments; pub use function::TranspiledFunctionArguments;
mod variables; mod variables;
#[cfg(feature = "shulkerbox")]
pub use variables::{Scope, VariableData}; pub use variables::{Scope, VariableData};
pub mod util; pub mod util;

View File

@ -33,14 +33,14 @@ use super::{
MismatchedTypes, MismatchedTypes,
}, },
expression::{ComptimeValue, DataLocation, ExpectedType, StorageType}, expression::{ComptimeValue, DataLocation, ExpectedType, StorageType},
internal_functions::InternalFunction,
FunctionData, TranspileAnnotationValue, TranspileError, TranspileResult, FunctionData, TranspileAnnotationValue, TranspileError, TranspileResult,
}; };
#[cfg(feature = "shulkerbox")] #[cfg(feature = "shulkerbox")]
use super::Transpiler; use super::{internal_functions::InternalFunction, Transpiler};
/// Stores the data required to access a variable. /// Stores the data required to access a variable.
#[cfg(feature = "shulkerbox")]
#[derive(Debug, Clone, EnumAsInner)] #[derive(Debug, Clone, EnumAsInner)]
pub enum VariableData { pub enum VariableData {
/// A function. /// A function.
@ -122,6 +122,7 @@ impl<'a> From<&'a AssignmentDestination> for TranspileAssignmentTarget<'a> {
} }
/// A scope that stores variables. /// A scope that stores variables.
#[cfg(feature = "shulkerbox")]
#[derive(Default)] #[derive(Default)]
pub struct Scope<'a> { pub struct Scope<'a> {
/// Parent scope where variables are inherited from. /// Parent scope where variables are inherited from.
@ -132,6 +133,7 @@ pub struct Scope<'a> {
shadowed: RwLock<HashMap<String, usize>>, shadowed: RwLock<HashMap<String, usize>>,
} }
#[cfg(feature = "shulkerbox")]
impl<'a> Scope<'a> { impl<'a> Scope<'a> {
/// Creates a new scope. /// Creates a new scope.
#[must_use] #[must_use]
@ -226,6 +228,7 @@ impl<'a> Scope<'a> {
} }
} }
#[cfg(feature = "shulkerbox")]
impl Debug for Scope<'_> { impl Debug for Scope<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
struct VariableWrapper<'a>(&'a RwLock<HashMap<String, Arc<VariableData>>>); struct VariableWrapper<'a>(&'a RwLock<HashMap<String, Arc<VariableData>>>);

View File

@ -107,7 +107,7 @@ pub fn identifier_to_scoreboard_target(ident: &str) -> std::borrow::Cow<str> {
let new_ident = ident let new_ident = ident
.chars() .chars()
.map(|c| { .map(|c| {
if *c != '_' && !c.is_ascii_alphanumeric() { if c != '_' && !c.is_ascii_alphanumeric() {
'_' '_'
} else { } else {
c c