Last active
December 25, 2015 00:59
-
-
Save kingcons/6891925 to your computer and use it in GitHub Desktop.
Now with more stuff!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defpackage :cl-basics | |
;; Clauses we're not using: import-from, export, shadow | |
(:use :cl)) | |
(in-package :cl-basics) | |
(defvar *foo* "bar" | |
"A simple variable with docstring.") | |
(defun foo (bar) | |
"A silly example function." | |
(if bar | |
'baz | |
'quux)) | |
(defun y-u-no-destructure? (features &key (lacking '(:destructuring | |
:bagwell-hash-tries))) | |
"A slightly more involved function..." | |
;; We could also have a named lambda here with "flet" which roughly == let-fn, | |
;; and then called the named fn like (remove-if #'predicate features) | |
(remove-if (lambda (x) (member x lacking)) features)) | |
#| | |
&key is a "Lambda List Keyword" for named variables, default args optional. | |
&optional is a keyword for optional positional variables, also supports defaults. | |
Other common lambda list keywords include: &rest, &body | |
|# | |
(defmacro when (test &body body) | |
"A simple macro." | |
`(if ,test | |
(progn | |
(format t "OMG... is true!") | |
,@body))) | |
;;;; Slightly weirder things... | |
;;; Instead of traditional try/catch exceptions, we have Conditions and Handlers... | |
;;; Which are really hard to advocate for in a small example. This, for example, | |
;;; is just a verbose plain old try/catch... | |
;;; see http://lambda-the-ultimate.org/node/1544 | |
;;; see http://en.wikibooks.org/wiki/Common_Lisp/Advanced_topics/Condition_System | |
(define-condition illegal-opcode () | |
((opcode :initarg :opcode :reader opcode)) | |
(:report (lambda (condition stream) | |
(format stream "~X is not a legal opcode." (opcode condition)))) | |
(:documentation "Illegal opcodes are not currently implemented.")) | |
(defun execute (cpu) | |
"Step the CPU until a BRK instruction." | |
(loop for opcode of-type u8 = (get-byte (cpu-pc cpu)) | |
do (handler-case (step-cpu cpu opcode) | |
(undefined-function () | |
(error 'illegal-opcode :opcode opcode))) | |
until (zerop opcode))) | |
;;; We have a DSL called _loop_ to perform iteration. | |
;;; This is from a static blog engine I wrote called Coleslaw. | |
(defun find-injections (content) | |
"Iterate over *INJECTIONS* collecting any that should be added to CONTENT." | |
(flet ((injections-for (location) | |
(loop for (injection predicate) in (getf *injections* location) | |
when (funcall predicate content) | |
collect injection))) | |
(list :head (injections-for :head) | |
:body (injections-for :body)))) | |
;;; We have a DSL called _format_ to perform string formatting. | |
;;; This is from a 6502 disassembler I wrote called cl-6502. | |
(defun print-instruction (bytes index name docs mode) | |
"Format the instruction at INDEX and its operands for display." | |
(let ((byte-str (format nil "~{~2,'0x ~}" bytes)) | |
(args-str (format nil "~A ~A" name (arg-formatter (rest bytes) mode)))) | |
(format t "$~4,'0x ~9A ;; ~14A ~A~%" index byte-str args-str docs))) | |
;;; We also have something called "generalized assignment"... | |
;;; You can define your own 'places' with (defun (setf foo) (new-val the-foo) ...) | |
;;; see http://www.lispworks.com/documentation/HyperSpec/Body/05_aa.htm | |
(setf *foo* #(1 2 3)) ; -> sets *foo* to the vector 1,2,3 | |
(setf (elt *foo* 0) "cookie") ; -> sets *foo* to the vector "cookie",2,3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment