- Negative zeros and the atan function:

Versions: 00.0017.

The treatment of negative zeros is not entirely consistent in Armpit Scheme. One consequence is that the atan function can return an incorrect value when called with zero as its first argument. The following trace examplifies.`30156 armpit> (- 0.0) ; a negative zero is o.k. -0.0 30156 armpit> (/ 0.0 -1.0) ; division gives a positive zero only (when result is zero) 0.0 30156 armpit> (atan 0.0 -1.0) ; atan thinks (0 -1) is in the 1st quadrant 0.0 30156 armpit> (/ 1e-20 -1.0) ; division properly gives a negative number -1.e-20 30156 armpit> (atan 1e-20 -1.0) ; atan finds the right quadrant 3.14159`

- Floating point function accuracy:

Versions: 00.0017.

Floating point functions in Armpit Scheme are implemented using Taylor series and are accurate but not ultra accurate (floats and ints are 30-bit). The example below examplifies.`32176 armpit> (expt 2 3) 7.99998 32176 armpit> (* 2.0 2.0 2.0) 8. 32176 armpit> (/ (- (expt 2 3) 8) 8) -1.90735e-6 32176 armpit> (expt 2 9) 5.11998e2 32176 armpit> (/ (- (expt 2 9) 512) 512) -4.76837e-6`

- Numbers with many digits:

Versions: 00.0017.

Armpit Scheme uses 30 bits to represent integers (two's complement) and floats. This limits float accuracy to 6 or 7 decimal digits. The parser was designed to work within this limit and entering numbers with more than 8 digits at the REP can generate incorrect results. The following examplifies.`3504 armpit> 500000000 ; 5e8 is o.k. for a 30-bit integer 500000000 3504 armpit> 600000000 ; 6e8 is above the largest 30-bit integer and becomes nan nan 3504 armpit> 3.141592 ; pi is o.k. with 7 digits 3.14159 3504 armpit> 3.14159265 ; 9 digits are also o.k. for pi (trailing digits are not stored) 3.14159 3504 armpit> 3.141592653 ; 10 digits is too many -7.96328e-2`

- Fractions:

Versions: 00.0017.

Scheme fractions are not implemented in Armpit Scheme. The division sign (/) in a fraction is assumed to represent an exponent sign (normally: e):`3504 armpit> 1/2 ; interpreted as 1e2 1.e2 3504 armpit> 1/-2 ; interpreted as 1e-2 1.e-2`

- * and / return floats:

Versions: 00.0017.

In most cases, multiplications and divisions return floating point numbers even if the operands are all integers. This can lead equality tests to produce incorrect answers as in the following r5rs example:`32108 armpit> (case (* 2 3) ; doesn't work because (* 2 3) returns float 6. ((2 3 5 7) 'prime) ((1 4 6 8 9) 'composite)) 32108 armpit> (case (round (* 2 3)) ; a possible workaround ((2 3 5 7) 'prime) ((1 4 6 8 9) 'composite)) composite`

- char->integer, integer->char, string->number:

Versions: 00.0017 (fixed in 00.0017b).

In Armpit Scheme Version 00.0017, the functions char->integer, integer->char and string->number were implemented incorrectly. They have been fixed in Version 00.0017b. - write and display:

Versions: 00.0017.

In Armpit Scheme, the functions write and display produce the same result. - Upper and lower case characters in symbols:

Versions: 00.0017.

In Armpit Scheme, symbols can have upper and lower case characters and are not considered equivalent if their case differs.`3504 armpit> (eqv? 'hello 'HeLlO) #f`

- Port functions:

Versions: 00.0017.

Some port functions, for example (current-input-port) are not implemented in Armpit Scheme. - Comments and parentheses:

Versions: 00.0017.

Armpit Scheme counts parentheses and double-quotes inside comments when identifying whether an expression entered at the REP is complete or not. It is necessary to close these parentheses and double-quote (within a comment) for proper operation.`3440 armpit> (+ 3 4) ; this comment opens a parenthesis ( ; which needs to be closed ; before Armpit evaluates the sum (+ 3 4) ; let's close the parenthesis here: ) 7`

- Error handling:

Versions: 00.0017.

The only error currently handled by Armpit Scheme is an apply error. When such an error is encountered, the current return (continuation) and data stacks are cleared and the system jumps back to the REP. This may cause unknown problems if an apply error occurs in a thread other than the top-level REP. The example below illustrates handling of an apply error.`32176 armpit> (9 10) (apply error: 9)`

- System Lock Up:

Versions: 00.0017.

Armpit Scheme can lock-up if improper arguments are given as function inputs. If this arises, reset the MCU. The example code below causes such a lock-up.`32108 armpit> (string-length 10 20)`

- Reset at end of memory:

Versions: 00.0017.

When Armpit Scheme runs out of heap space, it performs a soft reset of the Scheme environment. However, not all functions are properly reinitialized such that it is best to manually perform a hard reset prior to continuing its use.

- LPC2131 Limitations:

Versions: 00.0017.

The LPC2131 ARM device is the smallest on which Armpit Scheme is known to run. It has 32kB of FLASH and 8kB of RAM. Armpit Scheme reserves 1 sector of FLASH (4 kB) for a user startup scheme program which leaves 28kB of FLASH for the Armpit core. In order to fit Armpit Scheme within this limited space, several functions were left out of the 2131 version of Armpit: force, delay, values, cxxxr (eg. cddar), cxxxxr (eg. cadadr), call-with-values, do, case, the Taylor-series-based floating-point functions (exp, expt, log, tan, cos, ...), the real-time-clock functions and others. Typing the name of an undefined function (or an undefined symbol) at the REP returns '(). - Memory Considerations:

Versions: 00.0017.

Armpit Scheme uses a stop-and-copy garbage collector and 1kB of RAM for its read-buffer and system stack. The available heap size at startup can be estimated as (MCU-or-board-RAM - 1kB) / 2. The actual number of bytes of heap available space is reported by Armpit Scheme in front of the "armpit>" prompt and is current when the prompt is printed. New cons cells use 8 bytes of heap space (4 bytes for the car and 4 bytes for the cdr), new symbols have an 8-byte overhead and use an additional number of bytes equal to the number of characters in the symbol rounded up to the next multiple of 4 (32-bit boundary), plus, they need 16 bytes (2 cons cells) for linkage into the obarray (eg. typing x or xx or xyz or xyz0 at the rep consumes 28 bytes of heap space if these symbols were not previously defined). Defining a symbol (eg. (define y 10)) consumes a minimum of 16 bytes (2 cons cells) of heap space for linkage into the environment on top of the bytes used for the symbol and obarray (eg. 44 bytes are used by (define y 10) if y didn't exist before). - Peripherals:

Versions: 00.0017.

Many, but not all, MCU peripherals are available to Armpit Scheme. GPIO, PWM, ADC and RTC are generally available. Peripherals requiring a callback Interrupt Service Routine (ISR -- eg. I2C communications) are generally not implemented, except Timer 0 (useable for multitasking). The default configuration of MCU I/O pins set by Armpit Scheme at startup can be read using (for example, on a Tiny2106):

and the pinsel ports can similarly be used to set alternative functions for MCU pins, using, for example: (write #x0123abcd (pinsel 1)) -- but do refer to the LPC2xxx manual before setting arbitrary values into these MCU registers (scheme ports). Additionally, because 30-bit tagged integers are used in Armpit Scheme, the top 2 MSBs of pin assignments written to or read from pinsel ports are always equal to the 3rd MSB (hence exercise caution when modifying bits 29, 30 and 31 in pinsel ports as bits 30 and 31 will be set to the same value as bit 29).`32104 armpit> (number->string (read (pinsel 0)) 16) "00008005" 32104 armpit> (number->string (read (pinsel 1)) 2) "00000101010000000000000000000000"`

bioe-hubert-at-sourceforge.net