cpyte 4.2.2__tar.gz → 4.2.3__tar.gz

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 (42) hide show
  1. {cpyte-4.2.2/source/cpyte.egg-info → cpyte-4.2.3}/PKG-INFO +1 -1
  2. cpyte-4.2.3/source/cpyte/__init__.py +143 -0
  3. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/_bignum_bc.py +3 -2
  4. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/_runtime_bc.py +3 -2
  5. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/astparse.py +44 -1
  6. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/bytecoding.py +260 -10
  7. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/compiling.py +2 -2
  8. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/formatter.py +4 -0
  9. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/lexar.py +1 -0
  10. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/linker.py +8 -3
  11. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/mainpie.py +1 -1
  12. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/optimizations.py +26 -59
  13. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/semantic_analasis.py +395 -17
  14. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/winjit_patch.py +25 -25
  15. {cpyte-4.2.2 → cpyte-4.2.3/source/cpyte.egg-info}/PKG-INFO +1 -1
  16. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte.egg-info/SOURCES.txt +2 -1
  17. cpyte-4.2.3/test/test_fuzz_del_has.py +544 -0
  18. cpyte-4.2.2/source/cpyte/__init__.py +0 -1
  19. {cpyte-4.2.2 → cpyte-4.2.3}/MANIFEST.in +0 -0
  20. {cpyte-4.2.2 → cpyte-4.2.3}/pyproject.toml +0 -0
  21. {cpyte-4.2.2 → cpyte-4.2.3}/readme.md +0 -0
  22. {cpyte-4.2.2 → cpyte-4.2.3}/setup.cfg +0 -0
  23. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/__main__.py +0 -0
  24. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/bignum.c +0 -0
  25. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/clib.py +0 -0
  26. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/extension_hooks.py +0 -0
  27. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/gc_runtime.c +0 -0
  28. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/generate_bc.py +0 -0
  29. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/lsp_server.py +0 -0
  30. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/package_manifest.py +0 -0
  31. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/runtime.c +0 -0
  32. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/runtime_scorpion.c +0 -0
  33. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/sef.py +0 -0
  34. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/ugc.h +0 -0
  35. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/ui.py +0 -0
  36. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/update_check.py +0 -0
  37. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte/winjit_stubs.c +0 -0
  38. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte.egg-info/dependency_links.txt +0 -0
  39. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte.egg-info/entry_points.txt +0 -0
  40. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte.egg-info/requires.txt +0 -0
  41. {cpyte-4.2.2 → cpyte-4.2.3}/source/cpyte.egg-info/top_level.txt +0 -0
  42. {cpyte-4.2.2 → cpyte-4.2.3}/test/test_bignum_jit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cpyte
3
- Version: 4.2.2
3
+ Version: 4.2.3
4
4
  Summary: The Cpyte programming language compiler
5
5
  Author: Hoang Duy Tung
6
6
  License: MIT
@@ -0,0 +1,143 @@
1
+ __version__ = "4.2.3"
2
+
3
+ # ---------------------------------------------------------------------------
4
+ # Public library API.
5
+ #
6
+ # Consumers should import ONLY the ``cpyte`` package and use these entry
7
+ # points (``import cpyte; cpyte.parse_and_analyze(...)``) instead of reaching
8
+ # into ``cpyte.astparse`` / ``cpyte.lexar`` / ``cpyte.semantic_analasis`` /
9
+ # ``cpyte.bytecoding`` / ``cpyte.compiling`` internals. Everything here is an
10
+ # additive re-export or thin wrapper: compiler behavior is unchanged.
11
+ # ---------------------------------------------------------------------------
12
+
13
+ from . import astparse, bytecoding, compiling, lexar, mainpie, semantic_analasis, ui
14
+
15
+
16
+ class CpyteCompileError(Exception):
17
+ """Raised by the high-level library entry points on parse / analyze /
18
+ codegen failure (library calls never ``sys.exit``)."""
19
+
20
+
21
+ def parse_and_analyze(
22
+ source,
23
+ *,
24
+ tab_size=4,
25
+ strict=False,
26
+ enable_extensions=True,
27
+ no_gc=False,
28
+ filepath=None,
29
+ workspace_root=None,
30
+ ):
31
+ """Lex + parse + semantically analyze ``source``.
32
+
33
+ Returns ``(parsed, generic_instantiations, warnings_txt)`` or raises
34
+ :class:`CpyteCompileError`. Loads workspace package manifests when
35
+ extensions are enabled (same behavior as ``cpy build``).
36
+ """
37
+ if workspace_root is None:
38
+ workspace_root = mainpie._find_workspace_root(filepath)
39
+ if enable_extensions:
40
+ mainpie._load_package_manifests_from_source(workspace_root)
41
+ lex = lexar.Lexer(source, tab_size=tab_size, enable_extensions=enable_extensions)
42
+ tokens = lex.get_tokens()
43
+ try:
44
+ parsed, _ = astparse.parse_file(tokens, enable_extensions=enable_extensions)
45
+ except (lexar.LexerError, astparse.ParseError) as e:
46
+ raise CpyteCompileError(f"parse error: {e}") from e
47
+ result, warnings_txt, generic_instantiations = semantic_analasis.analyze(
48
+ source,
49
+ parsed,
50
+ strict=strict,
51
+ workspace_root=workspace_root,
52
+ filepath=filepath,
53
+ enable_extensions=enable_extensions,
54
+ no_gc=no_gc,
55
+ )
56
+ if result:
57
+ raise CpyteCompileError(str(result).rstrip())
58
+ return parsed, generic_instantiations, warnings_txt
59
+
60
+
61
+ def emit_program(
62
+ parsed,
63
+ *,
64
+ generic_instantiations=None,
65
+ no_userspace=False,
66
+ enable_extensions=True,
67
+ no_gc=False,
68
+ use_native_eh=False,
69
+ debug_instrument=False,
70
+ debug_nids=None,
71
+ debug_step_ids=None,
72
+ ):
73
+ """Emit LLVM IR for a parsed module.
74
+
75
+ Returns ``(module, src_files, emitter)``; the emitter carries the
76
+ ``_dbg_*`` debug metadata (tracer symbols, box slots/types) when
77
+ ``debug_instrument`` is enabled. Raises :class:`CpyteCompileError` on
78
+ codegen failure.
79
+ """
80
+ c = bytecoding.LLVM(
81
+ no_userspace=no_userspace,
82
+ enable_extensions=enable_extensions,
83
+ no_gc=no_gc,
84
+ use_native_eh=use_native_eh,
85
+ debug_instrument=debug_instrument,
86
+ debug_nids=debug_nids,
87
+ debug_step_ids=debug_step_ids,
88
+ )
89
+ c.generic_instantiations = generic_instantiations or {}
90
+ try:
91
+ prog, src_files = c.emit_program(parsed)
92
+ except Exception as e:
93
+ raise CpyteCompileError(f"codegen error: {type(e).__name__}: {e}") from e
94
+ return prog, src_files, c
95
+
96
+
97
+ # -- low-level re-exports (the whole compiler usable from one package) ------
98
+ from .astparse import ( # noqa: F401
99
+ Assert,
100
+ Assign,
101
+ Break,
102
+ Call,
103
+ ClassDef,
104
+ Continue,
105
+ DeferStmt,
106
+ DelStmt,
107
+ EnumDef,
108
+ ExprStmt,
109
+ FuncDef,
110
+ If,
111
+ Import,
112
+ ParseError,
113
+ Print,
114
+ Raise,
115
+ Return,
116
+ StructDef,
117
+ Switch,
118
+ Try,
119
+ TypeAlias,
120
+ VarDecl,
121
+ While,
122
+ parse_file,
123
+ )
124
+ from .bytecoding import LLVM # noqa: F401
125
+ from .compiling import ( # noqa: F401
126
+ Linker,
127
+ LinkerNotFoundError,
128
+ host_target,
129
+ run_aot,
130
+ run_jit,
131
+ )
132
+ from .compiling import _host_default_pic as host_default_pic
133
+ from .lexar import Lexer, LexerError # noqa: F401
134
+ from .mainpie import ( # noqa: F401
135
+ _collect_frameworks as collect_frameworks,
136
+ )
137
+ from .mainpie import (
138
+ _detect_nogc as detect_nogc,
139
+ )
140
+ from .mainpie import (
141
+ _find_workspace_root as find_workspace_root,
142
+ )
143
+ from .semantic_analasis import analyze # noqa: F401
@@ -1,6 +1,7 @@
1
- import base64, zlib
2
- from llvmlite import binding
1
+ import base64
2
+ import zlib
3
3
 
4
+ from llvmlite import binding
4
5
 
5
6
  _B64 = (
6
7
  "eJztvQ1YE1f6N3wmk8wMISQDggZJcIJo8ZMIqOFDOyGo6NrdiLZLW1sSBMUWNXyoaNnuJAGClrbRsl26"
@@ -1,6 +1,7 @@
1
- import base64, zlib
2
- from llvmlite import binding
1
+ import base64
2
+ import zlib
3
3
 
4
+ from llvmlite import binding
4
5
 
5
6
  _B64 = (
6
7
  "eJzsvX9AVGX2P/7cuTP3XoZh5gIDDjLAHQQb8deAv0CQ7syAobk2KpWZ5YBgWGojoiLr1p0f/BDJHY2M"
@@ -142,7 +142,14 @@ class ListLit(Node):
142
142
 
143
143
 
144
144
  class Call(Node):
145
- __slots__ = ("_token", "args", "callee", "inferred_type", "param_types")
145
+ __slots__ = (
146
+ "_token",
147
+ "args",
148
+ "callee",
149
+ "inferred_type",
150
+ "param_types",
151
+ "meta",
152
+ )
146
153
 
147
154
  def __init__(self, callee, args: list, token=None):
148
155
  self.callee = callee
@@ -150,6 +157,7 @@ class Call(Node):
150
157
  self._token = token
151
158
  self.inferred_type = None
152
159
  self.param_types = None
160
+ self.meta = None
153
161
 
154
162
  def __repr__(self):
155
163
  return f"Call({self.callee}, {self.args})"
@@ -1185,6 +1193,8 @@ def _parse_standard_statement(tokens: list[Token], pos: int):
1185
1193
  node, pos = parse_break(tokens, pos)
1186
1194
  elif tok.type == TokenType.KEYWORD and tok.value == "continue":
1187
1195
  node, pos = parse_continue(tokens, pos)
1196
+ elif tok.type == TokenType.KEYWORD and tok.value == "del":
1197
+ node, pos = parse_del(tokens, pos)
1188
1198
  elif tok.type == TokenType.KEYWORD and tok.value == "assert":
1189
1199
  node, pos = parse_assert(tokens, pos)
1190
1200
  elif tok.type == TokenType.KEYWORD and tok.value == "asm":
@@ -1987,6 +1997,26 @@ class DeferStmt(Node):
1987
1997
  return f"DeferStmt({self.body!r})"
1988
1998
 
1989
1999
 
2000
+ class DelStmt(Node):
2001
+ """`del <target>` — unbind a variable or clear a runtime slot.
2002
+
2003
+ Static locals are removed from the compiler scope (later uses become
2004
+ compile errors); dynamic/arena variables are marked deleted at runtime
2005
+ (kind DYN_NONE); heap pointers from `new`/`malloc` are freed; and
2006
+ `del obj.field` / `del arr[i]` / `del *p` clear the addressed slot.
2007
+ """
2008
+
2009
+ __slots__ = ("_token", "target", "del_kind")
2010
+
2011
+ def __init__(self, target, token=None):
2012
+ self.target = target
2013
+ self._token = token
2014
+ self.del_kind = None # "static" | "dynamic" | "heap" | "slot", set by semantic
2015
+
2016
+ def __repr__(self):
2017
+ return f"DelStmt({self.target!r})"
2018
+
2019
+
1990
2020
  class StructDef(Node):
1991
2021
  __slots__ = ("_token", "fields", "generic_params", "name")
1992
2022
 
@@ -2502,12 +2532,25 @@ def parse_defer(tokens: list[Token], pos: int):
2502
2532
  return DeferStmt(stmt, token=tok), pos
2503
2533
 
2504
2534
 
2535
+ def parse_del(tokens: list[Token], pos: int):
2536
+ tok = tokens[pos] # 'del'
2537
+ pos += 1
2538
+ if pos >= len(tokens):
2539
+ raise ParseError("Expected an expression after `del`", tok)
2540
+ target, pos = parse_expression(tokens, pos)
2541
+ _expect_newline(tokens, pos, tok)
2542
+ return DelStmt(target, token=tok), pos
2543
+
2544
+
2505
2545
  def parse_statement(tokens: list[Token], pos: int):
2506
2546
  if pos >= len(tokens):
2507
2547
  return None, pos
2508
2548
 
2509
2549
  tok = tokens[pos]
2510
2550
 
2551
+ if tok.type == TokenType.KEYWORD and tok.value == "del":
2552
+ return parse_del(tokens, pos)
2553
+
2511
2554
  if tok.type == TokenType.KEYWORD and tok.value == "return":
2512
2555
  return parse_return(tokens, pos)
2513
2556