implement rest of member access transpilation
This commit is contained in:
parent
927b0f52c1
commit
6e27474da4
|
@ -338,6 +338,11 @@ impl SourceElement for Tag {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parser<'_> {
|
impl Parser<'_> {
|
||||||
|
/// Parses a declaration
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// - cannot parse declaration from current position
|
||||||
|
#[expect(clippy::too_many_lines)]
|
||||||
#[tracing::instrument(level = "trace", skip_all)]
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
pub fn parse_declaration(
|
pub fn parse_declaration(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -94,6 +94,9 @@ impl Namespace {
|
||||||
|
|
||||||
impl Parser<'_> {
|
impl Parser<'_> {
|
||||||
/// Parses a [`ProgramFile`].
|
/// Parses a [`ProgramFile`].
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// - cannot parse a program file from current position
|
||||||
#[tracing::instrument(level = "debug", skip_all)]
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
pub fn parse_program(
|
pub fn parse_program(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -854,6 +854,9 @@ impl Parser<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a [`Statement`].
|
/// Parses a [`Statement`].
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// - cannot parse a [`Statement`] from current position
|
||||||
#[tracing::instrument(level = "trace", skip_all)]
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
pub fn parse_statement(
|
pub fn parse_statement(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -919,6 +922,9 @@ impl Parser<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a [`Semicolon`].
|
/// Parses a [`Semicolon`].
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// - cannot parse [`Semicolon`] from current position
|
||||||
#[tracing::instrument(level = "trace", skip_all)]
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
pub fn parse_semicolon(
|
pub fn parse_semicolon(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -994,6 +1000,10 @@ impl Parser<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a [`VariableDeclaration`].
|
/// Parses a [`VariableDeclaration`].
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// - cannot parse variable declaration from current position
|
||||||
|
#[expect(clippy::too_many_lines)]
|
||||||
#[tracing::instrument(level = "trace", skip_all)]
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
pub fn parse_variable_declaration(
|
pub fn parse_variable_declaration(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -17,11 +17,11 @@ use super::{
|
||||||
},
|
},
|
||||||
Scope, TranspileResult, Transpiler, VariableData,
|
Scope, TranspileResult, Transpiler, VariableData,
|
||||||
};
|
};
|
||||||
use crate::lexical::token::{Identifier, StringLiteral};
|
use crate::syntax::syntax_tree::expression::{Indexed, Parenthesized};
|
||||||
#[cfg(feature = "shulkerbox")]
|
#[cfg(feature = "shulkerbox")]
|
||||||
use crate::{
|
use crate::{
|
||||||
base::{self, source_file::SourceElement, Handler, VoidHandler},
|
base::{self, source_file::SourceElement, Handler, VoidHandler},
|
||||||
lexical::token::MacroStringLiteralPart,
|
lexical::token::{Identifier, MacroStringLiteralPart, StringLiteral},
|
||||||
syntax::syntax_tree::expression::{
|
syntax::syntax_tree::expression::{
|
||||||
Binary, BinaryOperator, Expression, MemberAccess, PrefixOperator, Primary,
|
Binary, BinaryOperator, Expression, MemberAccess, PrefixOperator, Primary,
|
||||||
},
|
},
|
||||||
|
@ -320,9 +320,7 @@ impl Primary {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::MemberAccess(_) => {
|
Self::MemberAccess(member_access) => member_access.can_yield_type(r#type, scope),
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
#[cfg_attr(not(feature = "lua"), expect(unused_variables))]
|
#[cfg_attr(not(feature = "lua"), expect(unused_variables))]
|
||||||
Self::Lua(lua) => {
|
Self::Lua(lua) => {
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
|
@ -429,7 +427,7 @@ impl Primary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn comptime_member_access(
|
pub(super) fn comptime_member_access(
|
||||||
&self,
|
&self,
|
||||||
member_access: &MemberAccess,
|
member_access: &MemberAccess,
|
||||||
scope: &Arc<Scope>,
|
scope: &Arc<Scope>,
|
||||||
|
@ -438,12 +436,53 @@ impl Primary {
|
||||||
match self {
|
match self {
|
||||||
Self::StringLiteral(s) => s.comptime_member_access(member_access, scope, handler),
|
Self::StringLiteral(s) => s.comptime_member_access(member_access, scope, handler),
|
||||||
Self::Identifier(ident) => ident.comptime_member_access(member_access, scope, handler),
|
Self::Identifier(ident) => ident.comptime_member_access(member_access, scope, handler),
|
||||||
|
Self::Indexed(idx) => idx.comptime_member_access(member_access, scope, handler),
|
||||||
|
Self::Parenthesized(paren) => {
|
||||||
|
paren.comptime_member_access(member_access, scope, handler)
|
||||||
|
}
|
||||||
|
|
||||||
_ => todo!(),
|
Self::Boolean(_)
|
||||||
|
| Self::FunctionCall(_)
|
||||||
|
| Self::Integer(_)
|
||||||
|
| Self::Lua(_)
|
||||||
|
| Self::MacroStringLiteral(_)
|
||||||
|
| Self::MemberAccess(_)
|
||||||
|
| Self::Prefix(_) => Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member_access_can_yield_type(
|
||||||
|
&self,
|
||||||
|
member_access: &MemberAccess,
|
||||||
|
r#type: ValueType,
|
||||||
|
scope: &Arc<Scope>,
|
||||||
|
) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::StringLiteral(_) => {
|
||||||
|
StringLiteral::member_access_can_yield_type(member_access, r#type, scope)
|
||||||
|
}
|
||||||
|
Self::Identifier(ident) => {
|
||||||
|
ident.member_access_can_yield_type(member_access, r#type, scope)
|
||||||
|
}
|
||||||
|
Self::Indexed(idx) => idx.member_access_can_yield_type(member_access, r#type, scope),
|
||||||
|
Self::Parenthesized(paren) => {
|
||||||
|
paren.member_access_can_yield_type(member_access, r#type, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Boolean(_)
|
||||||
|
| Self::FunctionCall(_)
|
||||||
|
| Self::Integer(_)
|
||||||
|
| Self::Lua(_)
|
||||||
|
| Self::MacroStringLiteral(_)
|
||||||
|
| Self::MemberAccess(_)
|
||||||
|
| Self::Prefix(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "shulkerbox")]
|
||||||
impl StringLiteral {
|
impl StringLiteral {
|
||||||
fn comptime_member_access(
|
fn comptime_member_access(
|
||||||
&self,
|
&self,
|
||||||
|
@ -461,8 +500,20 @@ impl StringLiteral {
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn member_access_can_yield_type(
|
||||||
|
member_access: &MemberAccess,
|
||||||
|
r#type: ValueType,
|
||||||
|
_scope: &Arc<Scope>,
|
||||||
|
) -> bool {
|
||||||
|
match member_access.member().span.str() {
|
||||||
|
"length" => r#type == ValueType::Integer,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "shulkerbox")]
|
||||||
impl Identifier {
|
impl Identifier {
|
||||||
#[expect(clippy::too_many_lines)]
|
#[expect(clippy::too_many_lines)]
|
||||||
fn comptime_member_access(
|
fn comptime_member_access(
|
||||||
|
@ -598,6 +649,248 @@ impl Identifier {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn member_access_can_yield_type(
|
||||||
|
&self,
|
||||||
|
member_access: &MemberAccess,
|
||||||
|
r#type: ValueType,
|
||||||
|
scope: &Arc<Scope>,
|
||||||
|
) -> bool {
|
||||||
|
scope
|
||||||
|
.get_variable(self.span.str())
|
||||||
|
.is_some_and(|data| match data.as_ref() {
|
||||||
|
VariableData::ComptimeValue { value, .. } => {
|
||||||
|
let value = value.read().unwrap();
|
||||||
|
value.as_ref().is_some_and(|value| match value {
|
||||||
|
ComptimeValue::String(_) => match member_access.member().span.str() {
|
||||||
|
"length" => r#type == ValueType::Integer,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
VariableData::BooleanStorage { .. } => match member_access.member().span.str() {
|
||||||
|
"path" | "storage" => r#type == ValueType::String,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
VariableData::BooleanStorageArray { .. } => {
|
||||||
|
match member_access.member().span.str() {
|
||||||
|
"storage" => r#type == ValueType::String,
|
||||||
|
#[expect(clippy::match_same_arms)]
|
||||||
|
"paths" => {
|
||||||
|
// TODO: implement when comptime arrays are implemented
|
||||||
|
false
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VariableData::Function { .. } => match member_access.member().span.str() {
|
||||||
|
"path" => r#type == ValueType::String,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
VariableData::InternalFunction { .. } => false,
|
||||||
|
VariableData::MacroParameter { .. } | VariableData::Tag { .. } => {
|
||||||
|
match member_access.member().span.str() {
|
||||||
|
"name" => r#type == ValueType::String,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VariableData::Scoreboard { .. } => match member_access.member().span.str() {
|
||||||
|
"objective" => r#type == ValueType::String,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
VariableData::ScoreboardArray { .. } => {
|
||||||
|
match member_access.member().span.str() {
|
||||||
|
"objective" => r#type == ValueType::String,
|
||||||
|
#[expect(clippy::match_same_arms)]
|
||||||
|
"targets" => {
|
||||||
|
// TODO: implement when comptime arrays are implemented
|
||||||
|
false
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VariableData::ScoreboardValue { .. } => match member_access.member().span.str() {
|
||||||
|
"target" | "objective" => r#type == ValueType::String,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "shulkerbox")]
|
||||||
|
impl Indexed {
|
||||||
|
fn comptime_member_access(
|
||||||
|
&self,
|
||||||
|
member_access: &MemberAccess,
|
||||||
|
scope: &Arc<Scope>,
|
||||||
|
handler: &impl Handler<base::Error>,
|
||||||
|
) -> Result<ComptimeValue, NotComptime> {
|
||||||
|
match self.object().as_ref() {
|
||||||
|
Primary::Identifier(ident) => scope.get_variable(ident.span.str()).map_or_else(
|
||||||
|
|| {
|
||||||
|
Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|data| match data.as_ref() {
|
||||||
|
VariableData::BooleanStorageArray {
|
||||||
|
storage_name,
|
||||||
|
paths,
|
||||||
|
} => {
|
||||||
|
if let Ok(ComptimeValue::Integer(idx)) =
|
||||||
|
self.index().comptime_eval(scope, handler)
|
||||||
|
{
|
||||||
|
usize::try_from(idx).map_or_else(
|
||||||
|
|_| {
|
||||||
|
Err(NotComptime {
|
||||||
|
expression: self.index().span(),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|idx| {
|
||||||
|
paths.get(idx).map_or_else(
|
||||||
|
|| {
|
||||||
|
Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|path| match member_access.member().span.str() {
|
||||||
|
"storage" => {
|
||||||
|
Ok(ComptimeValue::String(storage_name.to_owned()))
|
||||||
|
}
|
||||||
|
"path" => Ok(ComptimeValue::String(path.to_owned())),
|
||||||
|
_ => Err(NotComptime {
|
||||||
|
expression: member_access.member().span(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Err(NotComptime {
|
||||||
|
expression: self.index().span(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VariableData::ScoreboardArray { objective, targets } => {
|
||||||
|
if let Ok(ComptimeValue::Integer(idx)) =
|
||||||
|
self.index().comptime_eval(scope, handler)
|
||||||
|
{
|
||||||
|
usize::try_from(idx).map_or_else(
|
||||||
|
|_| {
|
||||||
|
Err(NotComptime {
|
||||||
|
expression: self.index().span(),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|idx| {
|
||||||
|
targets.get(idx).map_or_else(
|
||||||
|
|| {
|
||||||
|
Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|target| match member_access.member().span.str() {
|
||||||
|
"objective" => {
|
||||||
|
Ok(ComptimeValue::String(objective.to_owned()))
|
||||||
|
}
|
||||||
|
"target" => {
|
||||||
|
Ok(ComptimeValue::String(target.to_owned()))
|
||||||
|
}
|
||||||
|
_ => Err(NotComptime {
|
||||||
|
expression: member_access.member().span(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Err(NotComptime {
|
||||||
|
expression: self.index().span(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
_ => Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member_access_can_yield_type(
|
||||||
|
&self,
|
||||||
|
member_access: &MemberAccess,
|
||||||
|
r#type: ValueType,
|
||||||
|
scope: &Arc<Scope>,
|
||||||
|
) -> bool {
|
||||||
|
match self.object().as_ref() {
|
||||||
|
Primary::Identifier(ident) => {
|
||||||
|
scope
|
||||||
|
.get_variable(ident.span.str())
|
||||||
|
.is_some_and(|data| match data.as_ref() {
|
||||||
|
VariableData::BooleanStorageArray { .. } => {
|
||||||
|
matches!(r#type, ValueType::String)
|
||||||
|
&& matches!(member_access.member().span.str(), "storage" | "path")
|
||||||
|
&& self.index().can_yield_type(ValueType::Integer, scope)
|
||||||
|
}
|
||||||
|
VariableData::ScoreboardArray { .. } => {
|
||||||
|
matches!(r#type, ValueType::String)
|
||||||
|
&& matches!(
|
||||||
|
member_access.member().span.str(),
|
||||||
|
"objective" | "target"
|
||||||
|
)
|
||||||
|
&& self.index().can_yield_type(ValueType::Integer, scope)
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "shulkerbox")]
|
||||||
|
impl Parenthesized {
|
||||||
|
fn comptime_member_access(
|
||||||
|
&self,
|
||||||
|
member_access: &MemberAccess,
|
||||||
|
scope: &Arc<Scope>,
|
||||||
|
handler: &impl Handler<base::Error>,
|
||||||
|
) -> Result<ComptimeValue, NotComptime> {
|
||||||
|
match self.expression().as_ref() {
|
||||||
|
Expression::Primary(prim) => prim.comptime_member_access(member_access, scope, handler),
|
||||||
|
Expression::Binary(bin) => bin.comptime_member_access(member_access, scope, handler),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member_access_can_yield_type(
|
||||||
|
&self,
|
||||||
|
member_access: &MemberAccess,
|
||||||
|
r#type: ValueType,
|
||||||
|
scope: &Arc<Scope>,
|
||||||
|
) -> bool {
|
||||||
|
match self.expression().as_ref() {
|
||||||
|
Expression::Primary(prim) => {
|
||||||
|
prim.member_access_can_yield_type(member_access, r#type, scope)
|
||||||
|
}
|
||||||
|
Expression::Binary(bin) => {
|
||||||
|
bin.member_access_can_yield_type(member_access, r#type, scope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "shulkerbox")]
|
||||||
|
impl MemberAccess {
|
||||||
|
/// Returns whether the member access can yield a certain type.
|
||||||
|
#[must_use]
|
||||||
|
pub fn can_yield_type(&self, r#type: ValueType, scope: &Arc<Scope>) -> bool {
|
||||||
|
self.parent()
|
||||||
|
.member_access_can_yield_type(self, r#type, scope)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "shulkerbox")]
|
#[cfg(feature = "shulkerbox")]
|
||||||
|
@ -748,6 +1041,56 @@ impl Binary {
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn comptime_member_access(
|
||||||
|
&self,
|
||||||
|
member_access: &MemberAccess,
|
||||||
|
scope: &Arc<Scope>,
|
||||||
|
handler: &impl Handler<base::Error>,
|
||||||
|
) -> Result<ComptimeValue, NotComptime> {
|
||||||
|
match self.operator() {
|
||||||
|
BinaryOperator::Add(_) => match self.comptime_eval(scope, handler)? {
|
||||||
|
ComptimeValue::String(s) => match member_access.member().span.str() {
|
||||||
|
"length" => i64::try_from(s.len()).map_or_else(
|
||||||
|
|_| {
|
||||||
|
Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|len| Ok(ComptimeValue::Integer(len)),
|
||||||
|
),
|
||||||
|
_ => Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(NotComptime {
|
||||||
|
expression: self.span(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member_access_can_yield_type(
|
||||||
|
&self,
|
||||||
|
member_access: &MemberAccess,
|
||||||
|
r#type: ValueType,
|
||||||
|
scope: &Arc<Scope>,
|
||||||
|
) -> bool {
|
||||||
|
match self.operator() {
|
||||||
|
BinaryOperator::Add(_) => {
|
||||||
|
r#type == ValueType::Integer
|
||||||
|
&& member_access.member().span.str() == "length"
|
||||||
|
&& self.left_operand().can_yield_type(ValueType::String, scope)
|
||||||
|
&& self
|
||||||
|
.right_operand()
|
||||||
|
.can_yield_type(ValueType::String, scope)
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "shulkerbox")]
|
#[cfg(feature = "shulkerbox")]
|
||||||
|
@ -878,7 +1221,13 @@ impl Transpiler {
|
||||||
Primary::Parenthesized(parenthesized) => {
|
Primary::Parenthesized(parenthesized) => {
|
||||||
self.transpile_expression(parenthesized.expression(), target, scope, handler)
|
self.transpile_expression(parenthesized.expression(), target, scope, handler)
|
||||||
}
|
}
|
||||||
Primary::MemberAccess(_) => todo!(),
|
Primary::MemberAccess(member_access) => member_access
|
||||||
|
.parent()
|
||||||
|
.comptime_member_access(member_access, scope, handler)
|
||||||
|
.map_or_else(
|
||||||
|
|_| todo!("implement non-comptime member access"),
|
||||||
|
|value| self.store_comptime_value(&value, target, member_access, handler),
|
||||||
|
),
|
||||||
Primary::Lua(lua) =>
|
Primary::Lua(lua) =>
|
||||||
{
|
{
|
||||||
#[expect(clippy::option_if_let_else)]
|
#[expect(clippy::option_if_let_else)]
|
||||||
|
@ -1441,7 +1790,35 @@ impl Transpiler {
|
||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Primary::MemberAccess(_) => todo!(),
|
Primary::MemberAccess(member_access) => member_access
|
||||||
|
.parent()
|
||||||
|
.comptime_member_access(member_access, scope, handler)
|
||||||
|
.map_or_else(
|
||||||
|
|_| todo!("implement non-comptime member access"),
|
||||||
|
|value| match value {
|
||||||
|
ComptimeValue::Boolean(b) => {
|
||||||
|
Ok((Vec::new(), ExtendedCondition::Comptime(b)))
|
||||||
|
}
|
||||||
|
ComptimeValue::Integer(_) => {
|
||||||
|
let err = TranspileError::MismatchedTypes(MismatchedTypes {
|
||||||
|
expected_type: ExpectedType::Boolean,
|
||||||
|
expression: primary.span(),
|
||||||
|
});
|
||||||
|
handler.receive(err.clone());
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
ComptimeValue::String(s) => Ok((
|
||||||
|
Vec::new(),
|
||||||
|
ExtendedCondition::Runtime(Condition::Atom(
|
||||||
|
MacroString::String(s).into(),
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
ComptimeValue::MacroString(s) => Ok((
|
||||||
|
Vec::new(),
|
||||||
|
ExtendedCondition::Runtime(Condition::Atom(s.into())),
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
),
|
||||||
Primary::Prefix(prefix) => match prefix.operator() {
|
Primary::Prefix(prefix) => match prefix.operator() {
|
||||||
PrefixOperator::LogicalNot(_) => {
|
PrefixOperator::LogicalNot(_) => {
|
||||||
let (cmds, cond) = self.transpile_primary_expression_as_condition(
|
let (cmds, cond) = self.transpile_primary_expression_as_condition(
|
||||||
|
|
|
@ -39,6 +39,7 @@ pub enum TranspiledFunctionArguments {
|
||||||
impl Transpiler {
|
impl Transpiler {
|
||||||
/// Gets the function at the given path, or transpiles it if it hasn't been transpiled yet.
|
/// Gets the function at the given path, or transpiles it if it hasn't been transpiled yet.
|
||||||
/// Returns the location of the function or None if the function does not exist.
|
/// Returns the location of the function or None if the function does not exist.
|
||||||
|
#[expect(clippy::too_many_lines)]
|
||||||
#[tracing::instrument(level = "trace", skip(self, handler))]
|
#[tracing::instrument(level = "trace", skip(self, handler))]
|
||||||
pub(super) fn get_or_transpile_function(
|
pub(super) fn get_or_transpile_function(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -357,7 +358,34 @@ impl Transpiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::Primary(Primary::MemberAccess(_)) => todo!(),
|
Expression::Primary(Primary::MemberAccess(member_access)) => {
|
||||||
|
if let Ok(value) = member_access.parent().comptime_member_access(
|
||||||
|
member_access,
|
||||||
|
scope,
|
||||||
|
handler,
|
||||||
|
) {
|
||||||
|
Ok(Parameter::Static(value.to_macro_string()))
|
||||||
|
} else {
|
||||||
|
let (storage_name, [path]) =
|
||||||
|
self.get_temp_storage_locations_array();
|
||||||
|
let prepare_cmds = self.transpile_expression(
|
||||||
|
expression,
|
||||||
|
&super::expression::DataLocation::Storage {
|
||||||
|
storage_name: storage_name.clone(),
|
||||||
|
path: path.clone(),
|
||||||
|
r#type: StorageType::Int,
|
||||||
|
},
|
||||||
|
scope,
|
||||||
|
handler,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(Parameter::Storage {
|
||||||
|
prepare_cmds,
|
||||||
|
storage_name,
|
||||||
|
path,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Expression::Primary(
|
Expression::Primary(
|
||||||
Primary::Parenthesized(_)
|
Primary::Parenthesized(_)
|
||||||
| Primary::Prefix(_)
|
| Primary::Prefix(_)
|
||||||
|
|
|
@ -68,6 +68,7 @@ impl Transpiler {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// - [`TranspileError::MissingFunctionDeclaration`] If a called function is missing
|
/// - [`TranspileError::MissingFunctionDeclaration`] If a called function is missing
|
||||||
|
#[expect(clippy::too_many_lines)]
|
||||||
#[tracing::instrument(level = "trace", skip_all)]
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
pub fn transpile(
|
pub fn transpile(
|
||||||
mut self,
|
mut self,
|
||||||
|
@ -622,7 +623,8 @@ impl Transpiler {
|
||||||
Primary::Integer(_)
|
Primary::Integer(_)
|
||||||
| Primary::Boolean(_)
|
| Primary::Boolean(_)
|
||||||
| Primary::Prefix(_)
|
| Primary::Prefix(_)
|
||||||
| Primary::Indexed(_) => {
|
| Primary::Indexed(_)
|
||||||
|
| Primary::MemberAccess(_) => {
|
||||||
let error = TranspileError::UnexpectedExpression(UnexpectedExpression(
|
let error = TranspileError::UnexpectedExpression(UnexpectedExpression(
|
||||||
Expression::Primary(expression.clone()),
|
Expression::Primary(expression.clone()),
|
||||||
));
|
));
|
||||||
|
@ -653,8 +655,6 @@ impl Transpiler {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Primary::MemberAccess(_) => todo!(),
|
|
||||||
|
|
||||||
Primary::Parenthesized(parenthesized) => match parenthesized.expression().as_ref() {
|
Primary::Parenthesized(parenthesized) => match parenthesized.expression().as_ref() {
|
||||||
Expression::Primary(expression) => {
|
Expression::Primary(expression) => {
|
||||||
self.transpile_run_expression(expression, scope, handler)
|
self.transpile_run_expression(expression, scope, handler)
|
||||||
|
|
Loading…
Reference in New Issue