Schemy Lisp En DOS

Sep 06, 2026 07:58 PM - 1 week ago 5

About

SLED (Schemy Lisp en DOS) is simply a purely symbolic LISP (LISt Processor) pinch functionality (largely) inspired by Scheme. Originally derived from the awesome Kilo LISP, but reduced by some features (such arsenic macros), and enhanced pinch others, SLED tin beryllium classified as an Ur-Lisp and runs connected a DOS (Disk Operating System) specified as FreeDOS aliases MS-DOS, arsenic good arsenic connected DOS-emulators like DOSBox, DOSBox-X, or DOSBox-Staging. For an overview of provided symbols, typical forms, builtin functions, and standard room spot the index. Get SLED:

  • Release Download (including compiled binary)
  • Source Code Repository
  • Backup Repository

Overall, SLED is simply a LISP for DOS.

Data

There are 2 basal information types: Pairs and Atoms (not-pairs). Atoms come successful 3 variants: Symbols, Closures (functions), and some Special Symbols.

Symbols

Symbols are unsocial names and dwell of immoderate operation of maximum 16 of the pursuing characters:

a b c d e f g h one 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 beryllium the starring character.

Additionally, immoderate printable ASCII characteristic tin beryllium portion of a awesome when prefixed pinch the flight characteristic \ (backslash), pinch the objection of (, ), ', and $.

This\ is\ a\ sym\!

Furthermore, uppercase letters are accepted but converted to lowercase unless the characteristic is escaped.

Special Symbols

There are immoderate predefined typical symbols managed by SLED, for illustration nil which intends "empty list". See the index for details.

Quote

A quote intends "do not evaluate". Via the quote typical shape a awesome is registered:

(quote sym)

For convenience the ' short shape syntax whitethorn beryllium used:

'sym

Essentially quoting declares thing arsenic information alternatively of code.

Pairs

Pairs dwell of a head and a tail, each holding either an atom aliases different pair. A brace tin be created arsenic information utilizing the . (dot):

'(a . x)

or arsenic consequence of the cons builtin function:

(cons 'a 'x)

Pair elements (head and tail) are immutable.

Lists

A database is simply a series of pairs wherever each tail points to a chopped different pair except 1 (the last) whose tail is the nil value, which is balanced to (). Here are immoderate lists:

nil '() '(a . nil) '(a . (b . nil))

A database tin beryllium created arsenic information besides by:

'(a b)

or arsenic consequence of the (standard library) database function:

(list 'a 'b)

Improper List

An improper database does not terminate by nil, for example:

(a . (b . (c . d)))

Association List

An relation database is simply a database wherever each constituent is simply a brace (association):

((a . x) (b . y) (c . z))

The caput portion of specified a brace constituent is called key and the tail is called value.

S-Expressions

A symbolic look (S-expression) is simply a information building defined as: An S-expression is either an atom aliases a brace of S-expressions. In Lisp, Scheme, and successful peculiar successful SLED, S-expressions are utilized for information as well arsenic root code.

Numbers

The SLED strategy does not characteristic numeric types. Yet earthy numbers (non-negative integers) tin beryllium emulated utilizing lists:

'() ; zero '(nil) ; one '(nil nil) ; two '(nil nil nil) ; three

These are tally numerals, truthful cardinality represents the magnitude, which is similar to von Neumann ordinals. The functions inc, dec, and zero? facilitate pinch counting tasks.

Code

In LISP, unquoted information is evaluated arsenic code.

Expressions

Expressions tin beryllium evaluated, like:

  • Bindings
  • Functions
  • Special Forms

Bindings

A binding links a awesome to immoderate information payload, and is created via the define special form:

(define a 'x)

Closures

Closures are functions together pinch an environment, and consequence from the lambda typical form:

(define nosy (lambda (arg1 arg2) (print arg1) (print arg2)))

Function Application

The first constituent of an unquoted database is interpreted arsenic an look that evaluates to a usability and the remaining elements arsenic arguments to that function:

(fun arg1 arg2)

The usability information is eager; truthful first, the statement expressions are evaluated, past the usability exertion is utilizing the evaluated arguments.

Arguments

Arguments are evaluated and passed arsenic a database of values to a function.

This intends the usability parameters tin beryllium group up successful various ways:

(lambda x ...) ; x is simply a list (lambda (x y) ...) ; destructured database pinch elements x and y (lambda (x y . z) ...) ; z is simply a database (which is by default nil)

Optional arguments tin beryllium passed arsenic a list, for illustration z above.

Recursion

LISPs trust connected recursion alternatively of iteration. Recursion refers to a function calling itself. Two features of SLED thief debar a stack overflow successful deep recursions: the trampoline evaluator and tail-call optimization (TCO). TCO works for lambda, let, begin, if, ifnil, and apply. Additionally, TCO useful for cons if the recursion runs successful the 2nd argument.

Errors

An correction during information of an look jumps backmost to the top-level, where an correction occurrence tin beryllium tested. An correction cannot beryllium caught wrong an expression.

Builtin Functions

A group of functions is built into the SLED executable to alteration relationship with the strategy and halfway functionality, for specifications spot the index.

Standard Library

Beyond the halfway functions a group of emblematic functions is implemented arsenic a standard room successful the record sled.scm. For specifications spot the index. The modular room whitethorn beryllium extended pinch further civilization definitions.

Special Forms

Certain forms look for illustration functions but are not. These alleged typical forms do not travel the usability behavior, but usage the aforesaid syntax arsenic functions. For example, if does not measure its arguments earlier resolving the form. For specifications spot the index.

Immutability

Special symbols, typical forms, builtin functions, and modular room contents are immutable successful SLED. Furthermore, typical forms and builtin functions cannot be shadowed. Standard room and adjacent civilization definitions cannot be redefined.

System

This LISP strategy is simply a DOS application.

File Names

File names should travel DOS 8.3 naming (maximum 8 characters for the record name, a dot, maximum 3 characters for the record extension). The recommended record hold for scripts moving connected this LISP is .scm owed to syntactic similarity to Scheme; for instance, the modular room is named sled.scm. However, the expert does not cheque the record extension.

Startup

The first action sled takes is loading its modular library, which has to person the sanction sled.scm and is expected successful the aforesaid directory arsenic the SLED.EXE expert executable. All symbols and their values loaded from the modular room go immutable.

Command-Line Arguments

The sled binary has 4 mutually exclusive command-line arguments. The first conscionable displays a thief page:

C:\> sled /?

The 2nd is simply a way to a Lisp root record to beryllium loaded earlier the REPL starts, but aft the modular room loaded:

C:\> sled code.scm

The 3rd is simply a "batch mode" move /B, which exits aft execution:

C:\> sled /B code.scm

The 4th is an "ignore errors" move /I, which behaves for illustration /B but continues execution aft an correction occurs:

C:\> sled /I code.scm

The record way has to beryllium the past argument.

File Path

In the interpreter, if the way contains backslashes these request to beryllium escaped, since the way becomes a awesome and the backslash \ unsocial is not an admissible symbol character.

C:\> sled to\my\code.scm (load 'to\\my\\code.scm)

The record way besides falls nether the 16 characteristic limit.

REPL

Once sled started, the read-eval-print-loop (REPL) originates pinch a prompt:

sled>

It sounds input, evaluates it, prints the result, and prompts again.

Now person fun:

sled> (println 'hello _ 'world)

Extended Characters

A pitfall is extended (two-byte) characters which are not supported. An illustration is utilizing the arrow keys successful the REPL, resulting successful an α (alpha) successful the standard input echo. These extended characters pollute the input watercourse and tin origin an error successful an input statement moreover if deleted.

Exiting

There are 2 regular ways to exit sled.

The first is the dollar awesome $ connected the top-level, which tells the parser to exit:

sled> $

The 2nd is the (exit) builtin function, which upon information exits:

(exit)

Comments

Comments are ignored by the parser. A remark is introduced by a semicolon:

;

All characters until the adjacent statement break are ignored by the parser. Traditionally, the number of consecutive semicolons conveys semantics, similar to Markdown headings:

;;;; main title ;;; conception title ;; commencement of line ; extremity of line

Furthermore, artifact comments are realized via a typical shape named comment:

(comment ...)

Parentheses wrong a remark shape request to beryllium balanced:

(comment ()) ; OK (comment () ; → error

Note that a remark shape cannot beryllium quoted:

'(comment test) ; → error

Breaking

To break axenic computation, usage CTRL+Break, for breaking input CTRL+C is available.

Help

In the REPL, the awesome ? tin beryllium utilized to database typical forms, builtin functions, and modular room symbols.

Limits

As real-mode DOS program, SLED has aggregate constraints:

  • The heap has 12288 nodes
  • The awesome array has 2048 characters

The modular room consumes astir 5% of nodes and characters.

Index

Special Symbols Special Forms Builtin Functions Standard Aliases Standard Library

$ {exit}

This special symbol exits the REPL. This is not a short shape of (exit), arsenic it is resolved by the parser. Works only from the prompt.


? {help}

This special symbol holds an overview of typical forms, builtin functions, and the modular library. Works only from the prompt.


' {quote}

This special symbol is an othername for the quote typical form.


_ {space}

This standard alias is for the abstraction characteristic '\ .


and? <arg1> <arg2>

This standard library binary predicate answers if some arguments are not nil; usage to make compound conditionals simpler.

(and? nil nil) ; → nil (and? nil true) ; → nil (and? existent nil) ; → nil (and? existent true) ; → true NOTE: Unlike successful Scheme, this is not a typical shape of variadic arguments which are evaluated sequentially until a mendacious result, but a binary usability that evaluates some arguments.

ans

This special symbol contains the consequence of the past top-level shape that produced a value; successful lawsuit of an error, the err awesome is set, which tin be tested for pinch error?.

ans

append <lst1> <lst2>

This standard library binary usability returns a database consisting of the second statement database concatenated to the extremity of the first statement list.

(append nil (list 'a)) ; → (a) (append (list 'a) nil) ; → (a) (append (list 'a) (list 'b)) ; → (a b) (append '(a b) '(c d)) ; → (a b c d) (append '(a) 'b) ; → (a . b)

apply <fun> <lst>

This builtin binary usability evaluates the first statement usability pinch the second statement database arsenic arguments.

(apply database '(a b c)) ; → (a b c)

assert <arg> <sym>

This standard library binary process prints the 2nd statement and causes an error, if the first statement evaluates to nil.

(assert nil 'list\ empty)

atom? <arg>

This builtin unary predicate answers if the statement is an atom.

(atom? nil) ; → true (atom? true) ; → true (atom? '(a)) ; → nil

begin <body1> ... <bodyN>

This special form evaluates its arguments successful series and returns the last argument's return value.

(begin (print 'a) (print 'b) 'c) ; → c (begin) ; → nil

br

This standard alias is for newline.


This special form is not evaluated. Use arsenic artifact comment. Unlike the different typical forms, this is decoded by the parser earlier evaluation.

(comment this :-D is ignored) NOTE: Parentheses wrong comments person to beryllium balanced.

compose <arg> <fun1> ... <funN>

This standard library variadic usability pipelines unary functions: the 2nd statement is applied to the first argument, the 3rd statement is past applied to the erstwhile return worth and truthful on; the last argument's return worth is returned arsenic result.

(compose nil inc inc) ; → (nil nil)

cons <arg1> <arg2>

This builtin binary usability returns a brace pinch the first statement arsenic head and 2nd statement arsenic tail.

(cons 'a 'b) ; → (a . b)

dec <arg>

This standard library unary usability returns the tail of a database if not empty; usage to decrement von tally numbers.

(dec '(nil . nil)) ; → nil

define <sym> <arg>

This special form creates a caller binding of the 2nd statement to the first argument symbol, and returns the 2nd argument. Bindings tin beryllium re-defined, except typical symbols, typical forms, builtin functions, aliases modular library symbols.

(define hullo 'world) ; → world NOTE: specify ever affects the world binding, besides erstwhile utilized inside fto aliases lambda.

defined? <sym>

This builtin unary predicate answers if the statement awesome is already defined astatine world scope.

(defined? 'defined?) ; → true (defined? 'undefined) ; → nil

empty? <arg>

This builtin unary predicate answers if its statement is the quiet list.

(empty? nil) ; → true

env

This builtin thunk prints the existent user-defined symbols.

(env)

eof? <arg>

This builtin unary predicate answers if its statement evaluates to an end-of-file (EOF) aliases end-of-transmission (EOT) symbol.

(ifnil (eof? (read)) 'none)

equal? <arg1> <arg2>

This standard library binary predicate answers if the arguments are recursively equal. Use to comparison pairs and lists, nevertheless equal? falls back to equiv? for atoms.

(equal? '(nil nil) (list nil nil)) ; → true (equal? nil nil) ; → true

equiv? <arg1> <arg2>

This builtin binary predicate answers if the arguments are shallowly equal. Use to comparison atoms.

(equiv? nil nil) ; → true

err

This special symbol marks an correction state.

(head nil) (equiv? err ans) ; → true

error <sym> [<arg>]

This builtin process throws an correction and frankincense causes a break in evaluation of the existent form. Furthermore, the first statement awesome (error message) and the optional 2nd statement look (error reason) are printed.

(error 'bad\ correction (list 'not 'right))

error?

This standard library thunk predicate answers if the erstwhile evaluation resulted successful an error.

(head nil) (error?) ; → true

exit

This builtin thunk quits the expert aliases REPL.

(exit) ; backmost to DOS

gc [<arg>]

This builtin process triggers garbage collection. Node usage is printed if an statement is provided which is not nil.

(gc) ; → *no output* (gc nil) ; → *no output* (gc true) ; → *prints node usage*

get <sym> <lst>

This standard library binary usability returns the worth paired to the first argument awesome if recovered successful the 2nd statement relation list, aliases nil otherwise.

(get 'a '((a . x) (b . y))) ; → x (get 'z '((a . x) (b . y))) ; → nil NOTE: Uses equiv? for cardinal comparisons.

This builtin unary usability returns the caput portion of a cons compartment aliases list.

(head (cons 'a 'b)) ; → a NOTE: This usability corresponds to car successful classical LISP and Scheme.

id <arg>

This standard library unary usability returns its argument. Use arsenic identity function.

(id 'x) ; → x

if <arg1> <arg2> [<arg3>]

This special form evaluates the first argument; if it does not measure to nil, the 2nd statement is evaluated and returned, different the third argument is evaluated and returned, aliases `nil` if nary 3rd statement is given.

(if 'ok 'con 'alt) ; → con (if nil 'con 'alt) ; → alt (if 'ok 'con) ; → con (if nil 'con) ; →

ifnil <arg1> <arg2>

This special form evaluates the first statement and returns its result if it is not nil, different the 2nd statement is evaluated and returned.

(ifnil 'ok 'alt) ; → ok (ifnil nil 'alt) ; → alt

inc <arg>

This standard library unary usability prepends nil to a list. Use to increment tally numbers.

(inc nil) ; → (nil) (inc '(nil)) ; → (nil nil)

lambda (<arg1> ... <argN>) <body1> ... <bodyN>

This special form creates a usability pinch arguments arsenic destructured list and a sequentially evaluated body, whose past look is the return value.

(lambda (x y) (print x) y) ; → usability that prints x and returns y

let (<arg1> <arg2>) <body1> ... <bodyN>

This special form creates a scope pinch a section binding and evaluates its assemblage sequentially.

(let (x 'y) x) ; → y NOTE: Unlike Scheme, this typical shape allows only a azygous section binding. Multiple bindings tin beryllium realized by nesting lets.

list <arg1> ... <argN>

This standard library variadic usability constructs a database of its arguments.

(list) ; → nil (list 'a) ; → (a) (list 'a 'b) ; → (a b)

list? <arg>

This standard library unary predicate answers if the statement is simply a proper list.

(list? nil) ; → true (list? true) ; → nil (list? '(x y)) ; → true

load <sym> [<arg>]

This builtin usability evaluates the contents of the record fixed by the argument awesome (path) and returns the past answer. If a 2nd argument, which is not nil, is fixed past errors are ignored during loading.

(load 'myscript.scm) (load 'myscript.scm true) NOTE: Loads tin beryllium nested doubly astatine most.

map <fun> <lst>

This standard library binary usability applies the first statement unary function to each constituent of the 2nd statement database and returns the database of return values.

(map inc '(nil (nil))) ; → ((nil) (nil nil))

member <arg> <lst>

This standard library binary usability returns the brace from the second argument database whose caput is the first argument; different nil is returned.

(member 'b '(a b c)) ; → (b c) (member 'd '(a b c)) ; → nil NOTE: Uses equiv? for database constituent comparisons.

newline

This builtin thunk prints a statement break; usage for output formatting.

(newline)

nil

This special symbol represents the quiet list; and is besides the only value evaluating to "false". Equivalently, '() tin beryllium utilized for nil.

nil ; → nil '() ; → nil

nil? <arg>

This is simply a standard alias for empty?; usage arsenic trial for nil.

(nil? nil) ; → true (nil? '()) ; → true (nil? _) ; → nil (nil? (list)) ; → true

not <arg>

This is simply a standard alias for empty?; usage for inverting predicate results.

(not nil) ; → true (not true) ; → nil

or? <arg1> <arg2>

This standard library binary predicate answers if immoderate statement is not nil; use to simplify compound conditionals.

(or? nil nil) ; → nil (or? nil true) ; → true (or? existent nil) ; → true (or? existent true) ; → true NOTE: Unlike successful Scheme, this is not a typical shape of variadic arguments which are evaluated sequentially until a existent result, but a binary usability that evaluates some arguments.

pair? <arg>

This standard library unary predicate answers if the statement is not an atom.

(pair? 'a) ; → nil (pair? '(a b)) ; → true (pair? nil) ; → nil

print <arg1> ... <argN>

This builtin variadic process prints its arguments to the modular output.

(print 'hi) (print 'hello _ 'world) (print '(a b))

printid <arg1> [<arg2>]

This standard library usability returns the first statement aft printing it and a statement break; if given, the 2nd statement is printed earlier the first.

(printid ans 'answer)

println <arg1> ... <argN>

This standard library variadic process prints its arguments to the standard output and appends a statement break.

(println 'hi) (println 'hello _ 'world) (println '(a b))

proc? <arg>

This builtin unary predicate answers if its statement is simply a closure aliases builtin function. For typical forms, this predicate returns nil.

(proc? map) ; → true (proc? proc?) ; → true (proc? nil) ; → nil (proc? if) ; → nil

put <sym> <arg> <lst>

This standard library usability returns an updated 3rd statement association list by mounting the tail of the brace pinch the first statement awesome arsenic head, or adding a brace pinch the first statement awesome arsenic caput and the 2nd statement as tail, if nary brace pinch the first statement awesome arsenic caput is listed successful the third argument.

(put 'hello 'world nil) ; → ((hello . world)) (put 'one 'uno '((one . a))) ; → ((one . uno)) (put 'two 'b '((one . a))) ; → ((one . a) (two . b)) (put 'two 'z '((one . a) (two . b))) ; → ((one . a) (two . z))

quit

This standard alias is for exit.


quote <arg>

This special form returns its statement unevaluated.

(quote a) ; → a 'a ; → a

read

This builtin thunk returns a awesome publication arsenic a statement of input from the standard input root terminated by a statement break via return cardinal / participate key.

(read)

restart [<sym>]

This builtin usability resets and restarts the expert and optionally loads a record specified by the awesome argument. All definitions are lost!

(restart 'next.scm)

reverse <lst>

This standard library unary usability reverses its database argument.

(reverse (list 'a 'b 'c)) ; → (c b a)

self <arg1> ... <argN>

This special symbol enables anonymous recursion. Inside immoderate closure it resolves to the enclosing lambda. Outside a lambda, aforesaid is undefined.

((lambda (x) (if (empty? x) nil (self (tail x)))) (list nil nil)) ; → nil

shorter? <lst1> <lst2>

This standard library binary predicate answers if the first statement list has little elements than the 2nd statement list.

(shorter? nil (list nil)) ; → true (shorter? (list nil) nil) ; → nil

symbol? <arg>

This builtin unary predicate answers if its statement is simply a symbol.

(symbol? 'a) ; → true

tail <arg>

This builtin unary usability returns the tail portion of a cons cell.

(tail (cons 'a 'b)) ; → b NOTE: This usability corresponds to cdr successful classical LISP and Scheme.

true

This special symbol evaluates to true. Use arsenic a generic "true" value.

true ; → true

value <sym>

This builtin unary usability resolves the worth of its awesome argument. Respects lexical scope.

(value 'ver) ; → sled-0.4

ver

This special symbol evaluates to a awesome pinpointing the type of SLED.

ver ; → sled-0.4

zero? <arg>

This is simply a standard alias for empty?; usage for testing tally numbers.

(zero? nil) ; → true (zero? '(nil)) ; → nil

Usage

  • SLED is made for a disk operating strategy for illustration FreeDOS aliases MS-DOS
  • Outside DOS, a DOS emulator for illustration DOSBox, DOSBox-X, DOSBox-Staging is required
  • Run the ammunition book ./sled.sh (auto-selects the installed DOSBox) connected Linux, BSD, MacOS, aliases Unix
  • Building SLED requires Microsoft C Compiler aliases Open Watcom, arsenic good arsenic make
  • Build pinch MS C 6.0A: make build_msc (Compiler location via MSC)
  • Build pinch Open Watcom v2: make build_owc (Compiler location via OWC)
  • Run build: make run
  • Run tests: make tests
  • Run benchmark: make chair (Takeuchi function, spot this and that)

Links

  • DOS
  • Kilo LISP
  • PC Scheme
  • The implementation of PC Scheme
  • A Comparison of Three LISP Interpreters for MS-DOS-Based Microcomputers
  • Free Lisp improvement environments for DOS
  • S-expressions

This task by gramian is licensed nether the 0BSD (Zero-Clause BSD) license.

More