Schemy LISP en DOS
About SLED (Schemy Lisp en DOS) is a purely symbolic LISP (LISt Processor) with functionality (largely) inspired by Scheme. Originally derived from the fantastic Kilo LISP, but reduced by some features (such as macros), and enhanced with others, SLED can be classified as an Ur-Lisp and runs on a DOS (Disk Operating System) such as FreeDOS or MS-DOS, as well as on DOS-emulators like DOSBox, DOSBox-X, or DOSBox-Staging. For an overview of provided symbols, special forms, builtin functions, and standard library see the index. Get SLED: Release Download (including compiled binary)
Source Code Repository
Backup Repository Overall, SLED is a LISP for DOS.
Data There are two fundamental data types: Pairs and Atoms (not-pairs). Atoms come in three variants: Symbols, Closures (functions), and some Special Symbols. Symbols Symbols are unique names and consist of any combination of maximum 16 of the following characters: a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0 - . ? _ where . cannot be the leading character. Additionally, any printable ASCII character can be part of a symbol when prefixed with the escape character \ (backslash), with the exception of ( , ) , ' , and $ . This\ is\ a\ sym\! Furthermore, uppercase letters are accepted but converted to lowercase unless the character is escaped. Special Symbols There are some predefined special symbols managed by SLED, for example nil which means "empty list". See the index for details. Quote A quote means "do not evaluate". Via the quote special form a symbol is registered: (quote sym) For convenience the ' short form syntax may be used: 'sym Essentially quoting declares something as data instead of code. Pairs Pairs consist of a head and a tail, each holding either an atom or another pair . A pair can be created as data using the . (dot): '(a . x) or as result of the cons builtin function: (cons 'a 'x) Pair elements (head and tail) are immutable. Lists A list is a sequence of pairs where each tail points to a distinct other pair except one (the last) whose tail is the nil value, which is equivalent to () . Here are some lists: nil '() '(a . nil) '(a . (b . nil)) A list can be created as data also by: '(a b) or as result of the (standard library) list function: (list 'a 'b) Improper List An improper list does not terminate by nil , for example: (a . (b . (c . d))) Association List An association list is a list where each element is a pair (association): ((a . x) (b . y) (c . z)) The head part of such a pair element is called key and the tail is called value. S-Expressions A symbolic expression (S-expression) is a data structure defined as: An S-expression is either an atom or a pair of S-expressions. In Lisp, Scheme, and in particular in SLED, S-expressions are used for data as well as source code. Numbers The SLED system does not feature numeric types. Yet natural numbers (non-negative integers) can be emulated using lists: '() ; zero '(nil) ; one '(nil nil) ; two '(nil nil nil) ; three These are tally numerals, so cardinality represents the magnitude, which is similar to von Neumann ordinals. The functions inc , dec , and zero? facilitate with counting tasks.
Code In LISP, unquoted data is evaluated as code. Expressions Expressions can be evaluated, like: Bindings
Functions
Special Forms Bindings A binding links a symbol to some data payload, and is created via the define special form: (define a 'x) Closures Closures are functions together with an environment, and result from the lambda special form: (define fun (lambda (arg1 arg2) (print arg1) (print arg2))) Function Application The first element of an unquoted list is interpreted as an expression that evaluates to a function and the remaining elements as arguments to that function: (fun arg1 arg2) The function evaluation is eager; so first, the argument expressions are evaluated, then the function application is using the evaluated arguments. Arguments Arguments are evaluated and passed as a list of values to a function. This means the function parameters can be set up in various ways: (lambda x ...) ; x is a list (lambda (x y) ...) ; destructured list with elements x and y (lambda (x y . z) ...) ; z is a list (which is by default nil) Optional arguments can be passed as a list, like z above. Recursion LISPs rely on recursion instead of iteration. Recursion refers to a function calling itself. Two features of SLED help avoid a stack overflow in deep recursions: the trampoline evaluator and tail-call optimization (TCO). TCO works for lambda , let , begin , if , ifnil , and apply . Additionally, TCO works for cons if the recursion runs in the second argument. Errors An error during evaluation of an expression jumps back to the top-level, where an error occurrence can be tested. An error cannot be caught inside an expression. Builtin Functions A set of functions is built into the SLED executable to enable interaction with the system and core functionality, for details see the index. Standard Library Beyond the core functions a set of typical functions is implemented as a standard library in the file sled.scm . For details see the index. The standard library may be extended with additional custom definitions. Special Forms Certain forms appear like functions but are not. These so-called special forms do not follow the function behavior, but use the same syntax as functions. For example, if does not evaluate its arguments before resolving the form. For details see the index. Immutability Special symbols, special forms, builtin functions, and standard library contents are immutable in SLED. Furthermore, special forms and builtin functions cannot be shadowed. Standard library and adjacent custom definitions cannot be redefined.
System This LISP system is a DOS application. File Names File names should follow DOS 8.3 naming (maximum 8 characters for the file name, a dot, maximum 3 characters for the file extension). The recommended file extension for scripts running on this LISP is .scm due to syntactic similarity to Scheme ; for instance, the standard library is named sled.scm . However, the interpreter does not check the file extension. Startup The first action sled takes is loading its standard library, which has to have the name sled.scm and is expected in the same directory as the SLED.EXE interpreter executable. All symbols and their values loaded from the standard library become immutable. Command-Line Arguments The sled binary has four mutually exclusive command-line arguments. The first just displays a help page: C:\> sled /? The second is a path to a Lisp source file to be loaded before the REPL starts, but after the standard library loaded: C:\> sled code.scm The third is a "batch mode" switch /B , which exits after execution: C:\> sled /B code.scm The fourth is an "ignore errors" switch /I , which behaves like /B but continues execution after an error occurs: C:\> sled /I code.scm The file path has to be the last argument. File Path In the interpreter, if the path contains backslashes these need to be escaped, since the path becomes a symbol and the backslash \ alone is not an admissible symbol character. C:\> sled to\my\code.scm (load 'to\\my\\code.scm) The file path also falls under the 16 character limit. REPL Once sled started, the read-eval-print-loop (REPL) begins with a prompt: sled> It reads input, evaluates it, prints the result, and prompts again. Now have fun: sled> (println 'hello _ 'world) Extended Characters A pitfall is extended (two-byte) characters which are not supported. An example is using the arrow keys in the REPL, resulting in an α (alpha) in the standard input echo. These extended characters pollute the input stream and can cause an error in an input line even if deleted. Exiting There are two regular ways to exit sled . The first is the dollar symbol $ on the top-level, which tells the parser to exit: sled> $ The second is the (exit) builtin function, which upon evaluation exits: (exit) Comments Comments are ignored by the parser. A comment is introduced by a semicolon: ; All characters until the next line break are ignored by the parser. Traditionally, the number of consecutive semicolons conveys semantics, similar to Markdown headings: ;;;; main title ;;; section title ;; start of line ; end of line Furthermore, block comments are realized via a special form named comment : (comment ...) Parentheses inside a comment form need to be balanced: (comment ()) ; OK (comment () ; → error Note that a comment form cannot be quoted: '(comment test) ; → error Breaking To break pure computation, use CTRL+Break , for breaking input CTRL+C is available. Help In the REPL, the symbol ? can be used to list special forms, builtin functions, and standard library symbols. Limits As real-mode DOS program, SLED has multiple constraints: The heap has 12288 nodes
The symbol table has 2048 characters The standard library consumes about 5% of nodes and characters.
... continue reading