<commit_before>use value::{InternedString, Pair, Value};
use value::Value::*;
use cell_gc::{GcHeapSession, GcLeaf};
use cell_gc::collections::VecRef;

#[derive(IntoHeap)]
pub enum Expr<'h> {
    /// A constant (`quote` expressions produce this, but also numbers and
    /// other self-evaluating values).
    Con(Value<'h>),

    /// A variable-expression (evaluates to the variable's value).
    Var(GcLeaf<InternedString>),

    /// A lambda expression.
    Fun(CodeRef<'h>),

    /// A function call expression (an application).
    App(VecRef<'h, Expr<'h>>),

    /// A sequence-expression (`begin` used as an expression).
    Seq(VecRef<'h, Expr<'h>>),

    /// A conditional expression (`if`).
    If(IfRef<'h>),

    /// A definition.
    Def(DefRef<'h>),

    /// An assignment expression (`set!`).
    Set(DefRef<'h>),

    /// A `letrec*` expression.
    Letrec(LetrecRef<'h>),

    /// Evaluates to the current global environment.
    /// Used to implement (interactive-environment), for (eval).
    ToplevelEnv,
}

#[derive(IntoHeap)]
pub struct Code<'h> {
    pub params: VecRef<'h, GcLeaf<InternedString>>,
    pub rest: bool,
    pub body: Expr<'h>,
}

#[derive(IntoHeap)]
pub struct Def<'h> {
    pub name: GcLeaf<InternedString>,
    pub value: Expr<'h>
}

#[derive(IntoHeap)]
pub struct If<'h> {
    pub cond: Expr<'h>,
    pub t_expr: Expr<'h>,
    pub f_expr: Expr<'h>,
}

#[derive(IntoHeap)]
pub struct Letrec<'h> {<commit_msg>lisp: impl Debug for Expr, the type of compiled code.<commit_after>use value::{InternedString, Pair, Value};
use value::Value::*;
use cell_gc::{GcHeapSession, GcLeaf};
use cell_gc::collections::VecRef;
use std::fmt;

#[derive(IntoHeap)]
pub enum Expr<'h> {
    /// A constant (`quote` expressions produce this, but also numbers and
    /// other self-evaluating values).
    Con(Value<'h>),

    /// A variable-expression (evaluates to the variable's value).
    Var(GcLeaf<InternedString>),

    /// A lambda expression.
    Fun(CodeRef<'h>),

    /// A function call expression (an application).
    App(VecRef<'h, Expr<'h>>),

    /// A sequence-expression (`begin` used as an expression).
    Seq(VecRef<'h, Expr<'h>>),

    /// A conditional expression (`if`).
    If(IfRef<'h>),

    /// A definition.
    Def(DefRef<'h>),

    /// An assignment expression (`set!`).
    Set(DefRef<'h>),

    /// A `letrec*` expression.
    Letrec(LetrecRef<'h>),

    /// Evaluates to the current global environment.
    /// Used to implement (interactive-environment), for (eval).
    ToplevelEnv,
}

impl<'h> fmt::Debug for Expr<'h> {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            Expr::Con(ref v) => write!(f, "'{}", v),
            Expr::Var(ref s) => write!(f, "{}", Value::Symbol(s.clone())),
            Expr::Fun(ref c) => write!(f, "(lambda ... {:?})", c.body()),
            Expr::App(ref args) =>
                write!(f, "({})",
                       (0..args.len())
                       .map(|i| format!("{:?}", args.get(i)))
                       .collect::<Vec<String>>()
                       .join(" ")),
            Expr::Seq(ref exprs) =>
                write!(f, "(begin {})",
                       (0..exprs.len())
                       .map(|i| format!("{:?}", exprs.get(i)))
                       .collect::<Vec<String>>()
                       .join(" ")),
            Expr::If(ref r) =>
                write!(f, "(if {:?} {:?} {:?})", r.cond(), r.t_expr(), r.f_expr()),
            Expr::Def(ref r) =>
                write!(f, "(define {} {:?})", Value::Symbol(r.name()), r.value()),
            Expr::Set(ref r) =>
                write!(f, "(set! {} {:?})", Value::Symbol(r.name()), r.value()),
            Expr::Letrec(ref r) =>
                write!(f, "(letrec ({}) {:?})",
                       (0..r.names().len())
                       .map(|i| format!("({} {:?})",
                                        Value::Symbol(r.names().get(i)),
                                        r.exprs().get(i)))
                       .collect::<Vec<String>>()
                       .join(" "),
                       r.body()),
            Expr::ToplevelEnv => write!(f, "#<toplevel-env>"),
        }
    }
}

#[derive(IntoHeap)]
pub struct Code<'h> {
    pub params: VecRef<'h, GcLeaf<InternedString>>,
    pub rest: bool,
    pub body: Expr<'h>,
}

#[derive(IntoHeap)]
pub struct Def<'h> {
    pub name: GcLeaf<InternedString>,
    pub value: Expr<'h>
}

#[derive(IntoHeap)]
pub struct If<'h> {
    pub cond: Expr<'h>,
    pub t_expr: Expr<'h>,
    pub f_expr: Expr<'h>,
}

#[derive(IntoHeap)]
pub struct Letrec<'h> {
{'fraction_non_alphanumeric': 0.2026649473457984, 'fraction_numerical': 0.0006447453255963894, 'mean_word_length': 2.1964285714285716, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2087086', 'n_tokens_mistral': 1567, 'n_tokens_neox': 1580, 'n_words': 348}