diff options
Diffstat (limited to 'src/gscc')
| -rwxr-xr-x | src/gscc | 72 | 
1 files changed, 72 insertions, 0 deletions
diff --git a/src/gscc b/src/gscc new file mode 100755 index 0000000..801bdfe --- /dev/null +++ b/src/gscc @@ -0,0 +1,72 @@ +#!/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:  | 
