-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
135 additions
and
1 deletion.
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
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,112 @@ | ||
//! Generates a new rust module which contains the interface to the FPGA. | ||
//! | ||
//! This is still in rough shape but seems to prove the basic concept. | ||
use std::ffi::CString; | ||
|
||
use quote::quote; | ||
use syn::{ | ||
parse::{Parse, ParseStream, Result}, | ||
token::In, | ||
visit::Visit, | ||
ExprLit, LitByteStr, | ||
}; | ||
|
||
pub struct InterfaceDescription { | ||
pub signature: LitByteStr, | ||
pub filename: LitByteStr, | ||
} | ||
|
||
impl InterfaceDescription { | ||
pub fn parse_bindings(prefix: &str, content: &str) -> Self { | ||
let file = syn::parse_file(content).unwrap(); | ||
let mut sig_visitor = ByteConstantVisitor::new(prefix, "Signature"); | ||
let mut bitfile_visitor = ByteConstantVisitor::new(prefix, "Bitfile"); | ||
sig_visitor.visit_file(&file); | ||
bitfile_visitor.visit_file(&file); | ||
|
||
InterfaceDescription { | ||
signature: sig_visitor.value.unwrap(), | ||
filename: bitfile_visitor.value.unwrap(), | ||
} | ||
} | ||
|
||
pub fn generate_rust_output(&self) -> String { | ||
let signature = &self.signature; | ||
let signature_length = signature.value().len(); | ||
let bitfile = &self.filename; | ||
let bitfile_length = bitfile.value().len(); | ||
let file = syn::parse2(quote! { | ||
const SIGNATURE: [u8; #signature_length] = #signature; | ||
const FILENAME: [u8; #bitfile_length] = #bitfile; | ||
}) | ||
.unwrap(); | ||
prettyplease::unparse(&file) | ||
} | ||
} | ||
|
||
struct ByteConstantVisitor { | ||
name: String, | ||
value: Option<LitByteStr>, | ||
} | ||
|
||
impl ByteConstantVisitor { | ||
fn new(prefix: &str, suffix: &str) -> Self { | ||
Self { | ||
name: format!("NiFpga_{prefix}_{suffix}"), | ||
value: None, | ||
} | ||
} | ||
} | ||
|
||
impl<'ast> Visit<'ast> for ByteConstantVisitor { | ||
fn visit_item_const(&mut self, node: &'ast syn::ItemConst) { | ||
if node.ident == self.name { | ||
match node.expr.as_ref() { | ||
syn::Expr::Lit(ExprLit { | ||
attrs: _, | ||
lit: syn::Lit::ByteStr(lit_byte_str), | ||
}) => { | ||
self.value = Some(lit_byte_str.clone()); | ||
} | ||
_ => { | ||
Visit::visit_item_const(self, node); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::InterfaceDescription; | ||
|
||
#[test] | ||
fn test_signature_extraction() { | ||
let content = r#" | ||
pub const NiFpga_Main_Bitfile: &[u8; 19] = b"NiFpga_Main.lvbitx\0"; | ||
#[doc = " The signature of the FPGA bitfile."] | ||
pub const NiFpga_Main_Signature: &[u8; 33] = b"E3E0C23C5F01C0DBA61D947AB8A8F489\0"; | ||
"#; | ||
|
||
let description = InterfaceDescription::parse_bindings("Main", content); | ||
|
||
assert_eq!( | ||
description.signature.value(), | ||
b"E3E0C23C5F01C0DBA61D947AB8A8F489\0" | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_filename_extraction() { | ||
let content = r#" | ||
pub const NiFpga_Main_Bitfile: &[u8; 19] = b"NiFpga_Main.lvbitx\0"; | ||
#[doc = " The signature of the FPGA bitfile."] | ||
pub const NiFpga_Main_Signature: &[u8; 33] = b"E3E0C23C5F01C0DBA61D947AB8A8F489\0"; | ||
"#; | ||
|
||
let description = InterfaceDescription::parse_bindings("Main", content); | ||
|
||
assert_eq!(description.filename.value(), b"NiFpga_Main.lvbitx\0"); | ||
} | ||
} |
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