Data Types

Inlab Scheme has implemented a “pure indirect memory model” what actually means that every Inlab Scheme object is a pointer to a tagged object.

Constants

Pointer to constants are pointing to a statically memory area which identifies each individual constant. With Inlab Scheme the following constants exist:

#t

This is the boolean constant “true”.

#f

This is the boolean constant “false”, which is the only object that counts as false in conditional expressions like if and cond.

#u

This is the “unassigned constant” which may be bound to a variable. If a variable bound to this constant is used an error is signalled. This constant is used to detect some errors in derived expressions.

()

The empty list () is actually implemented as a separate constant and distinct from #f .

Symbols

Symbols are parsed (internalised) by read in lower case. Symbols have a name that has all properties of a string. It is guaranteed that a symbol with the same name is always the same in the sense of eq?.

Numbers

Inlab Scheme supports inexact reals (floating points) and exact integers as numeric data types:

Exact Integers

Exact Integers can be as large as the native word size of the machine on which Inlab Scheme is compiled on (32 bit or 64 bit signed). Internally, some static space is allocated for “often used” integers, integers lying outside the “often used” range are allocated dynamically. This actually means that eq? on integers may fail, even is two integers contain the same value. You should - as always - use eqv? to compare integer values for equality.

Inexact Reals

Inexact real numeric values are implemented using floating point standard arithmetic as provided by the host machine.

Characters

Inlab Scheme supports numeric character values from 0 to 255. Characters are static allocated objects what guarantees eq? to return #t for the same character.

As specified in the R4RS the following special character names are supported:

#\space
#\newline

A “#" followed by a 3 digit decimal value with leading zeroes may be used to specify each possible value from 0 to 255.

Example:

[1] #\048
#\0
[2] #\078
#\N

Characters are self evaluating. As specified in the R4RS case is significant in #<character> but not in #<character name>.

Strings

Strings are kept in the main heap and are dynamically allocated. Strings may contain any sequence of 8 bit characters (including 0), which allows storing any binary data using strings. To enter any possible 8 bit character value a followed by a three digit decimal value in the range 0 … 255 may be used. A special character that cannot be represented another way is also printed using that notation.

Example:

[1] "abc\\def"
"abc\\def"
[2] "\078"
"N"

Although the length of a string internally has no special limit (depends on the current heap size and the architecture of the machine) there is a limit in (read) which limits the length of a token to a maximum of 10KB. This actually means that a single string constant (e.g. in a program) larger than 10KB will cause a parsing error in Inlab Scheme.

Lists

Lists are implemented the well known and usual way using “cons cells”, there is nothing special to tell here.

Example:

[1] '(a . (b . (c . ())))
(a b c)
[2]

Vectors

Vectors are implemented as specified by the R4RS as a “heterogeneous structure” allocated in heap. Vectors are not self-evaluating and an error is signalled (artificially) when a vector is about to be evaluated.

Example:

[1] '#(this is a vector)
#(this is a vector)
[2]

Ports

The port concept of R4RS is extended by string-input-ports, string-output-ports, Unix popen-ports (reading and writing) and by providing access to UNIX stderr via current-error-port.

Procedures

Three types of procedures are implemented: Primitive procedures (implemented in C), compound procedures (written in Scheme) and syntax procedures which for the low level macro facility of Inlab Scheme (also written in Scheme).

Example:

[1] car
#<primitive-procedure car>
[2] caar
#<compound-procedure caar>
[3] (pp caar)
(lambda (x) (car (car x)))
ok
[4] quasiquote
#<syntax-procedure quasiquote>
[5] (pp quasiquote)
(named-syntax-lambda
  (quasiquote expr env)
  (internal-qq (cadr expr) 1 1))
ok
[6]

Primitive Procedures

Primitive procedures have a name associated with it. Primitive procedures are printed as #<primitive-procedure <name».

Example:

[1] car
#<primitive-procedure car>
[2] (define a car)
a
[3] a
#<primitive-procedure car>

Compound Procedures

Compound procedures may have a name associated with it for debugging purposes. Compound procedures with a name may be generated using named-lambda or using (define (<name> <args>) <body>).

Compound procedures with a name are printed as #<compound-procedure <name», anonymous compound procedures (as returned by lambda) as #<compound-procedure>.

Example:

[1] (define (plus1 n)
(+ n 1))
plus1
[2] plus1
#<compound-procedure plus1>
[3] (lambda (n) (+ n 1))
#<compound-procedure>
[4]

Syntax Procedures

Inlab Scheme implements its macro facility using syntax procedures, which are first class objects as ordinary compound procedures are.

A similar naming scheme to compound procedures is implemented by syntax-lambda and named-syntax-lambda.

Example:

[1] (pp let*)
(named-syntax-lambda
  (let* expr env)
  ((named-lambda
     (() binding-list body-list)
     (if (null? binding-list)
       (list (cons 'lambda (cons '() body-list)))
       (append
         (list 'let (list (car binding-list)))
         (list (cons 'let* (cons (cdr binding-list) body-list))))))
   (cadr expr)
   (cddr expr)))
ok
[2]

Graphical Data Types

On Linux all graphical data types can be “grabbed” from a v4l2-camera with YUV support and be written directly to the framebuffer at a chosen position.

Bitmaps

A bitmap is a data structure that allows to store bilevel (B/W) images in a compact form in memory. Each line (row) is stored occupying one bit per pixel and is filled up to a byte boundary at the end.

A 0 represents a white, a 1 a black pixel. The origin of a bitmap (0,0) is in the upper left. Addressing generally follows a row/column scheme (row as the first, column as the second parameter).

Reading and writing bitmap to/from the following graphic formats on disk is supported: TIFF G4, TIFF G4 multi-page, XBM and PNG.

The internal structure of a bitmap has the following fields:

Field Description
h the actual height of the bitmap
w the actual width of the bitmap
orow the original row position of that bitmap in another bitmap, -1 if undefined
ocol the original column position of that bitmap in another bitmap, -1 if undefined
xres the X resolution in DPI (floating point value), -1 if undefined
yres the Y resolution in DPI (floating point value), -1 if undefined

The contents of these fields are accessible / settable using the appropriate procedures. Printing a bitmap shows the actual contents of these fields.

Example:

[1] (define a
(bitmap-create 100 100))
a
[2] a
#<bitmap orow:-1 ocol:-1 xres:-1 yres:-1 h:100 w:100>
[3]

Greymaps

A greymap is a data structure that allows the storage of greylevel images in memory. One byte (256 greylevels, 8 bit depth) is allocated for each pixel.

0 represents white, 255 a black pixel, all grey levels are in between. The origin of a greymap (0,0) is in the upper left. Generally the same row/column addressing scheme as being used for bitmaps is used.

Reading greymaps from any PNG file is supported (performing a suitable conversion if necessary), greymaps may be written in greylevel format either interlaced or not.

The internal structure of a greymap has the following fields (similar to a bitmap):

Field Description
h the actual height of the greymap
w the actual width of the greymap
orow the original row position of that greymap in another greymap, -1 if undefined
ocol the original column position of that greymap in another greymap, -1 if undefined
xres the X resolution in DPI (floating point value), -1 if undefined
yres the Y resolution in DPI (floating point value), -1 if undefined

The contents of these fields are accessible / settable using the appropriate procedures. Printing a greymap shows the actual contents of these fields.

Example:

[1] (define a (greymap-create 100 100))
a
[2] a
#<greymap orow:-1 ocol:-1 xres:-1 yres:-1 h:100 w:100>
[3]

Colormaps

A colormap is a data structure that allows the storage of color images in memory. Three bytes representing RGB values are representing one pixel.

0 represents the lowest intensity of a RGB color channel, and 255 the highest intensity.

The origin of a colormap (0,0) is in the upper left. Generally the same row/column addressing scheme as for the other two graphical data types is used.

The internal structure of a colormap has the following fields (as with bitmaps and greymaps):

Field Description
h the actual height of the colormap
w the actual width of the colormap
orow the original row position of that colormap in another colormap, -1 if undefined
ocol the original column position of that colormap in another colormap, -1 if undefined
xres the X resolution in DPI (floating point value), -1 if undefined
yres the Y resolution in DPI (floating point value), -1 if undefined

The contents of these fields are accessible / settable using the appropriate procedures. Printing a colormap shows the actual contents of these fields.

Example:

[1] (define a (colormap-create 200 200))
a
[2] a
#<colormap orow:-1 ocol:-1 xres:-1 yres:-1 h:200 w:200>
[3]