mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-04-20 00:14:45 +00:00
Clean up and improve ident parsing
This commit is contained in:
parent
8d7c88c095
commit
dbd37f97ad
3 changed files with 84 additions and 84 deletions
111
gen/src/lib.rs
111
gen/src/lib.rs
|
@ -55,6 +55,7 @@ impl OpcodeDefinitions {
|
|||
let candidate = if let DotModifierRef::Direct {
|
||||
optional: false,
|
||||
value,
|
||||
..
|
||||
} = candidate
|
||||
{
|
||||
value
|
||||
|
@ -227,11 +228,13 @@ impl SingleOpcodeDefinition {
|
|||
DotModifierRef::Direct {
|
||||
optional,
|
||||
value: alts.alternatives[0].clone(),
|
||||
name: modifier,
|
||||
}
|
||||
} else {
|
||||
DotModifierRef::Indirect {
|
||||
optional,
|
||||
value: alts.clone(),
|
||||
name: modifier,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -239,7 +242,8 @@ impl SingleOpcodeDefinition {
|
|||
possible_modifiers.insert(modifier.clone());
|
||||
DotModifierRef::Direct {
|
||||
optional,
|
||||
value: modifier,
|
||||
value: modifier.clone(),
|
||||
name: modifier,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -306,8 +310,9 @@ pub fn derive_parser(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream
|
|||
})
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
let mut token_enum = parse_definitions.token_type;
|
||||
let (_, all_modifier) = write_definitions_into_tokens(&definitions, &mut token_enum.variants);
|
||||
let token_impl = emit_parse_function(&token_enum.ident, &definitions, all_modifier);
|
||||
let (all_opcode, all_modifier) =
|
||||
write_definitions_into_tokens(&definitions, &mut token_enum.variants);
|
||||
let token_impl = emit_parse_function(&token_enum.ident, &definitions, all_opcode, all_modifier);
|
||||
let tokens = quote! {
|
||||
#enum_types_tokens
|
||||
|
||||
|
@ -364,6 +369,7 @@ fn emit_enum_types(
|
|||
fn emit_parse_function(
|
||||
type_name: &Ident,
|
||||
defs: &FxHashMap<Ident, OpcodeDefinitions>,
|
||||
all_opcode: Vec<&Ident>,
|
||||
all_modifier: FxHashSet<&parser::DotModifier>,
|
||||
) -> TokenStream {
|
||||
use std::fmt::Write;
|
||||
|
@ -437,9 +443,24 @@ fn emit_parse_function(
|
|||
.to_tokens(&mut result);
|
||||
result
|
||||
});
|
||||
let opcodes = all_opcode.into_iter().map(|op_ident| {
|
||||
let op = op_ident.to_string();
|
||||
let variant = Ident::new(&capitalize(&op), op_ident.span());
|
||||
let value = op;
|
||||
quote! {
|
||||
#type_name :: #variant => Some(#value),
|
||||
}
|
||||
});
|
||||
let modifier_names = all_modifier.iter().map(|m| m.dot_capitalized());
|
||||
quote! {
|
||||
impl<'input> #type_name<'input> {
|
||||
fn opcode_text(self) -> Option<&'static str> {
|
||||
match self {
|
||||
#(#opcodes)*
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn modifier(self) -> bool {
|
||||
match self {
|
||||
#(
|
||||
|
@ -452,7 +473,7 @@ fn emit_parse_function(
|
|||
|
||||
#(#fns_)*
|
||||
|
||||
fn parse_instruction<'a, 'input>(stream: &mut ParserState<'a, 'input>) -> winnow::error::PResult<Instruction<ParsedOperand<'input>>>
|
||||
fn parse_instruction<'a, 'input>(stream: &mut ParserState<'a, 'input>) -> winnow::error::PResult<Instruction<ParsedOperand<'input>>>
|
||||
{
|
||||
use winnow::Parser;
|
||||
use winnow::token::*;
|
||||
|
@ -490,9 +511,8 @@ fn emit_definition_parser(
|
|||
});
|
||||
let ordered_parse = definition.ordered_modifiers.iter().rev().map(|modifier| {
|
||||
let arg_name = modifier.ident();
|
||||
let arg_type = modifier.type_of();
|
||||
match modifier {
|
||||
DotModifierRef::Direct { optional, value } => {
|
||||
DotModifierRef::Direct { optional, value, .. } => {
|
||||
let variant = value.dot_capitalized();
|
||||
if *optional {
|
||||
quote! {
|
||||
|
@ -504,7 +524,7 @@ fn emit_definition_parser(
|
|||
}
|
||||
}
|
||||
}
|
||||
DotModifierRef::Indirect { optional, value } => {
|
||||
DotModifierRef::Indirect { optional, value, .. } => {
|
||||
let variants = value.alternatives.iter().map(|alt| {
|
||||
let type_ = value.type_.as_ref().unwrap();
|
||||
let token_variant = alt.dot_capitalized();
|
||||
|
@ -546,8 +566,8 @@ fn emit_definition_parser(
|
|||
.unordered_modifiers
|
||||
.iter()
|
||||
.map(|modifier| match modifier {
|
||||
DotModifierRef::Direct { value, .. } => {
|
||||
let name = value.ident();
|
||||
DotModifierRef::Direct { name, value, .. } => {
|
||||
let name = name.ident();
|
||||
let token_variant = value.dot_capitalized();
|
||||
quote! {
|
||||
#token_type :: #token_variant => {
|
||||
|
@ -558,8 +578,8 @@ fn emit_definition_parser(
|
|||
}
|
||||
}
|
||||
}
|
||||
DotModifierRef::Indirect { value, .. } => {
|
||||
let variable = value.modifier.ident();
|
||||
DotModifierRef::Indirect { value, name, .. } => {
|
||||
let variable = name.ident();
|
||||
let type_ = value.type_.as_ref().unwrap();
|
||||
let alternatives = value.alternatives.iter().map(|alt| {
|
||||
let token_variant = alt.dot_capitalized();
|
||||
|
@ -585,9 +605,10 @@ fn emit_definition_parser(
|
|||
.map(|modifier| match modifier {
|
||||
DotModifierRef::Direct {
|
||||
optional: false,
|
||||
value,
|
||||
name,
|
||||
..
|
||||
} => {
|
||||
let variable = value.ident();
|
||||
let variable = name.ident();
|
||||
quote! {
|
||||
if !#variable {
|
||||
#return_error;
|
||||
|
@ -597,9 +618,10 @@ fn emit_definition_parser(
|
|||
DotModifierRef::Direct { optional: true, .. } => TokenStream::new(),
|
||||
DotModifierRef::Indirect {
|
||||
optional: false,
|
||||
value,
|
||||
name,
|
||||
..
|
||||
} => {
|
||||
let variable = value.modifier.ident();
|
||||
let variable = name.ident();
|
||||
quote! {
|
||||
let #variable = match #variable {
|
||||
Some(x) => x,
|
||||
|
@ -749,9 +771,11 @@ enum DotModifierRef {
|
|||
Direct {
|
||||
optional: bool,
|
||||
value: parser::DotModifier,
|
||||
name: parser::DotModifier,
|
||||
},
|
||||
Indirect {
|
||||
optional: bool,
|
||||
name: parser::DotModifier,
|
||||
value: Rc<parser::Rule>,
|
||||
},
|
||||
}
|
||||
|
@ -759,8 +783,8 @@ enum DotModifierRef {
|
|||
impl DotModifierRef {
|
||||
fn ident(&self) -> Ident {
|
||||
match self {
|
||||
DotModifierRef::Direct { value, .. } => value.ident(),
|
||||
DotModifierRef::Indirect { value, .. } => value.modifier.ident(),
|
||||
DotModifierRef::Direct { name, .. } => name.ident(),
|
||||
DotModifierRef::Indirect { name, .. } => name.ident(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -770,7 +794,9 @@ impl DotModifierRef {
|
|||
DotModifierRef::Direct {
|
||||
optional: false, ..
|
||||
} => return None,
|
||||
DotModifierRef::Indirect { optional, value } => {
|
||||
DotModifierRef::Indirect {
|
||||
optional, value, ..
|
||||
} => {
|
||||
let type_ = value
|
||||
.type_
|
||||
.as_ref()
|
||||
|
@ -798,55 +824,6 @@ impl DotModifierRef {
|
|||
}
|
||||
}
|
||||
|
||||
impl Hash for DotModifierRef {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
match self {
|
||||
DotModifierRef::Direct { optional, value } => {
|
||||
optional.hash(state);
|
||||
value.hash(state);
|
||||
}
|
||||
DotModifierRef::Indirect { optional, value } => {
|
||||
optional.hash(state);
|
||||
(value.as_ref() as *const parser::Rule).hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for DotModifierRef {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(
|
||||
Self::Direct {
|
||||
optional: l_optional,
|
||||
value: l_value,
|
||||
},
|
||||
Self::Direct {
|
||||
optional: r_optional,
|
||||
value: r_value,
|
||||
},
|
||||
) => l_optional == r_optional && l_value == r_value,
|
||||
(
|
||||
Self::Indirect {
|
||||
optional: l_optional,
|
||||
value: l_value,
|
||||
},
|
||||
Self::Indirect {
|
||||
optional: r_optional,
|
||||
value: r_value,
|
||||
},
|
||||
) => {
|
||||
l_optional == r_optional
|
||||
&& l_value.as_ref() as *const parser::Rule
|
||||
== r_value.as_ref() as *const parser::Rule
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for DotModifierRef {}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn generate_instruction_type(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(tokens as gen_impl::GenerateInstructionType);
|
||||
|
|
|
@ -7,6 +7,7 @@ use std::fmt::Write;
|
|||
use syn::bracketed;
|
||||
use syn::parse::Peek;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::LitInt;
|
||||
use syn::Type;
|
||||
use syn::{braced, parse::Parse, token, Ident, ItemEnum, Token};
|
||||
|
@ -155,6 +156,10 @@ impl Rule {
|
|||
struct IdentOrTypeSuffix(IdentLike);
|
||||
|
||||
impl IdentOrTypeSuffix {
|
||||
fn span(&self) -> Span {
|
||||
self.0.span()
|
||||
}
|
||||
|
||||
fn peek(input: syn::parse::ParseStream) -> bool {
|
||||
input.peek(Token![::])
|
||||
}
|
||||
|
@ -278,6 +283,15 @@ impl std::fmt::Debug for DotModifier {
|
|||
}
|
||||
|
||||
impl DotModifier {
|
||||
pub fn span(&self) -> Span {
|
||||
let part1 = self.part1.span();
|
||||
if let Some(ref part2) = self.part2 {
|
||||
part1.join(part2.span()).unwrap_or(part1)
|
||||
} else {
|
||||
part1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ident(&self) -> Ident {
|
||||
let mut result = String::new();
|
||||
write!(&mut result, "{}", self.part1).unwrap();
|
||||
|
@ -285,11 +299,11 @@ impl DotModifier {
|
|||
write!(&mut result, "_{}", part2.0).unwrap();
|
||||
} else {
|
||||
match self.part1 {
|
||||
IdentLike::Type | IdentLike::Const => result.push('_'),
|
||||
IdentLike::Type(_) | IdentLike::Const(_) => result.push('_'),
|
||||
IdentLike::Ident(_) | IdentLike::Integer(_) => {}
|
||||
}
|
||||
}
|
||||
Ident::new(&result.to_ascii_lowercase(), Span::call_site())
|
||||
Ident::new(&result.to_ascii_lowercase(), self.span())
|
||||
}
|
||||
|
||||
pub fn variant_capitalized(&self) -> Ident {
|
||||
|
@ -321,7 +335,7 @@ impl DotModifier {
|
|||
};
|
||||
result.push(c);
|
||||
}
|
||||
Ident::new(&result, Span::call_site())
|
||||
Ident::new(&result, self.span())
|
||||
}
|
||||
|
||||
pub fn tokens(&self) -> TokenStream {
|
||||
|
@ -353,17 +367,28 @@ impl Parse for DotModifier {
|
|||
|
||||
#[derive(PartialEq, Eq, Hash, Clone)]
|
||||
enum IdentLike {
|
||||
Type,
|
||||
Const,
|
||||
Type(Token![type]),
|
||||
Const(Token![const]),
|
||||
Ident(Ident),
|
||||
Integer(LitInt),
|
||||
}
|
||||
|
||||
impl IdentLike {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
IdentLike::Type(c) => c.span(),
|
||||
IdentLike::Const(t) => t.span(),
|
||||
IdentLike::Ident(i) => i.span(),
|
||||
IdentLike::Integer(l) => l.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for IdentLike {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
IdentLike::Type => f.write_str("type"),
|
||||
IdentLike::Const => f.write_str("const"),
|
||||
IdentLike::Type(_) => f.write_str("type"),
|
||||
IdentLike::Const(_) => f.write_str("const"),
|
||||
IdentLike::Ident(ident) => write!(f, "{}", ident),
|
||||
IdentLike::Integer(integer) => write!(f, "{}", integer),
|
||||
}
|
||||
|
@ -373,8 +398,8 @@ impl std::fmt::Display for IdentLike {
|
|||
impl ToTokens for IdentLike {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
IdentLike::Type => quote! { type }.to_tokens(tokens),
|
||||
IdentLike::Const => quote! { const }.to_tokens(tokens),
|
||||
IdentLike::Type(_) => quote! { type }.to_tokens(tokens),
|
||||
IdentLike::Const(_) => quote! { const }.to_tokens(tokens),
|
||||
IdentLike::Ident(ident) => quote! { #ident }.to_tokens(tokens),
|
||||
IdentLike::Integer(int) => quote! { #int }.to_tokens(tokens),
|
||||
}
|
||||
|
@ -385,11 +410,9 @@ impl Parse for IdentLike {
|
|||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let lookahead = input.lookahead1();
|
||||
Ok(if lookahead.peek(Token![const]) {
|
||||
input.parse::<Token![const]>()?;
|
||||
IdentLike::Const
|
||||
IdentLike::Const(input.parse::<Token![const]>()?)
|
||||
} else if lookahead.peek(Token![type]) {
|
||||
input.parse::<Token![type]>()?;
|
||||
IdentLike::Type
|
||||
IdentLike::Type(input.parse::<Token![type]>()?)
|
||||
} else if lookahead.peek(Ident) {
|
||||
IdentLike::Ident(input.parse::<Ident>()?)
|
||||
} else if lookahead.peek(LitInt) {
|
||||
|
|
|
@ -2,9 +2,8 @@ use gen::derive_parser;
|
|||
use logos::Logos;
|
||||
use std::mem;
|
||||
use std::num::{ParseFloatError, ParseIntError};
|
||||
use winnow::combinator::{alt, empty, fail, opt};
|
||||
use winnow::stream::SliceLen;
|
||||
use winnow::token::{any, literal};
|
||||
use winnow::combinator::*;
|
||||
use winnow::token::any;
|
||||
use winnow::{
|
||||
error::{ContextError, ParserError},
|
||||
stream::{Offset, Stream, StreamIsPartial},
|
||||
|
@ -206,6 +205,8 @@ fn ident<'a, 'input>(stream: &mut ParserState<'a, 'input>) -> PResult<&'input st
|
|||
any.verify_map(|t| {
|
||||
if let Token::Ident(text) = t {
|
||||
Some(text)
|
||||
} else if let Some(text) = t.opcode_text() {
|
||||
Some(text)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -563,7 +564,6 @@ derive_parser!(
|
|||
pub enum ScalarType { }
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov
|
||||
|
||||
mov.type d, a => {
|
||||
Instruction::Mov{
|
||||
data: MovDetails::new(type_.into()),
|
||||
|
|
Loading…
Add table
Reference in a new issue