skint/pre/ksf2c.ssc

67 lines
2.8 KiB
Text

;---------------------------------------------------------------------------------------------
; Skint k.sf precursor compiler (k.sf => k.c)
;---------------------------------------------------------------------------------------------
(import (only (skint hidden)
list2? list3?))
(define (list4? x) (and (pair? x) (list3? (cdr x))))
(define (path-strip-directory filename)
(let loop ([l (reverse (string->list filename))] [r '()])
(cond [(null? l) (list->string r)]
[(memv (car l) '(#\\ #\/ #\:)) (list->string r)]
[else (loop (cdr l) (cons (car l) r))])))
(define (path-strip-extension filename)
(let ([l (reverse (string->list filename))])
(let ([r (memv #\. l)])
(if r (list->string (reverse (cdr r))) filename))))
(define (module-name filename)
(path-strip-extension (path-strip-directory filename)))
(define *local-definitions*
'("#ifdef NAN_BOXING" "#ifndef FLONUMS_BOXED" "#else" "#endif"))
(define (process-top-form x oport)
(when (and (list2? x) (symbol? (car x)) (string? (cadr x)))
(case (car x)
[(%definition)
; make an exception for some conditional definitions!
(when (member (cadr x) *local-definitions*)
(display (cadr x) oport) (newline oport) (newline oport))]
[(%localdef) (display (cadr x) oport) (newline oport) (newline oport)] ; does not go into n.h
[(%include)]))) ; went into n.h
(define (process-file sfcpath ifname . ?ofname)
(define iport (open-input-file ifname)) ; relative to wd, not this script!
(define oport (if (pair? ?ofname) (open-output-file (car ?ofname)) (current-output-port)))
(define mname (module-name ifname))
(display "/* " oport) (display mname oport)
(display ".c -- generated via skint nsf2c.ssc " oport)
(display (path-strip-directory ifname) oport)
(display " */" oport) (newline oport) (newline oport)
(let loop ([x (read iport)] [end-of-includes? #f])
(unless (eof-object? x)
(cond [end-of-includes?
(process-top-form x oport)
(loop (read iport) #t)]
[(and (list2? x) (eq? (car x) '%include) (string? (cadr x)))
(display "#include " oport) (write (cadr x) oport) (newline oport)
(loop (read iport) #f)]
[else ; switching to body forms
(display "#include \"" oport) (display mname oport)
(display ".h\"" oport) (newline oport) (newline oport)
(process-top-form x oport)
(loop (read iport) #t)])))
(close-input-port iport)
(if (pair? ?ofname) (close-output-port oport)))
(define (main args)
(cond [(list3? args) (process-file (cadr args) (caddr args))]
[(list4? args) (process-file (cadr args) (caddr args) (cadddr args))]
[else (error "usage: scint ksf2c.ssc SFCPATH INFILE [OUTFILE]" args)]))
; this is not a real #! script, so call main manually
;(main (command-line))