@pineforge/codegen-pyodide 0.9.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/pineforge_codegen/__init__.py +3 -0
- package/pineforge_codegen/analyzer/base.py +3999 -140
- package/pineforge_codegen/analyzer/call_handlers.py +662 -48
- package/pineforge_codegen/analyzer/contracts.py +104 -7
- package/pineforge_codegen/analyzer/types.py +951 -14
- package/pineforge_codegen/codegen/base.py +2359 -249
- package/pineforge_codegen/codegen/drawing.py +94 -14
- package/pineforge_codegen/codegen/emit_top.py +732 -172
- package/pineforge_codegen/codegen/security.py +1456 -150
- package/pineforge_codegen/codegen/ta.py +435 -99
- package/pineforge_codegen/codegen/tables.py +224 -77
- package/pineforge_codegen/codegen/types.py +1196 -215
- package/pineforge_codegen/codegen/visit_call.py +1168 -99
- package/pineforge_codegen/codegen/visit_expr.py +354 -33
- package/pineforge_codegen/codegen/visit_stmt.py +1144 -200
- package/pineforge_codegen/finite_ta_length.py +798 -0
- package/pineforge_codegen/method_binding.py +163 -0
- package/pineforge_codegen/parser.py +48 -9
- package/pineforge_codegen/signatures.py +4 -4
- package/pineforge_codegen/support_checker.py +194 -19
- package/pineforge_codegen/symbols.py +65 -0
- package/pineforge_codegen-0.10.1.tar.gz +0 -0
- package/release.json +2 -2
- package/tables.json +9 -11
- package/pineforge_codegen-0.9.0.tar.gz +0 -0
|
@@ -20,7 +20,15 @@ reads only attributes established by ``CodeGen.__init__`` (``_uses_drawing``,
|
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
|
|
22
22
|
from ..ast_nodes import FuncCall, Identifier, MemberAccess
|
|
23
|
-
from
|
|
23
|
+
from ..symbols import method_receiver_type_name
|
|
24
|
+
from .tables import (
|
|
25
|
+
ARRAY_VOID_METHODS as _ARRAY_VOID_METHODS,
|
|
26
|
+
DRAWING_ARENA,
|
|
27
|
+
DRAWING_TYPE_TO_CPP,
|
|
28
|
+
MATRIX_VOID_METHODS as _MATRIX_VOID_METHODS,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
_MAP_VOID_METHODS = frozenset({"clear", "put_all"})
|
|
24
32
|
|
|
25
33
|
# ---------------------------------------------------------------------------
|
|
26
34
|
# Canonical Pine v6 constructor param-name lists (positional order).
|
|
@@ -478,26 +486,90 @@ class DrawingVisitor:
|
|
|
478
486
|
expression and so cannot be used as a function's return value / RHS.
|
|
479
487
|
|
|
480
488
|
Covers drawing setters/delete/visual-noop (delegated to
|
|
481
|
-
``_drawing_call_is_void``)
|
|
489
|
+
``_drawing_call_is_void``), the Pine array MUTATOR methods whose C++
|
|
482
490
|
lowering is void / an iterator (``array.push/insert/clear/set/fill/
|
|
483
|
-
sort/reverse/concat/unshift``)
|
|
484
|
-
|
|
485
|
-
|
|
491
|
+
sort/reverse/concat/unshift``), matrix mutators whose runtime lowering
|
|
492
|
+
returns void, and terminal map ``clear``/``put_all`` calls. A function
|
|
493
|
+
ending in one of these calls must emit it as a statement with a default
|
|
494
|
+
return, never ``return <void-expression>;``.
|
|
486
495
|
"""
|
|
487
|
-
if self._drawing_call_is_void(node):
|
|
488
|
-
return True
|
|
489
496
|
if not isinstance(node, FuncCall) or not isinstance(node.callee, MemberAccess):
|
|
490
497
|
return False
|
|
491
498
|
method = node.callee.member
|
|
492
|
-
|
|
493
|
-
|
|
499
|
+
direct_spec = self._type_spec_from_expr(node.callee.object)
|
|
500
|
+
direct_receiver_name = method_receiver_type_name(direct_spec)
|
|
501
|
+
direct_method_info = (
|
|
502
|
+
getattr(self, "_func_info_map", {}).get(
|
|
503
|
+
f"{direct_receiver_name}.{method}"
|
|
504
|
+
)
|
|
505
|
+
if direct_receiver_name is not None
|
|
506
|
+
else None
|
|
507
|
+
)
|
|
508
|
+
# Exact typed user methods have dispatch precedence over every builtin
|
|
509
|
+
# family. Resolve that once before drawing/array/matrix/map terminal
|
|
510
|
+
# classification, including when a parameter named after a namespace
|
|
511
|
+
# (for example ``array`` or ``label``) is the authored receiver.
|
|
512
|
+
if direct_method_info is not None and getattr(
|
|
513
|
+
direct_method_info, "is_udt_method", False
|
|
514
|
+
):
|
|
494
515
|
return False
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
if ns == "array":
|
|
516
|
+
|
|
517
|
+
if self._drawing_call_is_void(node):
|
|
498
518
|
return True
|
|
499
|
-
|
|
500
|
-
|
|
519
|
+
_fn, ns = self._resolve_callee(node.callee)
|
|
520
|
+
|
|
521
|
+
if method in _MATRIX_VOID_METHODS:
|
|
522
|
+
# Resolve the exact matrix receiver for both established spellings:
|
|
523
|
+
# ``matrix.set(id, ...)`` and ``id.set(...)``.
|
|
524
|
+
functional_namespace = ns == "matrix" and (
|
|
525
|
+
direct_spec is None or direct_spec.kind != "matrix"
|
|
526
|
+
)
|
|
527
|
+
recv_spec = direct_spec
|
|
528
|
+
if functional_namespace:
|
|
529
|
+
recv_spec = (
|
|
530
|
+
self._type_spec_from_expr(node.args[0])
|
|
531
|
+
if node.args
|
|
532
|
+
else None
|
|
533
|
+
)
|
|
534
|
+
if recv_spec is not None and recv_spec.kind == "matrix":
|
|
535
|
+
return True
|
|
536
|
+
|
|
537
|
+
if method in _ARRAY_VOID_METHODS:
|
|
538
|
+
# array.<method>(arr, ...) namespace form OR arr.<method>(...)
|
|
539
|
+
# method form on a std::vector receiver.
|
|
540
|
+
if ns == "array":
|
|
541
|
+
return True
|
|
542
|
+
if direct_spec is not None and direct_spec.kind == "array":
|
|
543
|
+
return True
|
|
544
|
+
|
|
545
|
+
if method not in _MAP_VOID_METHODS:
|
|
546
|
+
return False
|
|
547
|
+
# Preserve the unsupported arbitrary-map-receiver boundary. Namespace
|
|
548
|
+
# functional calls are established; method calls must use a named
|
|
549
|
+
# global/local/parameter receiver.
|
|
550
|
+
if ns == "map":
|
|
551
|
+
# The established namespace-functional form has a positional map
|
|
552
|
+
# receiver. Keyword-only receiver routing remains unsupported
|
|
553
|
+
# and must retain its pre-KI-48g fallback output.
|
|
554
|
+
expected_arity = 1 if method == "clear" else 2
|
|
555
|
+
return len(node.args) == expected_arity and not node.kwargs
|
|
556
|
+
if not isinstance(node.callee.object, Identifier):
|
|
557
|
+
return False
|
|
558
|
+
name = node.callee.object.name
|
|
559
|
+
param_spec = getattr(self, "_current_func_param_specs", {}).get(name)
|
|
560
|
+
if method == "clear":
|
|
561
|
+
if node.args or node.kwargs:
|
|
562
|
+
return False
|
|
563
|
+
elif param_spec is not None and param_spec.kind == "map":
|
|
564
|
+
if not (
|
|
565
|
+
(len(node.args) == 1 and not node.kwargs)
|
|
566
|
+
or (not node.args and set(node.kwargs) == {"id2"})
|
|
567
|
+
):
|
|
568
|
+
return False
|
|
569
|
+
elif len(node.args) != 1 or node.kwargs:
|
|
570
|
+
return False
|
|
571
|
+
recv_spec = param_spec or self._type_spec_from_expr(node.callee.object)
|
|
572
|
+
return recv_spec is not None and recv_spec.kind == "map"
|
|
501
573
|
|
|
502
574
|
# ------------------------------------------------------------------
|
|
503
575
|
# _uses_drawing detection + arena caps
|
|
@@ -527,6 +599,14 @@ class DrawingVisitor:
|
|
|
527
599
|
for spec in self._collection_types.values():
|
|
528
600
|
if self._spec_mentions_drawing(spec):
|
|
529
601
|
return True
|
|
602
|
+
for specs in self._func_collection_types.values():
|
|
603
|
+
for spec in specs.values():
|
|
604
|
+
if self._spec_mentions_drawing(spec):
|
|
605
|
+
return True
|
|
606
|
+
for specs in self._block_collection_types.values():
|
|
607
|
+
for spec in specs.values():
|
|
608
|
+
if self._spec_mentions_drawing(spec):
|
|
609
|
+
return True
|
|
530
610
|
for fields in self._udt_field_type_specs.values():
|
|
531
611
|
for spec in fields.values():
|
|
532
612
|
if self._spec_mentions_drawing(spec):
|