@@ 1,5 1,3 @@
-;;; lexer
-
(defstruct (token) text kind (value nil))
(defclass lexer ()
@@ 129,14 127,9 @@
(next-char l)
token)))
-;;; parser
-
(define-condition parsing-error (error)
((text :initarg :text :reader text)))
-;; Parser object keeps track of current token and checks if the code
-;; matches the grammar.
-
(defclass parser ()
((lexer :accessor lexer :initarg :lexer)
(emitter :accessor emitter :initarg :emitter)
@@ 178,7 171,12 @@
(:method ((p parser))
(header-line (emitter p) "#include <stdio.h>")
(header-line (emitter p) "#include <stdlib.h>")
+ (header-line (emitter p) "#include <time.h>")
(header-line (emitter p) "int main(void) {")
+ (header-line (emitter p) "int result;")
+ (header-line (emitter p) "char input;")
+ (header-line (emitter p) "time_t t;")
+ (header-line (emitter p) "srand((unsigned) time(&t));")
(loop while (check-token-kind p :NEWLINE)
do (next-token p))
@@ 354,6 352,15 @@
(emit-line (emitter p) (format nil "~a);" (token-value (current-token p))))
(next-token p))
+ ((check-token p :INPUT)
+ (next-token p)
+ (verify p :REGISTER)
+ (check-register p)
+ (emit-line (emitter p) (format nil "result = scanf(\"%c\", &input);"))
+ (emit-line (emitter p) (format nil "if(0 == result) { ~a = -1; }" (token-value (current-token p))))
+ (emit-line (emitter p) (format nil "~a = (int)input;" (token-value (current-token p))))
+ (next-token p))
+
(t (emit-line (emitter p) (format nil "// FIXME ~a" (current-token p))) (next-token p)))
(newline p)))
@@ 375,8 382,6 @@
do (next-token p))))
(format nil "~{~a~}" numbers))))
-;;; emitter
-
(defclass emitter ()
((header :accessor header :initform "")
(code :accessor code :initform "")))
@@ 393,5 398,9 @@
(:method ((e emitter) new-code)
(setf (header e) (format nil "~a~a~%" (header e) new-code))))
-;;; testing
-
+(defun compile-to-c (source-string)
+ (let* ((e (make-instance 'emitter))
+ (l (make-instance 'lexer :source source-string))
+ (p (make-instance 'parser :emitter e :lexer l)))
+ (program p)
+ (format t "~a ~a~%" (header e) (code e))))