add/fix input operation

remaining todo:
 - why are strings swallowing newlines? maybe off by one in substring,
   or the loop-until is wrong?
 - invalid input case is broken(?) supposed to be -1 for EOF but C-d
   sends it into a loop
 - make input/result and time.h conditional on use of INPUT and RAND
1 files changed, 20 insertions(+), 11 deletions(-)

M ttc.lisp
M ttc.lisp +20 -11
@@ 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))))