Skip to content

Commit

Permalink
tools: generate_syscall_library script
Browse files Browse the repository at this point in the history
very initial version of a tool that generates libraries from syn-serde
dumps of tock capsules

```
❯ ./generate_syscall_library.py ../button.json

extern "C" {

returncode_t libtock_button_command_enable_interrupt();

returncode_t libtock_button_command_disable_interrupt();

returncode_t libtock_button_command_read();

}
```
  • Loading branch information
bradjc committed Jul 19, 2024
1 parent d1034b0 commit 6c18398
Showing 1 changed file with 127 additions and 0 deletions.
127 changes: 127 additions & 0 deletions tools/generate_syscall_library.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env python3

# Licensed under the Apache License, Version 2.0 or the MIT License.
# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright Tock Contributors 2024.

"""
git clone [email protected]:taiki-e/syn-serde.git
cd syn-serde/examples/rust2json
cargo run -- ../../tock/capsules/core/src/button.rs > ../../tock/button.json
then run this
./generate_syscall_library.py ../button.json
"""


import json
import sys
import pathlib
from pathlib import Path

sys.setrecursionlimit(10**6)

syntax_filename = sys.argv[1]
capsule = pathlib.Path(syntax_filename).stem


def search(tree, goal):
if isinstance(tree, list):
found = []
for i in tree:
r = search(i, goal)
if r != None:
found.extend(r)
return found

elif isinstance(tree, dict):
found = []
for k, v in tree.items():
if k == goal:
found.append(v)
continue
r = search(v, goal)
if r != None:
found.extend(r)
return found
else:
if goal == tree:
return [tree]
return None

return None


def find_matching_fn(fns, search_fn):
for fn in fns:
function_name = fn["ident"]
if function_name == search_fn:
return fn


commands = []
fns = None


with open(syntax_filename) as f:
s = json.load(f)

fns = search(s, "fn")

fn = find_matching_fn(fns, "command")

function_name = fn["ident"]

if function_name == "command":
fn_body = fn["stmts"]

match_stmt = search(fn_body, "match")[0]

match_arms = match_stmt["arms"]

for arm in match_arms:
try:
command_index = arm["pat"]["lit"]["int"]

if command_index == 0:
continue

op = arm["body"]["method_call"]["method"]

commands.append((command_index, op))
except:
pass

c_header = """
#pragma once
#include "../../tock.h"
#ifdef __cplusplus
extern "C" {
#endif
"""
print(c_header)

c_fn_format = """
{comment}
returncode_t libtock_{capsule}_{fn_name}();
"""

for commandnum, fn_name in commands:
fn = find_matching_fn(fns, fn_name)

c_fn = c_fn_format.format(comment="", capsule=capsule, fn_name=fn_name)

print(c_fn)

c_footer = """
#ifdef __cplusplus
}
#endif
"""

print(c_footer)

0 comments on commit 6c18398

Please sign in to comment.