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