Skip to content

Commit

Permalink
feat: support new particle representation
Browse files Browse the repository at this point in the history
  • Loading branch information
vberlier committed Apr 10, 2024
1 parent 156b8e6 commit 23c576a
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 17 deletions.
4 changes: 2 additions & 2 deletions mecha/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ def from_value(cls, value: Any) -> "AstNbtPath":


@dataclass(frozen=True, slots=True)
class AstParticleParameters(AstNode):
class AstParticleParameters(AstNode): # legacy compat
"""Base ast node for particle parameters."""


Expand Down Expand Up @@ -1317,7 +1317,7 @@ class AstParticle(AstNode):
"""Ast particle node."""

name: AstResourceLocation = required_field()
parameters: Optional[AstParticleParameters] = None
parameters: Optional[Union[AstParticleParameters, AstNbtCompound]] = None

parser = "particle"

Expand Down
44 changes: 31 additions & 13 deletions mecha/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"parse_wildcard",
"parse_message",
"NbtPathParser",
"parse_particle",
"ParticleParser",
"AggregateParser",
"SingleLineConstraint",
"AlternativeParser",
Expand Down Expand Up @@ -355,7 +355,10 @@ def get_default_parsers() -> Dict[str, Parser]:
################################################################################
# Particle
################################################################################
"particle": parse_particle,
"particle": ParticleParser(
resource_location_parser=delegate("resource_location"),
generic_parameters_parser=delegate("nbt_compound"),
),
"particle:minecraft:dust": AggregateParser(
type=AstDustParticleParameters,
fields={
Expand Down Expand Up @@ -2034,19 +2037,34 @@ def parse_modifiers(self, stream: TokenStream) -> Iterator[Any]:
yield set_location(subscript_node, bracket, close_bracket)


def parse_particle(stream: TokenStream) -> AstParticle:
"""Parse particle."""
parameters = None
@dataclass
class ParticleParser:
resource_location_parser: Parser
generic_parameters_parser: Parser

def __call__(self, stream: TokenStream) -> AstParticle:
"""Parse particle."""
parameters = None

if isinstance(
name := self.resource_location_parser(stream), AstResourceLocation
):
with stream.syntax(hint=r"\{"), stream.intercept("whitespace"):
token = stream.peek()

if isinstance(name := delegate("resource_location", stream), AstResourceLocation):
try:
parameters = delegate(f"particle:{name.get_canonical_value()}", stream)
except UnrecognizedParser as exc:
if not exc.parser.startswith("particle:"):
raise
if token and token.match("hint"):
parameters = self.generic_parameters_parser(stream)
else:
try:
parameters = delegate(
f"particle:{name.get_canonical_value()}", stream
)
except UnrecognizedParser as exc:
if not exc.parser.startswith("particle:"):
raise

node = AstParticle(name=name, parameters=parameters)
return set_location(node, name, parameters if parameters else name)
node = AstParticle(name=name, parameters=parameters)
return set_location(node, name, parameters if parameters else name)


def parse_macro_line(stream: TokenStream) -> AstMacroLine:
Expand Down
10 changes: 9 additions & 1 deletion mecha/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
AstMessage,
AstNbt,
AstNbtBool,
AstNbtCompound,
AstNbtPath,
AstNbtPathKey,
AstNbtPathSubscript,
Expand Down Expand Up @@ -142,7 +143,6 @@ def unserializable(self, node: AstNode, result: List[str]):
@rule(AstVector2)
@rule(AstVector3)
@rule(AstParticleParameters)
@rule(AstParticle)
def aggregate(self, node: AstNode, result: List[str]):
sep = ""
for child in node:
Expand Down Expand Up @@ -389,6 +389,14 @@ def nbt_path(self, node: AstNbtPath, result: List[str]):
sep = "."
yield component

@rule(AstParticle)
def particle(self, node: AstParticle, result: List[str]):
yield node.name
if node.parameters:
if not isinstance(node.parameters, AstNbtCompound):
result.append(" ")
yield node.parameters

@rule(AstMacroLine)
def macro_line(self, node: AstMacroLine, result: List[str]):
result.append("$")
Expand Down
4 changes: 3 additions & 1 deletion tests/resources/argument_examples.json
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,9 @@
"item minecraft:apple{foo: bar}",
"vibration 5.0 64.0 0.0 200",
"sculk_charge 1.5707",
"shriek 100"
"shriek 100",
"minecraft:dust_color_transition{from_color: [1.0f, 0.0f, 0.0f], scale: 0.5f, to_color: [0.0f, 1.0f, 0.5f]}",
"minecraft:block{block_state: {Name: 'minecraft:redstone_lamp', Properties: {lit: 'true'}}}"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
minecraft:particle 0 11
---
{}
---
minecraft:dust_color_transition{from_color: [1.0f, 0.0f, 0.0f], scale: 0.5f, to_color: [0.0f, 1.0f, 0.5f]}
---
minecraft:dust_color_transition{from_color: [1.0f, 0.0f, 0.0f], scale: 0.5f, to_color: [0.0f, 1.0f, 0.5f]}
---
<class 'mecha.ast.AstParticle'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=106, lineno=1, colno=107)
name:
<class 'mecha.ast.AstResourceLocation'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=31, lineno=1, colno=32)
is_tag: False
namespace: 'minecraft'
path: 'dust_color_transition'
parameters:
<class 'mecha.ast.AstNbtCompound'>
location: SourceLocation(pos=31, lineno=1, colno=32)
end_location: SourceLocation(pos=106, lineno=1, colno=107)
entries:
<class 'mecha.ast.AstNbtCompoundEntry'>
location: SourceLocation(pos=32, lineno=1, colno=33)
end_location: SourceLocation(pos=62, lineno=1, colno=63)
key:
<class 'mecha.ast.AstNbtCompoundKey'>
location: SourceLocation(pos=32, lineno=1, colno=33)
end_location: SourceLocation(pos=42, lineno=1, colno=43)
value: 'from_color'
value:
<class 'mecha.ast.AstNbtList'>
location: SourceLocation(pos=44, lineno=1, colno=45)
end_location: SourceLocation(pos=62, lineno=1, colno=63)
elements:
<class 'mecha.ast.AstNbtValue'>
location: SourceLocation(pos=45, lineno=1, colno=46)
end_location: SourceLocation(pos=49, lineno=1, colno=50)
value: Float(1.0)
<class 'mecha.ast.AstNbtValue'>
location: SourceLocation(pos=51, lineno=1, colno=52)
end_location: SourceLocation(pos=55, lineno=1, colno=56)
value: Float(0.0)
<class 'mecha.ast.AstNbtValue'>
location: SourceLocation(pos=57, lineno=1, colno=58)
end_location: SourceLocation(pos=61, lineno=1, colno=62)
value: Float(0.0)
<class 'mecha.ast.AstNbtCompoundEntry'>
location: SourceLocation(pos=64, lineno=1, colno=65)
end_location: SourceLocation(pos=75, lineno=1, colno=76)
key:
<class 'mecha.ast.AstNbtCompoundKey'>
location: SourceLocation(pos=64, lineno=1, colno=65)
end_location: SourceLocation(pos=69, lineno=1, colno=70)
value: 'scale'
value:
<class 'mecha.ast.AstNbtValue'>
location: SourceLocation(pos=71, lineno=1, colno=72)
end_location: SourceLocation(pos=75, lineno=1, colno=76)
value: Float(0.5)
<class 'mecha.ast.AstNbtCompoundEntry'>
location: SourceLocation(pos=77, lineno=1, colno=78)
end_location: SourceLocation(pos=105, lineno=1, colno=106)
key:
<class 'mecha.ast.AstNbtCompoundKey'>
location: SourceLocation(pos=77, lineno=1, colno=78)
end_location: SourceLocation(pos=85, lineno=1, colno=86)
value: 'to_color'
value:
<class 'mecha.ast.AstNbtList'>
location: SourceLocation(pos=87, lineno=1, colno=88)
end_location: SourceLocation(pos=105, lineno=1, colno=106)
elements:
<class 'mecha.ast.AstNbtValue'>
location: SourceLocation(pos=88, lineno=1, colno=89)
end_location: SourceLocation(pos=92, lineno=1, colno=93)
value: Float(0.0)
<class 'mecha.ast.AstNbtValue'>
location: SourceLocation(pos=94, lineno=1, colno=95)
end_location: SourceLocation(pos=98, lineno=1, colno=99)
value: Float(1.0)
<class 'mecha.ast.AstNbtValue'>
location: SourceLocation(pos=100, lineno=1, colno=101)
end_location: SourceLocation(pos=104, lineno=1, colno=105)
value: Float(0.5)
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
minecraft:particle 0 12
---
{}
---
minecraft:block{block_state: {Name: 'minecraft:redstone_lamp', Properties: {lit: 'true'}}}
---
minecraft:block{block_state: {Name: "minecraft:redstone_lamp", Properties: {lit: "true"}}}
---
<class 'mecha.ast.AstParticle'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=90, lineno=1, colno=91)
name:
<class 'mecha.ast.AstResourceLocation'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=15, lineno=1, colno=16)
is_tag: False
namespace: 'minecraft'
path: 'block'
parameters:
<class 'mecha.ast.AstNbtCompound'>
location: SourceLocation(pos=15, lineno=1, colno=16)
end_location: SourceLocation(pos=90, lineno=1, colno=91)
entries:
<class 'mecha.ast.AstNbtCompoundEntry'>
location: SourceLocation(pos=16, lineno=1, colno=17)
end_location: SourceLocation(pos=89, lineno=1, colno=90)
key:
<class 'mecha.ast.AstNbtCompoundKey'>
location: SourceLocation(pos=16, lineno=1, colno=17)
end_location: SourceLocation(pos=27, lineno=1, colno=28)
value: 'block_state'
value:
<class 'mecha.ast.AstNbtCompound'>
location: SourceLocation(pos=29, lineno=1, colno=30)
end_location: SourceLocation(pos=89, lineno=1, colno=90)
entries:
<class 'mecha.ast.AstNbtCompoundEntry'>
location: SourceLocation(pos=30, lineno=1, colno=31)
end_location: SourceLocation(pos=61, lineno=1, colno=62)
key:
<class 'mecha.ast.AstNbtCompoundKey'>
location: SourceLocation(pos=30, lineno=1, colno=31)
end_location: SourceLocation(pos=34, lineno=1, colno=35)
value: 'Name'
value:
<class 'mecha.ast.AstNbtValue'>
location: SourceLocation(pos=36, lineno=1, colno=37)
end_location: SourceLocation(pos=61, lineno=1, colno=62)
value: String('minecraft:redstone_lamp')
<class 'mecha.ast.AstNbtCompoundEntry'>
location: SourceLocation(pos=63, lineno=1, colno=64)
end_location: SourceLocation(pos=88, lineno=1, colno=89)
key:
<class 'mecha.ast.AstNbtCompoundKey'>
location: SourceLocation(pos=63, lineno=1, colno=64)
end_location: SourceLocation(pos=73, lineno=1, colno=74)
value: 'Properties'
value:
<class 'mecha.ast.AstNbtCompound'>
location: SourceLocation(pos=75, lineno=1, colno=76)
end_location: SourceLocation(pos=88, lineno=1, colno=89)
entries:
<class 'mecha.ast.AstNbtCompoundEntry'>
location: SourceLocation(pos=76, lineno=1, colno=77)
end_location: SourceLocation(pos=87, lineno=1, colno=88)
key:
<class 'mecha.ast.AstNbtCompoundKey'>
location: SourceLocation(pos=76, lineno=1, colno=77)
end_location: SourceLocation(pos=79, lineno=1, colno=80)
value: 'lit'
value:
<class 'mecha.ast.AstNbtValue'>
location: SourceLocation(pos=81, lineno=1, colno=82)
end_location: SourceLocation(pos=87, lineno=1, colno=88)
value: String('true')

0 comments on commit 23c576a

Please sign in to comment.