scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  1#include <stdint.h>
  2
  3#define INPUTSIZ LINESIZ
  4
  5#define GLOBALCTX 0
  6#define PARAMCTX  1
  7
  8#define NR_USWITCHES 20
  9
 10#define FAIL   1
 11#define NOFAIL 0
 12
 13#define EQUAL  0
 14#define EQUIV  1
 15
 16/*
 17 * Definition of enumerations
 18 */
 19enum {
 20	NOALLOC,
 21	ALLOC
 22};
 23
 24enum typeprops {
 25	TDEFINED = 1 << 0,    /* type defined */
 26	TSIGNED  = 1 << 1,    /* signedness of the type */
 27	TINTEGER = 1 << 2,    /* the type is INT or ENUM */
 28	TARITH   = 1 << 3,    /* the type is INT, ENUM or FLOAT */
 29	TAGGREG  = 1 << 4,    /* the type is STRUCT or UNION */
 30	TK_R     = 1 << 5,    /* this is a K&R-function */
 31	TELLIPSIS= 1 << 6,    /* this function has an ellipsis par */
 32	TFUNDEF  = 1 << 7,    /* function definition */
 33};
 34
 35enum inputtype {
 36	IMACRO = 1 << 0,      /* macro expansion type */
 37	IFILE  = 1 << 1,      /* input file type */
 38	ISTDIN = 1 << 2,      /* stdin type */
 39	IPARAM = 1 << 3,      /* macro param expansion */
 40	IEOF   = 1 << 4,      /* EOF mark */
 41	ITYPE  = IMACRO | IFILE | ISTDIN | IPARAM,
 42};
 43
 44/* data type letters */
 45enum ns {
 46	L_INT8      = 'C',
 47	L_INT16     = 'I',
 48	L_INT32     = 'W',
 49	L_INT64     = 'Q',
 50	L_UINT8     = 'K',
 51	L_UINT16    = 'N',
 52	L_UINT32    = 'Z',
 53	L_UINT64    = 'O',
 54	L_BOOL      = 'B',
 55
 56	L_FLOAT     = 'J',
 57	L_DOUBLE    = 'D',
 58	L_LDOUBLE   = 'H',
 59
 60	L_ELLIPSIS  = 'E',
 61	L_VOID      = '0',
 62	L_POINTER   = 'P',
 63	L_FUNCTION  = 'F',
 64	L_ARRAY     = 'V',
 65	L_UNION     = 'U',
 66	L_STRUCT    = 'S',
 67	L_VA_ARG    = '1',
 68};
 69
 70/* recovery points */
 71enum {
 72	END_DECL,
 73	END_LDECL,
 74	END_COMP,
 75	END_COND
 76};
 77
 78/* type constructors */
 79enum typeop {
 80	FTN = 1,
 81	PTR,
 82	ARY,
 83	KRFTN
 84};
 85
 86/* namespaces */
 87enum namespaces {
 88	NS_DUMMY,
 89	NS_IDEN,
 90	NS_TAG,
 91	NS_LABEL,
 92	NS_CPP,
 93	NS_KEYWORD,
 94	NS_CPPCLAUSES,
 95	NS_MACROPAR,
 96
 97	/*
 98	 * This must be the last constant of the enum definition
 99	 * because it marks the beginning of the independent
100	 * struct namespaces
101	 */
102	NS_STRUCTS,
103};
104
105/* symbol flags */
106enum {
107	SAUTO     = 1 << 0,
108	SREGISTER = 1 << 1,
109	SDECLARED = 1 << 2,
110	SFIELD    = 1 << 3,
111	SEXTERN   = 1 << 4,
112	SUSED     = 1 << 5,
113	SCONSTANT = 1 << 6,
114	SGLOBAL   = 1 << 7,
115	SPRIVATE  = 1 << 8,
116	SLOCAL    = 1 << 9,
117	SEMITTED  = 1 << 10,
118	SDEFINED  = 1 << 11,
119	SRSTRING  = 1 << 11,
120	SSTRING   = 1 << 12,
121	STYPEDEF  = 1 << 13,
122	SINITLST  = 1 << 14,
123	SHASINIT  = 1 << 15,
124	SVARIADIC = 1 << 15,
125};
126
127/* node flags */
128enum {
129	NLVAL   = 1 << 0,
130	NCONST  = 1 << 1,
131	NEFFECT = 1 << 2,
132	NDECAY  = 1 << 3,
133};
134
135/* lexer mode, compiler or preprocessor directive */
136enum {
137	CCMODE,
138	CPPMODE
139};
140
141/* input tokens */
142enum tokens {
143	CONST      = 1 << 0,      /* type qualifier tokens are used as flags */
144	RESTRICT   = 1 << 1,
145	VOLATILE   = 1 << 2,
146	INLINE     = 1 << 3,
147	TQUALIFIER = 1 << 7,
148	MACROPAR   = 17,
149	CONCAT     = 18,
150	STRINGIZE  = 19,
151	NOEXPAND   = 20,
152	EXPAND     = 21,
153	TYPE       = 129,
154	IDEN,
155	SCLASS,
156	CONSTANT,
157	STRING,
158	SIZEOF,
159	INDIR,
160	INC,
161	DEC,
162	SHL,
163	SHR,
164	LE,
165	GE,
166	EQ,
167	NE,
168	AND,
169	OR,
170	MUL_EQ,
171	DIV_EQ,
172	MOD_EQ,
173	ADD_EQ,
174	SUB_EQ,
175	AND_EQ,
176	XOR_EQ,
177	OR_EQ,
178	SHL_EQ,
179	SHR_EQ,
180	ELLIPSIS,
181	CASE,
182	DEFAULT,
183	IF,
184	ELSE,
185	SWITCH,
186	WHILE,
187	DO,
188	FOR,
189	GOTO,
190	VOID,
191	FLOAT,
192	INT,
193	BOOL,
194	VA_LIST,
195	STRUCT,
196	UNION,
197	CHAR,
198	DOUBLE,
199	SHORT,
200	LONG,
201	LLONG,
202	COMPLEX,
203	TYPEDEF,
204	EXTERN,
205	STATIC,
206	AUTO,
207	REGISTER,
208	ENUM,
209	TYPEIDEN,
210	UNSIGNED,
211	SIGNED,
212	CONTINUE,
213	BREAK,
214	RETURN,
215	DEFINE,
216	DEFINED,
217	INCLUDE,
218	LINE,
219	PRAGMA,
220	ERROR,
221	IFDEF,
222	ELIF,
223	IFNDEF,
224	UNDEF,
225	ENDIF,
226	BUILTIN,
227	EOFTOK
228};
229
230/* operations */
231enum op {
232	OADD,
233	OMUL,
234	OSUB,
235	OINC,
236	ODEC,
237	ODIV,
238	OMOD,
239	OSHL,
240	OSHR,
241	OBAND,
242	OBXOR,
243	OBOR,
244	OSNEG,
245	ONEG,
246	OCPL,
247	OAND,
248	OOR,
249	OEQ,
250	ONE,
251	OLT,
252	OGE,
253	OLE,
254	OGT,
255	OASSIGN,
256	OA_MUL,
257	OA_DIV,
258	OA_MOD,
259	OA_ADD,
260	OA_SUB,
261	OA_SHL,
262	OA_SHR,
263	OA_AND,
264	OA_XOR,
265	OA_OR,
266	OADDR,
267	OCOMMA,
268	OCAST,
269	OPTR,
270	OSYM,
271	OASK,
272	OCOLON,
273	OFIELD,
274	OLABEL,
275	ODEFAULT,
276	OCASE,
277	OJUMP,
278	OBRANCH,
279	OEXPR,
280	OEFUN,
281	OELOOP,
282	OBLOOP,
283	OFUN,
284	OPAR,
285	OCALL,
286	OCALLE,
287	ORET,
288	ODECL,
289	OBSWITCH,
290	OESWITCH,
291	OINIT,
292	OBUILTIN,
293	OTYP,
294};
295
296/*
297 * Definition of structures
298 */
299typedef struct type Type;
300typedef struct symbol Symbol;
301typedef struct swtch Switch;
302typedef struct node Node;
303typedef struct macro Macro;
304typedef struct input Input;
305typedef struct arch Arch;
306typedef uint32_t Rune;
307
308struct limits {
309	union {
310		unsigned long long i;
311		double f;
312	} max;
313	union {
314		unsigned long long i;
315		double f;
316	} min;
317};
318
319struct builtin {
320	char *str;
321	Node *(*fun)(Symbol *);
322};
323
324struct type {
325	unsigned char op;           /* type builder operator */
326	int ns;                     /* namespace for struct members */
327	short id;                   /* type id, used in dcls */
328	char letter;                /* letter of the type */
329	unsigned char prop;         /* type properties */
330	unsigned char align;        /* align of the type */
331	unsigned long size;         /* sizeof the type */
332	Type *type;                 /* base type */
333	Symbol *tag;                /* symbol of the strug tag */
334	union {
335		Type **pars;            /* Function type parameters */
336		Symbol **fields;        /* fields of aggregate type */
337	} p;
338	union {
339		unsigned char rank;     /* conversion rank */
340		long long elem;         /* number of type parameters */
341	} n;
342	Type *next;                 /* local list pointer */
343	Type *h_next;               /* hash collision list */
344};
345
346struct symbol {
347	unsigned char ctx;
348	unsigned char hide;
349	int ns;
350	unsigned short id;
351	unsigned short flags;
352	char *name;
353	Type *type;
354	unsigned char token;
355	union {
356		long long i;
357		unsigned long long u;
358		float f;
359		double d;
360		long double ld;
361		char *s;
362		Rune *rs;
363		unsigned char token;
364		Node **init;
365		Symbol **pars;
366		Node *(*fun)(Symbol *);
367	} u;
368	struct symbol *next;
369	struct symbol *hash;
370};
371
372struct node {
373	unsigned char op;
374	unsigned char flags;
375	Type *type;
376	Symbol *sym;
377	struct node *left, *right;
378};
379
380struct swtch {
381	short nr;
382	char hasdef;
383};
384
385struct arch {
386	Type voidtype;
387	Type pvoidtype;
388	Type booltype;
389	Type schartype;
390	Type uchartype;
391	Type chartype;
392	Type ushorttype;
393	Type shorttype;
394	Type uinttype;
395	Type inttype;
396	Type longtype;
397	Type ulongtype;
398	Type ullongtype;
399	Type llongtype;
400	Type floattype;
401	Type doubletype;
402	Type ldoubletype;
403	Type sizettype;
404	Type pdifftype;
405	Type ellipsistype;
406	Type va_type;
407	Type va_list_type;
408	Type wchartype;
409
410	int (*valid_va_list)(Type *tp);
411};
412
413struct yystype {
414	Symbol *sym;
415	Symbol *cppsym;
416	unsigned char token;
417};
418
419#ifdef NR_MACROARG
420struct macro {
421	Symbol *sym;
422	char *fname;
423	char **arglist;
424	char *buffer;
425	char *def;
426	char *arg;
427	int bufsiz;
428	int argsiz;
429	int npars;
430	Symbol *hideset[NR_MACROARG];
431};
432#endif
433
434#if defined(stdin) && defined(NR_MACROARG)
435struct input {
436	char flags;
437	unsigned lineno;
438	char *filenam;
439	FILE *fp;
440	Macro *macro;
441	char *line, *begin, *p;
442	Symbol *hideset[NR_MACROARG];
443	struct input *next;
444};
445#endif
446
447/* error.c */
448void error(char *, ...);
449void warn(char *, ...);
450void unexpected(void);
451void errorp(char *, ...);
452void cpperror(char *, ...);
453Type *deftype(Type *);
454
455/* types.c */
456int eqtype(Type *, Type *, int);
457Type *ctype(int, int, int);
458Type *mktype(Type *, int, long long, Type *[]);
459Type *duptype(Type *);
460struct limits *getlimits(Type *);
461void typesize(Type *);
462void flushtypes(void);
463
464/* symbol.c */
465void dumpstab(Symbol **, char *);
466Symbol *lookup(int, char *, int);
467Symbol *nextsym(Symbol *, int);
468Symbol *install(int, Symbol *);
469Symbol *newsym(int, char *);
470void pushctx(void), popctx(void);
471void killsym(Symbol *);
472Symbol *newlabel(void);
473void builtins(struct builtin *);
474Symbol *newstring(char *, size_t);
475Symbol *newrstring(Rune *, size_t);
476unsigned newid(void);
477void isyms(void);
478
479/* stmt.c */
480void compound(Symbol *, Symbol *, Switch *);
481
482/* decl.c */
483Type *typename(void);
484void decl(void);
485
486/* lex.c */
487int ahead(void);
488int next(void);
489void expect(int);
490void discard(void);
491int moreinput(void);
492int addinput(int, void *, int);
493void delinput(void);
494void setsafe(int);
495void setloc(char *, unsigned);
496#define accept(t) ((yytoken == (t)) ? next() : 0)
497
498/* code.c */
499Node *prtree(char *, Node *);
500void emit(int, void *);
501Node *node(int, Type *, Node *, Node *);
502Node *varnode(Symbol *);
503Node *constnode(Symbol *);
504Node *sizeofnode(Type *);
505Node *offsetnode(Symbol *,  Type *);
506Node *addrnode(unsigned long long);
507void freetree(Node *);
508void icode(void);
509Node *zeronode(Type *);
510
511/* fold.c */
512Node *simplify(Node *);
513unsigned long long ones(int);
514
515/* expr.c */
516Node *decay(Node *), *negate(Node *np), *assign(void);
517Node *convert(Node *, Type *, int);
518Node *iconstexpr(void), *condexpr(int), *expr(void);
519int isnodecmp(int);
520int negop(int);
521int cmpnode(Node *, unsigned long long);
522int power2node(Node *, int *);
523
524/* init.c */
525void initializer(Symbol *);
526
527/* cpp.c */
528void icpp(void);
529int cpp(void);
530int expand(Symbol *);
531void incdir(char *);
532void outcpp(void);
533void defdefine(char *, char *, char *);
534void undefmacro(char *);
535void ppragmaln(void);
536void delmacro(Macro *);
537void sethideset(Input *), unsethideset(Input *);
538Macro *newmacro(Symbol *);
539Node *defined(void);
540
541
542/* builtin.c */
543void ibuilts(void);
544
545/* arch.c */
546void iarch(void);
547int valid_va_list(Type *);
548
549/* architectures */
550Arch *amd64_sysv(void);
551Arch *z80_scc(void);
552Arch *arm64_sysv(void);
553Arch *riscv64_sysv(void);
554Arch *i386_sysv(void);
555
556/*
557 * Definition of global variables
558 */
559extern struct yystype yylval;
560extern char yytext[];
561extern int yytoken, yyspace;
562extern unsigned short yylen;
563extern int disexpand, disstring;
564extern unsigned cppctx;
565extern Input *input;
566extern int lexmode, namespace;
567extern int onlycpp, onlyheader;
568extern unsigned curctx;
569extern Symbol *curfun, *zero, *one;
570extern unsigned lineno;
571extern char filenam[];
572extern char *architecture;
573
574extern Type *voidtype, *pvoidtype, *booltype,
575            *uchartype,   *chartype, *schartype,
576            *uinttype,    *inttype,
577            *sizettype, *pdifftype,
578            *ushorttype,   *shorttype,
579            *longtype,    *ulongtype,
580            *ullongtype,  *llongtype,
581            *floattype,   *doubletype,  *ldoubletype,
582            *ellipsistype, *va_list_type, *va_type,
583            *wchartype;