mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-21 06:39:16 +02:00
94 lines
2.8 KiB
Scheme
94 lines
2.8 KiB
Scheme
(import
|
|
(scheme base)
|
|
(scheme read)
|
|
(scheme cyclone pretty-print)
|
|
(scheme cyclone util))
|
|
;; TODO: a temporary file to develop a transform pass that validates the number of arguments passed to
|
|
;; built-in forms, and throws an error if any issues are found. The goal is to provide friendlier validation
|
|
;; for the compiler
|
|
;;
|
|
;; TODO: call this from cyclone.scm after it works, probably after "resolve macros"
|
|
;; TODO: will relocate this to another place, probably a separate file in scheme/cyclone
|
|
|
|
(define (validate-syntax exp)
|
|
;; Only need to track local vars if they shadow one of our keywords
|
|
(define (include-var? v)
|
|
(member v '(define set! if lambda let)))
|
|
|
|
(define (check-if exp)
|
|
(let ((args (length exp)))
|
|
(cond
|
|
((< args 3)
|
|
(error "Not enough arguments" exp))
|
|
((> args 4)
|
|
(error "Too many arguments" exp)))))
|
|
|
|
(define (check-define exp)
|
|
'todo)
|
|
|
|
(define (check-set exp)
|
|
'todo)
|
|
|
|
(define (check-lambda exp)
|
|
;(difference (reduce union (map search (lambda->exp exp)) '())
|
|
; (lambda-formals->list exp))
|
|
'todo)
|
|
|
|
;; TODO: could check primitives, etc
|
|
|
|
;; TODO: what if any keywords are shadowed? need to populate vars
|
|
(define (update-vars syms vars)
|
|
(append vars (filter include-var? syms)))
|
|
|
|
(define (search exp vars)
|
|
(pretty-print `(search ,exp ,vars))(newline)
|
|
(cond
|
|
;((ast:lambda? exp) 'TODO)
|
|
((const? exp) #f)
|
|
((quote? exp) #f)
|
|
((ref? exp) #f)
|
|
((lambda? exp)
|
|
(if (not (member 'lambda vars)) (check-lambda exp))
|
|
(for-each
|
|
(lambda (e)
|
|
(search e (update-vars (lambda-formals->list exp) vars)))
|
|
(lambda->exp exp))
|
|
)
|
|
((and (if? exp)
|
|
(not (member 'if vars)))
|
|
(check-if exp)
|
|
(search (if->condition exp) vars)
|
|
(search (if->then exp) vars)
|
|
(when (> (length exp) 3)
|
|
(search (if->else exp) vars)))
|
|
((define? exp)
|
|
(if (not (member 'define vars)) (check-define exp))
|
|
(search (define->var exp) vars)
|
|
(for-each
|
|
(lambda (e)
|
|
(search e (update-vars (list (define->var exp)) vars)))
|
|
(define->exp exp)))
|
|
((define-c? exp) #f)
|
|
((set!? exp)
|
|
(if (not (member 'set! vars)) (check-set exp))
|
|
(search (set!->var exp) vars)
|
|
(search (set!->exp exp) (update-vars (list (set!->var exp)) vars)))
|
|
; Future?
|
|
;((tagged-list? 'let exp)
|
|
; (set! let-vars (append (map car (cadr exp)) let-vars))
|
|
; (search (cdr exp)))
|
|
; Application:
|
|
((app? exp)
|
|
(for-each
|
|
(lambda (e)
|
|
(search e vars))
|
|
exp))
|
|
(else
|
|
(error "unknown expression: " exp))))
|
|
(search exp '()))
|
|
|
|
;(if)
|
|
;(if 1 2 3 4)
|
|
|
|
(let ((sexp (read-all (open-input-file "validation.scm"))))
|
|
(validate-syntax sexp))
|