支持 tls 关键字,全面准备清退 t, c
This commit is contained in:
1 parent
7a329f7d1e
commit
e8dc3e3787
3 files changed
+72
-2
No files matched your search
+1
-2
@@ -22,8 +22,7 @@ class _ProviderStack:
|
||||
_tls_index: ulong = 0
|
||||
|
||||
|
||||
@t.TLS
|
||||
def _init_tls():
|
||||
tls def _init_tls():
|
||||
"""Initialize TLS index (executes once; subsequent calls are skipped)."""
|
||||
global _tls_index
|
||||
# Double guard: VPC now implements @t.TLS (a per-function one-shot guard setting __tls_init_done), but this re-check is kept for compatibility with older VPC.exe builds.
|
||||
|
||||
@@ -688,6 +688,66 @@ def _ParseInlineModified(ps: Parser*, parent: AST*):
|
||||
parent.append(stmt)
|
||||
|
||||
|
||||
def _IsTlsModifier(ps: Parser*) -> int:
|
||||
"""Whether the current token is a `tls` modifier before a function definition, 1 = yes / 0 = no.
|
||||
|
||||
Soft keyword: matches only at statement start with a following def (or the fn/fun/func/function
|
||||
alias + '(' / '['), so `tls: local = local()` / `tls.set(...)` / `tls.get()` stay plain identifiers.
|
||||
"""
|
||||
if _cur_type(ps) != TokenType.Name:
|
||||
return 0
|
||||
if _cur_kw(ps) != Keyword.Tls:
|
||||
return 0
|
||||
nxt: Token* = ps.cur.next
|
||||
if nxt is None or nxt.type != TokenType.Name:
|
||||
return 0
|
||||
if nxt.kw_subtype == Keyword.Def:
|
||||
return 1
|
||||
nxt2: Token* = nxt.next
|
||||
if nxt.kw_subtype == Keyword.Fn or nxt.kw_subtype == Keyword.Fun \
|
||||
or nxt.kw_subtype == Keyword.Func or nxt.kw_subtype == Keyword.Function:
|
||||
if nxt2 is not None and nxt2.type == TokenType.Op \
|
||||
and (nxt2.op_subtype == TokOp.LPar or nxt2.op_subtype == TokOp.Lsqb):
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def _MakeTlsMarker(ps: Parser*) -> AST*:
|
||||
"""Build the marker node Attribute(Name('t'), 'TLS') from the current tls token.
|
||||
|
||||
Field-identical to the hand-written @t.TLS decorator, so FuncGenDef / ClassGenBase's existing
|
||||
_has_decorator("TLS") one-shot-init path is reused without any new test.
|
||||
"""
|
||||
marker: AST* = Attribute(ps.pool, Name(ps.pool, "t", ASTCtx.Load),
|
||||
"TLS", ASTCtx.Load)
|
||||
_set_pos(marker, _cur_lineno(ps), _cur_col(ps), 0, 0)
|
||||
return marker
|
||||
|
||||
|
||||
def _ParseTlsModified(ps: Parser*, parent: AST*):
|
||||
"""`tls def f(...)`: consume tls, synthesize @t.TLS and hand off to _parse_funcdef.
|
||||
|
||||
Same pending_decorators channel as _ParseVirtualModified / _ParseInlineModified, so
|
||||
`@deco` + `tls def` merge and position does not matter.
|
||||
"""
|
||||
marker: AST* = _MakeTlsMarker(ps)
|
||||
if marker is None:
|
||||
return
|
||||
_advance(ps) # consume the tls modifier
|
||||
merged: list[AST*]* = list[AST*](ps.pool, 8)
|
||||
if merged is None:
|
||||
return
|
||||
if ps.pending_decorators is not None:
|
||||
dn: sizet = len(ps.pending_decorators)
|
||||
for di in range(int(dn)):
|
||||
merged.append(ps.pending_decorators.get(di))
|
||||
merged.append(marker)
|
||||
ps.pending_decorators = merged
|
||||
stmt: AST* = _parse_funcdef(ps, 0)
|
||||
if stmt is not None:
|
||||
parent.append(stmt)
|
||||
|
||||
|
||||
def _IsStaticModifier(ps: Parser*) -> int:
|
||||
"""Whether the current token is a `static` modifier (soft keyword), 1 = yes / 0 = no.
|
||||
|
||||
@@ -2868,6 +2928,11 @@ def _parse_statement_into(ps: Parser*, parent: AST*):
|
||||
if _IsInlineModifier(ps) != 0:
|
||||
_ParseInlineModified(ps, parent)
|
||||
return
|
||||
# tls modifier (soft keyword): statement start + tls + def; synthesizes @t.TLS and reuses the
|
||||
# existing one-shot-init codegen path (FuncGenDef / ClassGenBase _has_decorator("TLS")).
|
||||
if _IsTlsModifier(ps) != 0:
|
||||
_ParseTlsModified(ps, parent)
|
||||
return
|
||||
# static modifier (soft keyword): statement start + static + (def | `Name :`). The function branch
|
||||
# synthesizes @t.CStatic (returns); the variable branch flags pending_static for _parse_type_ann.
|
||||
if _IsStaticModifier(ps) != 0:
|
||||
|
||||
@@ -134,6 +134,10 @@ enum Keyword:
|
||||
# `t.attr.bigend()` and identifiers named bigend/littlend are unaffected.
|
||||
BigEnd
|
||||
LittleEnd
|
||||
# tls modifier keyword (sugar for @t.TLS, see _ParseTlsModified), appended at the enum tail so
|
||||
# existing kw_subtype values stay unchanged. Soft keyword: only at statement start before a
|
||||
# function definition; identifiers named tls (e.g. a `vthreading.local` variable) are unaffected.
|
||||
Tls
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -401,6 +405,8 @@ def _init_keywords(pool: memhub.MemManager*):
|
||||
# see _ParseVirtualModified)
|
||||
_kw_intern(pool, "virtual", Keyword.Virtual)
|
||||
_kw_intern(pool, "novirtual", Keyword.Novirtual)
|
||||
# tls modifier soft keyword (statement start before def only, see _ParseTlsModified)
|
||||
_kw_intern(pool, "tls", Keyword.Tls)
|
||||
_kw_intern(pool, "union", Keyword.Union)
|
||||
# renum variant-type keyword (sugar, same as enum/union; see _parse_renumdef)
|
||||
_kw_intern(pool, "renum", Keyword.Renum)
|
||||
|
||||
Reference in new issue
Block a user