pine2pyne 0.2.4__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.
Files changed (75) hide show
  1. pine2pyne/__init__.py +84 -0
  2. pine2pyne/__main__.py +12 -0
  3. pine2pyne/ast_nodes.py +405 -0
  4. pine2pyne/ast_walk.py +93 -0
  5. pine2pyne/block_value_lowering.py +694 -0
  6. pine2pyne/bool_builtins.py +42 -0
  7. pine2pyne/bool_value_typing.py +580 -0
  8. pine2pyne/cli.py +247 -0
  9. pine2pyne/codegen.py +886 -0
  10. pine2pyne/compat/__init__.py +19 -0
  11. pine2pyne/compat/__main__.py +6 -0
  12. pine2pyne/compat/cli.py +114 -0
  13. pine2pyne/compat/comparison.py +105 -0
  14. pine2pyne/compat/corpus.py +73 -0
  15. pine2pyne/compat/report.py +95 -0
  16. pine2pyne/compat/runner.py +63 -0
  17. pine2pyne/condition_typing.py +260 -0
  18. pine2pyne/conditional_history_calls.py +96 -0
  19. pine2pyne/core/__init__.py +26 -0
  20. pine2pyne/core/contracts.py +125 -0
  21. pine2pyne/di.py +173 -0
  22. pine2pyne/emit/__init__.py +5 -0
  23. pine2pyne/emit/legacy.py +14 -0
  24. pine2pyne/emit/pynecomp/__init__.py +20 -0
  25. pine2pyne/emit/pynecomp/banner.py +30 -0
  26. pine2pyne/emit/pynecomp/blank_lines.py +69 -0
  27. pine2pyne/emit/pynecomp/emitter.py +61 -0
  28. pine2pyne/emit/pynecomp/imports.py +65 -0
  29. pine2pyne/emit/pynecomp/passes/__init__.py +84 -0
  30. pine2pyne/emit/pynecomp/passes/annotations.py +422 -0
  31. pine2pyne/emit/pynecomp/passes/base.py +69 -0
  32. pine2pyne/emit/pynecomp/passes/builtins.py +169 -0
  33. pine2pyne/emit/pynecomp/passes/hoisting.py +205 -0
  34. pine2pyne/emit/pynecomp/passes/imports.py +112 -0
  35. pine2pyne/emit/pynecomp/passes/legacy_colors.py +101 -0
  36. pine2pyne/emit/pynecomp/passes/library.py +205 -0
  37. pine2pyne/emit/pynecomp/passes/rewrites.py +215 -0
  38. pine2pyne/emit/pynecomp/printer.py +288 -0
  39. pine2pyne/emit/pynecomp/unparser.py +186 -0
  40. pine2pyne/emitted_names.py +152 -0
  41. pine2pyne/errors.py +69 -0
  42. pine2pyne/for_loop_end_bound.py +172 -0
  43. pine2pyne/grouped_history_lowering.py +310 -0
  44. pine2pyne/import_resolver.py +469 -0
  45. pine2pyne/input_hoisting.py +195 -0
  46. pine2pyne/legacy_function_names.py +74 -0
  47. pine2pyne/legacy_sessions.py +68 -0
  48. pine2pyne/lexer.py +630 -0
  49. pine2pyne/library_collision.py +434 -0
  50. pine2pyne/namespace_members.py +247 -0
  51. pine2pyne/node_ids.py +235 -0
  52. pine2pyne/once_lowering.py +75 -0
  53. pine2pyne/overload_resolution.py +475 -0
  54. pine2pyne/parse_repair.py +398 -0
  55. pine2pyne/parser.py +1873 -0
  56. pine2pyne/pine_builtins.py +394 -0
  57. pine2pyne/pine_semantics.py +604 -0
  58. pine2pyne/pipeline/__init__.py +18 -0
  59. pine2pyne/pipeline/service.py +70 -0
  60. pine2pyne/pipeline/stages.py +73 -0
  61. pine2pyne/scope_renamer.py +965 -0
  62. pine2pyne/strategy_when_lowering.py +101 -0
  63. pine2pyne/strict_boolean.py +101 -0
  64. pine2pyne/symbol_table.py +166 -0
  65. pine2pyne/tokens.py +143 -0
  66. pine2pyne/transformer.py +2510 -0
  67. pine2pyne/type_inference.py +422 -0
  68. pine2pyne/udt_field_defaults.py +149 -0
  69. pine2pyne/value_blocks.py +357 -0
  70. pine2pyne-0.2.4.dist-info/METADATA +99 -0
  71. pine2pyne-0.2.4.dist-info/RECORD +75 -0
  72. pine2pyne-0.2.4.dist-info/WHEEL +5 -0
  73. pine2pyne-0.2.4.dist-info/entry_points.txt +3 -0
  74. pine2pyne-0.2.4.dist-info/licenses/LICENSE +201 -0
  75. pine2pyne-0.2.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,70 @@
1
+ """The transpile use case, composed from injected stages."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Sequence
5
+
6
+ from ..core.contracts import (
7
+ AstNormalizer,
8
+ CodeEmitter,
9
+ CompilationUnit,
10
+ ScriptTransformer,
11
+ SemanticGuard,
12
+ SourceFilter,
13
+ SourceParser,
14
+ )
15
+
16
+
17
+ class TranspileService:
18
+ """Pine source -> Python source.
19
+
20
+ The service only orders the stages; it knows nothing about how any of
21
+ them works (S and D in SOLID). Swap a stage by registering another
22
+ implementation of its contract in the container.
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ source_filter: SourceFilter,
28
+ parser: SourceParser,
29
+ normalizers: Sequence[AstNormalizer],
30
+ guard: SemanticGuard,
31
+ transformer: ScriptTransformer,
32
+ emitter: CodeEmitter,
33
+ ) -> None:
34
+ self._source_filter = source_filter
35
+ self._parser = parser
36
+ self._normalizers = tuple(normalizers)
37
+ self._guard = guard
38
+ self._transformer = transformer
39
+ self._emitter = emitter
40
+
41
+ @property
42
+ def emitter(self) -> CodeEmitter:
43
+ return self._emitter
44
+
45
+ def _front_end(self, source: str):
46
+ script = self._parser.parse(source)
47
+ for normalizer in self._normalizers:
48
+ script = normalizer.normalize(script)
49
+ self._guard.check(script)
50
+ return script
51
+
52
+ def transpile(self, source: str) -> str:
53
+ """Python source for ``source``; an empty string for a comment-only source.
54
+
55
+ Raises:
56
+ Pine2PyneError: if any stage refuses the script.
57
+ """
58
+ if self._source_filter.is_blank(source):
59
+ return ''
60
+ script = self._front_end(source)
61
+ transformed = self._transformer.transform(script)
62
+ return self._emitter.emit(CompilationUnit(pine_source=source, pine_script=script, transformed=transformed))
63
+
64
+ def validate(self, source: str) -> None:
65
+ """Parse and run the semantic guard without generating code (``--validate``).
66
+
67
+ Unlike :meth:`transpile`, the legacy name pass is skipped, as the CLI's
68
+ ``--validate`` always did: it checks the script as written.
69
+ """
70
+ self._guard.check(self._parser.parse(source))
@@ -0,0 +1,73 @@
1
+ """Concrete pipeline stages: thin adapters over the transpiler engine.
2
+
3
+ Each class implements one contract from :mod:`pine2pyne.core.contracts` and
4
+ delegates to the engine module that already does the work, so the engine
5
+ keeps its own tests while the application layer sees only abstractions.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from ..ast_nodes import Script
10
+ from ..input_hoisting import hoist_inputs
11
+ from ..legacy_function_names import qualify_legacy_function_names
12
+ from ..legacy_sessions import qualify_legacy_sessions
13
+ from ..parse_repair import parse_source
14
+ from ..pine_semantics import enforce
15
+ from ..transformer import PyneTransformedScript, Transformer
16
+
17
+
18
+ class CommentOnlySourceFilter:
19
+ """A source made of comments and whitespace has nothing to transpile."""
20
+
21
+ def is_blank(self, source: str) -> bool:
22
+ if not source:
23
+ return True
24
+ for line in source.splitlines():
25
+ stripped = line.strip()
26
+ if stripped and not stripped.startswith('//'):
27
+ return False
28
+ return True
29
+
30
+
31
+ class RepairingSourceParser:
32
+ """Lex and parse; a rejected known spelling of valid Pine is repaired (card #55)."""
33
+
34
+ def parse(self, source: str) -> Script:
35
+ script, _repairs = parse_source(source)
36
+ return script
37
+
38
+
39
+ class LegacyFunctionNameNormalizer:
40
+ """Pine v1-v4 call names are spelled the way Pine v5 spells them (card #116)."""
41
+
42
+ def normalize(self, script: Script) -> Script:
43
+ return qualify_legacy_function_names(script)
44
+
45
+
46
+ class LegacySessionNormalizer:
47
+ """Pine v4 sessions of time()/time_close() get v4's default days (see :mod:`pine2pyne.legacy_sessions`)."""
48
+
49
+ def normalize(self, script: Script) -> Script:
50
+ return qualify_legacy_sessions(script)
51
+
52
+
53
+ class InputHoistingNormalizer:
54
+ """Every top-level input call becomes a main() parameter (see :mod:`pine2pyne.input_hoisting`)."""
55
+
56
+ def normalize(self, script: Script) -> Script:
57
+ return hoist_inputs(script)
58
+
59
+
60
+ class PineSemanticGuard:
61
+ """Refuse what TradingView's compiler refuses, at the Pine line (card #28)."""
62
+
63
+ def check(self, script: Script) -> None:
64
+ enforce(script)
65
+
66
+
67
+ class FreshTransformer:
68
+ """:class:`~pine2pyne.transformer.Transformer` is single-use (card #83):
69
+ this stage builds a fresh one for every script, so the stage itself is
70
+ stateless and safe to share."""
71
+
72
+ def transform(self, script: Script) -> PyneTransformedScript:
73
+ return Transformer().transform(script)