UP | HOME

Bootstrapping

Table of Contents

Arquivo: axioms/bootstrap.rs.

1. Importações

use gc::Gc;
use crate::core::{ Maj, MajState };
use crate::{ maj_list, maj_dotted_list };
use crate::evaluator::evaluation::maj_eval;
use crate::axioms::predicates::maj_errorp;

2. Constantes globais

2.1. *ulps*

(def *ulps* 3)

2.2. *stdin*, *stdout* e *stderr*

#[inline]
fn maj_define_standard_streams(mut state: &mut MajState) {
    let stdin_sym  = Maj::symbol(&mut state, "*stdin*");
    let stdout_sym = Maj::symbol(&mut state, "*stdout*");
    let stderr_sym = Maj::symbol(&mut state, "*stderr*");
    let stdin      = state.make_stream_stdin();
    let stdout     = state.make_stream_stdout();
    let stderr     = state.make_stream_stderr();
    state.push(stdin_sym, stdin);
    state.push(stdout_sym, stdout);
    state.push(stderr_sym, stderr);
}

2.3. Exportação de constantes

fn maj_put_constants(mut state: &mut MajState) {
    maj_define_ulps(&mut state);
    maj_define_standard_streams(&mut state);
}

3. Macros

3.1. defmac

(def defmac
  (mac (label lambda-list . body)
       `(def ,label
            (mac ,lambda-list ,@body))))

3.2. defn

(defmac defn (label lambda-list . body)
  `(def ,label (fn ,lambda-list ,@body)))

3.3. let

(defmac let (args . body)
  ((fn (sepfn)
     ((fn ((syms vals))
        `((fn ,syms ,@body)
          ,@vals))
      (sepfn args nil nil sepfn)))
   (fn (pairs syms vals recur)
       (if (nilp pairs)
           (list syms vals)
           (recur (cdr pairs)
                  (cons (caar pairs) syms)
                  (cons (car (cdar pairs)) vals)
                  recur)))))

3.4. let*

(defmac let* (clauses . body)
  (if (nilp clauses)
      (cons 'do body)
      `(let (,(car clauses))
         ,(if (nilp (cdr clauses))
              (cons 'do body)
              `(let* ,(cdr clauses)
                 ,@body)))))

3.5. letfn

(defmac letfn (defs . body)
  ((fn (sepfn)
     ((fn ((syms vals))
        `((fn ,syms ,@body)
          ,@vals))
      (sepfn defs nil nil sepfn)))
   (fn (pairs syms vals recur)
       (if (nilp pairs)
           (list syms vals)
           (recur (cdr pairs)
                  (cons (caar pairs) syms)
                  (cons (cons 'fn (cdar pairs)) vals)
                  recur)))))

3.6. letfn*

(defmac letfn* (clauses . body)
  (if (nilp clauses)
      (cons 'do body)
      `(letfn (,(car clauses))
         ,(if (nilp (cdr clauses))
              (cons 'do body)
              `(letfn* ,(cdr clauses)
                 ,@body)))))

3.7. when

(defmac when (pred . body)
  `(if ,pred (do ,@body) nil))

3.8. unless

(defmac unless (pred . body)
  `(if (not ,pred) (do ,@body) nil))

3.9. cond

(defmac cond clauses
  (if (nilp clauses)
      nil
      `(if ,(caar clauses)
           (do ,@(cdar clauses))
           ,(if (nilp (cdr clauses))
                nil
                (cons 'cond (cdr clauses))))))

3.10. until

(defmac until (pred . body)
  `(while (not ,pred) ,@body))

3.11. with-open-stream

(defmac with-open-stream ((sym dir file) . body)
  `(let ((,sym (open-stream ,dir ,file)))
     (unwind-protect (do ,@body)
       (close-stream ,sym))))

3.12. repeat

(defmac repeat (n . body)
  (let ((it (gensym))
        (res (gensym)))
    `(let ((,it   ,n)
           (,res nil))
       (while (> ,it 0)
         (set ,res (do ,@body))
         (set ,it (1- ,it)))
       ,res)))

4. Variações de car e cdr

(defn caar (x) (car (car x)))
(defn cadr (x) (car (cdr x)))
(defn cdar (x) (cdr (car x)))
(defn cddr (x) (cdr (cdr x)))
(def first car)
(def rest cdr)
(def first-of-first caar)
(def second cadr)
(def rest-of-first cdar)
(def rest-of-rest cddr)
(defn third (x) (car (cddr x)))
(defn fourth (x) (cadr (cddr x)))

5. Miscelânea

5.1. map

(defn map (f (x . xs))
  (unless (nilp x)
    (cons (f x)
          (map f xs))))

5.2. mapc

(defn mapc (f (x . xs))
  (unless (nilp x)
    (f x)
    (mapc f xs)))

5.3. vector=

(defn vector= (va vb)
  (when (eq (vec-type va) (vec-type vb))
    (let* ((len (vec-length va))
           (i 0)
           (continue t))
      (when (= len (vec-length vb))
        (while (and (< i len) continue)
          (unless (equal (vec-at i va)
                         (vec-at i vb))
            (set continue nil))
          (set i (1+ i)))
        continue))))

5.4. equal

(defn equal (x y)
  (cond ((and (numberp x) (numberp y))
         (= x y))
        ((and (vectorp x) (vectorp y))
         (vector= x y))
        ((and (symbolp x) (symbolp y))
         (eq x y))
        ((and (consp x) (consp y))
         (when (equal (car x) (car y))
           (equal (cdr x) (cdr y))))
        ((and (atomp x) (atomp y))
         (id x y))
        (t nil)))

5.5. assp e assoc

(defn assp (proc (x . xs))
  (unless (nilp x)
    (let (((key . rest) x))
      (or (and (proc key) x)
          (assp proc xs)))))
(defn assoc (sym alist)
  (assp (equal sym) alist))

5.6. 1+ e 1-

(defn 1+ (x) (+ 1 x))
(defn 1- (x) (+ -1 x))

5.7. member

(defn member (elt lst)
  (unless (nilp lst)
    (let (((x . rest) lst))
      (or (and (equal elt x)
               lst)
          (member elt rest)))))

6. Registro em contexto global

pub fn maj_gen_bootstrap(mut state: &mut MajState) {
    use crate::printing::maj_format;

    let mut expressions: Vec<Gc<Maj>> = vec![];

    expressions.append(&mut vec![
        bootstrap_defmac(&mut state),
        bootstrap_defn(&mut state),
        bootstrap_let(&mut state),
        bootstrap_letstar(&mut state),
        bootstrap_letfn(&mut state),
        bootstrap_letfnstar(&mut state),
        bootstrap_when(&mut state),
        bootstrap_unless(&mut state),
        bootstrap_until(&mut state),
        bootstrap_with_open_stream(&mut state),
        bootstrap_repeat(&mut state),
        bootstrap_map(&mut state),
        bootstrap_mapc(&mut state),
        bootstrap_vectorequal(&mut state),
        bootstrap_cond(&mut state),
        bootstrap_equal(&mut state),
        bootstrap_assp(&mut state),
        bootstrap_assoc(&mut state),
        bootstrap_member(&mut state),
    ]);
    expressions.append(&mut bootstrap_car_cdr(&mut state));
    expressions.append(&mut bootstrap_one_plusless(&mut state));
    for expression in expressions.iter() {
        let e = maj_eval(&mut state,
                         expression.clone(),
                         Maj::nil());

        if maj_errorp(e.clone()).to_bool() {
            panic!("Bootstrap error:\n{}\nOn eval:\n{}",
                   maj_format(&state, e),
                   maj_format(&state, expression.clone()));
        }
    }

    maj_put_constants(&mut state);
}

Author: Lucas S. Vieira

Created: 2022-10-24 seg 00:27

Validate