#!/run/current-system/profile/bin/guile \ -e main -s !# (use-modules (ice-9 getopt-long)) (define version "v0.1") (define (error message) (display (string-concatenate `(,message " Usage: gscc [OPTIONS] file Options: --version, -v: print version information --debug, -d: turn on verbose output --lex, -l: run the lexer, but stop before assembly generation --parse, -p: run the lexer and parser, but stop before assembly generation --codegen, -c: perform lexing, parsing, and assembly generation, but stop before code emission"))) (exit #f)) (define (preprocess file) "Preprocesses a source file using gcc. Returns #f on a failure, or the name of the preprocessed file on a success." (let ((preprocessed-file-name (tmpnam))) (and (zero? (system (string-concatenate `("gcc -E -P " ,file " -o " ,preprocessed-file-name)))) preprocessed-file-name))) (define (process file lex? parse? codegen?) "") (define (postprocess file dest) "Assembles and links file, producing an executable. Returns #f on a failure, #t on a success." (zero? (system (string-concatenate `("gcc " ,file " -o " ,dest))))) (define (main args) (let* ((option-spec '((version (single-char #\v) (value #f)) (debug (single-char #\d) (value #f)) (lex (single-char #\l) (value #f)) (parse (single-char #\p) (value #f)) (codegen (single-char #\c) (value #f)))) (options (getopt-long args option-spec)) (rest (option-ref options '() #f)) (file (if (null? rest) #f (car rest)))) (cond ((option-ref options 'version #f) (display (string-concatenate `("gscc (the 'Guile Scheme C Compiler', " ,version ")")))) ((not (equal? 1 (length rest))) (error "Wrong number of arguments.")) ((or (not file) (not (access? file R_OK)) (not (equal? 'regular (stat:type (stat file))))) (error "The file could not be read.")) (#t (let ((source (preprocess file))) (when source (display (string-concatenate `("Preprocess reported success (wrote " ,source ")."))) (process source (option-ref options 'lex #f) (option-ref options 'parse #f) (option-ref options 'codegen #f)) (newline) (display "Done!"))))))) ;; Local Variables: ;; mode: scheme ;; End: