Program Structure
A C program is built from tokens, organized into declarations and statements, and compiled in a specific order. Auto simplifies this structure but preserves the same logical organization. This chapter walks through the grammar, declarations, definitions, and statements of both languages.
2.1 Grammar
C programs are made of tokens: identifiers, keywords, literals, operators, and punctuation. The C standard defines a precise grammar that determines which sequences of tokens form valid programs.
Here are the basic token categories in C:
- Keywords:
int,double,if,for,while,return,struct,switch,case,break,default,void,const, ... - Identifiers: names you choose --
main,count,my_function,Point - Literals:
42,3.14,"hello",true - Operators:
+,-,*,/,=,==,<,>,&&,||, ... - Punctuation:
(,),{,},;,,
C's grammar is type-first. When you declare something, the type comes before the name:
int x = 5;
double pi = 3.14159;
const char* greeting = "hello";Auto's grammar is simpler. Types appear after names, and fewer keywords are needed:
let x int = 5
let pi float = 3.14159
let greeting str = "hello"Translation Units and Scope
A C program consists of one or more translation units -- source files that are compiled independently and then linked together. Each translation unit is processed in phases: preprocessing, tokenization, parsing, and code generation.
Auto follows the same model. Each .at file is a translation unit. The a2c transpiler processes each one independently, producing a .c file that is then compiled by the C compiler.
C has four scopes for identifiers:
- Block scope: visible within
{ ... }(the most common). - File scope: visible throughout the translation unit.
- Function scope: only for labels (rarely used).
- Function prototype scope: only within a function declaration.
Auto has two practical scopes: function scope (inside fn) and module scope (at the top level). The mapping is straightforward.
Takeaway: C's grammar puts types first; Auto's grammar puts names first. Both carry the same information, but Auto's order reads more naturally in English: "let x be an int equal to 5."
2.2 Declarations
A declaration in C introduces a name and associates it with a type. The most common form is a variable declaration:
int age = 25;
double height = 1.75;
char initial = 'A';
bool active = true;In Auto, the let keyword introduces an immutable binding, and var introduces a mutable one:
let age int = 25 // immutable
let height float = 1.75
var count int = 0 // mutableType Inference
Auto supports a limited form of type inference with var:
var x = 5 // inferred as int
var pi = 3.14159 // inferred as float
var name = "hello" // inferred as strThe a2c transpiler infers the type from the initializer and generates the appropriate C type. C's auto keyword (added in C23) provides similar functionality, but Auto's var works across all target C standards because the inference happens at transpile time.