draftcraft

AutoLISP

CADCraft runs AutoLISP routines (.lsp files). What is here and what is not yet: gaps.md (E1).

Loading and running

At startup

CADCraft loads LISP from its support folder, support in the settings folder (on Windows %APPDATA%\CADCraft\support, on macOS ~/Library/Application Support/CADCraft/support, on Linux ~/.config/cadcraft/support; created at first start):

(autoload "file" '("CMD1" "CMD2")) in a startup file makes CMD1 and CMD2 commands that load file (from the support folder too) the first time they are typed. Startup files run to the end without asking for input. A drawing’s own folder is never searched: an acaddoc.lsp that came with a downloaded drawing does not run.

Each drawing has its own variables and functions. A routine is one undo step, whatever commands it runs. A routine that waits for input (getpoint, pause) lets the window work meanwhile; Esc stops it with “Function cancelled”, which *error* receives. A long loop runs a slice per frame, so the window stays live and Esc stops it too.

The language

Integers are 32-bit and wrap as AutoLISP’s do; any real makes arithmetic real. Variables are dynamically scoped: a function’s arguments and its locals (after /) are bound while it runs. Symbols are case-insensitive. Reals print with six significant digits.

Nothing a routine does can crash the program: deep recursion is the error “internal stack limit reached”, malformed source is a reader error, and every built-in checks its arguments.

Built-in functions

Entity lists use the DXF group codes of CADCraft’s DXF files: what entget returns is what a DXF file holds for the object, plus -1 (its name) and 410 (its layout). Angles (groups 50–58) are in radians, as in AutoCAD, where the file holds degrees; entmake, entmod and ssget filters take radians too.

entmake defines blocks: a BLOCK list (2 name, 70 flags, 10 base point, 4 description) begins a definition, the entities made after it go into the block instead of the drawing, and an ENDBLK list adds the block (redefining one of the same name) and returns its name. Flag 1 with a *U name makes an anonymous block, named when it ends. A BLOCK while a definition is open, an xref (flag 4), an invalid name, a block that inserts itself and a block being edited in place (REFEDIT) return nil. A definition stays open across routines until ENDBLK, but a routine that fails drops the one it began.

Testing against the corpus

The AutoLISP conformance corpus (#648) lives in its own repository. Point CADCRAFT_LISP_CORPUS at it and run cargo test -p cadcraft-engine --test it lisp_corpus::; without the variable the test says it was skipped.