UP | HOME

Interpretação

Arquivo: evaluator/evaluation.rs

use gc::Gc;
use crate::maj_list;
use crate::core::{ Maj, MajState };
use crate::axioms::predicates::{
    maj_eq,
    maj_nilp,
    maj_symbolp,
    maj_errorp,
    maj_literalp,
    maj_numberp,
    maj_charp,
    maj_streamp,
    maj_stringp,
    maj_macrop
};
use crate::axioms::primitives::{
    maj_car,
    maj_cdr,
    maj_err,
    maj_length
};

use crate::axioms::utils::{
    STACK_RED_ZONE,
    STACK_PER_RECURSION
};

use super::maj_apply;

1. TODO Interpretação genérica

  • Um erro deverá suspender a interpretação imediatamente, sendo levado ao top-level da interpretação sem que mais ações sejam feitas;
  • Um objeto auto-interpretável deverá ser interpretado para si mesmo;
  • Um literal deve ser interpretado para si mesmo;
  • Uma variável deve ser consultada no contexto atual;
  • Uma expressão quotada deve retornar seu conteúdo;
  • Uma expressão quasiquotada deverá realizar substituições apropriadamente e retornar seu valor apropriado;
  • Uma definição deverá alterar o contexto global;
  • Uma condição deverá ter seu predicado interpretado, e então realizar branching para a situação adequada;
  • Uma clausura deverá ser transformada em um literal apropriado, condizente com clausuras;
  • Uma forma do deverá ter cada um de seus elementos interpretados, e será retornado o valor de interpretação do último;
  • and
  • or
  • Uma aplicação consistirá em delegar a aplicação do primeiro elemento aos argumentos informados. Antes desse passo de despacho, cada um dos elementos (incluindo o primeiro) deverá ser interpretado recursivamente;
  • Caso nenhuma das situações se encaixe, então constitui-se um erro de interpretação de uma forma desconhecida.
pub fn maj_eval(mut state: &mut MajState,
                expr: Gc<Maj>,
                env: Gc<Maj>) -> Gc<Maj> {
    // use crate::maj_format;
    // println!("EVAL: {}", maj_format(&state, expr.clone()));

    /* Errors */
    if maj_errorp(expr.clone()).to_bool() {
        expr
    }

    /* Special forms */
    // self-evaluating forms:
    // Literals, numbers, characters, streams
    else if maj_is_selfeval(expr.clone()) {
        expr
    }
    
    // variables
    else if maj_symbolp(expr.clone()).to_bool() {
        state.lookup(env, expr)
    }

    // quote
    else if maj_quotep(expr.clone()).to_bool() {
        maj_handle_quote(expr)
    }

    // quasiquote
    else if maj_quasiquotep(expr.clone()).to_bool() {
        maj_handle_quasiquote(&mut state, expr, env)
    }

    // macros
    else if maj_macp(expr.clone()).to_bool() {
        maj_handle_mac(expr, env)
    }

    // definitions
    else if maj_defp(&mut state, expr.clone()).to_bool() {
        maj_handle_definition(&mut state, expr, env)
    }

    // redefinitions
    else if maj_setp(&mut state, expr.clone()).to_bool() {
        maj_handle_redefinition(&mut state, expr, env)
    }

    // redefinitions for a cons cell
    else if maj_set_car_p(&mut state, expr.clone()).to_bool() {
        maj_handle_redefine_car(&mut state, expr, env)
    }
    else if maj_set_cdr_p(&mut state, expr.clone()).to_bool() {
        maj_handle_redefine_cdr(&mut state, expr, env)
    }

    // conditionals
    else if maj_ifp(&mut state, expr.clone()).to_bool() {
        maj_handle_if(&mut state, expr, env)
    }

    // closures
    else if maj_fnp(expr.clone()).to_bool() {
        maj_handle_fn(expr, env)
    }

    // do
    else if maj_dop(&mut state, expr.clone()).to_bool() {
        maj_handle_do(&mut state, expr, env)
    }

    // and
    else if maj_andp(&mut state, expr.clone()).to_bool() {
        maj_handle_and(&mut state, expr, env)
    }

    // or
    else if maj_orp(&mut state, expr.clone()).to_bool() {
        maj_handle_or(&mut state, expr, env)
    }

    // apply
    else if maj_applyp(expr.clone()).to_bool() {
        maj_handle_apply(&mut state, expr, env)
    }

    // while
    else if maj_whilep(&mut state, expr.clone()).to_bool() {
        maj_handle_while(&mut state, expr, env)
    }

    // letrec
    else if maj_letrecp(&mut state, expr.clone()).to_bool() {
        maj_handle_letrec(&mut state, expr, env)
    }

    // unwind-protect
    else if maj_unwind_protect_p(&mut state, expr.clone()).to_bool() {
        maj_handle_unwind_protect(&mut state, expr, env)
    }

    // application
    else {
        let fun = maj_eval(&mut state,
                           maj_car(expr.clone()),
                           env.clone());
        if maj_errorp(fun.clone()).to_bool() {
            return fun;
        }

        let args =
            if maj_macrop(fun.clone()).to_bool() {
                maj_cdr(expr)
            } else {
                maj_evlist(&mut state,
                           maj_cdr(expr),
                           env.clone())
            };
        
        if maj_errorp(args.clone()).to_bool() {
            return args;
        }

        stacker::maybe_grow(
            STACK_RED_ZONE,
            STACK_PER_RECURSION,
            || maj_apply(&mut state, fun, args, env))
    }
}

2. TODO Interpretação iterativa de listas

fn maj_evlist(mut state: &mut MajState,
              list: Gc<Maj>,
              env: Gc<Maj>) -> Gc<Maj> {
    let mut elts = Vec::new();
    let mut itr = list.clone();
    // Evaluate member by member
    while !maj_nilp(itr.clone()).to_bool() {
        let elt = maj_car(itr.clone());
        let elt = maj_eval(&mut state, elt, env.clone());
        if maj_errorp(elt.clone()).to_bool() {
            return elt;
        }
        elts.push(elt);
        itr = maj_cdr(itr);
    }
    elts.reverse();
    // Generate list of evaluated members backwards
    let mut new_list = Maj::nil();
    
    for elt in elts.iter() {
        new_list = Maj::cons(elt.clone(),
                             new_list.clone());
    }
    new_list
}

3. TODO Formas especiais

3.1. Expressão quotada

fn maj_handle_quote(expr: Gc<Maj>) -> Gc<Maj> {
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length != 2 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    maj_car(maj_cdr(expr))
}

3.2. Expressão quasiquotada

fn maj_handle_quasiquote(mut state: &mut MajState, expr: Gc<Maj>, env: Gc<Maj>) -> Gc<Maj> {
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length != 2 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }
    maj_do_quasiquote(&mut state, maj_car(maj_cdr(expr)), env)
}
fn maj_do_quasiquote(
    mut state: &mut MajState,
    expr: Gc<Maj>,
    env: Gc<Maj>
) -> Gc<Maj> {
    use crate::axioms::predicates::maj_atomp;
    use crate::axioms::primitives::maj_append;
    
    if maj_atomp(expr.clone()).to_bool() {
        return expr;
    }

    let car  = maj_car(expr.clone());
    let cdr  = maj_cdr(expr.clone());
    let cadr = maj_car(cdr.clone());

    if maj_unquotep(expr.clone()).to_bool() ||
        maj_unquote_splice_p(expr.clone()).to_bool() {
            maj_eval(&mut state, cadr.clone(), env.clone())
        } else {
            let should_append = maj_unquote_splice_p(
                car.clone()
            ).to_bool();
            let car_qquote = maj_do_quasiquote(
                &mut state, car.clone(), env.clone());

            if maj_errorp(car_qquote.clone()).to_bool() {
                return car_qquote;
            }

            let rest = maj_do_quasiquote(
                &mut state,
                cdr.clone(),
                env.clone());
            if maj_errorp(rest.clone()).to_bool() {
                return rest;
            }

            if should_append {
                maj_append(maj_list!(car_qquote, rest))
            } else {
                Maj::cons(car_qquote, rest)
            }
        }
}

3.3. Definição (def)

fn maj_handle_definition(
    mut state: &mut MajState,
    expr: Gc<Maj>,
    env: Gc<Maj>
) -> Gc<Maj> {
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length != 3 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    let sym = maj_car(maj_cdr(expr.clone()));
    let val = maj_car(maj_cdr(maj_cdr(expr)));

    // Evaluate associated value before binding
    let val = maj_eval(&mut state, val, env);
    if maj_errorp(val.clone()).to_bool() {
        return val;
    }

    if maj_symbolp(sym.clone()).to_bool() {
        // Try finding thing on environment.
        // An error means it does not exist
        let element = state.assoc(Maj::nil(), sym.clone());
        if !maj_errorp(element.clone()).to_bool() {
            // If exists, attribute destructively
            let new_entry = Maj::cons(sym.clone(), val);
            unsafe {
                let raw_element = Gc::into_raw(element.clone());
                std::ptr::copy_nonoverlapping(
                    Gc::into_raw(new_entry.clone()),
                    raw_element as *mut Maj, 1);
            }
            sym
        } else {
            // Else, push new element to state
            state.push(sym, val)
        }
    } else {
        maj_err(
            Maj::string("{} is not a symbol"),
            maj_list!(sym))
    }
}

3.4. Redefinição (set)

fn maj_handle_redefinition(
    mut state: &mut MajState,
    expr: Gc<Maj>,
    env: Gc<Maj>
) -> Gc<Maj> {
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length != 3 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    let sym = maj_car(maj_cdr(expr.clone()));
    let val = maj_car(maj_cdr(maj_cdr(expr)));

    // Evaluate associated value before binding
    let val = maj_eval(&mut state, val, env.clone());
    if maj_errorp(val.clone()).to_bool() {
        return val;
    }

    if maj_symbolp(sym.clone()).to_bool() {
        // Try finding thing on both environments.
        let element = state.assoc(env, sym.clone());
        if maj_errorp(element.clone()).to_bool() {
            element
        } else {
            // When found, replace binding cons
            let new_binding = Maj::cons(sym.clone(), val);
            unsafe {
                let rawelement = Gc::into_raw(element.clone());
                std::ptr::copy_nonoverlapping(
                    Gc::into_raw(new_binding.clone()),
                    rawelement as *mut Maj, 1);
            }
            sym
        }
    } else {
        maj_err(
            Maj::string("{} is not a symbol"),
            maj_list!(sym))
    }
}

3.5. Redefinições para células cons (set-car e set-cdr)

fn maj_handle_redefine_cxr_helper(
    mut state: &mut MajState,
    expr: Gc<Maj>,
    env: Gc<Maj>
) -> Result<(Gc<Maj>, Gc<Maj>), Gc<Maj>> {
    use crate::axioms::predicates::maj_consp;
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length != 3 {
        return Err(maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr)));
    }

    let value = maj_car(maj_cdr(maj_cdr(expr.clone())));
    let pair  = maj_car(maj_cdr(expr));

    let value = maj_eval(&mut state, value, env.clone());
    if maj_errorp(value.clone()).to_bool() {
        return Err(value);
    }
    
    let pair = maj_eval(&mut state, pair, env.clone());
    if maj_errorp(pair.clone()).to_bool() {
        return Err(pair);
    } else if !maj_consp(pair.clone()).to_bool() {
        return Err(maj_err(
            Maj::string("{} is not a cons cell"),
            maj_list!(pair)));
    }

    Ok((pair, value))
}
fn maj_handle_redefine_car(
    mut state: &mut MajState,
    expr: Gc<Maj>,
    env: Gc<Maj>
) -> Gc<Maj> {
    match maj_handle_redefine_cxr_helper(&mut state, expr, env) {
        Ok((pair, value)) => {
            let new_pair = Maj::cons(value, maj_cdr(pair.clone()));
            unsafe {
                let rawpair = Gc::into_raw(pair.clone());
                std::ptr::copy_nonoverlapping(
                    Gc::into_raw(new_pair.clone()),
                    rawpair as *mut Maj, 1);
            }
            pair
        },
        Err(error) => error,
    }
}
fn maj_handle_redefine_cdr(
    mut state: &mut MajState,
    expr: Gc<Maj>,
    env: Gc<Maj>
) -> Gc<Maj> {
    match maj_handle_redefine_cxr_helper(&mut state, expr, env) {
        Ok((pair, value)) => {
            let new_pair = Maj::cons(maj_car(pair.clone()), value);
            unsafe {
                let rawpair = Gc::into_raw(pair.clone());
                std::ptr::copy_nonoverlapping(
                    Gc::into_raw(new_pair.clone()),
                    rawpair as *mut Maj, 1);
            }
            pair
        },
        Err(error) => error,
    }
}

3.6. Condicional (if)

fn maj_handle_if(mut state: &mut MajState, expr: Gc<Maj>, env: Gc<Maj>) -> Gc<Maj> {
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length != 4 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    let pred   = maj_car(maj_cdr(expr.clone()));
    let conseq = maj_car(maj_cdr(maj_cdr(expr.clone())));
    let altern = maj_car(maj_cdr(maj_cdr(maj_cdr(expr))));
    
    let pred_result = maj_eval(&mut state, pred, env.clone());
    if maj_errorp(pred_result.clone()).to_bool() {
        pred_result
    } else {
        maj_eval(&mut state,
                 if maj_nilp(pred_result).to_bool() {
                     altern
                 } else {
                     conseq
                 },
                 env)
    }
}

3.7. Forma fn

fn maj_handle_fn(expr: Gc<Maj>, env: Gc<Maj>) -> Gc<Maj> {
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length < 3 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    // (fn lambda-list . body)
    let lambda_list = maj_car(maj_cdr(expr.clone()));
    let body = maj_cdr(maj_cdr(expr));

    if maj_errorp(lambda_list.clone()).to_bool() {
        lambda_list
    } else if maj_errorp(body.clone()).to_bool() {
        body
    } else {
        // (lit closure <env> <lambda-list> ((<body>)))
        maj_list!(Maj::lit(),
                  Maj::closure(),
                  env, lambda_list, body)
    }
}

3.8. Forma mac

fn maj_handle_mac(expr: Gc<Maj>, env: Gc<Maj>) -> Gc<Maj> {
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length < 3 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    // (mac lambda-list . body)
    let lambda_list = maj_car(maj_cdr(expr.clone()));
    let body = maj_cdr(maj_cdr(expr));

    // (lit macro (lit closure <env> lambda-list (body)))
    maj_list!(Maj::lit(),
              Maj::macro_sym(),
              maj_list!(
                  Maj::lit(),
                  Maj::closure(),
                  env, lambda_list, body))
}

3.9. Forma do

fn maj_handle_do(mut state: &mut MajState, expr: Gc<Maj>, env: Gc<Maj>) -> Gc<Maj> {
    let mut itr    = maj_cdr(expr.clone());
    let mut result = Maj::nil();
    while !maj_nilp(itr.clone()).to_bool() {
        let expr = maj_car(itr.clone());
        result = maj_eval(&mut state, expr, env.clone());
        if maj_errorp(result.clone()).to_bool() {
            return result;
        }
        itr = maj_cdr(itr.clone());
    }
    result
}

3.10. Forma apply

fn maj_handle_apply(mut state: &mut MajState, expr: Gc<Maj>, env: Gc<Maj>) -> Gc<Maj> {
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length != 3 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    // (apply fun args) -> (eval (cons fun args))
    let func = maj_car(maj_cdr(expr.clone()));
    let args = maj_car(maj_cdr(maj_cdr(expr)));

    let func = maj_eval(&mut state, func, env.clone());
    let args = maj_eval(&mut state, args, env.clone());

    if maj_errorp(func.clone()).to_bool() {
        func
    } else if maj_macrop(func.clone()).to_bool()
        || maj_macp(func.clone()).to_bool()
    {
        maj_err(
            Maj::string("Macros cannot be applied"),
            Maj::nil())
    } else if maj_errorp(args.clone()).to_bool() {
        args
    } else {
        maj_eval(&mut state, Maj::cons(func, args), env)
    }
}

3.11. Forma letrec

fn maj_handle_letrec(
    mut state: &mut MajState,
    expr: Gc<Maj>,
    env: Gc<Maj>
) -> Gc<Maj> {
    use crate::axioms::predicates::maj_consp;
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length < 3 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    // (letrec bindings . body)
    let bindings = maj_car(maj_cdr(expr.clone()));
    let body     = maj_cdr(maj_cdr(expr.clone()));

    // Implicit `do`
    let body = Maj::cons(Maj::do_sym(), body);

    let mut fnnames  = vec![];
    let mut fns      = vec![];
    let mut iter = bindings.clone();
    while !maj_nilp(iter.clone()).to_bool() {
        // (sym lambda-list . body)
        let clause = maj_car(iter.clone());
        if !maj_consp(clause.clone()).to_bool() {
            return maj_err(Maj::string(
                "Syntax error on letrec: {} is not a proper clause"),
                maj_list!(clause));
        }

        let sym = maj_car(clause.clone());
        if !maj_symbolp(sym.clone()).to_bool() {
            return maj_err(Maj::string(
                "Syntax error on letrec: {} is not a valid function name"),
                maj_list!(sym));
        }

        let function = Maj::cons(
            Maj::fn_sym(),
            maj_cdr(clause));

        fnnames.push(sym);
        fns.push(function);

        iter = maj_cdr(iter);
    }

    let mut closures = vec![];
    // iterate over fns, interpreting, putting results in closures
    for function in fns.iter() {
        let closure = maj_eval(
            &mut state,
            function.clone(),
            env.clone());
        if maj_errorp(closure.clone()).to_bool() {
            return closure;
        }
        closures.push(closure);
    }

    // iterate over fnnames and closures, creating an env.
    use crate::core::environment::maj_env_push;
    let mut new_env = Maj::nil();
    for i in 0..closures.len() {
        new_env = maj_env_push(new_env,
                               fnnames[i].clone(),
                               closures[i].clone());
    }

    // append new_env to env.
    use crate::core::environment::maj_env_union;
    new_env = maj_env_union(new_env, env.clone());

    // for each closure, inject this new environment
    for closure in closures.iter() {
        // (lit closure <env> <ll> . <body>)
        let clorest = maj_cdr(maj_cdr(closure.clone()));
        let clobody = maj_cdr(clorest.clone());
        
        // modify car of clobody
        unsafe {
            let rawclorest = Gc::into_raw(clorest.clone());
            let newcons = Maj::cons(new_env.clone(), clobody);
            std::ptr::copy_nonoverlapping(
                Gc::into_raw(newcons.clone()),
                rawclorest as *mut Maj, 1);
        }
    }
    maj_eval(&mut state, body, new_env)
}

3.12. Forma while

fn maj_handle_while(
    mut state: &mut MajState,
    expr: Gc<Maj>,
    env: Gc<Maj>
) -> Gc<Maj> {
    // (while pred . body)
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length < 2 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    let pred = maj_car(maj_cdr(expr.clone()));
    let body = maj_cdr(maj_cdr(expr));
    let body = Maj::cons(Maj::do_sym(), body);

    let mut body_result = Maj::nil();
    loop {
        let pred_result = maj_eval(&mut state,
                                   pred.clone(),
                                   env.clone());
        if maj_errorp(pred_result.clone()).to_bool() {
            return pred_result;
        }
        if !pred_result.to_bool() {
            break;
        }
        body_result = maj_eval(&mut state,
                               body.clone(),
                               env.clone());
        if maj_errorp(body_result.clone()).to_bool() {
            return body_result;
        }
    }
    body_result
}

3.13. Forma unwind-protect

fn maj_handle_unwind_protect(
    mut state: &mut MajState,
    expr: Gc<Maj>,
    env: Gc<Maj>
) -> Gc<Maj> {
    // (unwind-protect expr cleanup)
    let length = maj_length(expr.clone())
        .to_integer().unwrap();
    if length != 3 {
        return maj_err(
            Maj::string("Invalid syntax: {}"),
            maj_list!(expr));
    }

    let exp     = maj_car(maj_cdr(expr.clone()));
    let cleanup = maj_car(maj_cdr(maj_cdr(expr)));

    let result = maj_eval(&mut state, exp, env.clone());
    let _      = maj_eval(&mut state, cleanup, env);
    result
}

3.14. Formas lógicas

3.14.1. and

fn maj_handle_and(mut state: &mut MajState, expr: Gc<Maj>, env: Gc<Maj>) -> Gc<Maj> {
    let forms = maj_cdr(expr);
    let mut iter = forms;
    let mut result = Maj::t();
    while !maj_nilp(iter.clone()).to_bool() {
        let form = maj_car(iter.clone());
        result = maj_eval(&mut state, form, env.clone());
        if maj_nilp(result.clone()).to_bool() {
            return Maj::nil();
        }
        iter = maj_cdr(iter.clone());
    }
    result
}

3.14.2. or

fn maj_handle_or(mut state: &mut MajState, expr: Gc<Maj>, env: Gc<Maj>) -> Gc<Maj> {
    let forms = maj_cdr(expr);
    let mut iter = forms;
    let mut result = Maj::nil();
    while !maj_nilp(iter.clone()).to_bool() {
        let form = maj_car(iter.clone());
        result = maj_eval(&mut state, form, env.clone());
        if !maj_nilp(result.clone()).to_bool() {
            return result;
        }
        iter = maj_cdr(iter.clone());
    }
    result
}

4. Predicados auxiliares

fn maj_is_selfeval(x: Gc<Maj>) -> bool {
    maj_literalp(x.clone()).to_bool()
        || maj_nilp(x.clone()).to_bool()
        || maj_eq(x.clone(), Maj::t()).to_bool()
        || maj_eq(x.clone(), Maj::ampersand()).to_bool()
        || maj_eq(x.clone(), Maj::apply()).to_bool()
        || maj_numberp(x.clone()).to_bool()
        || maj_charp(x.clone()).to_bool()
        || maj_streamp(x.clone()).to_bool()
        || maj_stringp(x.clone()).to_bool()
}
pub fn maj_quotep(x: Gc<Maj>) -> Gc<Maj> {
    maj_eq(maj_car(x), Maj::quote())
}
pub fn maj_quasiquotep(x: Gc<Maj>) -> Gc<Maj> {
    maj_eq(maj_car(x), Maj::quasiquote())
}
pub fn maj_unquotep(x: Gc<Maj>) -> Gc<Maj> {
    maj_eq(maj_car(x), Maj::unquote())
}
pub fn maj_unquote_splice_p(x: Gc<Maj>) -> Gc<Maj> {
    maj_eq(maj_car(x), Maj::unquote_splice())
}
fn maj_defp(mut state: &mut MajState,
            x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "def"))
}
fn maj_setp(mut state: &mut MajState,
            x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "set"))
}
fn maj_set_car_p(mut state: &mut MajState,
            x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "set-car"))
}
fn maj_set_cdr_p(mut state: &mut MajState,
            x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "set-cdr"))
}
fn maj_dop(mut state: &mut MajState,
           x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "do"))
}
fn maj_andp(mut state: &mut MajState,
            x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "and"))
}
fn maj_orp(mut state: &mut MajState,
            x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "or"))
}
fn maj_ifp(mut state: &mut MajState,
           x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "if"))
}
#[inline]
fn maj_fnp(x: Gc<Maj>) -> Gc<Maj> {
    maj_eq(maj_car(x), Maj::fn_sym())
}
#[inline]
fn maj_applyp(x: Gc<Maj>) -> Gc<Maj> {
    maj_eq(maj_car(x), Maj::apply())
}
fn maj_whilep(mut state: &mut MajState,
              x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "while"))
}
#[inline]
fn maj_macp(x: Gc<Maj>) -> Gc<Maj> {
    maj_eq(maj_car(x), Maj::mac())
}
#[inline]
fn maj_letrecp(mut state: &mut MajState,
               x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "letrec"))
}
#[inline]
fn maj_unwind_protect_p(mut state: &mut MajState,
                        x: Gc<Maj>) -> Gc<Maj> {
    let car = maj_car(x);
    maj_eq(car, Maj::symbol(&mut state, "unwind-protect"))
}

Author: Lucas S. Vieira

Created: 2022-10-24 seg 00:27

Validate