Skip to content

Instantly share code, notes, and snippets.

Last active December 25, 2015 00:59
Show Gist options
  • Save kingcons/6891925 to your computer and use it in GitHub Desktop.
Save kingcons/6891925 to your computer and use it in GitHub Desktop.
Now with more stuff!
(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
(defun y-u-no-destructure? (features &key (lacking '(:destructuring
"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
(format t "OMG... is true!")
;;;; 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
;;; see
(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
(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