Overview of C-Flat 2008

This is an informal specification of C-Flat 2008, a working subset of C for use in a compiler class. C-flat includes expressions, basic control flow, recursive functions, and strict type checking. It is object-compatible with ordinary C and thus can take advantage of the standard C library, at least when using limited types. Note the emphasis on informal: the only precise specification of a language is the compiler itself, and it is your job to write the compiler! If there is anything unclear or ambiguous about this page, just ask, and we will clarify.

Tokens

Just as in C, identifiers (i.e. variable and function names) may contain letters, numbers, and underscores. Identifiers must begin with a letter or an underscore. These are examples of valid identifiers: i x mystr fog123 BigLongName55

The following strings are C-flat keywords and may not be used as identifiers: boolean char else false if int print return string true void while

In C-flat, whitespace is any combination of the following characters: tab (\t) space ( ) linefeed (\n) or carriage return (\r). Whitespace consiting of is not significant in C-flat. Both C-style and C++-style comments are valid in C-flat:

/* A C-style comment */
a=5; // A C++ style comment

C-flat has four atomic types: integers, characters, strings, and booleans. Each variable must be declared individually. Sample declarations are:

int     x = 123;
char    c = 'q';
string  s = "hello cflat\n";
boolean b = false;

An int is always a signed 32 bit value. char is a single ASCII character. string is a double-quoted string that cannot be modified. boolean can take the literal values true or false. C-flat does not have arrays, pointers or structures.

Both char and string may contain the following backslash codes. \n indicates a linefeed (ASCII value 10), \0 indicates a null (ASCII value zero), and a backslash followed by anything else indicates exactly the following character. Both strings and identifiers may be up to 256 characters long.

Expressions

C-flat has many of the arithmetic operators found in C, with the same meaning and level of precedence:
( ) (highest)
grouping
++ -- postfix increment/decrement
- unary ops
^ exponentiation
* / % multiplication
+ - addition
< <= >= == != comparison
&&logical and
||logical or
=assignment
(lowest)

C-flat is strictly typed. This means that you may only assign a value to a variable (or function parameter) if the types match exactly. You cannot perform many of the fast-and-loose conversions found in C.

Following are examples of some (but not all) type errors:

int x=65;
char y='A';
if(x>y) ... // error: x and y are of different types!

int f=0;
if(f) ...      // error: f is not a boolean!

void writechar( char c );
int a=65;
writechar(a);  // error: a is not a char!
Following are some (but not all) examples of correct type assignments:
boolean b;
int x=3, y=5;
b = x<y;     // ok: the expression x<y is boolean

int f=0;
if(f==0) ...    // ok: f==0 is a boolean expression

char c='a';
if(c=='a') ...  // ok: c and 'a' are both chars

Declarations and Statements

In C-flat, you may declare global variables with optional constant initializers, function prototypes, and function definitions. Within functions, you may declare local variables with optional initialization expressions. Scoping rules are identical to C. As in C, you should define a main function, but it should take no arguments. Function definitions may not be nested.

Within functions, basic statements may be arithmetic expressions, return statements, if and if-else statements, while loops, or code within inner { } groups. C-flat does not have switch statements, for-loops, or do-while loops.

Unlike C, C-flat has a print statement. Note that print is not a function call. A print statement takes a list of expressions separated by commas, and prints each out to the console.

Here is an example that pulls it all together:

int x=35;

void fib( int x )
{
	if(x<2) {
		return 1;
	} else {
		return fib(x-1)+fib(x-2);
	}
}

int main()
{
	int i=x;
	while(i>0) {
		print "fib(", i, ") = ", fib(i), "\n";
		i--;
	}

	return 0;
}