From 9a170384797d6caaf4d07637b7e7348ef479e674 Mon Sep 17 00:00:00 2001 From: Moritz Gmeiner Date: Sat, 7 Sep 2024 01:51:08 +0200 Subject: [PATCH] init commit --- .vscode/alive/fasl/tmp.fasl | Bin 0 -> 9924 bytes .vscode/alive/fasl/tmp.lisp | 11 +++++++++++ .vscode/alive/repl-history.json | 1 + .vscode/settings.json | 6 ++++++ cl-lox.asd | 8 ++++++++ package.lisp | 4 ++++ src/cl-lox.lisp | 11 +++++++++++ src/lexer.lisp | 6 ++++++ src/run.lisp | 13 +++++++++++++ src/token.fasl | Bin 0 -> 9898 bytes src/token.lisp | 11 +++++++++++ 11 files changed, 71 insertions(+) create mode 100644 .vscode/alive/fasl/tmp.fasl create mode 100644 .vscode/alive/fasl/tmp.lisp create mode 100644 .vscode/alive/repl-history.json create mode 100644 .vscode/settings.json create mode 100644 cl-lox.asd create mode 100644 package.lisp create mode 100644 src/cl-lox.lisp create mode 100644 src/lexer.lisp create mode 100644 src/run.lisp create mode 100644 src/token.fasl create mode 100644 src/token.lisp diff --git a/.vscode/alive/fasl/tmp.fasl b/.vscode/alive/fasl/tmp.fasl new file mode 100644 index 0000000000000000000000000000000000000000..24fc7a0916a25550a8e6d8402a8ebc04df1165c7 GIT binary patch literal 9924 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 literal 0 HcmV?d00001 diff --git a/.vscode/alive/fasl/tmp.lisp b/.vscode/alive/fasl/tmp.lisp new file mode 100644 index 0000000..045ea3f --- /dev/null +++ b/.vscode/alive/fasl/tmp.lisp @@ -0,0 +1,11 @@ +(in-package :cl-lox) + +(defstruct code-pos + (line 1 :type integer) + (col 0 :type integer)) + + +(defstruct token + (code-pos (make-code-pos) :type code-pos) + token-type + (data nil)) diff --git a/.vscode/alive/repl-history.json b/.vscode/alive/repl-history.json new file mode 100644 index 0000000..b9e832f --- /dev/null +++ b/.vscode/alive/repl-history.json @@ -0,0 +1 @@ +[{"pkgName":"cl-user","text":"(describe token-type)"},{"pkgName":"cl-user","text":"(describe 'token-type)"},{"pkgName":"cl-user","text":"(make-code-pos)"},{"pkgName":"cl-user","text":"(cl-lox::code-pos)"},{"pkgName":"cl-user","text":"(code-pos)"},{"pkgName":"cl-user","text":"(code-pos"},{"pkgName":"cl-user","text":"(typep \"asdf\" 'string)"},{"pkgName":"cl-user","text":"(describe 'integer)"},{"pkgName":"cl-user","text":"(describe 'string)"},{"pkgName":"cl-user","text":"'string"},{"pkgName":"cl-user","text":"string"},{"pkgName":"cl-user","text":"(type-of xyz)"},{"pkgName":"cl-user","text":"(setf xyz \"asdf\")"},{"pkgName":"cl-user","text":"xyz"},{"pkgName":"cl-user","text":"(defvar xyz 123)"},{"pkgName":"cl-user","text":"(cl-lox::scan-tokens 3)"},{"pkgName":"cl-user","text":"(scan-tokens 3)"},{"pkgName":"cl-user","text":"(cl-lox::run-repl)"},{"pkgName":"cl-user","text":"(cl-lox::run-file :path nil)"},{"pkgName":"cl-user","text":"(cl-lox:run-repl)"},{"pkgName":"cl-user","text":"(run-repl)"},{"pkgName":"cl-user","text":"(length argv)"},{"pkgName":"cl-user","text":"argv"},{"pkgName":"cl-user","text":"4"},{"pkgName":"cl-user","text":"(argv)"},{"pkgName":"cl-user","text":"(defvar argv (uiop:command-line-arguments))"},{"pkgName":"cl-user","text":"(define argv (uiop:command-line-arguments))"},{"pkgName":"cl-user","text":"(uiop:command-line-arguments)"},{"pkgName":"cl-user","text":"(cl-lox:main)"},{"pkgName":"cl-user","text":"(asdf:make :cl-lox)"},{"pkgName":"cl-user","text":"(my-command-line)"},{"pkgName":"cl-user","text":"(cl-lox:my-command-line)"},{"pkgName":"cl-user","text":"(cl-lox:hello)"},{"pkgName":"cl-user","text":"(hello)"},{"pkgName":"cl-user","text":"(ql:quickload \"cl-ppcre\")"},{"pkgName":"cl-user","text":"(ql:quickload cl-ppcre)"}] \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..99c2a0b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "editor.formatOnType": true, + "[commonlisp]": { + "editor.wordSeparators": "`|;:'\",()" + } +} diff --git a/cl-lox.asd b/cl-lox.asd new file mode 100644 index 0000000..96bf7c8 --- /dev/null +++ b/cl-lox.asd @@ -0,0 +1,8 @@ +(asdf:defsystem "cl-lox" + :description "Lox implementation in Common Lisp" + :serial t + :depends-on () + :components ((:file "package") + (:file "src/cl-lox") + (:file "src/token") + (:file "src/lexer"))) diff --git a/package.lisp b/package.lisp new file mode 100644 index 0000000..60ea194 --- /dev/null +++ b/package.lisp @@ -0,0 +1,4 @@ +(defpackage cl-lox + (:use cl) + (:export #:main) + (:export #:make-exe)) diff --git a/src/cl-lox.lisp b/src/cl-lox.lisp new file mode 100644 index 0000000..1fb351d --- /dev/null +++ b/src/cl-lox.lisp @@ -0,0 +1,11 @@ +(in-package :cl-lox) + + +(defun main () + (let* ((argv (uiop:command-line-arguments)) (argc (length argv))) + (cond ((= argc 0) (run-repl)) + ((= argc 1) (run-file :path (car argv)))))) + + +(defun make-exe () + (sb-ext:save-lisp-and-die "cl-lox" :toplevel #'main :executable t)) diff --git a/src/lexer.lisp b/src/lexer.lisp new file mode 100644 index 0000000..8d17266 --- /dev/null +++ b/src/lexer.lisp @@ -0,0 +1,6 @@ +(in-package :cl-lox) + + +(defun scan-tokens (source) + (declare (string source) + (ignore source))) diff --git a/src/run.lisp b/src/run.lisp new file mode 100644 index 0000000..8e4ada0 --- /dev/null +++ b/src/run.lisp @@ -0,0 +1,13 @@ +(in-package :cl-lox) + + +(defun run-file (&key path) + (let ((source (uiop:read-file-string path))) + (run source))) + + +(defun run-repl ()) + +(defun run (source) + (declare (string source) + (ignore source))) diff --git a/src/token.fasl b/src/token.fasl new file mode 100644 index 0000000000000000000000000000000000000000..20755b555d5559623c3d33e82c1fb3be277506e7 GIT binary patch literal 9898 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