Worked on semantics for graphs
This commit is contained in:
parent
02c10b48f4
commit
72461740eb
147
compiler.py
147
compiler.py
|
@ -741,6 +741,24 @@ class InlineAnimation:
|
|||
@property
|
||||
def file_info(self) -> FileInfo: return self._file_info
|
||||
|
||||
@property
|
||||
def range_start(self) -> Expression: return self._range_start
|
||||
|
||||
@property
|
||||
def range_start_inclusive(self) -> bool: return self._range_start_inclusive
|
||||
|
||||
@property
|
||||
def range_end(self) -> Expression: return self._range_end
|
||||
|
||||
@property
|
||||
def range_end_inclusive(self) -> bool: return self._range_end_inclusive
|
||||
|
||||
@property
|
||||
def step(self) -> Expression: return self._step
|
||||
|
||||
@property
|
||||
def direction(self) -> AnimationDirection: return self._direction
|
||||
|
||||
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
||||
s: str = f"{pre} Inline Animation\n"
|
||||
s += f"{pre_cont}├─ Range Start \
|
||||
|
@ -1850,6 +1868,19 @@ class UnderDefinedConstantDefinition(SemanticError):
|
|||
)
|
||||
|
||||
|
||||
class InvalidGraphDefinition(SemanticError): pass
|
||||
|
||||
|
||||
class MultipleAnimationsInGraph(InvalidGraphDefinition):
|
||||
|
||||
def __init__(self, file_info: FileInfo, file_info_context: FileInfo | None):
|
||||
super().__init__(
|
||||
"Only one animation is allowed in a graph.",
|
||||
file_info,
|
||||
file_info_context,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class GraphRuntimeError(CompilerError):
|
||||
|
||||
|
@ -2250,6 +2281,7 @@ class ContextFunction:
|
|||
|
||||
class ContextAnimation:
|
||||
|
||||
_file_info: FileInfo
|
||||
_current: int | float
|
||||
_range_start: ContextExpression
|
||||
_range_start_inclusive: bool
|
||||
|
@ -2261,6 +2293,7 @@ class ContextAnimation:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
file_info: FileInfo,
|
||||
start_value: int | float,
|
||||
range_start: ContextExpression,
|
||||
range_start_inclusive: bool,
|
||||
|
@ -2269,6 +2302,7 @@ class ContextAnimation:
|
|||
step: ContextExpression,
|
||||
direction: AnimationDirection,
|
||||
):
|
||||
self._file_info = file_info
|
||||
self._current = start_value
|
||||
self._range_start = range_start
|
||||
self._range_start_inclusive = range_start_inclusive
|
||||
|
@ -2278,6 +2312,9 @@ class ContextAnimation:
|
|||
self._direction = direction
|
||||
self._reversed = direction == AnimationDirection.Decrease
|
||||
|
||||
@property
|
||||
def file_info(self) -> FileInfo: return self._file_info
|
||||
|
||||
def step(self, context: ContextNamespace) -> int | float:
|
||||
if self._direction == AnimationDirection.Increase or (
|
||||
self._direction == AnimationDirection.Bounce and not self._reversed
|
||||
|
@ -2672,6 +2709,35 @@ def _simplify_expression(
|
|||
else: raise SemanticError("Expression Error", expression.file_info)
|
||||
|
||||
|
||||
def _simplify_animation(
|
||||
animation: Animation | InlineAnimation,
|
||||
constants: dict[str, ContextLiteral],
|
||||
functions: dict[str, ContextFunctionCallable],
|
||||
) -> ContextAnimation:
|
||||
range_start = _simplify_expression(
|
||||
animation.range_start, constants, functions, True)
|
||||
if not isinstance(range_start, ContextLiteral):
|
||||
raise UnderDefinedConstantDefinition(
|
||||
animation.range_start.file_info, None)
|
||||
start_value = float(range_start._value)
|
||||
range_end = _simplify_expression(
|
||||
animation.range_end, constants, functions, True)
|
||||
if not isinstance(range_end, ContextLiteral):
|
||||
raise UnderDefinedConstantDefinition(
|
||||
animation.range_end.file_info, None)
|
||||
step = _simplify_expression(animation.step, constants, functions, True)
|
||||
if not isinstance(step, ContextLiteral):
|
||||
raise UnderDefinedConstantDefinition(animation.step.file_info, None)
|
||||
return ContextAnimation(
|
||||
start_value,
|
||||
range_start,
|
||||
animation.range_start_inclusive,
|
||||
range_end,
|
||||
animation.range_end_inclusive,
|
||||
step,
|
||||
animation.direction,
|
||||
)
|
||||
|
||||
def semantics_analyzer(file: File) -> Context:
|
||||
screen: Screen | None = None
|
||||
constants: dict[str, ContextLiteral] = {}
|
||||
|
@ -2703,43 +2769,8 @@ def semantics_analyzer(file: File) -> Context:
|
|||
raise UnderDefinedConstantDefinition(child.file_info, None)
|
||||
constants[child.identifier.value] = value
|
||||
elif isinstance(child, Animation):
|
||||
range_start = _simplify_expression(
|
||||
child.range_start,
|
||||
constants,
|
||||
functions,
|
||||
True,
|
||||
)
|
||||
if not isinstance(range_start, ContextLiteral):
|
||||
raise UnderDefinedConstantDefinition(
|
||||
child.range_start.file_info, None)
|
||||
start_value = float(range_start._value)
|
||||
range_end = _simplify_expression(
|
||||
child.range_end,
|
||||
constants,
|
||||
functions,
|
||||
True,
|
||||
)
|
||||
if not isinstance(range_end, ContextLiteral):
|
||||
raise UnderDefinedConstantDefinition(
|
||||
child.range_end.file_info, None)
|
||||
step = _simplify_expression(
|
||||
child.step,
|
||||
constants,
|
||||
functions,
|
||||
True,
|
||||
)
|
||||
if not isinstance(step, ContextLiteral):
|
||||
raise UnderDefinedConstantDefinition(
|
||||
child.step.file_info, None)
|
||||
animations[child.identifier.value] = ContextAnimation(
|
||||
start_value,
|
||||
range_start,
|
||||
child.range_start_inclusive,
|
||||
range_end,
|
||||
child.range_end_inclusive,
|
||||
step,
|
||||
child.direction,
|
||||
)
|
||||
animations[child.identifier.value] = _simplify_animation(
|
||||
child, constants, functions)
|
||||
elif isinstance(child, Graph):
|
||||
x = None
|
||||
y = None
|
||||
|
@ -2756,23 +2787,27 @@ def semantics_analyzer(file: File) -> Context:
|
|||
color_luminosity = None
|
||||
if child.x is not None:
|
||||
if isinstance(child.x, InlineAnimation):
|
||||
pass
|
||||
x = _simplify_animation(
|
||||
child.x, constants, functions)
|
||||
else:
|
||||
x = _simplify_expression(
|
||||
child.x, constants, functions, True)
|
||||
if child.y is not None:
|
||||
if isinstance(child.y, InlineAnimation):
|
||||
pass
|
||||
y = _simplify_animation(
|
||||
child.y, constants, functions)
|
||||
else:
|
||||
y = _simplify_expression(
|
||||
child.y, constants, functions, True)
|
||||
if child.t is not None:
|
||||
pass
|
||||
t = _simplify_animation(
|
||||
child.t, constants, functions)
|
||||
if child.r is not None:
|
||||
r = _simplify_expression(
|
||||
child.r, constants, functions, True)
|
||||
if child.theta is not None:
|
||||
pass
|
||||
theta = _simplify_animation(
|
||||
child.theta, constants, functions)
|
||||
if child.color_alpha is not None:
|
||||
color_alpha = _simplify_expression(
|
||||
child.color_alpha, constants, functions, True)
|
||||
|
@ -2797,6 +2832,36 @@ def semantics_analyzer(file: File) -> Context:
|
|||
if child.color_luminosity is not None:
|
||||
color_luminosity = _simplify_expression(
|
||||
child.color_luminosity, constants, functions, True)
|
||||
|
||||
if isinstance(x, ContextAnimation):
|
||||
for i in [y, t, theta]:
|
||||
if isinstance(i, ContextAnimation):
|
||||
raise MultipleAnimationsInGraph(
|
||||
i.file_info,
|
||||
child.file_info
|
||||
)
|
||||
for i, j in [(t, 'T'),(r, 'R'),(theta, 'θ')]:
|
||||
if i is not None:
|
||||
raise InvalidGraphDefinition(
|
||||
f"{j} cannot be defined in an X-Independent Graph",
|
||||
i.file_info,
|
||||
child.file_info
|
||||
)
|
||||
if isinstance(y, ContextAnimation):
|
||||
for i in [t, theta]:
|
||||
if isinstance(i, ContextAnimation):
|
||||
raise MultipleAnimationsInGraph(
|
||||
i.file_info,
|
||||
child.file_info
|
||||
)
|
||||
for i, j in [(t, 'T'),(r, 'R'),(theta, 'θ')]:
|
||||
if i is not None:
|
||||
raise InvalidGraphDefinition(
|
||||
f"{j} cannot be defined in an Y-Independent Graph",
|
||||
i.file_info,
|
||||
child.file_info
|
||||
)
|
||||
|
||||
graphs.append(ContextGraph(
|
||||
x, y, t, r, theta, color_alpha, color_grey, color_red,
|
||||
color_green, color_blue, color_hue, color_saturation,
|
||||
|
|
Loading…
Reference in New Issue