pineforge-codegen 0.6.5__py3-none-any.whl
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.
- pineforge_codegen/__init__.py +53 -0
- pineforge_codegen/analyzer/__init__.py +60 -0
- pineforge_codegen/analyzer/base.py +1563 -0
- pineforge_codegen/analyzer/call_handlers.py +895 -0
- pineforge_codegen/analyzer/contracts.py +163 -0
- pineforge_codegen/analyzer/diagnostics.py +118 -0
- pineforge_codegen/analyzer/tables.py +204 -0
- pineforge_codegen/analyzer/types.py +250 -0
- pineforge_codegen/ast_nodes.py +293 -0
- pineforge_codegen/codegen/__init__.py +78 -0
- pineforge_codegen/codegen/base.py +1381 -0
- pineforge_codegen/codegen/emit_top.py +875 -0
- pineforge_codegen/codegen/helpers.py +163 -0
- pineforge_codegen/codegen/helpers_syminfo.py +134 -0
- pineforge_codegen/codegen/input.py +189 -0
- pineforge_codegen/codegen/security.py +1564 -0
- pineforge_codegen/codegen/ta.py +298 -0
- pineforge_codegen/codegen/tables.py +613 -0
- pineforge_codegen/codegen/types.py +573 -0
- pineforge_codegen/codegen/visit_call.py +1305 -0
- pineforge_codegen/codegen/visit_expr.py +701 -0
- pineforge_codegen/codegen/visit_stmt.py +729 -0
- pineforge_codegen/errors.py +98 -0
- pineforge_codegen/lexer.py +531 -0
- pineforge_codegen/parser.py +1198 -0
- pineforge_codegen/pragmas.py +117 -0
- pineforge_codegen/signatures.py +808 -0
- pineforge_codegen/support_checker.py +1111 -0
- pineforge_codegen/symbols.py +118 -0
- pineforge_codegen/tokens.py +406 -0
- pineforge_codegen/tv_input_choices.py +86 -0
- pineforge_codegen-0.6.5.dist-info/METADATA +462 -0
- pineforge_codegen-0.6.5.dist-info/RECORD +35 -0
- pineforge_codegen-0.6.5.dist-info/WHEEL +4 -0
- pineforge_codegen-0.6.5.dist-info/licenses/LICENSE +197 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""PineScript v6 to C++ transpiler."""
|
|
2
|
+
|
|
3
|
+
from .lexer import Lexer
|
|
4
|
+
from .parser import Parser
|
|
5
|
+
from .analyzer import Analyzer
|
|
6
|
+
from .codegen import CodeGen
|
|
7
|
+
from .pragmas import extract_pf_trace_pragmas
|
|
8
|
+
from .support_checker import check_support_or_raise
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def transpile(pine_source: str, *, check_support: bool = True, filename: str = "<input>") -> str:
|
|
12
|
+
"""Transpile PineScript v6 source code to C++ code.
|
|
13
|
+
|
|
14
|
+
Semantic rules enforced in :class:`Analyzer` (before codegen), including:
|
|
15
|
+
user ``enum`` blocks must appear **above** ``input.enum(Enum.member, ...)`` uses.
|
|
16
|
+
|
|
17
|
+
Before analysis, :func:`support_checker.check_support_or_raise` rejects
|
|
18
|
+
scripts that use language constructs PineForge cannot faithfully execute
|
|
19
|
+
(e.g. ``indicator()`` declarations, prohibited variables such as
|
|
20
|
+
``bar_index``, disallowed ``request.security`` parameters). Pass
|
|
21
|
+
``check_support=False`` to bypass this gate (intended for tests of legacy
|
|
22
|
+
fixtures only).
|
|
23
|
+
|
|
24
|
+
``// @pf-trace name=expr`` pragmas are extracted from ``pine_source``
|
|
25
|
+
via a pre-pass (the lexer strips comments before the parser sees them)
|
|
26
|
+
and attached to the analyzer context for codegen. See
|
|
27
|
+
:mod:`pineforge_codegen.pragmas` for the syntax.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
pine_source: PineScript v6 source string.
|
|
31
|
+
check_support: When True (default) the support checker runs after
|
|
32
|
+
parsing and raises ``CompileError`` on any unsupported feature
|
|
33
|
+
before semantic analysis or codegen.
|
|
34
|
+
filename: Source name threaded into every ``SourceLocation`` so the
|
|
35
|
+
``file:line:col`` shown in ``CompileError`` (both ``str()`` and
|
|
36
|
+
:meth:`~pineforge_codegen.errors.CompileError.format`) points back
|
|
37
|
+
at the caller's file. Defaults to ``"<input>"``.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Generated C++ source string.
|
|
41
|
+
"""
|
|
42
|
+
pragmas = extract_pf_trace_pragmas(pine_source)
|
|
43
|
+
tokens = Lexer(pine_source, filename=filename).tokenize()
|
|
44
|
+
ast = Parser(tokens, source=pine_source, filename=filename).parse()
|
|
45
|
+
if check_support:
|
|
46
|
+
check_support_or_raise(ast, filename=filename)
|
|
47
|
+
ctx = Analyzer(ast, filename=filename).analyze()
|
|
48
|
+
# Attach after analysis: pragma expressions are not part of the
|
|
49
|
+
# program body, so the analyzer never inspects them; the codegen
|
|
50
|
+
# consumes them directly from the context to emit the on_bar tail
|
|
51
|
+
# ``if (trace_enabled_) { trace(...); ... }`` block.
|
|
52
|
+
ctx.pf_trace_pragmas = pragmas
|
|
53
|
+
return CodeGen(ctx).generate()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Analyzer package facade.
|
|
2
|
+
|
|
3
|
+
Historically the semantic analyzer lived in a single ``analyzer.py`` module
|
|
4
|
+
that hit ~2,340 lines and ~74 methods on a single ``Analyzer`` class. This
|
|
5
|
+
package is the structural skeleton for an incremental split: ``base.py``
|
|
6
|
+
currently holds the original ``Analyzer`` verbatim, and future steps will
|
|
7
|
+
peel focused mixins out into sibling files (e.g. ``visit_func``,
|
|
8
|
+
``visit_udt``, ``visit_control``, ``visit_expr``, ``visit_call``, ``types``,
|
|
9
|
+
``helpers``) without changing the public API:
|
|
10
|
+
|
|
11
|
+
from pineforge_codegen.analyzer import Analyzer # primary
|
|
12
|
+
from pineforge_codegen.analyzer import AnalyzerContext # context
|
|
13
|
+
from pineforge_codegen.analyzer import TA_CLASS_MAP, ... # tables
|
|
14
|
+
|
|
15
|
+
Re-exports preserved for ``support_checker.py``, ``codegen/base.py`` and
|
|
16
|
+
external tests that imported the dataclasses or module-level dispatch
|
|
17
|
+
tables. Add new helper modules under ``compiler/transpiler/analyzer/`` and
|
|
18
|
+
re-export their public surface here.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from .base import Analyzer
|
|
22
|
+
from .contracts import (
|
|
23
|
+
# Output dataclasses (consumed by codegen + tests). Defined in
|
|
24
|
+
# contracts.py so the package's import graph stays a strict DAG.
|
|
25
|
+
AnalyzerContext,
|
|
26
|
+
FixnanCallSite,
|
|
27
|
+
FuncInfo,
|
|
28
|
+
MutableGlobalInfo,
|
|
29
|
+
SecurityCallInfo,
|
|
30
|
+
TACallSite,
|
|
31
|
+
)
|
|
32
|
+
from .tables import (
|
|
33
|
+
# Module-level dispatch tables (consumed by codegen + support_checker).
|
|
34
|
+
TA_CLASS_MAP,
|
|
35
|
+
TA_PERIOD_ARG,
|
|
36
|
+
TA_TUPLE_RETURNS,
|
|
37
|
+
TA_MULTI_CTOR,
|
|
38
|
+
TA_NO_CTOR,
|
|
39
|
+
BUILTIN_VARS,
|
|
40
|
+
BAR_FIELDS,
|
|
41
|
+
SKIP_FUNCS,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
__all__ = [
|
|
45
|
+
"Analyzer",
|
|
46
|
+
"TACallSite",
|
|
47
|
+
"FuncInfo",
|
|
48
|
+
"FixnanCallSite",
|
|
49
|
+
"MutableGlobalInfo",
|
|
50
|
+
"SecurityCallInfo",
|
|
51
|
+
"AnalyzerContext",
|
|
52
|
+
"TA_CLASS_MAP",
|
|
53
|
+
"TA_PERIOD_ARG",
|
|
54
|
+
"TA_TUPLE_RETURNS",
|
|
55
|
+
"TA_MULTI_CTOR",
|
|
56
|
+
"TA_NO_CTOR",
|
|
57
|
+
"BUILTIN_VARS",
|
|
58
|
+
"BAR_FIELDS",
|
|
59
|
+
"SKIP_FUNCS",
|
|
60
|
+
]
|