diff options
author | bd <bdunahu@operationnull.com> | 2025-03-20 13:51:28 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-03-20 13:51:28 -0400 |
commit | 6e338215192c26dfb16236398ca8e3762a8d4d0e (patch) | |
tree | 823d7102f43ea5a4b377d5c2cb04a5ec02fb20b7 /src | |
parent | 19d13c8339ee990fba358417a54aa6f1c94c7bca (diff) |
Add logic to open file, lex single character symbols, tests
Diffstat (limited to 'src')
-rw-r--r-- | src/lex.lisp | 52 | ||||
-rw-r--r-- | src/main.lisp | 15 | ||||
-rw-r--r-- | src/package.lisp | 6 |
3 files changed, 68 insertions, 5 deletions
diff --git a/src/lex.lisp b/src/lex.lisp new file mode 100644 index 0000000..ad386ba --- /dev/null +++ b/src/lex.lisp @@ -0,0 +1,52 @@ +(in-package #:lex) + +(defun file->tokens (file) + "Opens FILE and parses returns a list of tokens, or +NIL if the file could not be opened." + + (defun read-tokens (tokens-so-far) + "Collects tokens in FILE into TOKENS-SO-FAR." + (let ((token (read-token))) + (if token + (read-tokens (cons token tokens-so-far)) + (reverse tokens-so-far)))) + + (and (probe-file file) + (with-open-file (*standard-input* file :direction :input) + (read-tokens '())))) + +(defun read-token () + "Reads *STANDARD-INPUT* and returns a token, or nil if the end +of file has been reached. +Whitespace, commas, colons, and parentheses are token delimiters. +Comments start with a semi-colon ';' and all tokens after are ignored." + (let ((chr (read-char *standard-input* nil))) + (cond + ((null chr) chr) + ((whitespace-char-p chr) + (read-token)) + + ((char= chr #\;) + (progn (read-line *standard-input* nil) + (read-token))) + + ((char= chr #\() 'left-paren) + ((char= chr #\)) 'right-paren) + + ((digit-char-p chr) + (read-immediate chr)) + + ((alpha-char-p chr) + (read-identifier chr)) + + (t (error (format nil "~a is not a valid lexical symbol.~%" chr)))))) + +(defun read-immediate (chr) + 'immediate) + +(defun read-identifier (chr) + 'id) + +(defun whitespace-char-p (x) + (or (char= #\space x) + (not (graphic-char-p x)))) diff --git a/src/main.lisp b/src/main.lisp index c85e392..1f0afdd 100644 --- a/src/main.lisp +++ b/src/main.lisp @@ -35,14 +35,19 @@ _/_/ _/_/ " (defun driver (cmd) "Reads in a file and directs lexing, parsing, and binary emission." (print-splash) - (let ((args (clingon:command-arguments cmd)) - (parse? (not (clingon:getopt cmd :lex))) - (emit? (not (clingon:getopt cmd :parse)))) + (let* ((args (clingon:command-arguments cmd)) + (file (car args)) + (parse? (not (clingon:getopt cmd :lex))) + (emit? (not (clingon:getopt cmd :parse)))) (cond ;; complain about num arguments ((/= (length args) 1) (error "Wrong number of arguments.")) - ((not (util:asm-extension? (car args))) (error "The file is not an asm source code file.")))) - (error-cli "Nitimur in Vetitum")) + ((not (util:asm-extension? file)) + (error "The file is not an asm source code file, or it could not be opened.")) + (t (let ((tokens (lex:file->tokens file))) + (format t "~a" tokens) + (format t "Nitimur in Vetitum~%")))))) + (defun cli/command () "Returns a clingon command." diff --git a/src/package.lisp b/src/package.lisp index 9d21293..44399cb 100644 --- a/src/package.lisp +++ b/src/package.lisp @@ -5,3 +5,9 @@ (defpackage #:util (:use #:cl) (:export #:asm-extension?)) + +(defpackage #:lex + (:use #:cl) + (:export #:file->tokens + ;; exported for testing only + #:read-token)) |