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
|
#include <ctype.h>
#include "syntax.h"
#include "utils.h"
typedef struct {
Word word_germ;
String lit_germ;
} LexingBuffer;
typedef struct {
TokenVec* token_pool;
TokenPtrVec* top_tokens;
} PseudoAst;
static void consolidate_buffer(LexingBuffer* buf, PseudoAst ps_ast) {
if (buf->lit_germ.count > 0) {
push_to_Word(&buf->word_germ, (Chunk){
.qmode = UN_Q,
.kind = CHUNK_LIT,
.as.lit_str = inner(&buf->lit_germ)
});
buf->lit_germ = make_String(256);
}
if (buf->word_germ.count > 0) {
Token* tok_ptr = push_to_TokenVec(ps_ast.token_pool, (Token){
.kind = TOK_WORD,
.as.word = buf->word_germ
});
push_to_TokenPtrVec(ps_ast.top_tokens, tok_ptr);
}
}
static Chunk collect_single_q_section(char* line, size_t* pos) {
(*pos)++;
String buf = make_String(256);
size_t i;
for (i = *pos; line[*pos] != '\'' && line[*pos] != '\0'; i++) {
push_to_String(&buf, line[*pos]);
}
if (line[i] == '\0') exit(44);
*pos = i;
return (Chunk){
.qmode = SINGLE_Q,
.kind = LITERAL,
.as.literal_str = inner(&buf)
};
}
DECLARE_MAYBE(SpecialToken, MaybeSpecialToken)
static MaybeSpecialToken recognize_spec_token(char* line, size_t* pos) {
// TODO: add more error guards for peekaheads
char next_ch;
switch (line[*pos]) {
case '|':
(*pos)++;
return (MaybeSpecialToken){.some = true, .value = SPEC_PIPE};
case '>':
next_ch = line[(*pos)+1];
switch (next_ch) {
case '(':
return (MaybeSpecialToken){.some = false};
case '>':
*pos += 2;
return (MaybeSpecialToken){.some = true, .value = SPEC_REDIR_W_APPEND};
default:
(*pos)++;
return (MaybeSpecialToken){.some = true, .value = SPEC_REDIR_W_TRUNC};
}
case '<':
next_ch = line[(*pos)+1];
if (line[(*pos)+1] == '(') {
return (MaybeSpecialToken){.some = false};
} else {
(*pos)++;
return (MaybeSpecialToken){.some = true, .value = SPEC_REDIR_R};
}
default:
return (MaybeSpecialToken){.some = false};
}
}
static void lex_level(char* line, size_t* pos, char until, PseudoAst ps_ast) {
LexingBuffer buf = {.word_germ = make_Word(256), .lit_germ = make_String(256)};
while (line[*pos] != until) {
if (line[*pos] == ' ') {
consolidate_buffer(&buf, ps_ast);
while (line[*pos] == ' ') (*pos)++;
continue;
}
MaybeSpecialToken m_spec = recognize_spec_token(line, pos);
}
}
Ast lex(char* input) {
size_t line_pos = 0;
}
|