Skip to content

Commit 342572b

Browse files
committed
fix: fixed gen slot cpp use before declare error
1 parent e2a6499 commit 342572b

File tree

1 file changed

+53
-89
lines changed

1 file changed

+53
-89
lines changed

tapa/common/floorplan/gen_slot_cpp.py

Lines changed: 53 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ def gen_slot_cpp(slot_name: str, top_name: str, ports: list, top_cpp: str) -> st
113113
if "*" in port_type:
114114
port_type = "uint64_t"
115115

116+
# remove const from type for reinterpret_cast
117+
if port_type.startswith("const "):
118+
port_type = port_type.replace("const ", "")
119+
116120
cpp_ports.append(
117121
_PORT_TEMPLATE[port_cat].format(
118122
name=name,
@@ -174,116 +178,76 @@ def replacer(match: re.Match) -> str:
174178
return re.sub(pattern, replacer, code, flags=re.DOTALL | re.MULTILINE)
175179

176180

177-
# ruff: noqa: PLR0912, C901
178-
def find_function_definition(
179-
code: str, func_name: str
180-
) -> tuple[int | None, int | None]:
181-
"""Finds the start and end index of the function definition in the code.
181+
def find_extern_c_function_block(
182+
code: str, func_name: str, is_definition: bool
183+
) -> tuple[int, int] | None:
184+
"""Finds the start & end index of the extern "C" block of the given function.
182185
183186
Args:
184187
code: The full source code.
185188
func_name: Name of the function to locate.
189+
is_definition: Whether to look for a definition (with body) or
190+
declaration (ending in semicolon).
186191
187192
Returns:
188-
A tuple (start_index, end_index) of the function body, or (None, None)
189-
if not found.
193+
A tuple (start_index, end_index) of the full extern "C" block,
194+
or None if not found.
190195
"""
191-
code_no_comments = remove_comments_and_strings(code)
192-
193-
pattern = rf"\bvoid\s+{re.escape(func_name)}\s*\(([^)]*)\)\s*\{{"
194-
match = re.search(pattern, code_no_comments)
195-
if not match:
196-
return None, None
197-
198-
start = match.start()
199-
open_braces = 0
200-
in_comment = False
201-
i = match.end() - 1
202-
203-
while i < len(code):
204-
c = code[i]
205-
if code[i : i + 2] == "/*":
206-
in_comment = True
207-
i += 2
208-
continue
209-
if code[i : i + 2] == "*/" and in_comment:
210-
in_comment = False
211-
i += 2
212-
continue
213-
if code[i : i + 2] == "//" and not in_comment:
214-
i = code.find("\n", i)
215-
if i == -1:
216-
break
217-
continue
218-
if c in {'"', "'"} and not in_comment:
219-
quote = c
220-
i += 1
221-
while i < len(code) and code[i] != quote:
222-
if code[i] == "\\":
223-
i += 1 # Skip escaped characters
224-
i += 1
225-
i += 1
226-
continue
227-
228-
if not in_comment:
229-
if c == "{":
230-
open_braces += 1
231-
elif c == "}":
232-
open_braces -= 1
233-
if open_braces == 0:
234-
return start, i + 1
235-
i += 1
236-
237-
return None, None
238-
239-
240-
def replace_function_declaration(code: str, func_name: str, new_decl: str) -> str:
241-
"""Replaces the function declaration of the given function name with a new one.
196+
if is_definition:
197+
signature = rf"void\s+{re.escape(func_name)}\s*\([^)]*\)\s*\{{"
198+
else:
199+
signature = rf"void\s+{re.escape(func_name)}\s*\([^)]*\)\s*;"
200+
201+
# Full extern "C" block pattern
202+
pattern = (
203+
rf'extern\s+"C"\s*\{{\s*'
204+
rf"{signature}.*?"
205+
rf'\}}\s*//\s*extern\s+"C"'
206+
)
242207

243-
Args:
244-
code: The full source code.
245-
func_name: The function whose declaration is to be replaced.
246-
new_decl: The new declaration string (e.g., `void foo(int a);`)
247-
248-
Returns:
249-
The updated source code with the declaration replaced.
250-
"""
251-
pattern = rf"\bvoid\s+{re.escape(func_name)}\s*\([^)]*\)\s*;"
252-
return re.sub(pattern, new_decl, code)
208+
match = re.search(pattern, code, flags=re.DOTALL)
209+
if match:
210+
return match.start(), match.end()
211+
return None
253212

254213

255-
def replace_function_definition(code: str, func_name: str, new_def: str) -> str:
256-
"""Replaces the full function definition of the given function.
214+
def remove_extern_c_function_block(
215+
code: str, func_name: str, is_definition: bool
216+
) -> str:
217+
"""Removes the extern "C" block containing the specified function.
257218
258219
Args:
259-
code: The full source code.
260-
func_name: The function whose definition is to be replaced.
261-
new_def: The new function definition code block.
220+
code: The source code.
221+
func_name: The name of the function.
222+
is_definition: Whether it's a definition or declaration.
262223
263224
Returns:
264-
The updated source code with the definition replaced.
265-
266-
Raises:
267-
ValueError: If the function definition is not found.
225+
The source code with the block removed.
268226
"""
269-
start, end = find_function_definition(code, func_name)
270-
if start is None or end is None:
271-
msg = f"Function definition for '{func_name}' not found."
272-
raise ValueError(msg)
273-
return code[:start] + new_def + code[end:]
227+
bounds = find_extern_c_function_block(code, func_name, is_definition)
228+
if bounds:
229+
start, end = bounds
230+
return code[:start] + code[end:]
231+
return code
274232

275233

276234
def replace_function(code: str, func_name: str, new_decl: str, new_def: str) -> str:
277-
"""Replaces both declaration and definition of a function in a C++ source file.
235+
"""Replaces both the extern "C" declaration and definition of a function.
278236
279237
Args:
280-
code: Original source code.
238+
code: The original source code.
281239
func_name: The function to replace.
282-
new_decl: The new declaration string.
283-
new_def: The new definition string.
240+
new_decl: The new declaration (e.g., `void foo(int x);`)
241+
new_def: The new full definition (e.g., `void foo(int x) { ... }`)
284242
285243
Returns:
286-
The updated code with both declaration and definition replaced.
244+
The updated source code with the function declaration and definition replaced.
287245
"""
288-
code = replace_function_declaration(code, func_name, new_decl)
289-
return replace_function_definition(code, func_name, new_def)
246+
# Remove old extern "C" declaration and definition blocks
247+
code = remove_extern_c_function_block(code, func_name, is_definition=False)
248+
code = remove_extern_c_function_block(code, func_name, is_definition=True)
249+
250+
# Append new extern "C" declaration and definition blocks to the end
251+
decl_block = f'extern "C" {{\n{new_decl.strip()}\n}} // extern "C"\n'
252+
def_block = f'extern "C" {{\n{new_def.strip()}\n}} // extern "C"\n'
253+
return code.rstrip() + "\n\n" + decl_block + "\n\n" + def_block + "\n"

0 commit comments

Comments
 (0)