skint/pre/nsf2c.ssc

69 lines
2.8 KiB
Text
Raw Permalink Normal View History

2024-08-01 05:17:37 +02:00
#! /usr/bin/env skint -s
;---------------------------------------------------------------------------------------------
; Skint n.sf precursor compiler (n.sf => n.c)
;---------------------------------------------------------------------------------------------
(import (only (skint hidden)
list2? list3?))
(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 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)
2024-07-23 00:24:24 +02:00
(let loop ([x (read iport)] [end-of-includes? #f])
(unless (eof-object? x)
2024-07-23 00:24:24 +02:00
(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 [(list2? args) (process-file (cadr args))]
[(list3? args) (process-file (cadr args) (caddr args))]
[else (error "usage: scint nsf2c.ssc INFILE [OUTFILE]" args)]))
; this is not a real #! script, so call main manually
(main (command-line))