Another day, another commit.
[sod] / lex.lisp
index cd0a5a8..0c0fa65 100644 (file)
--- a/lex.lisp
+++ b/lex.lisp
 ;; Class definition.
 
 (defclass lexer ()
-  ((stream :initarg :stream
-          :type stream
-          :reader lexer-stream)
-   (char :initform nil
-        :type (or character null)
-        :reader lexer-char)
-   (pushback-chars :initform nil
-                  :type list)
-   (token-type :initform nil
-              :accessor token-type)
-   (token-value :initform nil
-               :accessor token-value)
-   (pushback-tokens :initform nil
-                   :type list))
+  ((stream :initarg :stream :type stream :reader lexer-stream)
+   (char :initform nil :type (or character null) :reader lexer-char)
+   (pushback-chars :initform nil :type list)
+   (token-type :initform nil :accessor token-type)
+   (token-value :initform nil :accessor token-value)
+   (pushback-tokens :initform nil :type list))
   (:documentation
    "Base class for lexical analysers.
 
 (defparameter *sod-keywords*
   (make-keyword-table
 
-   ;; Words with important meanings to us.
-   "class"
-   "import" "load" "lisp" "typename"
-   "code"
-   "extern"
-
    ;; Words with a meaning to C's type system.
    "char" "int" "float" "void"
    "long" "short" "signed" "unsigned" "double"
    "struct" "union" "enum"))
 
 (defclass sod-lexer (lexer)
-  ((keywords :initarg :keywords
-            :initform *sod-keywords*
-            :type hash-table
-            :reader lexer-keywords))
+  ()
   (:documentation
    "Lexical analyser for the SOD lanuage.
 
                                           (char= ch #\_))))
                          (return))))))
 
-           ;; Check to see whether we match any keywords.
-           (multiple-value-bind (keyword foundp) (gethash id keywords)
-             (return (values (if foundp keyword :id) id)))))
+           ;; Done.
+           (return (values :id id))))
 
         ;; Pick out numbers.  Currently only integers, but we support
         ;; multiple bases.
 ;;; C fragments.
 
 (defclass c-fragment ()
-  ((location :initarg :location
-            :type file-location
+  ((location :initarg :location :type file-location
             :accessor c-fragment-location)
-   (text :initarg :text
-        :type string
-        :accessor c-fragment-text))
+   (text :initarg :text :type string :accessor c-fragment-text))
   (:documentation
    "Represents a fragment of C code to be written to an output file.
 
            ;; Something else.  Eat it and continue.
            (t (getch)))))
 
-      ;; Return the fragment we've collected.
-      (make-instance 'c-fragment
-                    :location start-floc
-                    :text (get-output-stream-string output)))))
+      (let* ((string (get-output-stream-string output))
+            (end (position-if (lambda (char)
+                                (or (char= char #\newline)
+                                    (not (whitespace-char-p char))))
+                              string
+                              :from-end t))
+            (trimmed (if end
+                         (subseq string 0 (1+ end))
+                         "")))
+
+       ;; Return the fragment we've collected.
+       (make-instance 'c-fragment
+                      :location start-floc
+                      :text trimmed)))))
 
 (defun c-fragment-reader (stream char arg)
   "Reader for C-fragment syntax #{ ... stuff ... }."