Skip to content

Commit f82dddc

Browse files
committed
Implement STRINGIZING zxbpp operator
1 parent 37e421c commit f82dddc

9 files changed

Lines changed: 79 additions & 3 deletions

File tree

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: 9 additions & 2 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

@@ -692,6 +693,12 @@ def p_macrocall_paste(p):
692693
p[0] = Concatenation(p[1].lineno, ID_TABLE, p[1], p[3])
693694

694695

696+
def p_macrocall_stringizing(p):
697+
""" macrocall : STRINGIZING macrocall
698+
"""
699+
p[0] = Stringizing(p[2].lineno, ID_TABLE, p[2])
700+
701+
695702
def p_args(p):
696703
""" args : LLP arglist RRP
697704
"""
@@ -826,7 +833,7 @@ def main(argv):
826833
return global_.has_errors
827834

828835

829-
parser = src.api.utils.get_or_create('zxbpp', lambda: yacc.yacc(debug=True))
836+
parser = yacc.yacc(debug=True)
830837

831838
parser.defaulted_states = {}
832839
ID_TABLE = DefinesTable()

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

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+

tests/functional/stringizing1.bi

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

tests/functional/stringizing1.out

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

tests/functional/stringizing2.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("a "" string")
6+
7+

tests/functional/stringizing2.out

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

0 commit comments

Comments
 (0)