Shmall is an all integer subset of the C language. The motivation of Shmall is to provide a minimal language for the implementation of the Schant (SCHeme And Tiny) Scheme compiler. The Shmall compiler may be useful for other applications written in C as well. Shmall compiles C into an imperative subset of Scheme (Schimper).
The only data type supported is
int
or single dimension
int
arrays.
The
int
type is signed 32 bit integer.
Hexadecimal constants
0x
... are supported.
Character constants of the form
'x'
are supported. They are treated as integers.
Variables are declared globally at the top level or local to functions. Arrays must be globally declared at the top level.
Variables local to a function can only be declared at the topmost function or procedure block.
The
static
keyword is unrecognized. Local static variables have to be
declared globally.
No preprocessor directive is supported except
#define
which can only
define integer constants.
#include
is parsed and provides compatibility with other C compilers
but is ignored. To achieve the effect of an include one must use
cat a b c >d
at the sh/bash shell.
Likewise, the effect of
#ifdef
can be achieved using
if
...
else
...
fi
at the sh/bash shell.
The two standard I/O routines
getchar
and
putchar
are supported. Putchar does not buffer output.
An implicit fflush(stdout) occurs after each putchar.
There are only two forms of
printf
supported:
printf("string")
or
printf("%d", expression)
.
If the string form is used a string cannot exceed 256 characters. If the string
has a \n newline character it must be at the end of the string.
The arithmetic operators:
+ - * / %
are supported.
The bitwise operators:
& | ^ << >> ~
are supported.
The boolean operators:
&& ||
are supported.
The shortcut incrementor / decrementor
++
and
--
are not supported except in
a for statement. Use the form
x = x + 1
.
The assignments
+=
or
-=
are not supported. Use the form
x = x + n
.
The ternary operator
?:
is not supported.
if
...
else
supported.
while
statement supported.
do
...
while
supported.
For statements must be of the form
for (var = expr; boolean_expression; var++)
or
for (var = expr; boolean_expression; var--)
.
The forever idiom:
for (;;)
is no longer supported. Use
while (1)
instead.
The
switch
statement is supported.
The statement must implement all of 0 .. n cases of the switch selector variable
and the cases must appear sequentially in order from 0 to n.
The sole purpose of the switch statement in shmall is to implement an efficient
computed goto.
There is no support for the
default
case.
The
break
statement is only supported for breaking out of cases in a switch statement.
The
continue
statement is not supported.
The
goto
and
label statements are not supported.
Functions can be recursive and only return a value of type
int
or
void
.
Code execution paths in
void
typed functions (procedures) have to end with a return statement.
Arrays can be passed by reference and be referenced locally in a function e.g.
int x[10];
int fn(int y[]) {
...
}
ret = fn(x);
There is a limit of 32 variable arguments to a function or procedure.
No
argv
command line arguments are supported in the
main
function.
Only
int main() {
...
}
is supported.
exit(n)
is supported.
cat source.c | ./shmall
The shmall compiler is good about reporting out of bounds constraints errors on the various array data structures used during compilation. If such an error occurs the shmall compiler can be recompiled by changing the appropriate constant in src/consts.h:
#define POOL_SIZE 32768
#define HASH_TABLE_SIZE 4093 // prime number
#define ERRORS_SIZE 10
#define VECTOR_POOL_SIZE 2000000
#define MAX_TOKENS 512
#define MAX_FORMAL_PARAMETERS 32
#define MAX_STACK 2048
#define MAX_OUTPUT_QUEUE 3072
#define MAX_CONS_CELL 8192
The most likely change will be to increase the vector size for
VECTOR_POOL_SIZE.
Most of the arrays used by shmall are slices out of this vector pool.
When a sliced array exceeds its size an attempt is automatically made to
reallocate the structure with a larger size from the vector pool.
Schimper translates the imperative style scheme code output from the Shmall C compiler. Schimper targets Simpvir virtual machine bytecodes, 32 bit x86 assembly, 32 bit ARM assembly, 32 bit riscv assembly.
cat bin/schimper.txt compilation-mode.txt x.scm | bin/schant-int
Schimper expects the following possible arguments in the compilation-mode.txt file:
vm
arm {v6 | v7} literal-pool-threshold
x86
riscv