1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
/*
* Copyright (c) 2026, Chloe M.
* Provided under the BSD-3 clause
*/
#include <stdint.h>
#include <errno.h>
#include "cescal/log.h"
#include "cescal/parser.h"
#include "cescal/state.h"
#include "cescal/lexer.h"
/* Symbolic token */
#define symtok(tok) \
"[" tok "]"
/* Quoted token */
#define qtok(tok) \
"'" tok "'"
/* Convert token to string */
#define tokstr1(tt) \
toktab[(tt)]
/* Convert token to string */
#define tokstr(tok) \
toktab[(tok)->type]
/*
* Converts numeric tokens into human readable strings
*/
static const char *toktab[] = {
[TT_NONE] = symtok("none"),
[TT_IDENT] = symtok("ident"),
[TT_COMMENT] = symtok("comment"),
[TT_INTLIT] = symtok("number"),
[TT_LPAREN] = qtok("("),
[TT_RPAREN] = qtok(")"),
[TT_COMMA] = qtok(","),
[TT_COLON] = qtok(":"),
[TT_ARROW] = qtok("->"),
[TT_PLUS] = qtok("+"),
[TT_MINUS] = qtok("-"),
[TT_SLASH] = qtok("/"),
[TT_STAR] = qtok("*"),
[TT_EQUALS] = qtok("="),
[TT_DEFINE] = qtok("#define"),
[TT_IFNDEF] = qtok("#ifndef"),
[TT_IFDEF] = qtok("#ifdef"),
[TT_RETURN] = qtok("return"),
[TT_PUB] = qtok("pub"),
[TT_PROC] = qtok("proc"),
[TT_BEGIN] = qtok("begin"),
[TT_END] = qtok("end"),
[TT_U8] = qtok("u8"),
[TT_U16] = qtok("u16"),
[TT_U32] = qtok("u32"),
[TT_U64] = qtok("u64")
};
/*
* Push a token to the token buffer in the preprocessing stage
*
* @tokbuf: Token buffer to push to
* @tok: Token to push
*
* Returns zero on success
*/
static int
preprocessor_push(struct tokbuf *tokbuf, struct token *tok)
{
if (tokbuf == NULL || tok == NULL) {
return -1;
}
switch (tok->type) {
case TT_IFNDEF:
case TT_IFDEF:
case TT_DEFINE:
break;
default:
if (tokbuf_push(tokbuf, tok) < 0) {
return -1;
}
}
return 0;
}
static int
parser_nom(struct cescal_state *state, struct token *res)
{
struct token tok;
if (state == NULL || res == NULL) {
errno = EINVAL;
return -1;
}
switch (state->pass) {
case 0: /* Pre-processor */
if (lexer_nom(state, &tok) < 0) {
return -1;
}
printf("* %s\n", tokstr(&tok));
if (preprocessor_push(&state->tokbuf, &tok) < 0) {
return -1;
}
break;
case 1: /* Parse */
if (tokbuf_pop(&state->tokbuf, &tok) < 0) {
return -1;
}
break;
}
*res = tok;
return 0;
}
int
parser_parse(struct cescal_state *state)
{
struct token tok;
if (state == NULL) {
errno = EINVAL;
return -1;
}
while (parser_nom(state, &tok) == 0) {
cc_trace("got token %s\n", tokstr(&tok));
}
++state->pass;
return 0;
}
|