Take price of choice references into account

This commit is contained in:
Midgard 2020-09-26 01:10:37 +02:00
parent a841be3c48
commit 6a052fae73
Signed by: midgard
GPG key ID: 511C112F1331BBB4

View file

@ -21,6 +21,12 @@ def filter_instance(cls, iterable):
return [item for item in iterable if isinstance(item, cls)] return [item for item in iterable if isinstance(item, cls)]
class ChoiceReference:
def __init__(self, identifier, price):
self.identifier = identifier
self.price = price
# pylint: disable=no-self-use # pylint: disable=no-self-use
class HldsSemanticActions: class HldsSemanticActions:
def location(self, ast) -> Location: def location(self, ast) -> Location:
@ -31,7 +37,16 @@ class HldsSemanticActions:
for dish in dishes: for dish in dishes:
for i, choice in enumerate(dish.choices): for i, choice in enumerate(dish.choices):
if not isinstance(choice[1], Choice): if not isinstance(choice[1], Choice):
dish.choices[i] = (dish.choices[i][0], deepcopy(choices[choice[1]])) choiceId, choiceRef = choice
assert isinstance(choiceRef, ChoiceReference)
# We must replace the ChoiceReference with the Choice it refers to. A deep copy
# allows us to modify the individual Options of the Choice.
choiceObject = deepcopy(choices[choiceRef.identifier])
for option in choiceObject.options:
option.price += choiceRef.price
dish.choices[i] = (choiceId, choiceObject)
# Move the base price to the first single_choice if the dish has a fixed price # Move the base price to the first single_choice if the dish has a fixed price
first_single_choice = first( first_single_choice = first(
@ -68,7 +83,7 @@ class HldsSemanticActions:
def choice_block(self, ast) -> Choice: def choice_block(self, ast) -> Choice:
if ast["price"] or ast["tags"]: if ast["price"] or ast["tags"]:
raise SemanticError( raise SemanticError(
"Choice blocks cannot have price or tags, put them on each of its options instead" "Choice block definitions cannot have price or tags, put them on each of its options instead"
) )
return Choice( return Choice(
@ -79,11 +94,14 @@ class HldsSemanticActions:
) )
def indent_choice_block(self, ast) -> Tuple[str, Union[Choice, AST]]: def indent_choice_block(self, ast) -> Tuple[str, Union[Choice, AST]]:
return ( if ast["kind"] == "declaration":
(ast["type"], self.choice_block(ast)) return (ast["type"], self.choice_block(ast))
if ast["kind"] == "declaration" else:
else (ast["type"], ast["id"]) if ast["type"] == "single_choice" and ast["price"]:
) raise SemanticError(
"Single_choice choices can't have a price, because it would always be triggered"
)
return (ast["type"], ChoiceReference(ast["id"], ast["price"] or 0))
def indent_choice_entry(self, ast) -> Option: def indent_choice_entry(self, ast) -> Option:
return Option( return Option(