Some simple information syncing
This commit is contained in:
@@ -11,7 +11,7 @@ from .tokens import (
|
||||
from .base import (
|
||||
AST, ASTKind, ASTCtx, OpKind, ASTFlag,
|
||||
# 常量
|
||||
CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE,
|
||||
CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE, CONST_CHAR,
|
||||
FLAG_IS_ASYNC, FLAG_SIMPLE, FLAG_HAS_STAR,
|
||||
# 辅助函数
|
||||
_init_ast, _copy_str, _set_pos, _inherit_pos, _set_parent_list,
|
||||
|
||||
@@ -148,6 +148,7 @@ CONST_FLOAT: t.CDefine = 2
|
||||
CONST_STR: t.CDefine = 3
|
||||
CONST_BOOL: t.CDefine = 4
|
||||
CONST_NONE: t.CDefine = 5
|
||||
CONST_CHAR: t.CDefine = 6
|
||||
|
||||
# 标志位
|
||||
FLAG_IS_ASYNC: t.CDefine = 1
|
||||
|
||||
@@ -6,7 +6,7 @@ from .base import (
|
||||
AST, ASTKind, ASTCtx, OpKind,
|
||||
_init_ast, _copy_str, _set_parent_list,
|
||||
_emit, _emit_str, _emit_int, _dump_list, _dump_op_list, _op_name,
|
||||
CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE
|
||||
CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE, CONST_CHAR
|
||||
)
|
||||
|
||||
|
||||
@@ -106,6 +106,11 @@ class Constant(AST):
|
||||
else:
|
||||
pos = _emit(buf, size, pos, "(null)")
|
||||
pos = _emit(buf, size, pos, "'")
|
||||
elif self.const_kind == CONST_CHAR:
|
||||
# 单引号单字符 → 显示为字符 ASCII 值
|
||||
pos = _emit(buf, size, pos, "char(")
|
||||
pos = _emit_int(buf, size, pos, self.int_val)
|
||||
pos = _emit(buf, size, pos, ")")
|
||||
elif self.const_kind == CONST_BOOL:
|
||||
if self.int_val != 0:
|
||||
pos = _emit(buf, size, pos, "True")
|
||||
|
||||
@@ -530,6 +530,8 @@ def _read_string(lx: Lexer | t.CPtr):
|
||||
tok: Token | t.CPtr = new_token(lx.pool, TokenType.String, start_lineno, start_col)
|
||||
if tok == None: return
|
||||
content_len: t.CSizeT = content_end - content_buf_start
|
||||
# esc_len: 转义后实际字节数(用于判断单字符)
|
||||
esc_len: t.CSizeT = content_len
|
||||
|
||||
# 处理转义序列(非 raw 字符串)
|
||||
if is_raw == 0 and content_len > 0:
|
||||
@@ -572,15 +574,22 @@ def _read_string(lx: Lexer | t.CPtr):
|
||||
rpos += 1
|
||||
conv_buf[wpos] = '\0'
|
||||
token_set_str_literal(lx.pool, tok, conv_buf)
|
||||
esc_len = wpos
|
||||
else:
|
||||
token_set_str(lx.pool, tok, lx.src, content_buf_start, content_len)
|
||||
tok.end_lineno = lx.lineno
|
||||
tok.end_col_offset = lx.col
|
||||
# flags 字段复用:bit0=raw, bit1=bytes, bit2=fstring, bit3=triple
|
||||
# flags 字段复用:bit0=raw, bit1=bytes, bit2=fstring, bit3=triple, bit4=dquote, bit5=单字符候选
|
||||
if is_raw: tok.kw_subtype = tok.kw_subtype | 1
|
||||
if is_bytes: tok.kw_subtype = tok.kw_subtype | 2
|
||||
if is_fstring: tok.kw_subtype = tok.kw_subtype | 4
|
||||
if is_triple: tok.kw_subtype = tok.kw_subtype | 8
|
||||
# bit4 (16) = 双引号(0=单引号, 1=双引号)
|
||||
if quote == '"': tok.kw_subtype = tok.kw_subtype | 16
|
||||
# bit5 (32) = 单字符候选(非三引号、非 fstring、转义后正好 1 字节)
|
||||
# 用于 CONST_CHAR 判定,避免 '\0' 等含 NUL 字节被 strlen 误判为空字符串
|
||||
if is_triple == 0 and is_fstring == 0 and esc_len == 1:
|
||||
tok.kw_subtype = tok.kw_subtype | 32
|
||||
_emit(lx, tok)
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from .base import (
|
||||
AST, ASTCtx, ASTKind, OpKind, ASTFlag,
|
||||
_set_pos, _binop_from_op, _augop_from_op, _cmpop_from_op, _copy_str, _inherit_pos,
|
||||
_init_ast,
|
||||
CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE,
|
||||
CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE, CONST_CHAR,
|
||||
FLAG_IS_ASYNC,
|
||||
)
|
||||
from .exprs import (
|
||||
@@ -169,7 +169,30 @@ def _new_const_float(pool: memhub.MemManager | t.CPtr, val: t.CDouble,
|
||||
|
||||
|
||||
def _new_const_str(pool: memhub.MemManager | t.CPtr, val: str,
|
||||
lineno: t.CInt, col: t.CInt) -> AST | t.CPtr:
|
||||
lineno: t.CInt, col: t.CInt,
|
||||
is_dquote: t.CInt = 1,
|
||||
is_triple: t.CInt = 0,
|
||||
is_char: t.CInt = 0) -> AST | t.CPtr:
|
||||
"""创建字符串/字符常量节点
|
||||
|
||||
is_dquote: 0=单引号, 非0=双引号(默认双引号)
|
||||
is_triple: 非0=三引号字符串
|
||||
is_char: 非0=单字符候选(lexer 已确认转义后正好 1 字节, 含 '\\0')
|
||||
语义区分:
|
||||
- 'x' (单引号单字符, 非三引号) → CONST_CHAR (i8 值)
|
||||
- "x" (双引号, 含\\0终止符) → CONST_STR (i8* 指针, i8 x 2)
|
||||
- 'ab' (单引号多字符) → CONST_STR (i8* 指针)
|
||||
- '''x''' / \"\"\"x\"\"\" (三引号) → CONST_STR (i8* 指针)
|
||||
- '' / \"\" (空字符串) → CONST_STR (i8* 指针)
|
||||
"""
|
||||
# 单引号、非三引号、lexer 标记的单字符候选 → CONST_CHAR
|
||||
# 用 is_char 标记而非 strlen(val),因为 '\0' 转义后是 NUL 字节,strlen 会返回 0
|
||||
if is_dquote == 0 and is_triple == 0 and is_char != 0:
|
||||
# 单字符 → CONST_CHAR,int_val 存储字符 ASCII 值
|
||||
# val[0] 即使是 NUL 也是合法值 0
|
||||
ch_val: t.CInt64T = val[0]
|
||||
return Constant(pool, CONST_CHAR, ch_val, 0.0, val, lineno, col)
|
||||
# 其他情况 → CONST_STR
|
||||
return Constant(pool, CONST_STR, 0, 0.0, val, lineno, col)
|
||||
|
||||
|
||||
@@ -751,10 +774,13 @@ def _parse_atom(ps: Parser | t.CPtr) -> AST | t.CPtr:
|
||||
if ttype == TokenType.String:
|
||||
sval: str = _cur_str(ps)
|
||||
is_fstr: t.CInt = ps.cur.kw_subtype & 4
|
||||
is_triple: t.CInt = ps.cur.kw_subtype & 8
|
||||
is_dquote: t.CInt = ps.cur.kw_subtype & 16
|
||||
is_char: t.CInt = ps.cur.kw_subtype & 32
|
||||
_advance(ps)
|
||||
if is_fstr:
|
||||
return _parse_fstring(ps, sval, lineno, col)
|
||||
return _new_const_str(ps.pool, sval, lineno, col)
|
||||
return _new_const_str(ps.pool, sval, lineno, col, is_dquote, is_triple, is_char)
|
||||
|
||||
if _match_op(ps, TokOp.Ellipsis):
|
||||
_advance(ps)
|
||||
@@ -1551,12 +1577,14 @@ def _parse_from_import(ps: Parser | t.CPtr) -> AST | t.CPtr:
|
||||
level += 3
|
||||
_advance(ps)
|
||||
module_name: str = None
|
||||
if _cur_type(ps) == TokenType.Name:
|
||||
# 关键字(如 import)的 token type 也是 Name,必须通过 kw_subtype 排除,
|
||||
# 否则 `from . import` 中的 `import` 会被误认为 module_name
|
||||
if _cur_type(ps) == TokenType.Name and _cur_kw(ps) == Keyword.NotKeyword:
|
||||
module_name = _cur_str(ps)
|
||||
_advance(ps)
|
||||
while _match_op(ps, TokOp.Dot):
|
||||
_advance(ps)
|
||||
if _cur_type(ps) == TokenType.Name:
|
||||
if _cur_type(ps) == TokenType.Name and _cur_kw(ps) == Keyword.NotKeyword:
|
||||
next_name: str = _cur_str(ps)
|
||||
mlen: t.CInt = string.strlen(module_name)
|
||||
nlen: t.CInt = string.strlen(next_name)
|
||||
@@ -1571,6 +1599,7 @@ def _parse_from_import(ps: Parser | t.CPtr) -> AST | t.CPtr:
|
||||
ps.error_count += 1
|
||||
return None
|
||||
_advance(ps)
|
||||
_skip_nl(ps)
|
||||
# import *
|
||||
if _match_op(ps, TokOp.Star):
|
||||
_advance(ps)
|
||||
@@ -2058,8 +2087,9 @@ def _parse_closed_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr:
|
||||
# 字符串字面量 pattern
|
||||
if ttype == TokenType.String:
|
||||
sval = _cur_str(ps)
|
||||
is_dquote_m: t.CInt = ps.cur.kw_subtype & 16
|
||||
_advance(ps)
|
||||
val = _new_const_str(ps.pool, sval, lineno, col)
|
||||
val = _new_const_str(ps.pool, sval, lineno, col, is_dquote_m)
|
||||
node = MatchValue(ps.pool, val)
|
||||
_set_pos(node, lineno, col, 0, 0)
|
||||
return node
|
||||
|
||||
Reference in New Issue
Block a user