<commit_before>(load "stdlib.scm")
;(load "traceback.scm")

(define (compile lexp)
  ('compile (parse lexp) global-static-env '(halt)))

(define (parse lexp)
  (if (symbol? lexp)
      (var-ref<- lexp)
      (if (is? (lexp 0) 'lambda)
          (abstraction<- ((lexp 1) 0)
                         (parse (lexp 2)))
          (call<- (parse (lexp 0))
                  (parse (lexp 1))))))

;; Variable reference
(define (var-ref<- v)
  (make ('free-vars () (list<- v))
        ('compile (r k) (cons (r v) k))))

;; Lambda expression
(define (abstraction<- v e)
  (let ((free-vars (delq v ('free-vars e))))
    (make ('free-vars () free-vars)
          ('compile (r k)
            (let ((code ('compile e (static-env<- v free-vars) '(return))))
              (chain (list<- 'make-closure ('count free-vars) ('count code))
                     (map r free-vars)
                     code
                     k))))))

;; Application
(define (call<- e1 e2)
  (make ('free-vars () (union ('free-vars e1) ('free-vars e2)))
        ('compile (r k)
          (let ((code ('compile e2 r ('compile e1 r '(invoke)))))
            (if (is? ('first k) 'return)
                code
                (chain (list<- 'pushcont ('count code)) code k))))))

(define (global-static-env v)
  (error "Unbound variable" v))

(define (static-env<- param free-vars)
  (lambda (v)
    (if (is? v param)
        'local
        ('+ 1 (list-index free-vars v)))))


;; Smoke test

(print (compile
;  '(lambda (x) x)<commit_msg>a little cleanup of lambdacompiler<commit_after>(load "stdlib.scm")
;(load "traceback.scm")

(define (compile lexp)
  ('compile (parse lexp) global-static-env '(halt)))

(define (parse lexp)
  (if (symbol? lexp)
      (var-ref<- lexp)
      (if (is? (lexp 0) 'lambda)
          (abstraction<- ((lexp 1) 0)
                         (parse (lexp 2)))
          (call<- (parse (lexp 0))
                  (parse (lexp 1))))))

;; Variable reference
(define (var-ref<- v)
  (make ('free-vars () (list<- v))
        ('compile (s k) (cons (s v) k))))

;; Lambda expression
(define (abstraction<- v body)
  (let ((free-vars (delq v ('free-vars body))))
    (make ('free-vars () free-vars)
          ('compile (s k)
            (let ((code ('compile body (static-env<- v free-vars) '(return))))
              (chain (list<- 'make-closure ('count free-vars) ('count code))
                     (map s free-vars)
                     code
                     k))))))

;; Application
(define (call<- operator operand)
  (make ('free-vars () (union ('free-vars operator) ('free-vars operand)))
        ('compile (s k)
          (let ((code ('compile operand s ('compile operator s '(invoke)))))
            (if (is? ('first k) 'return)
                code
                (chain (list<- 'pushcont ('count code)) code k))))))


;; Static environments (called 's' above)

(define (global-static-env v)
  (error "Unbound variable" v))

(define (static-env<- param free-vars)
  (lambda (v)
    (if (is? v param)
        'local
        ('+ 1 (list-index free-vars v)))))


;; Smoke test

(print (compile
;  '(lambda (x) x)
{'fraction_non_alphanumeric': 0.18603154168007724, 'fraction_numerical': 0.006437077566784679, 'mean_word_length': 2.0925373134328358, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4848639', 'n_tokens_mistral': 1082, 'n_tokens_neox': 1022, 'n_words': 326}