-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tools: generate_syscall_library script
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
Showing
1 changed file
with
127 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |