serde nonsense

This commit is contained in:
Parker TenBroeck 2026-01-11 16:35:17 -05:00
parent 90d96f0738
commit c06a0a0147
4 changed files with 176 additions and 81 deletions

View file

@ -2,51 +2,60 @@ use std::collections::HashSet;
use super::*;
use crate::{delta_lower, gamma_upper, loader::{
use crate::{delta_lower, dual_struct_serde, gamma_upper, loader::{
Context, INITIAL_STACK, INITIAL_STATE, Spanned, ast::{self, Symbol as Sym}, log::LogSink
}, sigma_upper};
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct TransitionFrom<'a> {
pub state: State<'a>,
pub letter: Option<Letter<'a>>,
pub symbol: Symbol<'a>,
dual_struct_serde! {
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct TransitionFrom<'a> {
#[serde(borrow)]
pub state: State<'a>,
#[serde(borrow)]
pub letter: Option<Letter<'a>>,
#[serde(borrow)]
pub symbol: Symbol<'a>,
}
}
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct TransitionTo<'a> {
pub state: State<'a>,
pub stack: Vec<Symbol<'a>>,
dual_struct_serde! {
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct TransitionTo<'a> {
#[serde(borrow)]
pub state: State<'a>,
#[serde(borrow)]
pub stack: Vec<Symbol<'a>>,
pub transition: Span,
pub function: Span,
pub transition: Span,
pub function: Span,
}
}
#[derive(Clone, Debug)]
#[allow(unused)]
#[cfg_attr(feature = "serde", serde_with::serde_as)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Pda<'a> {
pub initial_state: State<'a>,
pub initial_stack: Symbol<'a>,
pub states: HashMap<State<'a>, StateInfo>,
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
pub alphabet: HashMap<Letter<'a>, LetterInfo>,
dual_struct_serde! { {#[serde_with::serde_as]}
#[derive(Clone, Debug)]
pub struct Pda<'a> {
#[serde(borrow)]
pub initial_state: State<'a>,
#[serde(borrow)]
pub initial_stack: Symbol<'a>,
#[serde(borrow)]
pub states: HashMap<State<'a>, StateInfo>,
#[serde(borrow)]
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
#[serde(borrow)]
pub alphabet: HashMap<Letter<'a>, LetterInfo>,
pub final_states: Option<HashMap<State<'a>, StateInfo>>,
#[serde(borrow)]
pub final_states: Option<HashMap<State<'a>, StateInfo>>,
#[cfg(feature = "serde")]
#[serde_as(as = "serde_with::Seq<(_, _)>")]
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
#[cfg(not(feature = "serde"))]
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
#[serde(borrow)]
#[serde_as(as = "serde_with::Seq<(_, _)>")]
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
}
}
impl<'a> Pda<'a> {
pub fn parse(
pub fn compile(
items: impl Iterator<Item = Spanned<ast::TopLevel<'a>>>,
ctx: &mut Context<'a>,
options: Options,

View file

@ -2,57 +2,65 @@ use std::collections::HashSet;
use super::*;
use crate::{delta_lower, gamma_upper, loader::{
use crate::{delta_lower, dual_struct_serde, gamma_upper, loader::{
BLANK_SYMBOL, Context, Spanned, ast::{self, Symbol as Sym}, log::LogSink
}};
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct TransitionFrom<'a> {
pub state: State<'a>,
pub symbol: Symbol<'a>,
dual_struct_serde! {
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct TransitionFrom<'a> {
#[serde(borrow)]
pub state: State<'a>,
#[serde(borrow)]
pub symbol: Symbol<'a>,
}
}
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Direction {
Left,
Right,
None,
}
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct TransitionTo<'a> {
pub state: State<'a>,
pub symbol: Symbol<'a>,
pub direction: Direction,
dual_struct_serde! {
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct TransitionTo<'a> {
#[serde(borrow)]
pub state: State<'a>,
#[serde(borrow)]
pub symbol: Symbol<'a>,
pub direction: Direction,
pub transition: Span,
pub function: Span,
pub transition: Span,
pub function: Span,
}
}
#[derive(Clone, Debug)]
#[allow(unused)]
#[cfg_attr(feature = "serde", serde_with::serde_as)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Tm<'a> {
pub initial_state: State<'a>,
pub initial_tape: Symbol<'a>,
pub states: HashMap<State<'a>, StateInfo>,
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
dual_struct_serde! {{#[serde_with::serde_as]}
#[derive(Clone, Debug)]
pub struct Tm<'a> {
#[serde(borrow)]
pub initial_state: State<'a>,
#[serde(borrow)]
pub initial_tape: Symbol<'a>,
#[serde(borrow)]
pub states: HashMap<State<'a>, StateInfo>,
#[serde(borrow)]
pub symbols: HashMap<Symbol<'a>, SymbolInfo>,
pub final_states: HashMap<State<'a>, StateInfo>,
#[serde(borrow)]
pub final_states: HashMap<State<'a>, StateInfo>,
#[cfg(feature = "serde")]
#[serde_as(as = "serde_with::Seq<(_, _)>")]
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
#[cfg(not(feature = "serde"))]
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
#[serde(borrow)]
#[serde_as(as = "serde_with::Seq<(_, _)>")]
pub transitions: HashMap<TransitionFrom<'a>, HashSet<TransitionTo<'a>>>,
}
}
impl<'a> Tm<'a> {
pub fn parse(
pub fn compile(
items: impl Iterator<Item = Spanned<ast::TopLevel<'a>>>,
ctx: &mut Context<'a>,
options: Options,

View file

@ -1,7 +1,6 @@
pub mod automatan;
pub mod loader;
#[macro_export]
macro_rules! dual_struct_serde {
($({$(#[$serde_specific:meta])*})?
@ -34,3 +33,82 @@ macro_rules! dual_struct_serde {
}
};
}
#[macro_export]
macro_rules! dual_enum_serde {
(
$( {$(#[$serde_specific:meta])*} )?
$(#[$enum_meta:meta])*
$vis:vis enum $Name:ident $(<$($gen:tt),*>)?
{
$(
$(#[$variant_meta:meta])*
$Variant:ident
$(
// Tuple variant: Variant(T1, T2, ...)
( $(
$(#[$tfield_meta:meta])*
$tfield_ty:ty
),* $(,)? )
)?
$(
// Struct variant: Variant { a: T, b: U, ... }
{ $(
$(#[$sfield_meta:meta])*
$sfield_vis:vis $sfield_name:ident : $sfield_ty:ty
),* $(,)? }
)?
),* $(,)?
}
) => {
#[cfg(feature = "serde")]
$(#[$enum_meta])*
#[derive(serde::Serialize, serde::Deserialize)]
$( $(#[$serde_specific])* )?
$vis enum $Name $(<$($gen),*>)? {
$(
$(#[$variant_meta])*
$Variant
$(
(
$(
$(#[$tfield_meta])*
$tfield_ty
),*
)
)?
$(
{
$(
$(#[$sfield_meta])*
$sfield_vis $sfield_name: $sfield_ty
),*
}
)?
),*
}
#[cfg(not(feature = "serde"))]
$(#[$enum_meta])*
$vis enum $Name $(<$($gen),*>)? {
$(
// strip variant + field attrs in non-serde version
$Variant
$(
(
$(
$tfield_ty
),*
)
)?
$(
{
$(
$sfield_vis $sfield_name: $sfield_ty
),*
}
)?
),*
}
};
}

View file

@ -1,9 +1,8 @@
use crate::{
automatan::*,
loader::{
automatan::*, dual_enum_serde, dual_struct_serde, loader::{
ast::TopLevel,
log::{LogEntry, LogSink},
},
}
};
pub mod ast;
@ -120,13 +119,14 @@ impl<'a> Context<'a> {
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[cfg_attr(feature = "serde", serde(tag = "type"))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Machine<'a> {
Fa(fa::Fa<'a>),
Pda(pda::Pda<'a>),
Tm(tm::Tm<'a>),
dual_enum_serde!{
{#[serde(tag = "type")] #[serde(rename_all = "snake_case")]}
#[derive(Clone, Debug)]
pub enum Machine<'a> {
Fa(#[serde(borrow)] fa::Fa<'a>),
Pda(#[serde(borrow)] pda::Pda<'a>),
Tm(#[serde(borrow)] tm::Tm<'a>),
}
}
pub fn parse_universal<'a>(ctx: &mut Context<'a>) -> Option<Machine<'a>> {
@ -194,9 +194,9 @@ pub fn parse_universal<'a>(ctx: &mut Context<'a>) -> Option<Machine<'a>> {
Some(match parse_type(items.next(), ctx)? {
Type::Dfa => Machine::Fa(fa::Fa::compile(items, ctx, D)?),
Type::Nfa => Machine::Fa(fa::Fa::compile(items, ctx, N)?),
Type::Dpda => Machine::Pda(pda::Pda::parse(items, ctx, D)?),
Type::Npda => Machine::Pda(pda::Pda::parse(items, ctx, N)?),
Type::Tm => Machine::Tm(tm::Tm::parse(items, ctx, D)?),
Type::Ntm => Machine::Tm(tm::Tm::parse(items, ctx, N)?),
Type::Dpda => Machine::Pda(pda::Pda::compile(items, ctx, D)?),
Type::Npda => Machine::Pda(pda::Pda::compile(items, ctx, N)?),
Type::Tm => Machine::Tm(tm::Tm::compile(items, ctx, D)?),
Type::Ntm => Machine::Tm(tm::Tm::compile(items, ctx, N)?),
})
}