summaryrefslogtreecommitdiff
path: root/src/gscc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gscc')
-rwxr-xr-xsrc/gscc72
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: