# HG changeset patch # User Nolan Prescott # Date 1617866064 14400 # Thu Apr 08 03:14:24 2021 -0400 # Node ID 8d4153304666be4dc947c4711c8059a940cec2bd # Parent c8c93ee54fdd198ae3d373d2067bebc18e9f621f 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 diff --git a/ttc.lisp b/ttc.lisp --- a/ttc.lisp +++ b/ttc.lisp @@ -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 ") (header-line (emitter p) "#include ") + (header-line (emitter p) "#include ") (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))))