from __future__ import annotations
from enum import Enum, auto
from dataclasses import dataclass
from typing import List
class Type(Enum):
Void = auto()
Int = auto()
IntPointer = auto()
Double = auto()
DoublePointer = auto()
def to_rust(self) -> str:
if self == Type.Void:
return "()"
elif self == Type.Double:
return "f64"
elif self == Type.DoublePointer:
return "*mut f64"
elif self == Type.Int:
return "::libc::c_int"
elif self == Type.IntPointer:
return "*mut ::libc::c_int"
else:
raise ValueError("Type not supported")
@dataclass
class Arg:
name: str
type_: Type
@staticmethod
def from_str(inp: str) -> Arg:
inp = inp.strip()
type_, name = inp.split()
if type_ == "double":
final_type = Type.Double
elif type_ == "void":
final_type = Type.Void
elif type_ == "int":
final_type = Type.Int
else:
raise NotImplementedError(f"Type not supported: {type_}")
if name.startswith("*"):
if final_type == Type.Double:
final_type = Type.DoublePointer
elif final_type == Type.Int:
final_type = Type.IntPointer
name = name[1:]
return Arg(name, final_type)
def to_rust(self) -> str:
return f"{self.name}: {self.type_.to_rust()}"
@dataclass
class Function:
name: str
return_type: Type
args: List[Arg]
@staticmethod
def from_decl(full_decl: str) -> Function:
decl_string, params_string = full_decl.split("(")
decl = Arg.from_str(decl_string)
params = [Arg.from_str(p) for p in params_string.split(")")[0].split(",")]
return Function(decl.name, decl.type_, params)
def to_rust(self) -> str:
params = ",".join(arg.to_rust() for arg in self.args)
return_type = ""
if self.return_type != Type.Void:
return_type = f"-> {self.return_type.to_rust()}"
return f"""
#[no_mangle]
pub unsafe extern "C" fn {self.name}({params}) {return_type} {{
unimplemented!()
}}
"""
def main() -> None:
functions = []
with open("gswteos-10.h", "r") as header:
current_line: List[str] = []
for line in header:
line = line.strip()
if line.startswith("extern") and not 'extern "C"' in line:
line = line.strip("extern ")
if current_line:
full_decl = "".join(current_line)
functions.append(Function.from_decl(full_decl))
current_line = [line.strip()]
elif not line.startswith("extern") and current_line:
current_line += line
if current_line:
full_decl = "".join(current_line)
functions.append(Function.from_decl(full_decl))
for func in functions:
print(func.to_rust())
if __name__ == "__main__":
main()