Skip to content

Commit 525a7d9

Browse files
authored
Merge pull request #432 from boriel/feature/add_stringizing_operator
Feature/add stringizing operator
2 parents 681fb21 + 4f95334 commit 525a7d9

14 files changed

Lines changed: 107 additions & 14 deletions

src/libzxbpp/prepro/operators.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,21 @@ def __init__(self, lineno: int, table: 'prepro.DefinesTable', left: MacroCall, r
2020

2121
def __call__(self, symbolTable: 'prepro.DefinesTable' = None) -> str:
2222
return self.left(symbolTable).rstrip() + self.right(symbolTable).lstrip()
23+
24+
25+
class Stringizing(MacroCall):
26+
""" Implements stringizing operator (#). Converts the result of the
27+
macrocall into a BASIC string (double quotes " as delimiters, escaped as
28+
doubled-double quote 'Hello "dear"' => 'Hello ""dear""').
29+
"""
30+
def __init__(self, lineno: int, table: 'prepro.DefinesTable', macro_call: MacroCall):
31+
super().__init__(lineno=lineno, table=table, id_='')
32+
self.macro_call = macro_call
33+
34+
@staticmethod
35+
def stringize(s: str) -> str:
36+
s = s.replace('"', '""')
37+
return f'"{s}"'
38+
39+
def __call__(self, symbolTable: 'prepro.DefinesTable' = None) -> str:
40+
return self.stringize(self.macro_call(symbolTable))

src/libzxbpp/zxbpp.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from .prepro import DefinesTable, ID, MacroCall, Arg, ArgList
3232
from .prepro.exceptions import PreprocError
3333
from .prepro.operators import Concatenation
34+
from .prepro.operators import Stringizing
3435

3536
from src import arch
3637

@@ -64,7 +65,7 @@ class IfDef(NamedTuple):
6465
('nonassoc', 'DUMMY'),
6566
('left', 'EQ', 'NE', 'LT', 'LE', 'GT', 'GE'),
6667
('right', 'LLP'),
67-
('left', 'PASTE'),
68+
('left', 'PASTE', 'STRINGIZING'),
6869
)
6970

7071

@@ -423,14 +424,18 @@ def p_warningmsg(p):
423424
def p_define(p):
424425
""" define : DEFINE ID params defs
425426
"""
427+
id_ = p[2]
428+
params = p[3]
429+
defs = p[4]
430+
426431
if ENABLED:
427-
if p[4]:
428-
if p[4][0] in ' \t': # remove leading whitespaces
429-
p[4][0] = p[4][0].lstrip(' \t')
432+
if defs:
433+
if isinstance(defs[0], str) and defs[0] in ' \t': # remove leading whitespaces
434+
defs[0] = defs[0].lstrip(' \t')
430435
else:
431436
warning(p.lineno(1), "missing whitespace after macro name")
432437

433-
ID_TABLE.define(p[2], args=p[3], value=p[4], lineno=p.lineno(2),
438+
ID_TABLE.define(id_, args=params, value=defs, lineno=p.lineno(2),
434439
fname=output.CURRENT_FILE[-1])
435440
p[0] = []
436441

@@ -692,6 +697,12 @@ def p_macrocall_paste(p):
692697
p[0] = Concatenation(p[1].lineno, ID_TABLE, p[1], p[3])
693698

694699

700+
def p_macrocall_stringizing(p):
701+
""" macrocall : STRINGIZING macrocall
702+
"""
703+
p[0] = Stringizing(p[2].lineno, ID_TABLE, p[2])
704+
705+
695706
def p_args(p):
696707
""" args : LLP arglist RRP
697708
"""

src/libzxbpp/zxbpplex.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
_tokens = ('STRING', 'TOKEN', 'NEWLINE', '_ENDFILE_', 'FILENAME', 'ID',
4444
'INTEGER', 'EQ', 'PUSH', 'POP', 'LP', 'LLP', 'RRP', 'RP', 'COMMA',
4545
'CONTINUE', 'NUMBER', 'SEPARATOR', 'GT', 'GE', 'LT', 'LE', 'NE',
46-
'PASTE')
46+
'PASTE', 'STRINGIZING')
4747

4848
reserved_directives = {
4949
'include': 'INCLUDE',
@@ -344,6 +344,10 @@ def t_defexpr_PASTE(self, t):
344344
r'[ \t]*\#\#[ \t]*'
345345
return t
346346

347+
def t_defexpr_STRINGIZING(self, t):
348+
r'\#[ \t]*'
349+
return t
350+
347351
def t_INITIAL_defexpr_asm_SEPARATOR(self, t):
348352
r'[ \t]+'
349353
return t

src/parsetab/tabs.dbm.bak

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
'zxbpp', (0, 70950)
2-
'asmparse', (71168, 254311)
3-
'zxnext_asmparse', (325632, 285299)
4-
'zxbparser', (611328, 712099)
1+
'zxbpp', (0, 72571)
2+
'asmparse', (72704, 254311)
3+
'zxnext_asmparse', (327168, 285299)
4+
'zxbparser', (612864, 712099)

src/parsetab/tabs.dbm.dat

1.5 KB
Binary file not shown.

src/parsetab/tabs.dbm.dir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
'zxbpp', (0, 70950)
2-
'asmparse', (71168, 254311)
3-
'zxnext_asmparse', (325632, 285299)
4-
'zxbparser', (611328, 712099)
1+
'zxbpp', (0, 72571)
2+
'asmparse', (72704, 254311)
3+
'zxnext_asmparse', (327168, 285299)
4+
'zxbparser', (612864, 712099)

tests/functional/prepro63.bi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
3+
#define q(a)XX##a
4+
5+
q(5)
6+

tests/functional/prepro63.out

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#line 1 "prepro63.bi"
2+
3+
4+
5+
6+
XX5
7+

tests/functional/stringizing0.bi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
3+
#define z(x) # x
4+
5+
z(1)
6+
7+

tests/functional/stringizing0.out

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#line 1 "stringizing0.bi"
2+
3+
4+
5+
6+
"1"
7+
8+

0 commit comments

Comments
 (0)