SECD virtual machine for pure_LISP

SECD: [ index ] [ collection ] [ hard_SECK reference ]
LISP: [ reference ] [ tutorial ] [ implementation scheme ]


This document describes an modified SECD virtual machine, used for implementation of the pure_LISP language.
This modified version of the Landin's original SECD machine may be named hard_SECK machine.
The main differences with the original:

This document is not yet finished, so you may use the next additional sources of info for my SECD machine:


1. Data types, registers, syntax of the command codes.

Data types:

Terminal data types:

Composite data types:

Registers:

hard_SECK has many registers, but 3 of them (S, E and C) may be treated as main registers:

hard_SECK include the following additional variables:

Syntax of the SECD codes and commands:

SECD codes are packed togeder with 1 or 2 parameters into 32-bit integers.
If the SECD code is i and parameter is p, then the appropriate SECD command is represented by integer i*2^24+p.
In my SECD machine there is special mnemonicks for the positive integers, bigger than 2^24.
Such integers are represented by strings with syntax #cod_par, where cod is the SECD code mnemonick, par is the parameter value.
Examples:

Note that this is only other syntax for integers, you may do all arithmetick operations with it as with normal integers.
In compiler.lib source there is many function calls like (add #trrec i), constructing the proper SECD commands.
The purpose of these mnemonicks is to make SECD executables (files *.sec) more readable.


2. Main codes (single process commands).

These codes may be devided into 2 groups:

1. Control codes - they may change E and C registers or may intrrupt user process in some cases.

For proper handling of tail recursion there is the only code for the control restoration - #rtn,  represented by the nil value of the C register.
There is also a pre-code CleanX, used by codes #rtn, #rec and #trrec.
Post-code StartRec(p) begins a process of recovering for wating recipe:

Non-regular control codes:

 Regular control codes:

Apply-like control codes:

These codes are twins of normal/tail-recursive forms.
Normal forms push C and E into the stack S, working like procedure call in procedure languages.
Tail-recursive forms work like goto statement.
All they have parameter n, representing the number of actual parameters for corresponding LISP function.
All they bind the list of actual parameters S to some environment (current for let/letrec, other for app), changing the register E.
#let and #trlet are used for implementation of let block.
#letrec nad #trletr implements letrec block.
#app and #trapp are used when function, defined by lambda expression is called.
Sn is S with top n elements droped (Sn:=Drop(S,n)).

2. Primitive codes - they change only the S register.

Two argument codes:

One argument codes:


3. Special codes (user calls, interrupts, runtime error handling).

These codes changes all registers. They are used to swap control between kernel and user processes.

Interrupts:


4. Kernel codes (low-level i/o, ipc, synchronization).

Kernel primitive codes:


(c) Skelet, Nov 2002 in terms of GNU GPL

Mail me at home or work