UNPKG

10.6 kBTypeScriptView Raw
1/**
2 * C1 AST
3 *
4 * Aims to mostly-faithfully capture the the C1 Grammar as described in
5 * http://c0.typesafety.net/doc/c0-reference.pdf
6 *
7 * Exceptions:
8 * - Does not distinguish <sid>, <vid>, <fid>, and <aid> categories. These are used by the parser to
9 * disambiguate syntactic forms (especially the unfortunate <aid> vs. <tid> distinction needed to parse the
10 * statement `x * y;` as a binary expression or variable declaration). Within a full syntax tree
11 * they are unambiguous and can all be represented with Identifier.
12 * - The restrictions that a variable declaration not appear in the update of a ForStatement is expressed
13 * (this is a property of static semantics in the spec, see C0.23, "The step statement in a for loop may
14 * not be a declaration".).
15 * - SimpleStatement does not include variable declarations, which facilitates the above exception.
16 * - The placement restrictions on requires, ensures, loop_invariant, and assert contracts are
17 * expressed. These are properties of static semantics in the spec, see C0.23, "@requires and @ensures can
18 * only annotate functions," etc.
19 * - Arbitrary pragmas are accepted (this matches the actual behavior of the C0 compiler, which only warns on
20 * unknown pragmas)
21 *
22 * Loosely based on Esprima, with the notable and stubborn distinction of using "tag" instead of "type."
23 * Esprima Spec: https://esprima.readthedocs.io/en/latest/syntax-tree-format.html
24 * Esprima Demo: http://esprima.org/demo/parse.html
25 */
26export interface Syn {
27 readonly tag: string;
28 readonly range?: [number, number];
29 readonly loc?: SourceLocation;
30}
31export interface Position {
32 readonly line: number;
33 readonly column: number;
34}
35export interface SourceLocation {
36 readonly start: Position;
37 readonly end: Position;
38 readonly source?: string | null;
39}
40export interface Identifier extends Syn {
41 readonly tag: "Identifier";
42 readonly name: string;
43}
44export declare type Type = IntType | BoolType | StringType | CharType | VoidType | PointerType | ArrayType | StructType | Identifier;
45export interface IntType extends Syn {
46 readonly tag: "IntType";
47}
48export interface BoolType extends Syn {
49 readonly tag: "BoolType";
50}
51export interface StringType extends Syn {
52 readonly tag: "StringType";
53}
54export interface CharType extends Syn {
55 readonly tag: "CharType";
56}
57export interface VoidType extends Syn {
58 readonly tag: "VoidType";
59}
60export interface PointerType extends Syn {
61 readonly tag: "PointerType";
62 readonly argument: Type;
63}
64export interface ArrayType extends Syn {
65 readonly tag: "ArrayType";
66 readonly argument: Type;
67}
68export interface StructType extends Syn {
69 readonly tag: "StructType";
70 readonly id: Identifier;
71}
72export declare type Expression = Identifier | IntLiteral | StringLiteral | CharLiteral | BoolLiteral | NullLiteral | ArrayMemberExpression | StructMemberExpression | CallExpression | IndirectCallExpression | CastExpression | UnaryExpression | BinaryExpression | LogicalExpression | ConditionalExpression | AllocExpression | AllocArrayExpression | ResultExpression | LengthExpression | HasTagExpression;
73export interface IntLiteral extends Syn {
74 readonly tag: "IntLiteral";
75 readonly value: number;
76 readonly raw: string;
77}
78export interface StringLiteral extends Syn {
79 readonly tag: "StringLiteral";
80 readonly value: string;
81 readonly raw: string;
82}
83export interface CharLiteral extends Syn {
84 readonly tag: "CharLiteral";
85 readonly value: string;
86 readonly raw: string;
87}
88export interface BoolLiteral extends Syn {
89 readonly tag: "BoolLiteral";
90 readonly value: boolean;
91}
92export interface NullLiteral extends Syn {
93 readonly tag: "NullLiteral";
94}
95/**
96 * Array access `e[e]`
97 */
98export interface ArrayMemberExpression extends Syn {
99 readonly tag: "ArrayMemberExpression";
100 readonly object: Expression;
101 readonly index: Expression;
102}
103/**
104 * Struct field access:
105 * - `e.f` (deref === false)
106 * - `e->f` (deref === true)
107 */
108export interface StructMemberExpression extends Syn {
109 readonly tag: "StructMemberExpression";
110 readonly deref: boolean;
111 readonly object: Expression;
112 readonly field: Identifier;
113}
114/**
115 * Regular function calls `f(e1,e2,...,en)`
116 */
117export interface CallExpression extends Syn {
118 readonly tag: "CallExpression";
119 readonly callee: Identifier;
120 readonly arguments: Expression[];
121}
122/**
123 * Function pointer calls `(*e)(e1,e2,...,en)`
124 */
125export interface IndirectCallExpression extends Syn {
126 readonly tag: "IndirectCallExpression";
127 readonly callee: Expression;
128 readonly arguments: Expression[];
129}
130/**
131 * Prefix cast operation `(ty)e`.
132 */
133export interface CastExpression extends Syn {
134 readonly tag: "CastExpression";
135 readonly kind: Type;
136 readonly argument: Expression;
137}
138/**
139 * Prefix unary operations `~e` and friends.
140 */
141export interface UnaryExpression extends Syn {
142 readonly tag: "UnaryExpression";
143 readonly operator: "&" | "!" | "~" | "-" | "*";
144 readonly argument: Expression;
145}
146/**
147 * Eager binary operations `e+e` and friends
148 */
149export interface BinaryExpression extends Syn {
150 readonly tag: "BinaryExpression";
151 readonly operator: "*" | "/" | "%" | "+" | "-" | "<<" | ">>" | "<" | "<=" | ">=" | ">" | "==" | "!=" | "&" | "^" | "|";
152 readonly left: Expression;
153 readonly right: Expression;
154}
155/**
156 * Short-circuiting binary operations `e && e` and `e || e`.
157 */
158export interface LogicalExpression extends Syn {
159 readonly tag: "LogicalExpression";
160 readonly operator: "||" | "&&";
161 readonly left: Expression;
162 readonly right: Expression;
163}
164/**
165 * `e ? e : e`
166 */
167export interface ConditionalExpression extends Syn {
168 readonly tag: "ConditionalExpression";
169 readonly test: Expression;
170 readonly consequent: Expression;
171 readonly alternate: Expression;
172}
173/**
174 * `alloc(ty)`
175 */
176export interface AllocExpression extends Syn {
177 readonly tag: "AllocExpression";
178 readonly kind: Type;
179}
180/**
181 * `alloc(ty)`
182 */
183export interface AllocArrayExpression extends Syn {
184 readonly tag: "AllocArrayExpression";
185 readonly kind: Type;
186 readonly size: Expression;
187}
188/**
189 * `\result`
190 */
191export interface ResultExpression extends Syn {
192 readonly tag: "ResultExpression";
193}
194/**
195 * `\length(e)`
196 */
197export interface LengthExpression extends Syn {
198 readonly tag: "LengthExpression";
199 readonly argument: Expression;
200}
201/**
202 * `\hastag(ty,e)`
203 */
204export interface HasTagExpression extends Syn {
205 readonly tag: "HasTagExpression";
206 readonly kind: Type;
207 readonly argument: Expression;
208}
209/**
210 * LValues are a refinement of Expressions
211 */
212export declare type LValue = Identifier | StructMemberLValue | DereferenceLValue | ArrayMemberLValue;
213export interface StructMemberLValue extends StructMemberExpression {
214 readonly object: LValue;
215}
216export interface DereferenceLValue extends UnaryExpression {
217 readonly operator: "*";
218 readonly argument: LValue;
219}
220export interface ArrayMemberLValue extends ArrayMemberExpression {
221 readonly object: LValue;
222}
223export declare type SimpleStatement = AssignmentStatement | UpdateStatement | ExpressionStatement;
224export declare type Statement = SimpleStatement | VariableDeclaration | IfStatement | WhileStatement | ForStatement | ReturnStatement | BlockStatement | AssertStatement | ErrorStatement | BreakStatement | ContinueStatement;
225export interface AssignmentStatement extends Syn {
226 readonly tag: "AssignmentStatement";
227 readonly operator: "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | "&=" | "^=" | "|=";
228 readonly left: LValue;
229 readonly right: Expression;
230}
231export interface UpdateStatement extends Syn {
232 readonly tag: "UpdateStatement";
233 readonly operator: "++" | "--";
234 readonly argument: Expression;
235}
236export interface ExpressionStatement extends Syn {
237 readonly tag: "ExpressionStatement";
238 readonly expression: Expression;
239}
240export interface VariableDeclaration extends Syn {
241 readonly tag: "VariableDeclaration";
242 readonly kind: Type;
243 readonly id: Identifier;
244 readonly init: Expression | null;
245}
246export interface IfStatement extends Syn {
247 readonly tag: "IfStatement";
248 readonly test: Expression;
249 readonly consequent: Statement;
250 readonly alternate?: Statement;
251}
252export interface WhileStatement extends Syn {
253 readonly tag: "WhileStatement";
254 readonly invariants: Expression[];
255 readonly test: Expression;
256 readonly body: Statement;
257}
258export interface ForStatement extends Syn {
259 readonly tag: "ForStatement";
260 readonly invariants: Expression[];
261 readonly init: SimpleStatement | VariableDeclaration | null;
262 readonly test: Expression;
263 readonly update: SimpleStatement | null;
264 readonly body: Statement;
265}
266export interface ReturnStatement extends Syn {
267 readonly tag: "ReturnStatement";
268 readonly argument: Expression | null;
269}
270export interface BlockStatement extends Syn {
271 readonly tag: "BlockStatement";
272 readonly body: Statement[];
273}
274export interface AssertStatement extends Syn {
275 readonly tag: "AssertStatement";
276 readonly contract: boolean;
277 readonly test: Expression;
278}
279export interface ErrorStatement extends Syn {
280 readonly tag: "ErrorStatement";
281 readonly argument: Expression;
282}
283export interface BreakStatement extends Syn {
284 readonly tag: "BreakStatement";
285}
286export interface ContinueStatement extends Syn {
287 readonly tag: "ContinueStatement";
288}
289export declare type Declaration = StructDeclaration | FunctionDeclaration | TypeDefinition | FunctionTypeDefinition | Pragma;
290export interface StructDeclaration {
291 readonly tag: "StructDeclaration";
292 readonly id: Identifier;
293 readonly definitions: VariableDeclarationOnly[];
294}
295export interface VariableDeclarationOnly extends Syn {
296 readonly kind: Type;
297 readonly id: Identifier;
298}
299export interface FunctionDeclaration {
300 readonly tag: "FunctionDeclaration";
301 readonly returns: Type;
302 readonly id: Identifier;
303 readonly params: VariableDeclarationOnly[];
304 readonly preconditions: Expression[];
305 readonly postconditions: Expression[];
306 readonly body: null | BlockStatement;
307}
308export interface TypeDefinition {
309 readonly tag: "TypeDefinition";
310 readonly definition: VariableDeclarationOnly;
311}
312export interface FunctionTypeDefinition {
313 readonly tag: "FunctionTypeDefinition";
314 readonly definition: FunctionDeclaration;
315}
316export interface Pragma {
317 readonly tag: "Pragma";
318 readonly pragma: string;
319 readonly contents: string;
320}