Skip to content

Commit fe798d9

Browse files
committed
Add more macro cases
1 parent af19b7c commit fe798d9

File tree

1 file changed

+80
-3
lines changed

1 file changed

+80
-3
lines changed

src/generator/macro.jl

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,20 @@ function is_macro_constants(toks)
8989
end
9090
end
9191

92+
function is_macro_constants_with_conv(toks)
93+
if toks.size == 5 &&
94+
toks[1].kind == CXToken_Identifier &&
95+
toks[2].kind == CXToken_Identifier &&
96+
toks[3].kind == CXToken_Punctuation &&
97+
toks[4].kind == CXToken_Literal &&
98+
toks[5].kind == CXToken_Punctuation
99+
# `#define CONSTANT_LITERALS_CONV CLONG ( 1 )`
100+
return true
101+
else
102+
return false
103+
end
104+
end
105+
92106
function is_macro_naive_alias(toks)
93107
if toks.size == 2 &&
94108
toks[1].kind == CXToken_Identifier &&
@@ -181,6 +195,39 @@ function is_macro_binary_operator(toks)
181195
end
182196
end
183197

198+
function is_macro_naive_arithmetic(toks)
199+
toks[1].kind != CXToken_Identifier && return false
200+
toks.size < 4 && return false
201+
202+
# only allows `Identifier`, `Literal`, `Punctuation`(C_OPERATORS and brackets)
203+
is_naive = all(toks) do tok
204+
if tok.kind == CXToken_Punctuation
205+
return tok.text C_OPERATORS || tok.text == "(" || tok.text == ")"
206+
elseif tok.kind == CXToken_Identifier
207+
return !startswith(tok.text, "__") # ignore compiler defs
208+
else
209+
return true
210+
end
211+
end
212+
213+
# if there is no binary operator, skip
214+
all(x->x.text C_OPERATORS, toks) && return false
215+
216+
# try to parse the expression
217+
if is_naive
218+
try
219+
txts = [tok.kind == CXToken_Literal ? literally(tok) : tok.text for tok in collect(toks)[2:end]]
220+
str = reduce(add_spaces_for_macros, txts)
221+
Meta.parse(str)
222+
return true
223+
catch err
224+
# pass
225+
end
226+
end
227+
228+
return false
229+
end
230+
184231
function add_spaces_for_macros(lhs, rhs)
185232
if startswith(rhs, "(") # handle function call
186233
if endswith(lhs, "?") || endswith(lhs, ":") # handle trinary operator
@@ -253,9 +300,11 @@ function macro_emit!(dag::ExprDAG, node::ExprNode{MacroDefault}, options::Dict)
253300
cursor = node.cursor
254301
tokens = tokenize(cursor)
255302

256-
if !ignore_pure_def && is_macro_pure_definition(tokens)
257-
sym = make_symbol_safe(tokens[1].text)
258-
push!(node.exprs, Expr(:const, Expr(:(=), sym, :nothing)))
303+
if is_macro_pure_definition(tokens)
304+
if !ignore_pure_def
305+
sym = make_symbol_safe(tokens[1].text)
306+
push!(node.exprs, Expr(:const, Expr(:(=), sym, :nothing)))
307+
end
259308
return dag
260309
end
261310

@@ -268,6 +317,16 @@ function macro_emit!(dag::ExprDAG, node::ExprNode{MacroDefault}, options::Dict)
268317
return dag
269318
end
270319

320+
if is_macro_constants_with_conv(tokens)
321+
literal_tok = tokens[4]
322+
literals = literally(literal_tok)
323+
sym = make_symbol_safe(tokens[1].text)
324+
csym = make_symbol_safe(tokens[2].text)
325+
literal_sym = Meta.parse(literals)
326+
push!(node.exprs, Expr(:const, Expr(:(=), sym, Expr(:call, csym, literal_sym))))
327+
return dag
328+
end
329+
271330
if is_macro_naive_alias(tokens)
272331
lhs, rhs = tokens
273332
lhs_sym = make_symbol_safe(lhs.text)
@@ -312,6 +371,24 @@ function macro_emit!(dag::ExprDAG, node::ExprNode{MacroDefault}, options::Dict)
312371
return dag
313372
end
314373

374+
if is_macro_naive_arithmetic(tokens)
375+
sym = make_symbol_safe(tokens[1].text)
376+
txts = Vector{String}(undef, length(tokens)-1)
377+
for (i, tok) in enumerate(collect(tokens)[2:end])
378+
if tok.kind == CXToken_Literal
379+
txts[i] = literally(tok)
380+
elseif tok.kind == CXToken_Punctuation && tok.text C_OPERATORS
381+
txts[i] = tok.text == "/" ? "÷" :
382+
tok.text == "^" ? "" : tok.text
383+
else
384+
txts[i] = tok.text
385+
end
386+
end
387+
str = reduce(add_spaces_for_macros, txts)
388+
push!(node.exprs, Expr(:const, Expr(:(=), sym, Meta.parse(str))))
389+
return dag
390+
end
391+
315392
# for all the other cases, we just blindly use Julia's Meta.parse to parse the C code.
316393
if tokens.size > 1 && tokens[1].kind == CXToken_Identifier && mode == "aggressive"
317394
sym = make_symbol_safe(tokens[1].text)

0 commit comments

Comments
 (0)