airlang 0.25.0

Air is a minimalist and universal programming language.
Documentation
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::ops::Deref;
use std::str::FromStr;

use const_format::concatcp;

use crate::cfg::repr::func::generate_func;
use crate::cfg::utils::key;
use crate::semantics::cfg::Cfg;
use crate::semantics::core::PREFIX_CELL;
use crate::semantics::val::CFG;
use crate::semantics::val::DynVal;
use crate::semantics::val::FUNC;
use crate::semantics::val::FuncVal;
use crate::semantics::val::LINK;
use crate::semantics::val::LinkVal;
use crate::semantics::val::Val;
use crate::syntax::FmtCtx;
use crate::syntax::FmtRepr;
use crate::syntax::ParseError;
use crate::syntax::ParseRepr;
use crate::syntax::parse;
use crate::type_::Bit;
use crate::type_::Byte;
use crate::type_::Call;
use crate::type_::Cell;
use crate::type_::Decimal;
use crate::type_::Int;
use crate::type_::Key;
use crate::type_::List;
use crate::type_::Map;
use crate::type_::Pair;
use crate::type_::Quote;
use crate::type_::Text;
use crate::type_::Unit;

impl ParseRepr for Val {}

impl FromStr for Val {
    type Err = ParseError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        parse(s)
    }
}

impl Display for Val {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        FmtRepr::fmt(self, FmtCtx::default(), f)
    }
}

impl Debug for Val {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        FmtRepr::fmt(self, FmtCtx::default(), f)
    }
}

impl FmtRepr for Val {
    fn fmt(&self, ctx: FmtCtx, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            Val::Unit(unit) => <Unit as Display>::fmt(unit, f),
            Val::Bit(bit) => <Bit as Display>::fmt(bit, f),
            Val::Key(key) => <Key as Display>::fmt(key, f),
            Val::Text(text) => <Text as Display>::fmt(text, f),
            Val::Int(int) => <Int as Display>::fmt(int, f),
            Val::Decimal(decimal) => <Decimal as Display>::fmt(decimal, f),
            Val::Byte(byte) => <Byte as Display>::fmt(byte, f),
            Val::Cell(cell) => <Cell<Val> as FmtRepr>::fmt(cell, ctx, f),
            Val::Pair(pair) => <Pair<Val, Val> as FmtRepr>::fmt(pair, ctx, f),
            Val::List(list) => <List<Val> as FmtRepr>::fmt(list, ctx, f),
            Val::Map(map) => <Map<Key, Val> as FmtRepr>::fmt(map, ctx, f),
            Val::Quote(quote) => <Quote<Val> as FmtRepr>::fmt(quote, ctx, f),
            Val::Call(call) => <Call<Val, Val> as FmtRepr>::fmt(call, ctx, f),
            Val::Link(link) => <LinkVal as Display>::fmt(link, f),
            Val::Cfg(cfg) => <Cfg as Display>::fmt(cfg, f),
            Val::Func(func) => <FuncVal as Display>::fmt(func, f),
            Val::Dyn(val) => <dyn DynVal as Display>::fmt(val.deref(), f),
        }
    }

    fn is_call(&self) -> bool {
        matches!(self, Val::Call(_))
    }

    fn is_pair(&self) -> bool {
        matches!(self, Val::Pair(_))
    }

    fn to_pair(&self) -> Pair<&dyn FmtRepr, &dyn FmtRepr> {
        let Val::Pair(pair) = self else { panic!("called `FmtRepr::to_pair()` on non-pair value") };
        Pair::new(&pair.left, &pair.right)
    }

    fn is_text_list_map(&self) -> bool {
        matches!(self, Val::Text(_) | Val::List(_) | Val::Map(_))
    }
}

impl Display for LinkVal {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let id = self.ptr_addr();
        let id = Key::from_string_unchecked(format!("{id:x}"));
        let repr = Val::Key(id);
        let tag = key(concatcp!(PREFIX_CELL, LINK));
        let call = Call::new(tag, repr);
        Display::fmt(&call, f)
    }
}

impl Debug for LinkVal {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        Display::fmt(self, f)
    }
}

impl Display for Cfg {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let repr = Val::Map(Map::clone(self).into());
        let tag = key(concatcp!(PREFIX_CELL, CFG));
        let call = Call::new(tag, repr);
        Display::fmt(&call, f)
    }
}

impl Debug for Cfg {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        Display::fmt(self, f)
    }
}

impl Display for FuncVal {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let repr = generate_func(self.clone());
        let tag = key(concatcp!(PREFIX_CELL, FUNC));
        let call = Call::new(tag, repr);
        Display::fmt(&call, f)
    }
}

impl Debug for FuncVal {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        Display::fmt(self, f)
    }
}

pub(in crate::cfg) mod func;