Lisp Operating System, Abstraction Kernel
Programming Language Description
Copyright (C) 2004 - 2012 by Omar Jarjur
Overview:
The language implemented by the system is a purely functional
dialect of Lisp. It uses static scope and an eager evaluation
strategy. It also provides fixed precision integer arithmetic
operations. The mainstream dialect that it most closely resembles is
probably Scheme.
A losak program is repeatedly evaluated with the result being used
for I/O. Specifically, if a program evaluates to a function then the
next input event (or null if no such events are available and the program
was compiled without multitasking support) is passed to this function as a
parameter and evaluation continues. Otherwise, if a program evaluates to a
pair, the head of the pair is executed as an output event, and the tail of the
pair is evaluated as the remainder of the computation.
Kernel Parameters:
Although subsequent stages of the process take a single parameter,
the first value that a program evaluates to is a function that takes two
parameters; one for the number of available cons cells, and the second for
the parameter string. The parameter string is a list of integers, with each
integer representing the ascii value of a character in the string.
System Input:
Each of the system input events have the following form. If it is (), then
no new input is available yet. If it is a number, then it is a keycode
received from the keyboard. Otherwise, it should be a pair of numbers,
where the first number is an I/O port and the second number is the value
in that port.
System Output:
Each output event generated by the program is interpreted as
follows: If it is a number, then it is the next ascii value to be
written to the screen. If it is a pair of numbers then the first number
is an I/O port and the second number is a value to be written to that
port. If it is a list of one number, then it is a request to poll that
numbered I/O port. If it is a list of two numbers, then the first number
is a memory location (less than 1 megabyte) and the second number is
a (8-bit) value to be written to that memory location.
Multitasking:
Losak programs can be compiled in multitasking mode by passing the "-m"
parameter to the compiler. This adds the ability to run multiple concurrent
threads in the program.
Child threads are forked by evaluating to a pair of the definition of the
child thread, and the subsequent value of the parent thread. The child thread
is defined using a list of the child thread's ID, the amount of memory
allocated to it, and the child thread's initial value.
A thread can send a message to another thread by evaluating to a pair of
the message and the thread's subsequent value. If the message is a single
element list, then that element is sent to the thread's parent. If the message
is a two element list, then the first element identifies a child thread, and
the second element is a value to be sent to that child thread.
The root thread is considered to have the host system as its parent. Thus,
system input events are sent to the top-level thread, and messages sent by that
thread to its parent are treated as system output events.
Language Constructs:
A program consists of zero or more definitions followed by an expression.
Any malformed expressions evaluate to ().
Each primitive is a function except for define, quote, quasiquote, unquote,
fn, if, cond, and let.
Each parameter to a function is evaluated before that function is applied
to it. Pattern matching is used both in let expressions and in function
application. So, for example "((fn ((a . b) c) (cons a c)) '(1 . 2) 3)"
evaluates to "(1 . 3)".
Syntactic sugar is provided for defining quoted expressions and for quoted
lists of integers. ' is equivalent to (quote ), ` is equivalent to
(quasiquote ), , is equivalent to (unquote ), and "" is
equivalent to (quote (<#X> <#Y> <#Z>)) where <#X> is the ascii value of the
character . So "hello" will be parse as (quote (104 101 108 108 111)).
(define ( . ) ) : Add a new function with the name
, arg list of , and body of to the global
definitions. This is only allowed at the top level; anywhere else
it will simply evaluate to ().
(define ) : Evaluate and add it to the global
definitions with the name . This is only allowed at the top
level; anywhere else it will simply evaluate to ().
(quote ) or ' : Return without evaluating it.
(quaisquote ) or ` : Return without evaluating it, except for
subexpressions preceeded by a , or unquote.
(unquote ) or , : Evaluate even if it is inside of a quasiquote.
(fn ) : Return a static scoped function with the argument
list and the value .
(if ) : Evaluate . If it returned any value
other than (), then evaluate and return its value. Otherwise,
evaluate and return its value.
(cond ( ) ( ) ...) : Repeatedly evaluate a until
one of them returns a value other than (). At that
point evaluate the corresponding and return its
value. If every returns (), then return ().
(let (( ) ( ) ... ) ):
Evaluate each and bind its value to the
corresponding . Then evaluate in the new
environment and return its value.
( . ) : If is a function then evaluate
and apply the function to it. Otherwise
return ().
(cons ) : Return the pair ( . )
(car ) : If is a pair return its first element. Otherwise return ().
(cdr ) : If is a pair return its second element. Otherwise return ().
(null? ) : If is null return a non-nil value. Otherwise return ().
(pair? ) : If is a pair return a non-nil value. Otherwise return ().
(symbol? ) : If is a symbol return a non-nil value. Otherwise return ().
(number? ) : If is a number return a non-nil value. Otherwise
return ().
(function? ) : If is a function return a non-nil value. Otherwise
return ().
(= ) : Return a non-nil value if and are the same number or
the same symbol. Otherwise return ().
(< ) : Return a non-nil value if and are numbers and is
less than , or if and are symbols and
alphabetically precedes (In terms of ASCII characters).
Otherwise return ().
(> ) : Return a non-nil value if and are numbers and is
greater than , or if and are symbols and
alphabetically follows (In terms of ASCII characters).
Otherwise return ().
(+ ) : Return the sum of the two numbers and .
(- ) : Return the negation of .
(- ) : Return the difference of the two numbers and .
(* ) : Return the product of the two numbers and .
(/ ) : Return the integer quotient of divided by .
(% ) : Return the integer remainder of divided by .
(>> ) : Signed right shift of by places.
(>>> ) : Unsigned right shift of by places.
(<< ) : Left shift of by places.
(& ) : Return the bitwise and of and .
(| ) : Return the bitwise or of and .
(^ ) : Return the bitwise xor of and .
(~ ) : Return the bitwise negation of .