Skip to content

Commit 6b1f6b3

Browse files
committed
Move marshalling API into submodule
1 parent 32f772a commit 6b1f6b3

File tree

2 files changed

+247
-241
lines changed

2 files changed

+247
-241
lines changed

pikelet/src/lang/core.rs

+1-241
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::sync::Arc;
99

1010
use crate::lang::Located;
1111

12+
pub mod marshall;
1213
pub mod semantics;
1314
pub mod typing;
1415

@@ -313,244 +314,3 @@ impl<Entry: Clone + fmt::Debug> fmt::Debug for Locals<Entry> {
313314
.finish()
314315
}
315316
}
316-
317-
pub trait HasType {
318-
fn r#type() -> Arc<Term>;
319-
}
320-
321-
macro_rules! impl_has_type {
322-
($Self:ty, $term:expr) => {
323-
impl HasType for $Self {
324-
fn r#type() -> Arc<Term> {
325-
Arc::new($term)
326-
}
327-
}
328-
};
329-
}
330-
331-
impl_has_type!(bool, Term::generated(TermData::Global("Bool".to_owned())));
332-
impl_has_type!(u8, Term::generated(TermData::Global("U8".to_owned())));
333-
impl_has_type!(u16, Term::generated(TermData::Global("U16".to_owned())));
334-
impl_has_type!(u32, Term::generated(TermData::Global("U32".to_owned())));
335-
impl_has_type!(u64, Term::generated(TermData::Global("U64".to_owned())));
336-
impl_has_type!(i8, Term::generated(TermData::Global("S8".to_owned())));
337-
impl_has_type!(i16, Term::generated(TermData::Global("S16".to_owned())));
338-
impl_has_type!(i32, Term::generated(TermData::Global("S32".to_owned())));
339-
impl_has_type!(i64, Term::generated(TermData::Global("S64".to_owned())));
340-
impl_has_type!(f32, Term::generated(TermData::Global("F32".to_owned())));
341-
impl_has_type!(f64, Term::generated(TermData::Global("F64".to_owned())));
342-
impl_has_type!(char, Term::generated(TermData::Global("Char".to_owned())));
343-
impl_has_type!(
344-
String,
345-
Term::generated(TermData::Global("String".to_owned()))
346-
);
347-
impl_has_type!(str, Term::generated(TermData::Global("String".to_owned())));
348-
349-
impl<T: HasType> HasType for Vec<T> {
350-
fn r#type() -> Arc<Term> {
351-
Arc::new(Term::generated(TermData::FunctionElim(
352-
Arc::new(Term::generated(TermData::Global("List".to_owned()))),
353-
T::r#type(),
354-
)))
355-
}
356-
}
357-
358-
macro_rules! impl_has_type_array {
359-
($($len:expr),*) => {
360-
$(impl<T: HasType> HasType for [T; $len] {
361-
fn r#type() -> Arc<Term> {
362-
Arc::new(Term::generated(TermData::FunctionElim(
363-
Arc::new(Term::generated(TermData::FunctionElim(
364-
Arc::new(Term::generated(TermData::Global("List".to_owned()))),
365-
Arc::new(Term::generated(TermData::from(Constant::U32($len as u32)))),
366-
))),
367-
T::r#type(),
368-
)))
369-
}
370-
})*
371-
};
372-
}
373-
374-
impl_has_type_array!(
375-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
376-
26, 27, 28, 29, 30, 31, 32
377-
);
378-
379-
/// Attempt to deserialize something from a `Term`.
380-
///
381-
/// # Laws
382-
///
383-
/// ```skipped
384-
/// check_type(&term, &Self::r#type()) && Self::try_from_term(term).is_ok()
385-
/// ```
386-
// TODO: Make more efficient with visitors
387-
pub trait TryFromTerm: HasType + Sized {
388-
type Error: Sized;
389-
fn try_from_term(term: &Term) -> Result<Self, Self::Error>;
390-
}
391-
392-
macro_rules! impl_try_from_term {
393-
($Self:ty, |$p:pat| $term:expr) => {
394-
impl TryFromTerm for $Self {
395-
type Error = ();
396-
397-
fn try_from_term(term: &Term) -> Result<$Self, ()> {
398-
match &term.data {
399-
$p => $term,
400-
_ => Err(()),
401-
}
402-
}
403-
}
404-
};
405-
}
406-
407-
impl_try_from_term!(bool, |TermData::Global(name)| match name.as_str() {
408-
"true" => Ok(true),
409-
"false" => Ok(false),
410-
_ => Err(()),
411-
});
412-
impl_try_from_term!(u8, |TermData::Constant(Constant::U8(value))| Ok(*value));
413-
impl_try_from_term!(u16, |TermData::Constant(Constant::U16(value))| Ok(*value));
414-
impl_try_from_term!(u32, |TermData::Constant(Constant::U32(value))| Ok(*value));
415-
impl_try_from_term!(u64, |TermData::Constant(Constant::U64(value))| Ok(*value));
416-
impl_try_from_term!(i8, |TermData::Constant(Constant::S8(value))| Ok(*value));
417-
impl_try_from_term!(i16, |TermData::Constant(Constant::S16(value))| Ok(*value));
418-
impl_try_from_term!(i32, |TermData::Constant(Constant::S32(value))| Ok(*value));
419-
impl_try_from_term!(i64, |TermData::Constant(Constant::S64(value))| Ok(*value));
420-
impl_try_from_term!(f32, |TermData::Constant(Constant::F32(value))| Ok(*value));
421-
impl_try_from_term!(f64, |TermData::Constant(Constant::F64(value))| Ok(*value));
422-
impl_try_from_term!(char, |TermData::Constant(Constant::Char(value))| Ok(*value));
423-
impl_try_from_term!(String, |TermData::Constant(Constant::String(value))| Ok(
424-
value.clone(),
425-
));
426-
427-
impl<T: TryFromTerm> TryFromTerm for Vec<T> {
428-
type Error = ();
429-
430-
fn try_from_term(term: &Term) -> Result<Vec<T>, ()> {
431-
match &term.data {
432-
TermData::ListTerm(entry_terms) => entry_terms
433-
.iter()
434-
.map(|entry_term| T::try_from_term(entry_term).map_err(|_| ()))
435-
.collect::<Result<Vec<_>, ()>>(),
436-
_ => Err(()),
437-
}
438-
}
439-
}
440-
441-
macro_rules! impl_try_from_term_array {
442-
($($len:expr),*) => {
443-
$(impl<T: TryFromTerm + Sized> TryFromTerm for [T; $len] {
444-
type Error = ();
445-
446-
fn try_from_term(term: &Term) -> Result<[T; $len], ()> {
447-
match &term.data {
448-
TermData::ArrayTerm(entry_terms) if entry_terms.len() == $len => {
449-
use std::mem::MaybeUninit;
450-
451-
let mut entries: [MaybeUninit::<T>; $len] = unsafe {
452-
MaybeUninit::uninit().assume_init()
453-
};
454-
for (i, entry_term) in entry_terms.iter().enumerate() {
455-
entries[i] = MaybeUninit::new(T::try_from_term(entry_term).map_err(|_| ())?);
456-
}
457-
458-
// NOTE: We'd prefer to do the following:
459-
//
460-
// ```
461-
// Ok(unsafe { std::mem::transmute::<_, [T; $len]>(entries) })
462-
// ```
463-
//
464-
// Sadly we run into the following issue: https://github.com/rust-lang/rust/issues/61956
465-
// For this reason we need to do the following (hideous) workaround:
466-
467-
let ptr = &mut entries as *mut _ as *mut [T; $len];
468-
let result = unsafe { ptr.read() };
469-
core::mem::forget(entries);
470-
Ok(result)
471-
},
472-
_ => Err(()),
473-
}
474-
}
475-
})*
476-
};
477-
}
478-
479-
impl_try_from_term_array!(
480-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
481-
26, 27, 28, 29, 30, 31, 32
482-
);
483-
484-
/// Serialize something to a `Term`.
485-
///
486-
/// # Laws
487-
///
488-
/// ```skipped
489-
/// check_type(&Self::to_term(&value), &Self::r#type()) == true
490-
/// ```
491-
// TODO: Make more efficient with visitors
492-
pub trait ToTerm: HasType {
493-
fn to_term(&self) -> Term;
494-
}
495-
496-
macro_rules! impl_to_term {
497-
($Self:ty, |$p:pat| $term_data:expr) => {
498-
impl ToTerm for $Self {
499-
fn to_term(&self) -> Term {
500-
let $p = self;
501-
Term::generated($term_data)
502-
}
503-
}
504-
};
505-
}
506-
507-
impl_to_term!(bool, |value| match value {
508-
true => TermData::Global("true".to_owned()),
509-
false => TermData::Global("false".to_owned()),
510-
});
511-
impl_to_term!(u8, |value| TermData::from(Constant::U8(*value)));
512-
impl_to_term!(u16, |value| TermData::from(Constant::U16(*value)));
513-
impl_to_term!(u32, |value| TermData::from(Constant::U32(*value)));
514-
impl_to_term!(u64, |value| TermData::from(Constant::U64(*value)));
515-
impl_to_term!(i8, |value| TermData::from(Constant::S8(*value)));
516-
impl_to_term!(i16, |value| TermData::from(Constant::S16(*value)));
517-
impl_to_term!(i32, |value| TermData::from(Constant::S32(*value)));
518-
impl_to_term!(i64, |value| TermData::from(Constant::S64(*value)));
519-
impl_to_term!(f32, |value| TermData::from(Constant::F32(*value)));
520-
impl_to_term!(f64, |value| TermData::from(Constant::F64(*value)));
521-
impl_to_term!(char, |value| TermData::from(Constant::Char(*value)));
522-
impl_to_term!(String, |value| TermData::from(Constant::String(
523-
value.clone()
524-
)));
525-
impl_to_term!(str, |value| TermData::from(Constant::String(
526-
value.to_owned()
527-
)));
528-
529-
impl<T: ToTerm> ToTerm for Vec<T> {
530-
fn to_term(&self) -> Term {
531-
Term::generated(TermData::ListTerm(
532-
self.iter()
533-
.map(|entry_term| Arc::new(T::to_term(entry_term)))
534-
.collect(),
535-
))
536-
}
537-
}
538-
539-
macro_rules! impl_to_term_array {
540-
($($len:expr),*) => {
541-
$(impl<T: ToTerm> ToTerm for [T; $len] {
542-
fn to_term(&self) -> Term {
543-
Term::generated(TermData::ArrayTerm(
544-
self.iter()
545-
.map(|entry_term| Arc::new(T::to_term(entry_term)))
546-
.collect(),
547-
))
548-
}
549-
})*
550-
};
551-
}
552-
553-
impl_to_term_array!(
554-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
555-
26, 27, 28, 29, 30, 31, 32
556-
);

0 commit comments

Comments
 (0)