feat: rename core types to scc prefix for consistency
Updated type names from `core_*` to `scc_*` across lex_parser and stream modules to maintain naming consistency within the SCC codebase. This includes changes to function signatures and internal usage of types like `core_probe_stream_t`, `core_pos_t`, and `cstring_t` to their `scc_*` counterparts.
This commit is contained in:
@@ -11,16 +11,16 @@ static inline cbool lex_parse_is_whitespace(int ch) {
|
||||
return ch == ' ' || ch == '\t';
|
||||
}
|
||||
|
||||
int lex_parse_char(core_probe_stream_t *input, core_pos_t *pos);
|
||||
cbool lex_parse_string(core_probe_stream_t *input, core_pos_t *pos,
|
||||
cstring_t *output);
|
||||
cbool lex_parse_number(core_probe_stream_t *input, core_pos_t *pos,
|
||||
int lex_parse_char(scc_probe_stream_t *input, scc_pos_t *pos);
|
||||
cbool lex_parse_string(scc_probe_stream_t *input, scc_pos_t *pos,
|
||||
scc_cstring_t *output);
|
||||
cbool lex_parse_number(scc_probe_stream_t *input, scc_pos_t *pos,
|
||||
usize *output);
|
||||
cbool lex_parse_identifier(core_probe_stream_t *input, core_pos_t *pos,
|
||||
cstring_t *output);
|
||||
void lex_parse_skip_endline(core_probe_stream_t *input, core_pos_t *pos);
|
||||
void lex_parse_skip_block_comment(core_probe_stream_t *input, core_pos_t *pos);
|
||||
void lex_parse_skip_line(core_probe_stream_t *input, core_pos_t *pos);
|
||||
void lex_parse_skip_whitespace(core_probe_stream_t *input, core_pos_t *pos);
|
||||
cbool lex_parse_identifier(scc_probe_stream_t *input, scc_pos_t *pos,
|
||||
scc_cstring_t *output);
|
||||
void lex_parse_skip_endline(scc_probe_stream_t *input, scc_pos_t *pos);
|
||||
void lex_parse_skip_block_comment(scc_probe_stream_t *input, scc_pos_t *pos);
|
||||
void lex_parse_skip_line(scc_probe_stream_t *input, scc_pos_t *pos);
|
||||
void lex_parse_skip_whitespace(scc_probe_stream_t *input, scc_pos_t *pos);
|
||||
|
||||
#endif /* __SMCC_LEX_PARSER_H__ */
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#include <lex_parser.h>
|
||||
|
||||
void lex_parse_skip_endline(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
void lex_parse_skip_endline(scc_probe_stream_t *input, scc_pos_t *pos) {
|
||||
Assert(input != null && pos != null);
|
||||
core_probe_stream_reset(input);
|
||||
int ch = core_probe_stream_peek(input);
|
||||
scc_probe_stream_reset(input);
|
||||
int ch = scc_probe_stream_peek(input);
|
||||
if (ch == '\r') {
|
||||
core_probe_stream_consume(input);
|
||||
ch = core_probe_stream_peek(input);
|
||||
scc_probe_stream_consume(input);
|
||||
ch = scc_probe_stream_peek(input);
|
||||
if (ch == '\n') {
|
||||
core_probe_stream_consume(input);
|
||||
scc_probe_stream_consume(input);
|
||||
}
|
||||
core_pos_next_line(pos);
|
||||
} else if (ch == '\n') {
|
||||
core_probe_stream_consume(input);
|
||||
scc_probe_stream_consume(input);
|
||||
core_pos_next_line(pos);
|
||||
} else {
|
||||
LOG_WARN("not a newline character");
|
||||
@@ -57,12 +57,12 @@ static inline int got_simple_escape(int ch) {
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
void lex_parse_skip_line(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
core_probe_stream_t *stream = input;
|
||||
void lex_parse_skip_line(scc_probe_stream_t *input, scc_pos_t *pos) {
|
||||
scc_probe_stream_t *stream = input;
|
||||
Assert(stream != null && pos != null);
|
||||
core_probe_stream_reset(stream);
|
||||
scc_probe_stream_reset(stream);
|
||||
while (1) {
|
||||
int ch = core_probe_stream_peek(stream);
|
||||
int ch = scc_probe_stream_peek(stream);
|
||||
|
||||
if (ch == core_stream_eof) {
|
||||
return;
|
||||
@@ -73,29 +73,29 @@ void lex_parse_skip_line(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
lex_parse_skip_endline(stream, pos);
|
||||
return;
|
||||
} else {
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lex_parse_skip_block_comment(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
core_probe_stream_t *stream = input;
|
||||
void lex_parse_skip_block_comment(scc_probe_stream_t *input, scc_pos_t *pos) {
|
||||
scc_probe_stream_t *stream = input;
|
||||
Assert(stream != null && pos != null);
|
||||
int ch;
|
||||
core_probe_stream_reset(stream);
|
||||
ch = core_probe_stream_consume(stream);
|
||||
scc_probe_stream_reset(stream);
|
||||
ch = scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
// FIXME Assertion
|
||||
Assert(ch == '/');
|
||||
ch = core_probe_stream_consume(stream);
|
||||
ch = scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
Assert(ch == '*');
|
||||
|
||||
// all ready match `/*`
|
||||
while (1) {
|
||||
core_probe_stream_reset(stream);
|
||||
ch = core_probe_stream_peek(stream);
|
||||
scc_probe_stream_reset(stream);
|
||||
ch = scc_probe_stream_peek(stream);
|
||||
|
||||
if (ch == core_stream_eof) {
|
||||
LOG_WARN("Unterminated block comment");
|
||||
@@ -106,12 +106,12 @@ void lex_parse_skip_block_comment(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
lex_parse_skip_endline(stream, pos);
|
||||
continue;
|
||||
}
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
if (ch == '*') {
|
||||
ch = core_probe_stream_peek(stream);
|
||||
ch = scc_probe_stream_peek(stream);
|
||||
if (ch == '/') {
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
return;
|
||||
}
|
||||
@@ -119,35 +119,35 @@ void lex_parse_skip_block_comment(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
}
|
||||
}
|
||||
|
||||
void lex_parse_skip_whitespace(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
core_probe_stream_t *stream = input;
|
||||
void lex_parse_skip_whitespace(scc_probe_stream_t *input, scc_pos_t *pos) {
|
||||
scc_probe_stream_t *stream = input;
|
||||
Assert(stream != null && pos != null);
|
||||
core_probe_stream_reset(stream);
|
||||
scc_probe_stream_reset(stream);
|
||||
while (1) {
|
||||
int ch = core_probe_stream_peek(stream);
|
||||
int ch = scc_probe_stream_peek(stream);
|
||||
|
||||
if (!lex_parse_is_whitespace(ch)) {
|
||||
return;
|
||||
}
|
||||
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
}
|
||||
}
|
||||
|
||||
static inline cbool _lex_parse_uint(core_probe_stream_t *input, core_pos_t *pos,
|
||||
static inline cbool _lex_parse_uint(scc_probe_stream_t *input, scc_pos_t *pos,
|
||||
int base, usize *output) {
|
||||
Assert(input != null && pos != null);
|
||||
if (input == null || pos == null) {
|
||||
return false;
|
||||
}
|
||||
Assert(base == 2 || base == 8 || base == 10 || base == 16);
|
||||
core_probe_stream_reset(input);
|
||||
scc_probe_stream_reset(input);
|
||||
int ch, tmp;
|
||||
usize n = 0;
|
||||
usize offset = pos->offset;
|
||||
while (1) {
|
||||
ch = core_probe_stream_peek(input);
|
||||
ch = scc_probe_stream_peek(input);
|
||||
|
||||
if (ch == core_stream_eof) {
|
||||
break;
|
||||
@@ -166,7 +166,7 @@ static inline cbool _lex_parse_uint(core_probe_stream_t *input, core_pos_t *pos,
|
||||
return false;
|
||||
}
|
||||
|
||||
core_probe_stream_consume(input);
|
||||
scc_probe_stream_consume(input);
|
||||
core_pos_next(pos);
|
||||
n = n * base + tmp;
|
||||
// TODO number overflow
|
||||
@@ -187,11 +187,11 @@ static inline cbool _lex_parse_uint(core_probe_stream_t *input, core_pos_t *pos,
|
||||
* @return int
|
||||
* https://cppreference.cn/w/c/language/character_constant
|
||||
*/
|
||||
int lex_parse_char(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
core_probe_stream_t *stream = input;
|
||||
int lex_parse_char(scc_probe_stream_t *input, scc_pos_t *pos) {
|
||||
scc_probe_stream_t *stream = input;
|
||||
Assert(stream != null && pos != null);
|
||||
core_probe_stream_reset(stream);
|
||||
int ch = core_probe_stream_peek(stream);
|
||||
scc_probe_stream_reset(stream);
|
||||
int ch = scc_probe_stream_peek(stream);
|
||||
int ret = core_stream_eof;
|
||||
|
||||
if (ch == core_stream_eof) {
|
||||
@@ -201,17 +201,17 @@ int lex_parse_char(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
LOG_WARN("Unexpected character '%c' at begin", ch);
|
||||
goto ERR;
|
||||
}
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
|
||||
ch = core_probe_stream_consume(stream);
|
||||
ch = scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
|
||||
if (ch == core_stream_eof) {
|
||||
LOG_WARN("Unexpected EOF at middle");
|
||||
goto ERR;
|
||||
} else if (ch == '\\') {
|
||||
ch = core_probe_stream_consume(stream);
|
||||
ch = scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
if (ch == '0') {
|
||||
// 数字转义序列
|
||||
@@ -237,7 +237,7 @@ int lex_parse_char(core_probe_stream_t *input, core_pos_t *pos) {
|
||||
} else {
|
||||
ret = ch;
|
||||
}
|
||||
if ((ch = core_probe_stream_consume(stream)) != '\'') {
|
||||
if ((ch = scc_probe_stream_consume(stream)) != '\'') {
|
||||
LOG_ERROR("Unclosed character literal '%c' at end, expect `'`", ch);
|
||||
core_pos_next(pos);
|
||||
goto ERR;
|
||||
@@ -257,14 +257,14 @@ ERR:
|
||||
* @return cbool
|
||||
* https://cppreference.cn/w/c/language/string_literal
|
||||
*/
|
||||
cbool lex_parse_string(core_probe_stream_t *input, core_pos_t *pos,
|
||||
cstring_t *output) {
|
||||
core_probe_stream_t *stream = input;
|
||||
cbool lex_parse_string(scc_probe_stream_t *input, scc_pos_t *pos,
|
||||
scc_cstring_t *output) {
|
||||
scc_probe_stream_t *stream = input;
|
||||
Assert(stream != null && pos != null && output != null);
|
||||
core_probe_stream_reset(stream);
|
||||
int ch = core_probe_stream_peek(stream);
|
||||
scc_probe_stream_reset(stream);
|
||||
int ch = scc_probe_stream_peek(stream);
|
||||
|
||||
Assert(cstring_is_empty(output));
|
||||
Assert(scc_cstring_is_empty(output));
|
||||
if (ch == core_stream_eof) {
|
||||
LOG_WARN("Unexpected EOF at begin");
|
||||
goto ERR;
|
||||
@@ -272,12 +272,12 @@ cbool lex_parse_string(core_probe_stream_t *input, core_pos_t *pos,
|
||||
LOG_WARN("Unexpected character '%c' at begin", ch);
|
||||
goto ERR;
|
||||
}
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
|
||||
cstring_t str = cstring_from_cstr("");
|
||||
scc_cstring_t str = scc_cstring_from_cstr("");
|
||||
while (1) {
|
||||
ch = core_probe_stream_peek(stream);
|
||||
ch = scc_probe_stream_peek(stream);
|
||||
|
||||
if (ch == core_stream_eof) {
|
||||
LOG_ERROR("Unexpected EOF at string literal");
|
||||
@@ -287,30 +287,30 @@ cbool lex_parse_string(core_probe_stream_t *input, core_pos_t *pos,
|
||||
goto ERR;
|
||||
} else if (ch == '\\') {
|
||||
// TODO bad practice and maybe bugs here
|
||||
core_probe_stream_consume(stream);
|
||||
ch = core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
ch = scc_probe_stream_consume(stream);
|
||||
int val = got_simple_escape(ch);
|
||||
if (val == -1) {
|
||||
LOG_ERROR("Invalid escape character it is \\%c [%d]", ch, ch);
|
||||
} else {
|
||||
cstring_append_ch(&str, val);
|
||||
scc_cstring_append_ch(&str, val);
|
||||
continue;
|
||||
}
|
||||
} else if (ch == '"') {
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
break;
|
||||
}
|
||||
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
cstring_append_ch(&str, ch);
|
||||
scc_cstring_append_ch(&str, ch);
|
||||
}
|
||||
|
||||
*output = str;
|
||||
return true;
|
||||
ERR:
|
||||
cstring_free(&str);
|
||||
scc_cstring_free(&str);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -323,12 +323,12 @@ ERR:
|
||||
* @return cbool
|
||||
* https://cppreference.cn/w/c/language/integer_constant
|
||||
*/
|
||||
cbool lex_parse_number(core_probe_stream_t *input, core_pos_t *pos,
|
||||
cbool lex_parse_number(scc_probe_stream_t *input, scc_pos_t *pos,
|
||||
usize *output) {
|
||||
core_probe_stream_t *stream = input;
|
||||
scc_probe_stream_t *stream = input;
|
||||
Assert(stream != null && pos != null && output != null);
|
||||
core_probe_stream_reset(stream);
|
||||
int ch = core_probe_stream_peek(stream);
|
||||
scc_probe_stream_reset(stream);
|
||||
int ch = scc_probe_stream_peek(stream);
|
||||
int base = 10; // 默认十进制
|
||||
|
||||
if (ch == core_stream_eof) {
|
||||
@@ -338,20 +338,20 @@ cbool lex_parse_number(core_probe_stream_t *input, core_pos_t *pos,
|
||||
|
||||
if (ch == '0') {
|
||||
// 消费 '0'
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
|
||||
// 查看下一个字符
|
||||
ch = core_probe_stream_peek(stream);
|
||||
ch = scc_probe_stream_peek(stream);
|
||||
if (ch == 'x' || ch == 'X') {
|
||||
// 十六进制
|
||||
base = 16;
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
} else if (ch == 'b' || ch == 'B') {
|
||||
// 二进制 (C23扩展)
|
||||
base = 2;
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
} else if (ch >= '0' && ch <= '7') {
|
||||
// 八进制
|
||||
@@ -374,7 +374,7 @@ cbool lex_parse_number(core_probe_stream_t *input, core_pos_t *pos,
|
||||
}
|
||||
|
||||
// 解析整数部分
|
||||
core_probe_stream_reset(stream);
|
||||
scc_probe_stream_reset(stream);
|
||||
usize n;
|
||||
if (_lex_parse_uint(stream, pos, base, &n) == false) {
|
||||
// 如果没有匹配任何数字,但输入是 '0',已经处理过了
|
||||
@@ -383,7 +383,7 @@ cbool lex_parse_number(core_probe_stream_t *input, core_pos_t *pos,
|
||||
// 单个数字的情况,例如 "1"
|
||||
// 我们需要消费这个数字并返回它的值
|
||||
if (ch >= '1' && ch <= '9') {
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
*output = ch - '0';
|
||||
return true;
|
||||
@@ -406,23 +406,23 @@ ERR:
|
||||
* @return cbool
|
||||
* https://cppreference.cn/w/c/language/identifier
|
||||
*/
|
||||
cbool lex_parse_identifier(core_probe_stream_t *input, core_pos_t *pos,
|
||||
cstring_t *output) {
|
||||
cbool lex_parse_identifier(scc_probe_stream_t *input, scc_pos_t *pos,
|
||||
scc_cstring_t *output) {
|
||||
Assert(input != null && pos != null && output != null);
|
||||
Assert(cstring_is_empty(output));
|
||||
core_probe_stream_t *stream = input;
|
||||
core_probe_stream_reset(stream);
|
||||
int ch = core_probe_stream_peek(stream);
|
||||
Assert(scc_cstring_is_empty(output));
|
||||
scc_probe_stream_t *stream = input;
|
||||
scc_probe_stream_reset(stream);
|
||||
int ch = scc_probe_stream_peek(stream);
|
||||
|
||||
if (ch == core_stream_eof) {
|
||||
LOG_WARN("Unexpected EOF at begin");
|
||||
} else if (ch == '_' || (ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z')) {
|
||||
while (1) {
|
||||
cstring_append_ch(output, ch);
|
||||
core_probe_stream_consume(stream);
|
||||
scc_cstring_append_ch(output, ch);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(pos);
|
||||
ch = core_probe_stream_peek(stream);
|
||||
ch = scc_probe_stream_peek(stream);
|
||||
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
|
||||
(ch == '_') || (ch >= '0' && ch <= '9')) {
|
||||
continue;
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
cbool check_char(const char *str, int expect, int *output) {
|
||||
log_set_level(&__default_logger_root, 0);
|
||||
core_pos_t pos = core_pos_init();
|
||||
core_mem_probe_stream_t mem_stream;
|
||||
core_probe_stream_t *stream =
|
||||
core_mem_probe_stream_init(&mem_stream, str, smcc_strlen(str), false);
|
||||
scc_pos_t pos = scc_pos_init();
|
||||
scc_mem_probe_stream_t mem_stream;
|
||||
scc_probe_stream_t *stream =
|
||||
scc_mem_probe_stream_init(&mem_stream, str, scc_strlen(str), false);
|
||||
*output = lex_parse_char(stream, &pos);
|
||||
return *output == expect;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
#include <lex_parser.h>
|
||||
#include <utest/acutest.h>
|
||||
|
||||
cbool check_identifier(const char *str, const char *expect, cstring_t *output) {
|
||||
cbool check_identifier(const char *str, const char *expect,
|
||||
scc_cstring_t *output) {
|
||||
log_set_level(&__default_logger_root, 0);
|
||||
core_pos_t pos = core_pos_init();
|
||||
core_mem_probe_stream_t mem_stream;
|
||||
core_probe_stream_t *stream =
|
||||
core_mem_probe_stream_init(&mem_stream, str, smcc_strlen(str), false);
|
||||
scc_pos_t pos = scc_pos_init();
|
||||
scc_mem_probe_stream_t mem_stream;
|
||||
scc_probe_stream_t *stream =
|
||||
scc_mem_probe_stream_init(&mem_stream, str, scc_strlen(str), false);
|
||||
|
||||
cbool ret = lex_parse_identifier(stream, &pos, output);
|
||||
if (ret && expect) {
|
||||
@@ -18,19 +19,19 @@ cbool check_identifier(const char *str, const char *expect, cstring_t *output) {
|
||||
|
||||
#define CHECK_IDENTIFIER_VALID(str, expect) \
|
||||
do { \
|
||||
cstring_t _output = cstring_new(); \
|
||||
scc_cstring_t _output = scc_cstring_new(); \
|
||||
cbool ret = check_identifier(str, expect, &_output); \
|
||||
TEST_CHECK(ret == true); \
|
||||
TEST_CHECK(strcmp(_output.data, expect) == 0); \
|
||||
cstring_free(&_output); \
|
||||
scc_cstring_free(&_output); \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_IDENTIFIER_INVALID(str) \
|
||||
do { \
|
||||
cstring_t _output = cstring_new(); \
|
||||
scc_cstring_t _output = scc_cstring_new(); \
|
||||
cbool ret = check_identifier(str, NULL, &_output); \
|
||||
TEST_CHECK(ret == false); \
|
||||
cstring_free(&_output); \
|
||||
scc_cstring_free(&_output); \
|
||||
} while (0)
|
||||
|
||||
void test_valid_identifier(void) {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#include <lex_parser.h>
|
||||
#include <utest/acutest.h>
|
||||
|
||||
cbool check(const char *str, usize expect, usize *output) {
|
||||
// TODO maybe have other logger
|
||||
(void)(expect);
|
||||
log_set_level(&__default_logger_root, 0);
|
||||
core_pos_t pos = core_pos_init();
|
||||
core_mem_probe_stream_t mem_stream;
|
||||
core_probe_stream_t *stream =
|
||||
core_mem_probe_stream_init(&mem_stream, str, smcc_strlen(str), false);
|
||||
scc_pos_t pos = scc_pos_init();
|
||||
scc_mem_probe_stream_t mem_stream;
|
||||
scc_probe_stream_t *stream =
|
||||
scc_mem_probe_stream_init(&mem_stream, str, scc_strlen(str), false);
|
||||
return lex_parse_number(stream, &pos, output);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
void check_skip_block_comment(const char *str, const char *expect_remaining) {
|
||||
log_set_level(&__default_logger_root, 0);
|
||||
core_pos_t pos = core_pos_init();
|
||||
core_mem_probe_stream_t mem_stream;
|
||||
core_probe_stream_t *stream =
|
||||
core_mem_probe_stream_init(&mem_stream, str, smcc_strlen(str), false);
|
||||
scc_pos_t pos = scc_pos_init();
|
||||
scc_mem_probe_stream_t mem_stream;
|
||||
scc_probe_stream_t *stream =
|
||||
scc_mem_probe_stream_init(&mem_stream, str, scc_strlen(str), false);
|
||||
|
||||
lex_parse_skip_block_comment(stream, &pos);
|
||||
|
||||
@@ -15,7 +15,7 @@ void check_skip_block_comment(const char *str, const char *expect_remaining) {
|
||||
char buffer[256] = {0};
|
||||
int i = 0;
|
||||
int ch;
|
||||
while ((ch = core_probe_stream_consume(stream)) != core_stream_eof &&
|
||||
while ((ch = scc_probe_stream_consume(stream)) != core_stream_eof &&
|
||||
i < 255) {
|
||||
buffer[i++] = (char)ch;
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
void check_skip_line(const char *str, const char *expect_remaining) {
|
||||
log_set_level(&__default_logger_root, 0);
|
||||
core_pos_t pos = core_pos_init();
|
||||
core_mem_probe_stream_t mem_stream;
|
||||
core_probe_stream_t *stream =
|
||||
core_mem_probe_stream_init(&mem_stream, str, smcc_strlen(str), false);
|
||||
scc_pos_t pos = scc_pos_init();
|
||||
scc_mem_probe_stream_t mem_stream;
|
||||
scc_probe_stream_t *stream =
|
||||
scc_mem_probe_stream_init(&mem_stream, str, scc_strlen(str), false);
|
||||
|
||||
lex_parse_skip_line(stream, &pos);
|
||||
|
||||
@@ -15,7 +15,7 @@ void check_skip_line(const char *str, const char *expect_remaining) {
|
||||
char buffer[256] = {0};
|
||||
int i = 0;
|
||||
int ch;
|
||||
while ((ch = core_probe_stream_consume(stream)) != core_stream_eof &&
|
||||
while ((ch = scc_probe_stream_consume(stream)) != core_stream_eof &&
|
||||
i < 255) {
|
||||
buffer[i++] = (char)ch;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
#include <lex_parser.h>
|
||||
#include <utest/acutest.h>
|
||||
|
||||
cbool check_string(const char *str, const char *expect, cstring_t *output) {
|
||||
cbool check_string(const char *str, const char *expect, scc_cstring_t *output) {
|
||||
log_set_level(&__default_logger_root, 0);
|
||||
core_pos_t pos = core_pos_init();
|
||||
core_mem_probe_stream_t mem_stream;
|
||||
core_probe_stream_t *stream =
|
||||
core_mem_probe_stream_init(&mem_stream, str, smcc_strlen(str), false);
|
||||
scc_pos_t pos = scc_pos_init();
|
||||
scc_mem_probe_stream_t mem_stream;
|
||||
scc_probe_stream_t *stream =
|
||||
scc_mem_probe_stream_init(&mem_stream, str, scc_strlen(str), false);
|
||||
|
||||
cbool ret = lex_parse_string(stream, &pos, output);
|
||||
if (ret && expect) {
|
||||
@@ -18,19 +18,19 @@ cbool check_string(const char *str, const char *expect, cstring_t *output) {
|
||||
|
||||
#define CHECK_STRING_VALID(str, expect) \
|
||||
do { \
|
||||
cstring_t _output = cstring_new(); \
|
||||
scc_cstring_t _output = scc_cstring_new(); \
|
||||
cbool ret = check_string(str, expect, &_output); \
|
||||
TEST_CHECK(ret == true); \
|
||||
TEST_CHECK(strcmp(_output.data, expect) == 0); \
|
||||
cstring_free(&_output); \
|
||||
scc_cstring_free(&_output); \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_STRING_INVALID(str) \
|
||||
do { \
|
||||
cstring_t _output = cstring_new(); \
|
||||
scc_cstring_t _output = scc_cstring_new(); \
|
||||
cbool ret = check_string(str, NULL, &_output); \
|
||||
TEST_CHECK(ret == false); \
|
||||
cstring_free(&_output); \
|
||||
scc_cstring_free(&_output); \
|
||||
} while (0)
|
||||
|
||||
void test_simple_string(void) {
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* @brief C语言词法分析器核心数据结构与接口
|
||||
*/
|
||||
|
||||
#ifndef __SMCC_CC_LEXER_H__
|
||||
#define __SMCC_CC_LEXER_H__
|
||||
#ifndef __SCC_LEXER_H__
|
||||
#define __SCC_LEXER_H__
|
||||
|
||||
#include "lexer_token.h"
|
||||
#include <libcore.h>
|
||||
|
||||
typedef struct lexer_token {
|
||||
token_type_t type;
|
||||
core_cvalue_t value;
|
||||
core_pos_t loc;
|
||||
scc_tok_type_t type;
|
||||
scc_cvalue_t value;
|
||||
scc_pos_t loc;
|
||||
} lexer_tok_t;
|
||||
|
||||
/**
|
||||
@@ -21,16 +21,16 @@ typedef struct lexer_token {
|
||||
* 封装词法分析所需的状态信息和缓冲区管理
|
||||
*/
|
||||
typedef struct cc_lexer {
|
||||
core_probe_stream_t *stream;
|
||||
core_pos_t pos;
|
||||
} smcc_lexer_t;
|
||||
scc_probe_stream_t *stream;
|
||||
scc_pos_t pos;
|
||||
} scc_lexer_t;
|
||||
|
||||
/**
|
||||
* @brief 初始化词法分析器
|
||||
* @param[out] lexer 要初始化的词法分析器实例
|
||||
* @param[in] stream 输入流对象指针
|
||||
*/
|
||||
void lexer_init(smcc_lexer_t *lexer, core_probe_stream_t *stream);
|
||||
void scc_lexer_init(scc_lexer_t *lexer, scc_probe_stream_t *stream);
|
||||
|
||||
/**
|
||||
* @brief 获取原始token
|
||||
@@ -39,7 +39,7 @@ void lexer_init(smcc_lexer_t *lexer, core_probe_stream_t *stream);
|
||||
*
|
||||
* 此函数会返回所有类型的token,包括空白符等无效token
|
||||
*/
|
||||
void lexer_get_token(smcc_lexer_t *lexer, lexer_tok_t *token);
|
||||
void scc_lexer_get_token(scc_lexer_t *lexer, lexer_tok_t *token);
|
||||
|
||||
/**
|
||||
* @brief 获取有效token
|
||||
@@ -48,6 +48,6 @@ void lexer_get_token(smcc_lexer_t *lexer, lexer_tok_t *token);
|
||||
*
|
||||
* 此函数会自动跳过空白符等无效token,返回对语法分析有意义的token
|
||||
*/
|
||||
void lexer_get_valid_token(smcc_lexer_t *lexer, lexer_tok_t *token);
|
||||
void scc_lexer_get_valid_token(scc_lexer_t *lexer, lexer_tok_t *token);
|
||||
|
||||
#endif
|
||||
#endif /* __SCC_LEXER_H__ */
|
||||
|
||||
@@ -3,138 +3,138 @@
|
||||
|
||||
#include <libcore.h>
|
||||
|
||||
typedef enum ckeyword {
|
||||
CSTD_C89,
|
||||
CSTD_C99,
|
||||
CEXT_ASM,
|
||||
} ckeyword_t;
|
||||
typedef enum scc_cstd {
|
||||
SCC_CSTD_C89,
|
||||
SCC_CSTD_C99,
|
||||
SCC_CEXT_ASM,
|
||||
} scc_cstd_t;
|
||||
|
||||
/* clang-format off */
|
||||
// WARNING: Using Binary Search To Fast Find Keyword
|
||||
// 你必须确保其中是按照字典序排列
|
||||
#define KEYWORD_TABLE \
|
||||
X(asm , TK_BASIC_KEYWORD , TOKEN_ASM , CEXT_ASM) \
|
||||
X(break , TK_BASIC_KEYWORD , TOKEN_BREAK , CSTD_C89) \
|
||||
X(case , TK_BASIC_KEYWORD , TOKEN_CASE , CSTD_C89) \
|
||||
X(char , TK_BASIC_KEYWORD , TOKEN_CHAR , CSTD_C89) \
|
||||
X(const , TK_BASIC_KEYWORD , TOKEN_CONST , CSTD_C89) \
|
||||
X(continue , TK_BASIC_KEYWORD , TOKEN_CONTINUE , CSTD_C89) \
|
||||
X(default , TK_BASIC_KEYWORD , TOKEN_DEFAULT , CSTD_C89) \
|
||||
X(do , TK_BASIC_KEYWORD , TOKEN_DO , CSTD_C89) \
|
||||
X(double , TK_BASIC_KEYWORD , TOKEN_DOUBLE , CSTD_C89) \
|
||||
X(else , TK_BASIC_KEYWORD , TOKEN_ELSE , CSTD_C89) \
|
||||
X(enum , TK_BASIC_KEYWORD , TOKEN_ENUM , CSTD_C89) \
|
||||
X(extern , TK_BASIC_KEYWORD , TOKEN_EXTERN , CSTD_C89) \
|
||||
X(float , TK_BASIC_KEYWORD , TOKEN_FLOAT , CSTD_C89) \
|
||||
X(for , TK_BASIC_KEYWORD , TOKEN_FOR , CSTD_C89) \
|
||||
X(goto , TK_BASIC_KEYWORD , TOKEN_GOTO , CSTD_C89) \
|
||||
X(if , TK_BASIC_KEYWORD , TOKEN_IF , CSTD_C89) \
|
||||
X(inline , TK_BASIC_KEYWORD , TOKEN_INLINE , CSTD_C99) \
|
||||
X(int , TK_BASIC_KEYWORD , TOKEN_INT , CSTD_C89) \
|
||||
X(long , TK_BASIC_KEYWORD , TOKEN_LONG , CSTD_C89) \
|
||||
X(register , TK_BASIC_KEYWORD , TOKEN_REGISTER , CSTD_C89) \
|
||||
X(restrict , TK_BASIC_KEYWORD , TOKEN_RESTRICT , CSTD_C99) \
|
||||
X(return , TK_BASIC_KEYWORD , TOKEN_RETURN , CSTD_C89) \
|
||||
X(short , TK_BASIC_KEYWORD , TOKEN_SHORT , CSTD_C89) \
|
||||
X(signed , TK_BASIC_KEYWORD , TOKEN_SIGNED , CSTD_C89) \
|
||||
X(sizeof , TK_BASIC_KEYWORD , TOKEN_SIZEOF , CSTD_C89) \
|
||||
X(static , TK_BASIC_KEYWORD , TOKEN_STATIC , CSTD_C89) \
|
||||
X(struct , TK_BASIC_KEYWORD , TOKEN_STRUCT , CSTD_C89) \
|
||||
X(switch , TK_BASIC_KEYWORD , TOKEN_SWITCH , CSTD_C89) \
|
||||
X(typedef , TK_BASIC_KEYWORD , TOKEN_TYPEDEF , CSTD_C89) \
|
||||
X(union , TK_BASIC_KEYWORD , TOKEN_UNION , CSTD_C89) \
|
||||
X(unsigned , TK_BASIC_KEYWORD , TOKEN_UNSIGNED , CSTD_C89) \
|
||||
X(void , TK_BASIC_KEYWORD , TOKEN_VOID , CSTD_C89) \
|
||||
X(volatile , TK_BASIC_KEYWORD , TOKEN_VOLATILE , CSTD_C89) \
|
||||
X(while , TK_BASIC_KEYWORD , TOKEN_WHILE , CSTD_C89) \
|
||||
#define SCC_CKEYWORD_TABLE \
|
||||
X(asm , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_ASM , SCC_CEXT_ASM) \
|
||||
X(break , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_BREAK , SCC_CSTD_C89) \
|
||||
X(case , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_CASE , SCC_CSTD_C89) \
|
||||
X(char , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_CHAR , SCC_CSTD_C89) \
|
||||
X(const , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_CONST , SCC_CSTD_C89) \
|
||||
X(continue , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_CONTINUE , SCC_CSTD_C89) \
|
||||
X(default , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_DEFAULT , SCC_CSTD_C89) \
|
||||
X(do , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_DO , SCC_CSTD_C89) \
|
||||
X(double , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_DOUBLE , SCC_CSTD_C89) \
|
||||
X(else , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_ELSE , SCC_CSTD_C89) \
|
||||
X(enum , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_ENUM , SCC_CSTD_C89) \
|
||||
X(extern , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_EXTERN , SCC_CSTD_C89) \
|
||||
X(float , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_FLOAT , SCC_CSTD_C89) \
|
||||
X(for , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_FOR , SCC_CSTD_C89) \
|
||||
X(goto , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_GOTO , SCC_CSTD_C89) \
|
||||
X(if , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_IF , SCC_CSTD_C89) \
|
||||
X(inline , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_INLINE , SCC_CSTD_C99) \
|
||||
X(int , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_INT , SCC_CSTD_C89) \
|
||||
X(long , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_LONG , SCC_CSTD_C89) \
|
||||
X(register , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_REGISTER , SCC_CSTD_C89) \
|
||||
X(restrict , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_RESTRICT , SCC_CSTD_C99) \
|
||||
X(return , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_RETURN , SCC_CSTD_C89) \
|
||||
X(short , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_SHORT , SCC_CSTD_C89) \
|
||||
X(signed , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_SIGNED , SCC_CSTD_C89) \
|
||||
X(sizeof , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_SIZEOF , SCC_CSTD_C89) \
|
||||
X(static , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_STATIC , SCC_CSTD_C89) \
|
||||
X(struct , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_STRUCT , SCC_CSTD_C89) \
|
||||
X(switch , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_SWITCH , SCC_CSTD_C89) \
|
||||
X(typedef , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_TYPEDEF , SCC_CSTD_C89) \
|
||||
X(union , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_UNION , SCC_CSTD_C89) \
|
||||
X(unsigned , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_UNSIGNED , SCC_CSTD_C89) \
|
||||
X(void , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_VOID , SCC_CSTD_C89) \
|
||||
X(volatile , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_VOLATILE , SCC_CSTD_C89) \
|
||||
X(while , SCC_TOK_SUBTYPE_KEYWORD , SCC_TOK_WHILE , SCC_CSTD_C89) \
|
||||
// KEYWORD_TABLE
|
||||
|
||||
#define TOKEN_TABLE \
|
||||
X(unknown , TK_BASIC_INVALID, TOKEN_UNKNOWN ) \
|
||||
X(EOF , TK_BASIC_EOF, TOKEN_EOF ) \
|
||||
X(blank , TK_BASIC_EMPTYSPACE, TOKEN_BLANK ) \
|
||||
X("==" , TK_BASIC_OPERATOR, TOKEN_EQ ) \
|
||||
X("=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN ) \
|
||||
X("++" , TK_BASIC_OPERATOR, TOKEN_ADD_ADD ) \
|
||||
X("+=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_ADD ) \
|
||||
X("+" , TK_BASIC_OPERATOR, TOKEN_ADD ) \
|
||||
X("--" , TK_BASIC_OPERATOR, TOKEN_SUB_SUB ) \
|
||||
X("-=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_SUB ) \
|
||||
X("->" , TK_BASIC_OPERATOR, TOKEN_DEREF ) \
|
||||
X("-" , TK_BASIC_OPERATOR, TOKEN_SUB ) \
|
||||
X("*=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_MUL ) \
|
||||
X("*" , TK_BASIC_OPERATOR, TOKEN_MUL ) \
|
||||
X("/=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_DIV ) \
|
||||
X("/" , TK_BASIC_OPERATOR, TOKEN_DIV ) \
|
||||
X("//" , TK_BASIC_COMMENT , TOKEN_LINE_COMMENT ) \
|
||||
X("/* */" , TK_BASIC_COMMENT , TOKEN_BLOCK_COMMENT ) \
|
||||
X("%=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_MOD ) \
|
||||
X("%" , TK_BASIC_OPERATOR, TOKEN_MOD ) \
|
||||
X("&&" , TK_BASIC_OPERATOR, TOKEN_AND_AND ) \
|
||||
X("&=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_AND ) \
|
||||
X("&" , TK_BASIC_OPERATOR, TOKEN_AND ) \
|
||||
X("||" , TK_BASIC_OPERATOR, TOKEN_OR_OR ) \
|
||||
X("|=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_OR ) \
|
||||
X("|" , TK_BASIC_OPERATOR, TOKEN_OR ) \
|
||||
X("^=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_XOR ) \
|
||||
X("^" , TK_BASIC_OPERATOR, TOKEN_XOR ) \
|
||||
X("<<=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_L_SH ) \
|
||||
X("<<" , TK_BASIC_OPERATOR, TOKEN_L_SH ) \
|
||||
X("<=" , TK_BASIC_OPERATOR, TOKEN_LE ) \
|
||||
X("<" , TK_BASIC_OPERATOR, TOKEN_LT ) \
|
||||
X(">>=" , TK_BASIC_OPERATOR, TOKEN_ASSIGN_R_SH ) \
|
||||
X(">>" , TK_BASIC_OPERATOR, TOKEN_R_SH ) \
|
||||
X(">=" , TK_BASIC_OPERATOR, TOKEN_GE ) \
|
||||
X(">" , TK_BASIC_OPERATOR, TOKEN_GT ) \
|
||||
X("!" , TK_BASIC_OPERATOR, TOKEN_NOT ) \
|
||||
X("!=" , TK_BASIC_OPERATOR, TOKEN_NEQ ) \
|
||||
X("~" , TK_BASIC_OPERATOR, TOKEN_BIT_NOT ) \
|
||||
X("[" , TK_BASIC_OPERATOR, TOKEN_L_BRACKET ) \
|
||||
X("]" , TK_BASIC_OPERATOR, TOKEN_R_BRACKET ) \
|
||||
X("(" , TK_BASIC_OPERATOR, TOKEN_L_PAREN ) \
|
||||
X(")" , TK_BASIC_OPERATOR, TOKEN_R_PAREN ) \
|
||||
X("{" , TK_BASIC_OPERATOR, TOKEN_L_BRACE ) \
|
||||
X("}" , TK_BASIC_OPERATOR, TOKEN_R_BRACE ) \
|
||||
X(";" , TK_BASIC_OPERATOR, TOKEN_SEMICOLON ) \
|
||||
X("," , TK_BASIC_OPERATOR, TOKEN_COMMA ) \
|
||||
X(":" , TK_BASIC_OPERATOR, TOKEN_COLON ) \
|
||||
X("." , TK_BASIC_OPERATOR, TOKEN_DOT ) \
|
||||
X("..." , TK_BASIC_OPERATOR, TOKEN_ELLIPSIS ) \
|
||||
X("?" , TK_BASIC_OPERATOR, TOKEN_COND ) \
|
||||
X(ident , TK_BASIC_IDENTIFIER, TOKEN_IDENT ) \
|
||||
X(int_literal , TK_BASIC_LITERAL, TOKEN_INT_LITERAL ) \
|
||||
X(float_literal , TK_BASIC_LITERAL, TOKEN_FLOAT_LITERAL ) \
|
||||
X(char_literal , TK_BASIC_LITERAL, TOKEN_CHAR_LITERAL ) \
|
||||
X(string_literal , TK_BASIC_LITERAL, TOKEN_STRING_LITERAL ) \
|
||||
#define SCC_CTOK_TABLE \
|
||||
X(unknown , SCC_TOK_SUBTYPE_INVALID, SCC_TOK_UNKNOWN ) \
|
||||
X(EOF , SCC_TOK_SUBTYPE_EOF, SCC_TOK_EOF ) \
|
||||
X(blank , SCC_TOK_SUBTYPE_EMPTYSPACE, SCC_TOK_BLANK ) \
|
||||
X("==" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_EQ ) \
|
||||
X("=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN ) \
|
||||
X("++" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ADD_ADD ) \
|
||||
X("+=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_ADD ) \
|
||||
X("+" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ADD ) \
|
||||
X("--" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_SUB_SUB ) \
|
||||
X("-=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_SUB ) \
|
||||
X("->" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_DEREF ) \
|
||||
X("-" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_SUB ) \
|
||||
X("*=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_MUL ) \
|
||||
X("*" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_MUL ) \
|
||||
X("/=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_DIV ) \
|
||||
X("/" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_DIV ) \
|
||||
X("//" , SCC_TOK_SUBTYPE_COMMENT , SCC_TOK_LINE_COMMENT ) \
|
||||
X("/* */" , SCC_TOK_SUBTYPE_COMMENT , SCC_TOK_BLOCK_COMMENT ) \
|
||||
X("%=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_MOD ) \
|
||||
X("%" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_MOD ) \
|
||||
X("&&" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_AND_AND ) \
|
||||
X("&=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_AND ) \
|
||||
X("&" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_AND ) \
|
||||
X("||" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_OR_OR ) \
|
||||
X("|=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_OR ) \
|
||||
X("|" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_OR ) \
|
||||
X("^=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_XOR ) \
|
||||
X("^" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_XOR ) \
|
||||
X("<<=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_L_SH ) \
|
||||
X("<<" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_L_SH ) \
|
||||
X("<=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_LE ) \
|
||||
X("<" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_LT ) \
|
||||
X(">>=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN_R_SH ) \
|
||||
X(">>" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_R_SH ) \
|
||||
X(">=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_GE ) \
|
||||
X(">" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_GT ) \
|
||||
X("!" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_NOT ) \
|
||||
X("!=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_NEQ ) \
|
||||
X("~" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_BIT_NOT ) \
|
||||
X("[" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_L_BRACKET ) \
|
||||
X("]" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_R_BRACKET ) \
|
||||
X("(" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_L_PAREN ) \
|
||||
X(")" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_R_PAREN ) \
|
||||
X("{" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_L_BRACE ) \
|
||||
X("}" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_R_BRACE ) \
|
||||
X(";" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_SEMICOLON ) \
|
||||
X("," , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_COMMA ) \
|
||||
X(":" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_COLON ) \
|
||||
X("." , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_DOT ) \
|
||||
X("..." , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ELLIPSIS ) \
|
||||
X("?" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_COND ) \
|
||||
X(ident , SCC_TOK_SUBTYPE_IDENTIFIER, SCC_TOK_IDENT ) \
|
||||
X(int_literal , SCC_TOK_SUBTYPE_LITERAL, SCC_TOK_INT_LITERAL ) \
|
||||
X(float_literal , SCC_TOK_SUBTYPE_LITERAL, SCC_TOK_FLOAT_LITERAL ) \
|
||||
X(char_literal , SCC_TOK_SUBTYPE_LITERAL, SCC_TOK_CHAR_LITERAL ) \
|
||||
X(string_literal , SCC_TOK_SUBTYPE_LITERAL, SCC_TOK_STRING_LITERAL ) \
|
||||
// END
|
||||
/* clang-format on */
|
||||
|
||||
// 定义TokenType枚举
|
||||
typedef enum cc_tktype {
|
||||
typedef enum scc_tok_type {
|
||||
// 处理普通token
|
||||
#define X(str, subtype, tok) tok,
|
||||
TOKEN_TABLE
|
||||
SCC_CTOK_TABLE
|
||||
#undef X
|
||||
|
||||
// 处理关键字(保持原有格式)
|
||||
#define X(name, subtype, tok, std) tok,
|
||||
KEYWORD_TABLE
|
||||
SCC_CKEYWORD_TABLE
|
||||
#undef X
|
||||
} token_type_t;
|
||||
} scc_tok_type_t;
|
||||
|
||||
typedef enum token_subtype {
|
||||
TK_BASIC_INVALID, // 错误占位
|
||||
TK_BASIC_KEYWORD, // 关键字
|
||||
TK_BASIC_OPERATOR, // 操作符
|
||||
TK_BASIC_IDENTIFIER, // 标识符
|
||||
TK_BASIC_LITERAL, // 字面量
|
||||
typedef enum scc_tok_subtype {
|
||||
SCC_TOK_SUBTYPE_INVALID, // 错误占位
|
||||
SCC_TOK_SUBTYPE_KEYWORD, // 关键字
|
||||
SCC_TOK_SUBTYPE_OPERATOR, // 操作符
|
||||
SCC_TOK_SUBTYPE_IDENTIFIER, // 标识符
|
||||
SCC_TOK_SUBTYPE_LITERAL, // 字面量
|
||||
|
||||
TK_BASIC_EMPTYSPACE, // 空白
|
||||
TK_BASIC_COMMENT, // 注释
|
||||
TK_BASIC_EOF // 结束标记
|
||||
} token_subtype_t;
|
||||
SCC_TOK_SUBTYPE_EMPTYSPACE, // 空白
|
||||
SCC_TOK_SUBTYPE_COMMENT, // 注释
|
||||
SCC_TOK_SUBTYPE_EOF // 结束标记
|
||||
} scc_tok_subtype_t;
|
||||
|
||||
token_subtype_t get_tok_subtype(token_type_t type);
|
||||
const char *get_tok_name(token_type_t type);
|
||||
scc_tok_subtype_t scc_get_tok_subtype(scc_tok_type_t type);
|
||||
const char *scc_get_tok_name(scc_tok_type_t type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,11 +32,11 @@ David Hanson / drh@drhanson.net
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
ckeyword_t std_type;
|
||||
token_type_t tok;
|
||||
scc_cstd_t std_type;
|
||||
scc_tok_type_t tok;
|
||||
} keywords[] = {
|
||||
#define X(name, subtype, tok, std_type, ...) {#name, std_type, tok},
|
||||
KEYWORD_TABLE
|
||||
SCC_CKEYWORD_TABLE
|
||||
#undef X
|
||||
};
|
||||
|
||||
@@ -75,23 +75,23 @@ static inline int keyword_cmp(const char *name, int len) {
|
||||
return -1; // Not a keyword.
|
||||
}
|
||||
|
||||
void lexer_init(smcc_lexer_t *lexer, core_probe_stream_t *stream) {
|
||||
void scc_lexer_init(scc_lexer_t *lexer, scc_probe_stream_t *stream) {
|
||||
lexer->stream = stream;
|
||||
lexer->pos = core_pos_init();
|
||||
lexer->pos = scc_pos_init();
|
||||
// FIXME
|
||||
lexer->pos.name = cstring_from_cstr(cstring_as_cstr(&stream->name));
|
||||
lexer->pos.name = scc_cstring_from_cstr(scc_cstring_as_cstr(&stream->name));
|
||||
}
|
||||
|
||||
#define set_err_token(token) ((token)->type = TOKEN_UNKNOWN)
|
||||
#define set_err_token(token) ((token)->type = SCC_TOK_UNKNOWN)
|
||||
|
||||
static void parse_line(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
static void parse_line(scc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
token->loc = lexer->pos;
|
||||
core_probe_stream_t *stream = lexer->stream;
|
||||
core_probe_stream_reset(stream);
|
||||
int ch = core_probe_stream_next(stream);
|
||||
scc_probe_stream_t *stream = lexer->stream;
|
||||
scc_probe_stream_reset(stream);
|
||||
int ch = scc_probe_stream_next(stream);
|
||||
|
||||
usize n;
|
||||
cstring_t str = cstring_new();
|
||||
scc_cstring_t str = scc_cstring_new();
|
||||
|
||||
if (ch == core_stream_eof) {
|
||||
LEX_WARN("Unexpected EOF at begin");
|
||||
@@ -104,7 +104,7 @@ static void parse_line(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
const char line[] = "line";
|
||||
|
||||
for (int i = 0; i < (int)sizeof(line); i++) {
|
||||
ch = core_probe_stream_consume(stream);
|
||||
ch = scc_probe_stream_consume(stream);
|
||||
core_pos_next(&lexer->pos);
|
||||
if (ch != line[i]) {
|
||||
LEX_WARN("Maroc does not support in lexer rather in preprocessor, "
|
||||
@@ -118,12 +118,12 @@ static void parse_line(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
goto SKIP_LINE;
|
||||
}
|
||||
|
||||
if (core_probe_stream_consume(stream) != ' ') {
|
||||
if (scc_probe_stream_consume(stream) != ' ') {
|
||||
lex_parse_skip_line(lexer->stream, &lexer->pos);
|
||||
token->loc.line = token->value.n;
|
||||
}
|
||||
|
||||
if (core_probe_stream_next(stream) != '"') {
|
||||
if (scc_probe_stream_next(stream) != '"') {
|
||||
LEX_ERROR("Invalid `#` line");
|
||||
goto SKIP_LINE;
|
||||
}
|
||||
@@ -135,259 +135,259 @@ static void parse_line(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
lex_parse_skip_line(lexer->stream, &lexer->pos);
|
||||
token->loc.line = n;
|
||||
// FIXME memory leak
|
||||
token->loc.name = cstring_from_cstr(cstring_as_cstr(&str));
|
||||
cstring_free(&str);
|
||||
token->loc.name = scc_cstring_from_cstr(scc_cstring_as_cstr(&str));
|
||||
scc_cstring_free(&str);
|
||||
return;
|
||||
SKIP_LINE:
|
||||
lex_parse_skip_line(lexer->stream, &lexer->pos);
|
||||
ERR:
|
||||
set_err_token(token);
|
||||
cstring_free(&str);
|
||||
scc_cstring_free(&str);
|
||||
}
|
||||
|
||||
// /zh/c/language/operator_arithmetic.html
|
||||
void lexer_get_token(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
void scc_lexer_get_token(scc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
token->loc = lexer->pos;
|
||||
token->type = TOKEN_UNKNOWN;
|
||||
core_probe_stream_t *stream = lexer->stream;
|
||||
token->type = SCC_TOK_UNKNOWN;
|
||||
scc_probe_stream_t *stream = lexer->stream;
|
||||
|
||||
core_probe_stream_reset(stream);
|
||||
token_type_t type = TOKEN_UNKNOWN;
|
||||
int ch = core_probe_stream_next(stream);
|
||||
scc_probe_stream_reset(stream);
|
||||
scc_tok_type_t type = SCC_TOK_UNKNOWN;
|
||||
int ch = scc_probe_stream_next(stream);
|
||||
|
||||
// once step
|
||||
switch (ch) {
|
||||
case '=':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '=':
|
||||
type = TOKEN_EQ;
|
||||
type = SCC_TOK_EQ;
|
||||
goto double_char;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_ASSIGN;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_ASSIGN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '+':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '+':
|
||||
type = TOKEN_ADD_ADD;
|
||||
type = SCC_TOK_ADD_ADD;
|
||||
goto double_char;
|
||||
case '=':
|
||||
type = TOKEN_ASSIGN_ADD;
|
||||
type = SCC_TOK_ASSIGN_ADD;
|
||||
goto double_char;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_ADD;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_ADD;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '-':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '-':
|
||||
type = TOKEN_SUB_SUB;
|
||||
type = SCC_TOK_SUB_SUB;
|
||||
goto double_char;
|
||||
case '=':
|
||||
type = TOKEN_ASSIGN_SUB;
|
||||
type = SCC_TOK_ASSIGN_SUB;
|
||||
goto double_char;
|
||||
case '>':
|
||||
type = TOKEN_DEREF;
|
||||
type = SCC_TOK_DEREF;
|
||||
goto double_char;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_SUB;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_SUB;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '=':
|
||||
type = TOKEN_ASSIGN_MUL;
|
||||
type = SCC_TOK_ASSIGN_MUL;
|
||||
goto double_char;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_MUL;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_MUL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '=':
|
||||
type = TOKEN_ASSIGN_DIV;
|
||||
type = SCC_TOK_ASSIGN_DIV;
|
||||
goto double_char;
|
||||
case '/':
|
||||
lex_parse_skip_line(lexer->stream, &lexer->pos);
|
||||
token->type = TOKEN_LINE_COMMENT;
|
||||
token->type = SCC_TOK_LINE_COMMENT;
|
||||
goto END;
|
||||
case '*':
|
||||
lex_parse_skip_block_comment(lexer->stream, &lexer->pos);
|
||||
token->type = TOKEN_BLOCK_COMMENT;
|
||||
token->type = SCC_TOK_BLOCK_COMMENT;
|
||||
goto END;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_DIV;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_DIV;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '%':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '=':
|
||||
type = TOKEN_ASSIGN_MOD;
|
||||
type = SCC_TOK_ASSIGN_MOD;
|
||||
goto double_char;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_MOD;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_MOD;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '&':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '&':
|
||||
type = TOKEN_AND_AND;
|
||||
type = SCC_TOK_AND_AND;
|
||||
goto double_char;
|
||||
case '=':
|
||||
type = TOKEN_ASSIGN_AND;
|
||||
type = SCC_TOK_ASSIGN_AND;
|
||||
goto double_char;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_AND;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_AND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '|':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '|':
|
||||
type = TOKEN_OR_OR;
|
||||
type = SCC_TOK_OR_OR;
|
||||
goto double_char;
|
||||
case '=':
|
||||
type = TOKEN_ASSIGN_OR;
|
||||
type = SCC_TOK_ASSIGN_OR;
|
||||
goto double_char;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_OR;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_OR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '^':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '=':
|
||||
type = TOKEN_ASSIGN_XOR;
|
||||
type = SCC_TOK_ASSIGN_XOR;
|
||||
goto double_char;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_XOR;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_XOR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '<':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '=':
|
||||
type = TOKEN_LE;
|
||||
type = SCC_TOK_LE;
|
||||
goto double_char;
|
||||
case '<': {
|
||||
if (core_probe_stream_next(stream) == '=') {
|
||||
type = TOKEN_ASSIGN_L_SH;
|
||||
if (scc_probe_stream_next(stream) == '=') {
|
||||
type = SCC_TOK_ASSIGN_L_SH;
|
||||
goto triple_char;
|
||||
} else {
|
||||
type = TOKEN_L_SH;
|
||||
type = SCC_TOK_L_SH;
|
||||
goto double_char;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_LT;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_LT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '=':
|
||||
type = TOKEN_GE;
|
||||
type = SCC_TOK_GE;
|
||||
goto double_char;
|
||||
case '>': {
|
||||
if (core_probe_stream_next(stream) == '=') {
|
||||
type = TOKEN_ASSIGN_R_SH;
|
||||
if (scc_probe_stream_next(stream) == '=') {
|
||||
type = SCC_TOK_ASSIGN_R_SH;
|
||||
goto triple_char;
|
||||
} else {
|
||||
type = TOKEN_R_SH;
|
||||
type = SCC_TOK_R_SH;
|
||||
goto double_char;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_GT;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_GT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '~':
|
||||
type = TOKEN_BIT_NOT;
|
||||
type = SCC_TOK_BIT_NOT;
|
||||
break;
|
||||
case '!':
|
||||
switch (core_probe_stream_next(stream)) {
|
||||
switch (scc_probe_stream_next(stream)) {
|
||||
case '=':
|
||||
type = TOKEN_NEQ;
|
||||
type = SCC_TOK_NEQ;
|
||||
goto double_char;
|
||||
default:
|
||||
core_probe_stream_reset(stream), type = TOKEN_NOT;
|
||||
scc_probe_stream_reset(stream), type = SCC_TOK_NOT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
type = TOKEN_L_BRACKET;
|
||||
type = SCC_TOK_L_BRACKET;
|
||||
break;
|
||||
case ']':
|
||||
type = TOKEN_R_BRACKET;
|
||||
type = SCC_TOK_R_BRACKET;
|
||||
break;
|
||||
case '(':
|
||||
type = TOKEN_L_PAREN;
|
||||
type = SCC_TOK_L_PAREN;
|
||||
break;
|
||||
case ')':
|
||||
type = TOKEN_R_PAREN;
|
||||
type = SCC_TOK_R_PAREN;
|
||||
break;
|
||||
case '{':
|
||||
type = TOKEN_L_BRACE;
|
||||
type = SCC_TOK_L_BRACE;
|
||||
break;
|
||||
case '}':
|
||||
type = TOKEN_R_BRACE;
|
||||
type = SCC_TOK_R_BRACE;
|
||||
break;
|
||||
case ';':
|
||||
type = TOKEN_SEMICOLON;
|
||||
type = SCC_TOK_SEMICOLON;
|
||||
break;
|
||||
case ',':
|
||||
type = TOKEN_COMMA;
|
||||
type = SCC_TOK_COMMA;
|
||||
break;
|
||||
case ':':
|
||||
type = TOKEN_COLON;
|
||||
type = SCC_TOK_COLON;
|
||||
break;
|
||||
case '.':
|
||||
if (core_probe_stream_next(stream) == '.' &&
|
||||
core_probe_stream_next(stream) == '.') {
|
||||
type = TOKEN_ELLIPSIS;
|
||||
if (scc_probe_stream_next(stream) == '.' &&
|
||||
scc_probe_stream_next(stream) == '.') {
|
||||
type = SCC_TOK_ELLIPSIS;
|
||||
goto triple_char;
|
||||
}
|
||||
type = TOKEN_DOT;
|
||||
type = SCC_TOK_DOT;
|
||||
break;
|
||||
case '?':
|
||||
type = TOKEN_COND;
|
||||
type = SCC_TOK_COND;
|
||||
break;
|
||||
case '\v':
|
||||
case '\f':
|
||||
case ' ':
|
||||
case '\t':
|
||||
type = TOKEN_BLANK;
|
||||
type = SCC_TOK_BLANK;
|
||||
break;
|
||||
case '\r':
|
||||
case '\n':
|
||||
lex_parse_skip_endline(lexer->stream, &lexer->pos);
|
||||
token->type = TOKEN_BLANK;
|
||||
token->type = SCC_TOK_BLANK;
|
||||
goto END;
|
||||
case '#':
|
||||
parse_line(lexer, token);
|
||||
token->type = TOKEN_BLANK;
|
||||
token->type = SCC_TOK_BLANK;
|
||||
goto END;
|
||||
case '\0':
|
||||
case core_stream_eof:
|
||||
// EOF
|
||||
type = TOKEN_EOF;
|
||||
type = SCC_TOK_EOF;
|
||||
break;
|
||||
case '\'': {
|
||||
token->loc = lexer->pos;
|
||||
token->type = TOKEN_CHAR_LITERAL;
|
||||
token->type = SCC_TOK_CHAR_LITERAL;
|
||||
int ch = lex_parse_char(lexer->stream, &lexer->pos);
|
||||
if (ch == core_stream_eof) {
|
||||
LEX_ERROR("Unexpected character literal");
|
||||
token->type = TOKEN_UNKNOWN;
|
||||
token->type = SCC_TOK_UNKNOWN;
|
||||
} else {
|
||||
token->value.ch = ch;
|
||||
}
|
||||
@@ -395,14 +395,14 @@ void lexer_get_token(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
}
|
||||
case '"': {
|
||||
token->loc = lexer->pos;
|
||||
token->type = TOKEN_STRING_LITERAL;
|
||||
cstring_t output = cstring_new();
|
||||
token->type = SCC_TOK_STRING_LITERAL;
|
||||
scc_cstring_t output = scc_cstring_new();
|
||||
if (lex_parse_string(lexer->stream, &lexer->pos, &output) == true) {
|
||||
token->value.cstr.data = cstring_as_cstr(&output);
|
||||
token->value.cstr.len = cstring_len(&output);
|
||||
token->value.cstr.data = scc_cstring_as_cstr(&output);
|
||||
token->value.cstr.len = scc_cstring_len(&output);
|
||||
} else {
|
||||
LEX_ERROR("Unexpected string literal");
|
||||
token->type = TOKEN_UNKNOWN;
|
||||
token->type = SCC_TOK_UNKNOWN;
|
||||
}
|
||||
|
||||
goto END;
|
||||
@@ -412,13 +412,13 @@ void lexer_get_token(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
/* clang-format on */
|
||||
token->loc = lexer->pos;
|
||||
token->type = TOKEN_INT_LITERAL;
|
||||
token->type = SCC_TOK_INT_LITERAL;
|
||||
usize output;
|
||||
if (lex_parse_number(lexer->stream, &lexer->pos, &output) == true) {
|
||||
token->value.n = output;
|
||||
} else {
|
||||
LEX_ERROR("Unexpected number literal");
|
||||
token->type = TOKEN_UNKNOWN;
|
||||
token->type = SCC_TOK_UNKNOWN;
|
||||
}
|
||||
goto END;
|
||||
/* clang-format off */
|
||||
@@ -431,17 +431,17 @@ void lexer_get_token(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
|
||||
case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_':
|
||||
/* clang-format on */
|
||||
cstring_t str = cstring_new();
|
||||
scc_cstring_t str = scc_cstring_new();
|
||||
cbool ret = lex_parse_identifier(lexer->stream, &lexer->pos, &str);
|
||||
Assert(ret == true);
|
||||
|
||||
int res = keyword_cmp(cstring_as_cstr(&str), cstring_len(&str));
|
||||
int res = keyword_cmp(scc_cstring_as_cstr(&str), scc_cstring_len(&str));
|
||||
if (res == -1) {
|
||||
token->value.cstr.data = (char *)cstring_as_cstr(&str);
|
||||
token->value.cstr.len = cstring_len(&str);
|
||||
type = TOKEN_IDENT;
|
||||
token->value.cstr.data = (char *)scc_cstring_as_cstr(&str);
|
||||
token->value.cstr.len = scc_cstring_len(&str);
|
||||
type = SCC_TOK_IDENT;
|
||||
} else {
|
||||
cstring_free(&str);
|
||||
scc_cstring_free(&str);
|
||||
type = keywords[res].tok;
|
||||
}
|
||||
token->type = type;
|
||||
@@ -452,29 +452,31 @@ void lexer_get_token(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
}
|
||||
goto once_char;
|
||||
triple_char:
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(&lexer->pos);
|
||||
double_char:
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(&lexer->pos);
|
||||
once_char:
|
||||
core_probe_stream_consume(stream);
|
||||
scc_probe_stream_consume(stream);
|
||||
core_pos_next(&lexer->pos);
|
||||
token->type = type;
|
||||
END:
|
||||
LEX_DEBUG("get token `%s` in %s:%d:%d", get_tok_name(token->type),
|
||||
LEX_DEBUG("get token `%s` in %s:%d:%d", scc_get_tok_name(token->type),
|
||||
token->loc.name, token->loc.line, token->loc.column);
|
||||
}
|
||||
|
||||
// lexer_get_token maybe got invalid (with parser)
|
||||
void lexer_get_valid_token(smcc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
token_subtype_t type;
|
||||
// scc_lexer_get_token maybe got invalid (with parser)
|
||||
void scc_lexer_get_valid_token(scc_lexer_t *lexer, lexer_tok_t *token) {
|
||||
scc_tok_subtype_t type;
|
||||
do {
|
||||
lexer_get_token(lexer, token);
|
||||
type = get_tok_subtype(token->type);
|
||||
AssertFmt(type != TK_BASIC_INVALID, "Invalid token: `%s` at %s:%d:%d",
|
||||
get_tok_name(token->type), token->loc.name, token->loc.line,
|
||||
token->loc.col);
|
||||
Assert(type != TK_BASIC_INVALID);
|
||||
} while (type == TK_BASIC_EMPTYSPACE || type == TK_BASIC_COMMENT);
|
||||
scc_lexer_get_token(lexer, token);
|
||||
type = scc_get_tok_subtype(token->type);
|
||||
AssertFmt(type != SCC_TOK_SUBTYPE_INVALID,
|
||||
"Invalid token: `%s` at %s:%d:%d",
|
||||
scc_get_tok_name(token->type), token->loc.name,
|
||||
token->loc.line, token->loc.col);
|
||||
Assert(type != SCC_TOK_SUBTYPE_INVALID);
|
||||
} while (type == SCC_TOK_SUBTYPE_EMPTYSPACE ||
|
||||
type == SCC_TOK_SUBTYPE_COMMENT);
|
||||
}
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#include <lexer_token.h>
|
||||
|
||||
// 生成字符串映射(根据需求选择#str或#name)
|
||||
static const char* token_strings[] = {
|
||||
#define X(str, subtype, tok) [tok] = #str,
|
||||
TOKEN_TABLE
|
||||
#undef X
|
||||
static const char *token_strings[] = {
|
||||
#define X(str, subtype, tok) [tok] = #str,
|
||||
SCC_CTOK_TABLE
|
||||
#undef X
|
||||
|
||||
#define X(str, subtype, tok, std) [tok] = #str,
|
||||
KEYWORD_TABLE
|
||||
#undef X
|
||||
#define X(str, subtype, tok, std) [tok] = #str,
|
||||
SCC_CKEYWORD_TABLE
|
||||
#undef X
|
||||
};
|
||||
|
||||
static token_subtype_t token_subtypes[] = {
|
||||
#define X(str, subtype, tok) [tok] = subtype,
|
||||
TOKEN_TABLE
|
||||
#undef X
|
||||
static scc_tok_subtype_t token_subtypes[] = {
|
||||
#define X(str, subtype, tok) [tok] = subtype,
|
||||
SCC_CTOK_TABLE
|
||||
#undef X
|
||||
|
||||
#define X(str, subtype, tok, std) [tok] = subtype,
|
||||
KEYWORD_TABLE
|
||||
#undef X
|
||||
#define X(str, subtype, tok, std) [tok] = subtype,
|
||||
SCC_CKEYWORD_TABLE
|
||||
#undef X
|
||||
};
|
||||
|
||||
token_subtype_t get_tok_subtype(token_type_t type) {
|
||||
scc_tok_subtype_t scc_get_tok_subtype(scc_tok_type_t type) {
|
||||
return token_subtypes[type];
|
||||
}
|
||||
|
||||
const char* get_tok_name(token_type_t type) {
|
||||
const char *scc_get_tok_name(scc_tok_type_t type) {
|
||||
return token_strings[type];
|
||||
}
|
||||
|
||||
@@ -5,92 +5,92 @@
|
||||
|
||||
// 测试辅助函数
|
||||
static inline void test_lexer_string(const char *input,
|
||||
token_type_t expected_type) {
|
||||
smcc_lexer_t lexer;
|
||||
scc_tok_type_t expected_type) {
|
||||
scc_lexer_t lexer;
|
||||
lexer_tok_t token;
|
||||
core_mem_probe_stream_t stream;
|
||||
scc_mem_probe_stream_t stream;
|
||||
|
||||
lexer_init(&lexer, core_mem_probe_stream_init(&stream, input, strlen(input),
|
||||
false));
|
||||
lexer_get_token(&lexer, &token);
|
||||
scc_lexer_init(&lexer, scc_mem_probe_stream_init(&stream, input,
|
||||
strlen(input), false));
|
||||
scc_lexer_get_token(&lexer, &token);
|
||||
|
||||
TEST_CHECK(token.type == expected_type);
|
||||
TEST_MSG("Expected: %s", get_tok_name(expected_type));
|
||||
TEST_MSG("Got: %s", get_tok_name(token.type));
|
||||
TEST_MSG("Expected: %s", scc_get_tok_name(expected_type));
|
||||
TEST_MSG("Got: %s", scc_get_tok_name(token.type));
|
||||
}
|
||||
|
||||
// 基础运算符测试
|
||||
void test_operators() {
|
||||
TEST_CASE("Arithmetic operators");
|
||||
{
|
||||
test_lexer_string("+", TOKEN_ADD);
|
||||
test_lexer_string("++", TOKEN_ADD_ADD);
|
||||
test_lexer_string("+=", TOKEN_ASSIGN_ADD);
|
||||
test_lexer_string("-", TOKEN_SUB);
|
||||
test_lexer_string("--", TOKEN_SUB_SUB);
|
||||
test_lexer_string("-=", TOKEN_ASSIGN_SUB);
|
||||
test_lexer_string("*", TOKEN_MUL);
|
||||
test_lexer_string("*=", TOKEN_ASSIGN_MUL);
|
||||
test_lexer_string("/", TOKEN_DIV);
|
||||
test_lexer_string("/=", TOKEN_ASSIGN_DIV);
|
||||
test_lexer_string("%", TOKEN_MOD);
|
||||
test_lexer_string("%=", TOKEN_ASSIGN_MOD);
|
||||
test_lexer_string("+", SCC_TOK_ADD);
|
||||
test_lexer_string("++", SCC_TOK_ADD_ADD);
|
||||
test_lexer_string("+=", SCC_TOK_ASSIGN_ADD);
|
||||
test_lexer_string("-", SCC_TOK_SUB);
|
||||
test_lexer_string("--", SCC_TOK_SUB_SUB);
|
||||
test_lexer_string("-=", SCC_TOK_ASSIGN_SUB);
|
||||
test_lexer_string("*", SCC_TOK_MUL);
|
||||
test_lexer_string("*=", SCC_TOK_ASSIGN_MUL);
|
||||
test_lexer_string("/", SCC_TOK_DIV);
|
||||
test_lexer_string("/=", SCC_TOK_ASSIGN_DIV);
|
||||
test_lexer_string("%", SCC_TOK_MOD);
|
||||
test_lexer_string("%=", SCC_TOK_ASSIGN_MOD);
|
||||
}
|
||||
|
||||
TEST_CASE("Bitwise operators");
|
||||
{
|
||||
test_lexer_string("&", TOKEN_AND);
|
||||
test_lexer_string("&&", TOKEN_AND_AND);
|
||||
test_lexer_string("&=", TOKEN_ASSIGN_AND);
|
||||
test_lexer_string("|", TOKEN_OR);
|
||||
test_lexer_string("||", TOKEN_OR_OR);
|
||||
test_lexer_string("|=", TOKEN_ASSIGN_OR);
|
||||
test_lexer_string("^", TOKEN_XOR);
|
||||
test_lexer_string("^=", TOKEN_ASSIGN_XOR);
|
||||
test_lexer_string("~", TOKEN_BIT_NOT);
|
||||
test_lexer_string("<<", TOKEN_L_SH);
|
||||
test_lexer_string("<<=", TOKEN_ASSIGN_L_SH);
|
||||
test_lexer_string(">>", TOKEN_R_SH);
|
||||
test_lexer_string(">>=", TOKEN_ASSIGN_R_SH);
|
||||
test_lexer_string("&", SCC_TOK_AND);
|
||||
test_lexer_string("&&", SCC_TOK_AND_AND);
|
||||
test_lexer_string("&=", SCC_TOK_ASSIGN_AND);
|
||||
test_lexer_string("|", SCC_TOK_OR);
|
||||
test_lexer_string("||", SCC_TOK_OR_OR);
|
||||
test_lexer_string("|=", SCC_TOK_ASSIGN_OR);
|
||||
test_lexer_string("^", SCC_TOK_XOR);
|
||||
test_lexer_string("^=", SCC_TOK_ASSIGN_XOR);
|
||||
test_lexer_string("~", SCC_TOK_BIT_NOT);
|
||||
test_lexer_string("<<", SCC_TOK_L_SH);
|
||||
test_lexer_string("<<=", SCC_TOK_ASSIGN_L_SH);
|
||||
test_lexer_string(">>", SCC_TOK_R_SH);
|
||||
test_lexer_string(">>=", SCC_TOK_ASSIGN_R_SH);
|
||||
}
|
||||
|
||||
TEST_CASE("Comparison operators");
|
||||
{
|
||||
test_lexer_string("==", TOKEN_EQ);
|
||||
test_lexer_string("!=", TOKEN_NEQ);
|
||||
test_lexer_string("<", TOKEN_LT);
|
||||
test_lexer_string("<=", TOKEN_LE);
|
||||
test_lexer_string(">", TOKEN_GT);
|
||||
test_lexer_string(">=", TOKEN_GE);
|
||||
test_lexer_string("==", SCC_TOK_EQ);
|
||||
test_lexer_string("!=", SCC_TOK_NEQ);
|
||||
test_lexer_string("<", SCC_TOK_LT);
|
||||
test_lexer_string("<=", SCC_TOK_LE);
|
||||
test_lexer_string(">", SCC_TOK_GT);
|
||||
test_lexer_string(">=", SCC_TOK_GE);
|
||||
}
|
||||
|
||||
TEST_CASE("Special symbols");
|
||||
{
|
||||
test_lexer_string("(", TOKEN_L_PAREN);
|
||||
test_lexer_string(")", TOKEN_R_PAREN);
|
||||
test_lexer_string("[", TOKEN_L_BRACKET);
|
||||
test_lexer_string("]", TOKEN_R_BRACKET);
|
||||
test_lexer_string("{", TOKEN_L_BRACE);
|
||||
test_lexer_string("}", TOKEN_R_BRACE);
|
||||
test_lexer_string(";", TOKEN_SEMICOLON);
|
||||
test_lexer_string(",", TOKEN_COMMA);
|
||||
test_lexer_string(":", TOKEN_COLON);
|
||||
test_lexer_string(".", TOKEN_DOT);
|
||||
test_lexer_string("...", TOKEN_ELLIPSIS);
|
||||
test_lexer_string("->", TOKEN_DEREF);
|
||||
test_lexer_string("?", TOKEN_COND);
|
||||
test_lexer_string("(", SCC_TOK_L_PAREN);
|
||||
test_lexer_string(")", SCC_TOK_R_PAREN);
|
||||
test_lexer_string("[", SCC_TOK_L_BRACKET);
|
||||
test_lexer_string("]", SCC_TOK_R_BRACKET);
|
||||
test_lexer_string("{", SCC_TOK_L_BRACE);
|
||||
test_lexer_string("}", SCC_TOK_R_BRACE);
|
||||
test_lexer_string(";", SCC_TOK_SEMICOLON);
|
||||
test_lexer_string(",", SCC_TOK_COMMA);
|
||||
test_lexer_string(":", SCC_TOK_COLON);
|
||||
test_lexer_string(".", SCC_TOK_DOT);
|
||||
test_lexer_string("...", SCC_TOK_ELLIPSIS);
|
||||
test_lexer_string("->", SCC_TOK_DEREF);
|
||||
test_lexer_string("?", SCC_TOK_COND);
|
||||
}
|
||||
}
|
||||
|
||||
// 关键字测试
|
||||
void test_keywords() {
|
||||
TEST_CASE("C89 keywords");
|
||||
test_lexer_string("while", TOKEN_WHILE);
|
||||
test_lexer_string("sizeof", TOKEN_SIZEOF);
|
||||
test_lexer_string("while", SCC_TOK_WHILE);
|
||||
test_lexer_string("sizeof", SCC_TOK_SIZEOF);
|
||||
|
||||
TEST_CASE("C99 keywords");
|
||||
test_lexer_string("restrict", TOKEN_RESTRICT);
|
||||
// test_lexer_string("_Bool", TOKEN_INT); // 需确认你的类型定义
|
||||
test_lexer_string("restrict", SCC_TOK_RESTRICT);
|
||||
// test_lexer_string("_Bool", SCC_TOK_INT); // 需确认你的类型定义
|
||||
}
|
||||
|
||||
// 字面量测试
|
||||
@@ -98,55 +98,55 @@ void test_literals() {
|
||||
TEST_CASE("Integer literals");
|
||||
{
|
||||
// 十进制
|
||||
test_lexer_string("0", TOKEN_INT_LITERAL);
|
||||
test_lexer_string("123", TOKEN_INT_LITERAL);
|
||||
test_lexer_string("2147483647", TOKEN_INT_LITERAL);
|
||||
test_lexer_string("0", SCC_TOK_INT_LITERAL);
|
||||
test_lexer_string("123", SCC_TOK_INT_LITERAL);
|
||||
test_lexer_string("2147483647", SCC_TOK_INT_LITERAL);
|
||||
|
||||
// 十六进制
|
||||
test_lexer_string("0x0", TOKEN_INT_LITERAL);
|
||||
test_lexer_string("0x1A3F", TOKEN_INT_LITERAL);
|
||||
test_lexer_string("0XABCDEF", TOKEN_INT_LITERAL);
|
||||
test_lexer_string("0x0", SCC_TOK_INT_LITERAL);
|
||||
test_lexer_string("0x1A3F", SCC_TOK_INT_LITERAL);
|
||||
test_lexer_string("0XABCDEF", SCC_TOK_INT_LITERAL);
|
||||
|
||||
// 八进制
|
||||
test_lexer_string("0123", TOKEN_INT_LITERAL);
|
||||
test_lexer_string("0777", TOKEN_INT_LITERAL);
|
||||
test_lexer_string("0123", SCC_TOK_INT_LITERAL);
|
||||
test_lexer_string("0777", SCC_TOK_INT_LITERAL);
|
||||
|
||||
// 边界值测试
|
||||
test_lexer_string("2147483647", TOKEN_INT_LITERAL); // INT_MAX
|
||||
test_lexer_string("4294967295", TOKEN_INT_LITERAL); // UINT_MAX
|
||||
test_lexer_string("2147483647", SCC_TOK_INT_LITERAL); // INT_MAX
|
||||
test_lexer_string("4294967295", SCC_TOK_INT_LITERAL); // UINT_MAX
|
||||
}
|
||||
|
||||
TEST_CASE("Character literals");
|
||||
{
|
||||
test_lexer_string("'a'", TOKEN_CHAR_LITERAL);
|
||||
test_lexer_string("'\\n'", TOKEN_CHAR_LITERAL);
|
||||
test_lexer_string("'\\t'", TOKEN_CHAR_LITERAL);
|
||||
test_lexer_string("'\\\\'", TOKEN_CHAR_LITERAL);
|
||||
test_lexer_string("'\\0'", TOKEN_CHAR_LITERAL);
|
||||
test_lexer_string("'a'", SCC_TOK_CHAR_LITERAL);
|
||||
test_lexer_string("'\\n'", SCC_TOK_CHAR_LITERAL);
|
||||
test_lexer_string("'\\t'", SCC_TOK_CHAR_LITERAL);
|
||||
test_lexer_string("'\\\\'", SCC_TOK_CHAR_LITERAL);
|
||||
test_lexer_string("'\\0'", SCC_TOK_CHAR_LITERAL);
|
||||
}
|
||||
|
||||
TEST_CASE("String literals");
|
||||
{
|
||||
test_lexer_string("\"hello\"", TOKEN_STRING_LITERAL);
|
||||
test_lexer_string("\"multi-line\\nstring\"", TOKEN_STRING_LITERAL);
|
||||
test_lexer_string("\"escape\\\"quote\"", TOKEN_STRING_LITERAL);
|
||||
test_lexer_string("\"hello\"", SCC_TOK_STRING_LITERAL);
|
||||
test_lexer_string("\"multi-line\\nstring\"", SCC_TOK_STRING_LITERAL);
|
||||
test_lexer_string("\"escape\\\"quote\"", SCC_TOK_STRING_LITERAL);
|
||||
}
|
||||
|
||||
// TEST_CASE("Floating literals");
|
||||
// test_lexer_string("3.14e-5", TOKEN_FLOAT_LITERAL);
|
||||
// test_lexer_string("3.14e-5", SCC_TOK_FLOAT_LITERAL);
|
||||
}
|
||||
|
||||
// 边界测试
|
||||
void test_edge_cases() {
|
||||
// TEST_CASE("Long identifiers");
|
||||
// char long_id[LEXER_MAX_TOKEN_SIZE+2] = {0};
|
||||
// memset(long_id, 'a', LEXER_MAX_TOKEN_SIZE+1);
|
||||
// test_lexer_string(long_id, TOKEN_IDENT);
|
||||
// char long_id[LEXER_MAX_ SCC_TOK_SIZE+2] = {0};
|
||||
// memset(long_id, 'a', LEXER_MAX_ SCC_TOK_SIZE+1);
|
||||
// test_lexer_string(long_id, SCC_TOK_IDENT);
|
||||
|
||||
// TEST_CASE("Buffer boundary");
|
||||
// char boundary[LEXER_BUFFER_SIZE*2] = {0};
|
||||
// memset(boundary, '+', LEXER_BUFFER_SIZE*2-1);
|
||||
// test_lexer_string(boundary, TOKEN_ADD);
|
||||
// test_lexer_string(boundary, SCC_TOK_ADD);
|
||||
}
|
||||
|
||||
// 错误处理测试
|
||||
@@ -158,7 +158,7 @@ void test_edge_cases() {
|
||||
// init_lexer(&lexer, "test.c", NULL, test_read);
|
||||
// get_valid_token(&lexer, &token);
|
||||
|
||||
// TEST_CHECK(token.type == TOKEN_EOF); // 应触发错误处理
|
||||
// TEST_CHECK(token.type == SCC_TOK_EOF); // 应触发错误处理
|
||||
// }
|
||||
|
||||
// 测试列表
|
||||
|
||||
@@ -62,27 +62,28 @@ int main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
smcc_lexer_t lexer;
|
||||
core_mem_probe_stream_t mem_stream = {0};
|
||||
core_probe_stream_t *stream =
|
||||
core_mem_probe_stream_init(&mem_stream, buffer, fsize, false);
|
||||
scc_lexer_t lexer;
|
||||
scc_mem_probe_stream_t mem_stream = {0};
|
||||
scc_probe_stream_t *stream =
|
||||
scc_mem_probe_stream_init(&mem_stream, buffer, fsize, false);
|
||||
Assert(stream != null);
|
||||
cstring_clear(&stream->name);
|
||||
cstring_append_cstr(&stream->name, file_name, strlen(file_name));
|
||||
lexer_init(&lexer, stream);
|
||||
scc_cstring_clear(&stream->name);
|
||||
scc_cstring_append_cstr(&stream->name, file_name, strlen(file_name));
|
||||
scc_lexer_init(&lexer, stream);
|
||||
lexer_tok_t tok;
|
||||
|
||||
while (1) {
|
||||
lexer_get_valid_token(&lexer, &tok);
|
||||
if (tok.type == TOKEN_EOF) {
|
||||
scc_lexer_get_valid_token(&lexer, &tok);
|
||||
if (tok.type == SCC_TOK_EOF) {
|
||||
break;
|
||||
}
|
||||
LOG_DEBUG("token `%s` at %s:%u:%u", get_tok_name(tok.type),
|
||||
cstring_as_cstr(&tok.loc.name), tok.loc.line, tok.loc.col);
|
||||
LOG_DEBUG("token `%s` at %s:%u:%u", scc_get_tok_name(tok.type),
|
||||
scc_cstring_as_cstr(&tok.loc.name), tok.loc.line,
|
||||
tok.loc.col);
|
||||
Assert(tok.loc.offset <= fsize);
|
||||
// LOG_DEBUG("%s", tok.val.str);
|
||||
// printf("line: %d, column: %d, type: %3d, typename: %s\n",
|
||||
// lexer.line, lexer.index, tok.type, get_tok_name(tok.type));
|
||||
// lexer.line, lexer.index, tok.type, scc_get_tok_name(tok.type));
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
#ifndef __SMCC_CORE_IMPL_H__
|
||||
#define __SMCC_CORE_IMPL_H__
|
||||
#ifndef __SCC_CORE_IMPL_H__
|
||||
#define __SCC_CORE_IMPL_H__
|
||||
|
||||
#include "core_type.h"
|
||||
|
||||
/* ====== 内存管理核心接口 ====== */
|
||||
|
||||
void *smcc_malloc(usize size);
|
||||
void *smcc_calloc(usize count, usize size);
|
||||
void *smcc_realloc(void *ptr, usize new_size);
|
||||
void smcc_free(void *ptr);
|
||||
void *scc_malloc(usize size);
|
||||
void *scc_calloc(usize count, usize size);
|
||||
void *scc_realloc(void *ptr, usize new_size);
|
||||
void scc_free(void *ptr);
|
||||
|
||||
/* ====== 文件系统核心接口 ====== */
|
||||
|
||||
/* 文件句柄 - 不透明指针 */
|
||||
typedef struct smcc_file *smcc_file_t;
|
||||
typedef struct scc_file *scc_file_t;
|
||||
|
||||
/* 文件打开模式 - 只保留编译器真正需要的 */
|
||||
typedef enum {
|
||||
SMCC_FILE_READ, /* 读取源文件、头文件 */
|
||||
SMCC_FILE_WRITE, /* 写入目标文件、汇编文件 */
|
||||
SMCC_FILE_APPEND /* 日志、调试输出 */
|
||||
} smcc_file_mode_t;
|
||||
SCC_FILE_READ, /* 读取源文件、头文件 */
|
||||
SCC_FILE_WRITE, /* 写入目标文件、汇编文件 */
|
||||
SCC_FILE_APPEND /* 日志、调试输出 */
|
||||
} scc_fmode_t;
|
||||
|
||||
/* 核心文件操作 */
|
||||
smcc_file_t smcc_fopen(const char *path, smcc_file_mode_t mode);
|
||||
void smcc_fclose(smcc_file_t file);
|
||||
usize smcc_fread(smcc_file_t file, void *buffer, usize size);
|
||||
usize smcc_fwrite(smcc_file_t file, const void *buffer, usize size);
|
||||
cbool smcc_fexists(const char *path);
|
||||
scc_file_t scc_fopen(const char *path, scc_fmode_t mode);
|
||||
void scc_fclose(scc_file_t file);
|
||||
usize scc_fread(scc_file_t file, void *buffer, usize size);
|
||||
usize scc_fwrite(scc_file_t file, const void *buffer, usize size);
|
||||
cbool scc_fexists(const char *path);
|
||||
|
||||
/* ====== 输入输出核心接口 ====== */
|
||||
|
||||
void smcc_snprintf(char *buf, usize size, const char *format, ...);
|
||||
void scc_snprintf(char *buf, usize size, const char *format, ...);
|
||||
|
||||
/* 标准输出 - 用于编译进度、结果 */
|
||||
void smcc_printf(const char *format, ...);
|
||||
void scc_printf(const char *format, ...);
|
||||
|
||||
/* 错误输出 - 用于错误信息、警告 */
|
||||
void smcc_eprintf(const char *format, ...);
|
||||
void scc_eprintf(const char *format, ...);
|
||||
|
||||
/* ====== 系统核心接口 ====== */
|
||||
|
||||
/* 程序控制 */
|
||||
void smcc_exit(int code);
|
||||
void scc_exit(int code);
|
||||
|
||||
#endif // __SMCC_CORE_IMPL_H__
|
||||
#endif /* __SCC_CORE_IMPL_H__ */
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#ifndef __SMCC_CORE_LOG_H__
|
||||
#define __SMCC_CORE_LOG_H__
|
||||
#ifndef __SCC_CORE_LOG_H__
|
||||
#define __SCC_CORE_LOG_H__
|
||||
|
||||
#ifndef log_snprintf
|
||||
#define log_snprintf smcc_snprintf
|
||||
#define log_snprintf scc_snprintf
|
||||
#endif
|
||||
|
||||
#ifndef log_printf
|
||||
#define log_printf smcc_printf
|
||||
#define log_printf scc_printf
|
||||
#endif
|
||||
|
||||
#ifndef log_exit
|
||||
#define log_exit smcc_exit
|
||||
#define log_exit scc_exit
|
||||
#endif
|
||||
#include <log.h>
|
||||
|
||||
#endif /* __SMCC_CORE_LOG_H__ */
|
||||
#endif /* __SCC_CORE_LOG_H__ */
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#ifndef __SMCC_CORE_MACRO_H__
|
||||
#define __SMCC_CORE_MACRO_H__
|
||||
#ifndef __SCC_CORE_MACRO_H__
|
||||
#define __SCC_CORE_MACRO_H__
|
||||
|
||||
#define _SMCC_STR(str) #str
|
||||
#define SMCC_STR(str) _SMCC_STR(str)
|
||||
#define _SCC_STR(str) #str
|
||||
#define SCC_STR(str) _SCC_STR(str)
|
||||
|
||||
#define SMCC_ARRLEN(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
#define SCC_ARRLEN(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
#endif // __SMCC_CORE_MACRO_H__
|
||||
#define SCC_FUNC
|
||||
|
||||
#endif // __SCC_CORE_MACRO_H__
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#ifndef __SMCC_CORE_MEM_H__
|
||||
#define __SMCC_CORE_MEM_H__
|
||||
#ifndef __SCC_CORE_MEM_H__
|
||||
#define __SCC_CORE_MEM_H__
|
||||
|
||||
#include "core_type.h"
|
||||
|
||||
void *smcc_memcpy(void *dest, const void *src, usize n);
|
||||
void *smcc_memmove(void *dest, const void *src, usize n);
|
||||
void *smcc_memset(void *s, int c, usize n);
|
||||
int smcc_memcmp(const void *s1, const void *s2, usize n);
|
||||
void *scc_memcpy(void *dest, const void *src, usize n);
|
||||
void *scc_memmove(void *dest, const void *src, usize n);
|
||||
void *scc_memset(void *s, int c, usize n);
|
||||
int scc_memcmp(const void *s1, const void *s2, usize n);
|
||||
|
||||
/**
|
||||
* @brief 使用FNV-1a进行 C 字符串哈希
|
||||
@@ -14,7 +14,7 @@ int smcc_memcmp(const void *s1, const void *s2, usize n);
|
||||
* @param s
|
||||
* @return u32
|
||||
*/
|
||||
static inline u32 smcc_strhash32(const char *s) {
|
||||
static inline u32 scc_strhash32(const char *s) {
|
||||
u32 hash = 2166136261u; // FNV-1a偏移基础值
|
||||
while (*s) {
|
||||
hash ^= *s++;
|
||||
@@ -29,7 +29,7 @@ static inline u32 smcc_strhash32(const char *s) {
|
||||
* @param str
|
||||
* @return usize
|
||||
*/
|
||||
static inline usize smcc_strlen(const char *str) {
|
||||
static inline usize scc_strlen(const char *str) {
|
||||
usize len = 0;
|
||||
while (*str) {
|
||||
len++;
|
||||
@@ -45,7 +45,7 @@ static inline usize smcc_strlen(const char *str) {
|
||||
* @param s2
|
||||
* @return int
|
||||
*/
|
||||
static inline int smcc_strcmp(const char *s1, const char *s2) {
|
||||
static inline int scc_strcmp(const char *s1, const char *s2) {
|
||||
while (*s1 && *s2 && *s1 == *s2) {
|
||||
s1++;
|
||||
s2++;
|
||||
@@ -53,4 +53,4 @@ static inline int smcc_strcmp(const char *s1, const char *s2) {
|
||||
return *s1 - *s2;
|
||||
}
|
||||
|
||||
#endif /* __SMCC_CORE_MEM_H__ */
|
||||
#endif /* __SCC_CORE_MEM_H__ */
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#ifndef __SMCC_CORE_POS_H__
|
||||
#define __SMCC_CORE_POS_H__
|
||||
#ifndef __SCC_CORE_POS_H__
|
||||
#define __SCC_CORE_POS_H__
|
||||
|
||||
#include "core_str.h"
|
||||
#include "core_type.h"
|
||||
typedef struct {
|
||||
cstring_t name;
|
||||
typedef struct scc_pos {
|
||||
scc_cstring_t name;
|
||||
usize line;
|
||||
usize col;
|
||||
usize offset;
|
||||
} core_pos_t;
|
||||
} scc_pos_t;
|
||||
|
||||
static inline core_pos_t core_pos_init() {
|
||||
return (core_pos_t){cstring_new(), 1, 1, 0};
|
||||
static inline scc_pos_t scc_pos_init() {
|
||||
return (scc_pos_t){scc_cstring_new(), 1, 1, 0};
|
||||
}
|
||||
|
||||
static inline void core_pos_next(core_pos_t *pos) {
|
||||
static inline void core_pos_next(scc_pos_t *pos) {
|
||||
pos->offset++;
|
||||
pos->col++;
|
||||
}
|
||||
|
||||
static inline void core_pos_next_line(core_pos_t *pos) {
|
||||
static inline void core_pos_next_line(scc_pos_t *pos) {
|
||||
pos->offset++;
|
||||
pos->line++;
|
||||
pos->col = 1;
|
||||
}
|
||||
|
||||
#endif /* __SMCC_CORE_POS_H__ */
|
||||
#endif /* __SCC_CORE_POS_H__ */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef __SMCC_CORE_STR_H__
|
||||
#define __SMCC_CORE_STR_H__
|
||||
#ifndef __SCC_CORE_STR_H__
|
||||
#define __SCC_CORE_STR_H__
|
||||
|
||||
#include "core_impl.h"
|
||||
#include "core_log.h"
|
||||
@@ -7,21 +7,21 @@
|
||||
|
||||
/**
|
||||
* @brief 动态字符串结构体
|
||||
* @attention 创建的字符串对象需要使用 cstring_free 释放
|
||||
* @attention 创建的字符串对象需要使用 scc_cstring_free 释放
|
||||
*/
|
||||
typedef struct cstring {
|
||||
typedef struct scc_cstring {
|
||||
usize size; /**< 字符串当前大小(包括结尾的'\0')*/
|
||||
usize cap; /**< 分配的容量 */
|
||||
char *data; /**< 实际存储数据的指针 */
|
||||
} cstring_t;
|
||||
} scc_cstring_t;
|
||||
|
||||
/**
|
||||
* @brief 创建一个新的空动态字符串对象
|
||||
*
|
||||
* @return cstring_t 初始化后的对象
|
||||
*/
|
||||
static inline cstring_t cstring_new(void) {
|
||||
return (cstring_t){.data = null, .size = 0, .cap = 0};
|
||||
static inline scc_cstring_t scc_cstring_new(void) {
|
||||
return (scc_cstring_t){.data = null, .size = 0, .cap = 0};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,9 +30,9 @@ static inline cstring_t cstring_new(void) {
|
||||
* @param s 输入的 C 风格字符串
|
||||
* @return cstring_t 新建对象,包含输入字符串的副本
|
||||
*/
|
||||
static inline cstring_t cstring_from_cstr(const char *s) {
|
||||
static inline scc_cstring_t scc_cstring_from_cstr(const char *s) {
|
||||
if (s == null) {
|
||||
return cstring_new();
|
||||
return scc_cstring_new();
|
||||
}
|
||||
|
||||
usize len = 0;
|
||||
@@ -40,12 +40,12 @@ static inline cstring_t cstring_from_cstr(const char *s) {
|
||||
while (*p++)
|
||||
len++;
|
||||
|
||||
char *data = (char *)smcc_malloc(len + 1);
|
||||
char *data = (char *)scc_malloc(len + 1);
|
||||
Assert(data != null);
|
||||
smcc_memcpy(data, s, len);
|
||||
scc_memcpy(data, s, len);
|
||||
data[len] = '\0';
|
||||
|
||||
return (cstring_t){.size = len + 1, .cap = len + 1, .data = data};
|
||||
return (scc_cstring_t){.size = len + 1, .cap = len + 1, .data = data};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,12 +53,12 @@ static inline cstring_t cstring_from_cstr(const char *s) {
|
||||
*
|
||||
* @param str 要被释放的字符串指针
|
||||
*/
|
||||
static inline void cstring_free(cstring_t *str) {
|
||||
static inline void scc_cstring_free(scc_cstring_t *str) {
|
||||
if (str == null) {
|
||||
return;
|
||||
}
|
||||
if (str->cap != 0 && str->data != null) {
|
||||
smcc_free(str->data);
|
||||
scc_free(str->data);
|
||||
str->data = null;
|
||||
}
|
||||
str->size = 0;
|
||||
@@ -72,8 +72,8 @@ static inline void cstring_free(cstring_t *str) {
|
||||
* @param data 要追加的 C 字符串指针
|
||||
* @param len 要追加的 C 字符串长度
|
||||
*/
|
||||
static inline void cstring_append_cstr(cstring_t *str, const char *data,
|
||||
usize len) {
|
||||
static inline void scc_cstring_append_cstr(scc_cstring_t *str, const char *data,
|
||||
usize len) {
|
||||
if (str == null || data == null || len == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -96,14 +96,14 @@ static inline void cstring_append_cstr(cstring_t *str, const char *data,
|
||||
// FIXME 处理溢出情况
|
||||
}
|
||||
|
||||
char *new_data = (char *)smcc_realloc(str->data, new_cap);
|
||||
char *new_data = (char *)scc_realloc(str->data, new_cap);
|
||||
Assert(new_data != null);
|
||||
|
||||
str->data = new_data;
|
||||
str->cap = new_cap;
|
||||
}
|
||||
|
||||
smcc_memcpy(str->data + str->size - 1, data, len);
|
||||
scc_memcpy(str->data + str->size - 1, data, len);
|
||||
str->size += len;
|
||||
str->data[str->size - 1] = '\0'; // 保证 C 字符串兼容性
|
||||
}
|
||||
@@ -114,8 +114,9 @@ static inline void cstring_append_cstr(cstring_t *str, const char *data,
|
||||
* @param str 目标动态字符串指针
|
||||
* @param other 要追加的动态字符串指针
|
||||
*/
|
||||
static inline void cstring_append(cstring_t *str, const cstring_t *other) {
|
||||
cstring_append_cstr(str, other->data, other->size - 1);
|
||||
static inline void scc_cstring_append(scc_cstring_t *str,
|
||||
const scc_cstring_t *other) {
|
||||
scc_cstring_append_cstr(str, other->data, other->size - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,8 +125,8 @@ static inline void cstring_append(cstring_t *str, const cstring_t *other) {
|
||||
* @param str 目标动态字符串指针
|
||||
* @param ch 要追加的字符
|
||||
*/
|
||||
static inline void cstring_append_ch(cstring_t *str, char ch) {
|
||||
cstring_append_cstr(str, &ch, 1);
|
||||
static inline void scc_cstring_append_ch(scc_cstring_t *str, char ch) {
|
||||
scc_cstring_append_cstr(str, &ch, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,7 +135,7 @@ static inline void cstring_append_ch(cstring_t *str, char ch) {
|
||||
* @param str 动态字符串指针
|
||||
* @return usize 字符串实际长度
|
||||
*/
|
||||
static inline usize cstring_len(const cstring_t *str) {
|
||||
static inline usize scc_cstring_len(const scc_cstring_t *str) {
|
||||
return str ? str->size - 1 : 0;
|
||||
}
|
||||
|
||||
@@ -144,7 +145,7 @@ static inline usize cstring_len(const cstring_t *str) {
|
||||
* @param str 动态字符串指针
|
||||
* @return cbool
|
||||
*/
|
||||
static inline cbool cstring_is_empty(const cstring_t *str) {
|
||||
static inline cbool scc_cstring_is_empty(const scc_cstring_t *str) {
|
||||
return str == null || str->size == 0;
|
||||
}
|
||||
|
||||
@@ -153,7 +154,7 @@ static inline cbool cstring_is_empty(const cstring_t *str) {
|
||||
*
|
||||
* @param str 动态字符串指针
|
||||
*/
|
||||
static inline void cstring_clear(cstring_t *str) {
|
||||
static inline void scc_cstring_clear(scc_cstring_t *str) {
|
||||
if (str) {
|
||||
str->size = 1;
|
||||
if (str->data) {
|
||||
@@ -168,11 +169,11 @@ static inline void cstring_clear(cstring_t *str) {
|
||||
* @param str 动态字符串指针
|
||||
* @return char* 返回指向内部缓冲区的 C 风格字符串指针
|
||||
*/
|
||||
static inline char *cstring_as_cstr(const cstring_t *str) {
|
||||
static inline char *scc_cstring_as_cstr(const scc_cstring_t *str) {
|
||||
if (str == null || str->data == null) {
|
||||
return "";
|
||||
}
|
||||
return str->data;
|
||||
}
|
||||
|
||||
#endif /* __SMCC_CORE_STR_H__ */
|
||||
#endif /* __SCC_CORE_STR_H__ */
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include "core_mem.h"
|
||||
#include "core_str.h"
|
||||
|
||||
struct core_probe_stream;
|
||||
typedef struct core_probe_stream core_probe_stream_t;
|
||||
struct scc_probe_stream;
|
||||
typedef struct scc_probe_stream scc_probe_stream_t;
|
||||
|
||||
#define core_stream_eof (-1)
|
||||
|
||||
@@ -18,90 +18,90 @@ typedef struct core_probe_stream core_probe_stream_t;
|
||||
* 尾指针只能向前移动,用于查看而不消费。
|
||||
* 头指针可以前进或单次后退,但不能一直后退到尾指针后面。
|
||||
*/
|
||||
struct core_probe_stream {
|
||||
cstring_t name;
|
||||
struct scc_probe_stream {
|
||||
scc_cstring_t name;
|
||||
|
||||
/// @brief 消费头指针处的字符(移动头指针)
|
||||
int (*consume)(core_probe_stream_t *stream);
|
||||
int (*consume)(scc_probe_stream_t *stream);
|
||||
|
||||
/// @brief 查看当前探针位置的字符,不移动任何指针
|
||||
int (*peek)(core_probe_stream_t *stream);
|
||||
int (*peek)(scc_probe_stream_t *stream);
|
||||
|
||||
/// @brief 移动探针位置并返回字符
|
||||
int (*next)(core_probe_stream_t *stream);
|
||||
int (*next)(scc_probe_stream_t *stream);
|
||||
|
||||
/// @brief 移动头指针到探针位置
|
||||
void (*sync)(core_probe_stream_t *stream);
|
||||
void (*sync)(scc_probe_stream_t *stream);
|
||||
|
||||
/// @brief 重置探针位置到头指针位置
|
||||
void (*reset)(core_probe_stream_t *stream);
|
||||
void (*reset)(scc_probe_stream_t *stream);
|
||||
|
||||
/// @brief 回退一个字符(单次后退,头指针后退一步)
|
||||
cbool (*back)(core_probe_stream_t *stream);
|
||||
cbool (*back)(scc_probe_stream_t *stream);
|
||||
|
||||
/// @brief 读取指定数量的字符到缓冲区
|
||||
usize (*read_buf)(core_probe_stream_t *stream, char *buffer, usize count);
|
||||
usize (*read_buf)(scc_probe_stream_t *stream, char *buffer, usize count);
|
||||
|
||||
/// @brief 检查是否到达流末尾
|
||||
cbool (*is_at_end)(core_probe_stream_t *stream);
|
||||
cbool (*is_at_end)(scc_probe_stream_t *stream);
|
||||
|
||||
/// @brief 销毁流并释放资源
|
||||
void (*drop)(core_probe_stream_t *stream);
|
||||
void (*drop)(scc_probe_stream_t *stream);
|
||||
};
|
||||
|
||||
static inline int core_probe_stream_consume(core_probe_stream_t *self) {
|
||||
static inline int scc_probe_stream_consume(scc_probe_stream_t *self) {
|
||||
return self->consume(self);
|
||||
}
|
||||
|
||||
static inline int core_probe_stream_peek(core_probe_stream_t *self) {
|
||||
static inline int scc_probe_stream_peek(scc_probe_stream_t *self) {
|
||||
return self->peek(self);
|
||||
}
|
||||
|
||||
static inline int core_probe_stream_next(core_probe_stream_t *self) {
|
||||
static inline int scc_probe_stream_next(scc_probe_stream_t *self) {
|
||||
return self->next(self);
|
||||
}
|
||||
|
||||
static inline void core_probe_stream_sync(core_probe_stream_t *self) {
|
||||
static inline void scc_probe_stream_sync(scc_probe_stream_t *self) {
|
||||
self->sync(self);
|
||||
}
|
||||
|
||||
static inline cbool core_probe_stream_back(core_probe_stream_t *self) {
|
||||
static inline cbool scc_probe_stream_back(scc_probe_stream_t *self) {
|
||||
return self->back(self);
|
||||
}
|
||||
|
||||
static inline void core_probe_stream_reset(core_probe_stream_t *self) {
|
||||
static inline void scc_probe_stream_reset(scc_probe_stream_t *self) {
|
||||
self->reset(self);
|
||||
}
|
||||
|
||||
static inline usize core_probe_stream_read_buf(core_probe_stream_t *self,
|
||||
char *buffer, usize count) {
|
||||
static inline usize scc_probe_stream_read_buf(scc_probe_stream_t *self,
|
||||
char *buffer, usize count) {
|
||||
return self->read_buf(self, buffer, count);
|
||||
}
|
||||
|
||||
static inline cbool core_probe_stream_is_at_end(core_probe_stream_t *self) {
|
||||
static inline cbool scc_probe_stream_is_at_end(scc_probe_stream_t *self) {
|
||||
return self->is_at_end(self);
|
||||
}
|
||||
|
||||
static inline cbool core_probe_stream_has_more(core_probe_stream_t *self) {
|
||||
static inline cbool scc_probe_stream_has_more(scc_probe_stream_t *self) {
|
||||
return !self->is_at_end(self);
|
||||
}
|
||||
|
||||
static inline void core_probe_stream_drop(core_probe_stream_t *self) {
|
||||
static inline void scc_probe_stream_drop(scc_probe_stream_t *self) {
|
||||
self->drop(self);
|
||||
}
|
||||
|
||||
#ifndef __SMCC_CORE_NO_MEM_PROBE_STREAM__
|
||||
#ifndef __SCC_NO_MEM_PROBE_STREAM__
|
||||
/**
|
||||
* @brief 内存探针流结构
|
||||
*/
|
||||
typedef struct core_mem_probe_stream {
|
||||
core_probe_stream_t stream;
|
||||
typedef struct scc_mem_probe_stream {
|
||||
scc_probe_stream_t stream;
|
||||
const char *data;
|
||||
usize data_length;
|
||||
usize curr_pos; // 当前读取位置
|
||||
usize probe_pos; // 探针位置(用于peek)
|
||||
cbool owned; // 是否拥有数据(需要释放)
|
||||
} core_mem_probe_stream_t;
|
||||
} scc_mem_probe_stream_t;
|
||||
|
||||
/**
|
||||
* @brief 初始化内存探针流
|
||||
@@ -112,9 +112,9 @@ typedef struct core_mem_probe_stream {
|
||||
* @param need_copy 是否需要复制数据
|
||||
* @return core_probe_stream_t* 成功返回流指针,失败返回NULL
|
||||
*/
|
||||
core_probe_stream_t *core_mem_probe_stream_init(core_mem_probe_stream_t *stream,
|
||||
const char *data, usize length,
|
||||
cbool need_copy);
|
||||
scc_probe_stream_t *scc_mem_probe_stream_init(scc_mem_probe_stream_t *stream,
|
||||
const char *data, usize length,
|
||||
cbool need_copy);
|
||||
#endif
|
||||
|
||||
#endif /* __SMCC_CORE_PROBE_STREAM_H__ */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __SMCC_CORE_TYPE_H__
|
||||
#define __SMCC_CORE_TYPE_H__
|
||||
#ifndef __SCC_CORE_TYPE_H__
|
||||
#define __SCC_CORE_TYPE_H__
|
||||
|
||||
#ifndef __SMCC_BUILTIN_TYPE__
|
||||
#ifndef __SCC_BUILTIN_TYPE__
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@@ -32,25 +32,25 @@ typedef bool cbool;
|
||||
static_assert(sizeof(cbool) == 1, "cbool size must 1");
|
||||
|
||||
#else
|
||||
#define __smcc_i8
|
||||
#define __smcc_i16
|
||||
#define __smcc_i32
|
||||
#define __smcc_i64
|
||||
#define __smcc_u8
|
||||
#define __smcc_u16
|
||||
#define __smcc_u32
|
||||
#define __smcc_u64
|
||||
#define __smcc_f32
|
||||
#define __smcc_f64
|
||||
#define __smcc_bool
|
||||
#define __smcc_char
|
||||
#define __smcc_void
|
||||
#define __smcc_null
|
||||
#define __smcc_isize
|
||||
#define __smcc_usize
|
||||
#define __scc_i8
|
||||
#define __scc_i16
|
||||
#define __scc_i32
|
||||
#define __scc_i64
|
||||
#define __scc_u8
|
||||
#define __scc_u16
|
||||
#define __scc_u32
|
||||
#define __scc_u64
|
||||
#define __scc_f32
|
||||
#define __scc_f64
|
||||
#define __scc_bool
|
||||
#define __scc_char
|
||||
#define __scc_void
|
||||
#define __scc_null
|
||||
#define __scc_isize
|
||||
#define __scc_usize
|
||||
#endif
|
||||
|
||||
typedef union core_cvalue {
|
||||
typedef union scc_cvalue {
|
||||
long double ld;
|
||||
double d;
|
||||
float f;
|
||||
@@ -68,6 +68,6 @@ typedef union core_cvalue {
|
||||
|
||||
/* 16 byte == 128 bit */
|
||||
char val[16];
|
||||
} core_cvalue_t;
|
||||
} scc_cvalue_t;
|
||||
|
||||
#endif
|
||||
#endif /* __SCC_CORE_TYPE_H__ */
|
||||
|
||||
@@ -5,19 +5,19 @@
|
||||
* 提供类型安全的动态数组容器实现,支持自动扩容和基本操作
|
||||
*/
|
||||
|
||||
#ifndef __SMCC_CORE_VEC_H__
|
||||
#define __SMCC_CORE_VEC_H__
|
||||
#ifndef __SCC_CORE_VEC_H__
|
||||
#define __SCC_CORE_VEC_H__
|
||||
|
||||
#include "core_impl.h"
|
||||
#include "core_type.h"
|
||||
|
||||
#define __vec_realloc smcc_realloc
|
||||
#define __vec_free smcc_free
|
||||
#define __scc_vec_realloc scc_realloc
|
||||
#define __scc_vec_free scc_free
|
||||
|
||||
/** @defgroup vec_struct 数据结构定义 */
|
||||
|
||||
/**
|
||||
* @def VEC(type)
|
||||
* @def SCC_VEC(type)
|
||||
* @brief 声明向量结构体
|
||||
* @param type 存储的数据类型
|
||||
*
|
||||
@@ -26,10 +26,11 @@
|
||||
* - cap: 数组容量
|
||||
* - data: 存储数组指针
|
||||
* @example
|
||||
* VEC(char) string; <=> char[dynamic_array] string;
|
||||
* struct people { VEC(char) name; int age; VEC(struct people) children; };
|
||||
* SCC_VEC(char) string; <=> char[dynamic_array] string;
|
||||
* struct people { SCC_VEC(char) name; int age; SCC_VEC(struct people) children;
|
||||
* };
|
||||
*/
|
||||
#define VEC(type) \
|
||||
#define SCC_VEC(type) \
|
||||
struct { \
|
||||
usize size; \
|
||||
usize cap; \
|
||||
@@ -39,19 +40,19 @@
|
||||
/** @defgroup vec_operations 动态数组操作宏 */
|
||||
|
||||
/**
|
||||
* @def vec_init(vec)
|
||||
* @def scc_vec_init(vec)
|
||||
* @brief 初始化向量结构体
|
||||
* @param vec 要初始化的向量结构体变量
|
||||
*
|
||||
* @note 此宏不会分配内存,仅做零初始化
|
||||
*/
|
||||
#define vec_init(vec) \
|
||||
#define scc_vec_init(vec) \
|
||||
do { \
|
||||
(vec).size = 0, (vec).cap = 0, (vec).data = 0; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @def vec_push(vec, value)
|
||||
* @def scc_vec_push(vec, value)
|
||||
* @brief 添加元素到向量末尾
|
||||
* @param vec 目标向量结构体
|
||||
* @param value 要添加的值(需匹配存储类型)
|
||||
@@ -59,11 +60,12 @@
|
||||
* @note 当容量不足时自动扩容为2倍(初始容量为4)
|
||||
* @warning 内存分配失败时会触发LOG_FATAL
|
||||
*/
|
||||
#define vec_push(vec, value) \
|
||||
#define scc_vec_push(vec, value) \
|
||||
do { \
|
||||
if ((vec).size >= (vec).cap) { \
|
||||
int cap = (vec).cap ? (vec).cap * 2 : 4; \
|
||||
void *data = __vec_realloc((vec).data, cap * sizeof(*(vec).data)); \
|
||||
void *data = \
|
||||
__scc_vec_realloc((vec).data, cap * sizeof(*(vec).data)); \
|
||||
if (!data) { \
|
||||
LOG_FATAL("vector_push: realloc failed\n"); \
|
||||
} \
|
||||
@@ -75,44 +77,44 @@
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @def vec_pop(vec)
|
||||
* @def scc_vec_pop(vec)
|
||||
* @brief 弹出最后一个元素
|
||||
* @param vec 目标向量结构体
|
||||
* @return 最后元素的引用
|
||||
* @warning 需确保size > 0时使用
|
||||
*/
|
||||
#define vec_pop(vec) ((vec).data[--(vec).size])
|
||||
#define scc_vec_pop(vec) ((vec).data[--(vec).size])
|
||||
|
||||
/**
|
||||
* @def vec_at(vec, idx)
|
||||
* @def scc_vec_at(vec, idx)
|
||||
* @brief 获取指定索引元素
|
||||
* @param vec 目标向量结构体
|
||||
* @param idx 元素索引(0 <= idx < size)
|
||||
* @return 对应元素的引用
|
||||
*/
|
||||
#define vec_at(vec, idx) (((vec).data)[idx])
|
||||
#define scc_vec_at(vec, idx) (((vec).data)[idx])
|
||||
|
||||
/**
|
||||
* @def vec_idx(vec, ptr)
|
||||
* @def scc_vec_idx(vec, ptr)
|
||||
* @brief 获取元素指针对应的索引
|
||||
* @param vec 目标向量结构体
|
||||
* @param ptr 元素指针(需在data数组范围内)
|
||||
* @return 元素索引值
|
||||
*/
|
||||
#define vec_idx(vec, ptr) ((ptr) - (vec).data)
|
||||
#define scc_vec_idx(vec, ptr) ((ptr) - (vec).data)
|
||||
|
||||
/**
|
||||
* @def vec_free(vec)
|
||||
* @def scc_vec_free(vec)
|
||||
* @brief 释放向量内存
|
||||
* @param vec 目标向量结构体
|
||||
*
|
||||
* @note 释放后需重新初始化才能再次使用
|
||||
*/
|
||||
#define vec_free(vec) \
|
||||
#define scc_vec_free(vec) \
|
||||
do { \
|
||||
__vec_free((vec).data); \
|
||||
__scc_vec_free((vec).data); \
|
||||
(vec).data = NULL; \
|
||||
(vec).size = (vec).cap = 0; \
|
||||
} while (0)
|
||||
|
||||
#endif // __SMCC_CORE_VEC_H__
|
||||
#endif /* __SCC_CORE_VEC_H__ */
|
||||
|
||||
@@ -1,29 +1,14 @@
|
||||
#ifndef __SMCC_CORE_H__
|
||||
#define __SMCC_CORE_H__
|
||||
#ifndef __SCC_CORE_H__
|
||||
#define __SCC_CORE_H__
|
||||
|
||||
#include <core_log.h>
|
||||
|
||||
#include <core_impl.h>
|
||||
#include <core_macro.h>
|
||||
#include <core_mem.h>
|
||||
|
||||
#define __SMCC_LOG_NO_STD_IMPL__
|
||||
#ifndef log_snprintf
|
||||
#define log_snprintf smcc_snprintf
|
||||
#endif
|
||||
#ifndef log_printf
|
||||
#define log_printf smcc_eprintf
|
||||
#endif
|
||||
#ifndef log_exit
|
||||
#define log_exit smcc_exit
|
||||
#endif
|
||||
#include <log.h>
|
||||
|
||||
#define _SMCC_STR(str) #str
|
||||
#define SMCC_STR(str) _SMCC_STR(str)
|
||||
|
||||
#define SMCC_ARRLEN(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
#include <core_pos.h>
|
||||
#include <core_str.h>
|
||||
#include <core_stream.h>
|
||||
#include <core_vec.h>
|
||||
|
||||
#endif // __SMCC_CORE_H__
|
||||
#endif // __SCC_CORE_H__
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
#endif
|
||||
|
||||
#include <core_impl.h>
|
||||
#define __SMCC_LOG_IMPORT_SRC__
|
||||
#define log_snprintf smcc_snprintf
|
||||
#define log_printf smcc_printf
|
||||
#define log_exit smcc_exit
|
||||
#define __SCC_LOG_IMPORT_SRC__
|
||||
#define log_snprintf scc_snprintf
|
||||
#define log_printf scc_printf
|
||||
#define log_exit scc_exit
|
||||
#include <log.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -16,77 +17,77 @@
|
||||
|
||||
/* ====== 内存管理核心接口实现 ====== */
|
||||
|
||||
void *smcc_malloc(usize size) { return malloc(size); }
|
||||
void *scc_malloc(usize size) { return malloc(size); }
|
||||
|
||||
void *smcc_calloc(usize count, usize size) { return calloc(count, size); }
|
||||
void *scc_calloc(usize count, usize size) { return calloc(count, size); }
|
||||
|
||||
void *smcc_realloc(void *ptr, usize new_size) { return realloc(ptr, new_size); }
|
||||
void *scc_realloc(void *ptr, usize new_size) { return realloc(ptr, new_size); }
|
||||
|
||||
void smcc_free(void *ptr) { free(ptr); }
|
||||
void scc_free(void *ptr) { free(ptr); }
|
||||
|
||||
/* ====== 文件系统核心接口实现 ====== */
|
||||
|
||||
static const char *get_file_mode_string(smcc_file_mode_t mode) {
|
||||
static const char *get_file_mode_string(scc_fmode_t mode) {
|
||||
switch (mode) {
|
||||
case SMCC_FILE_READ:
|
||||
case SCC_FILE_READ:
|
||||
return "rb";
|
||||
case SMCC_FILE_WRITE:
|
||||
case SCC_FILE_WRITE:
|
||||
return "wb";
|
||||
case SMCC_FILE_APPEND:
|
||||
case SCC_FILE_APPEND:
|
||||
return "ab";
|
||||
default:
|
||||
return "rb";
|
||||
}
|
||||
}
|
||||
|
||||
smcc_file_t smcc_fopen(const char *path, smcc_file_mode_t mode) {
|
||||
scc_file_t scc_fopen(const char *path, scc_fmode_t mode) {
|
||||
const char *mode_str = get_file_mode_string(mode);
|
||||
return (smcc_file_t)fopen(path, mode_str);
|
||||
return (scc_file_t)fopen(path, mode_str);
|
||||
}
|
||||
|
||||
void smcc_fclose(smcc_file_t file) {
|
||||
void scc_fclose(scc_file_t file) {
|
||||
if (file) {
|
||||
fclose((FILE *)file);
|
||||
}
|
||||
}
|
||||
|
||||
usize smcc_fread(smcc_file_t file, void *buffer, usize size) {
|
||||
usize scc_fread(scc_file_t file, void *buffer, usize size) {
|
||||
if (!file || !buffer)
|
||||
return 0;
|
||||
return fread(buffer, 1, size, (FILE *)file);
|
||||
}
|
||||
|
||||
usize smcc_fwrite(smcc_file_t file, const void *buffer, usize size) {
|
||||
usize scc_fwrite(scc_file_t file, const void *buffer, usize size) {
|
||||
if (!file || !buffer)
|
||||
return 0;
|
||||
return fwrite(buffer, 1, size, (FILE *)file);
|
||||
}
|
||||
|
||||
cbool smcc_fexists(const char *path) {
|
||||
smcc_file_t fp = smcc_fopen(path, SMCC_FILE_READ);
|
||||
cbool scc_fexists(const char *path) {
|
||||
scc_file_t fp = scc_fopen(path, SCC_FILE_READ);
|
||||
if (!fp)
|
||||
return false;
|
||||
smcc_fclose(fp);
|
||||
scc_fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ====== 输入输出核心接口实现 ====== */
|
||||
|
||||
void smcc_snprintf(char *buf, usize size, const char *format, ...) {
|
||||
void scc_snprintf(char *buf, usize size, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(buf, size, format, args); // NOLINT
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void smcc_printf(const char *format, ...) {
|
||||
void scc_printf(const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(stdout, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void smcc_eprintf(const char *format, ...) {
|
||||
void scc_eprintf(const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(stderr, format, args);
|
||||
@@ -95,4 +96,4 @@ void smcc_eprintf(const char *format, ...) {
|
||||
|
||||
/* ====== 系统核心接口实现 ====== */
|
||||
|
||||
void smcc_exit(int code) { exit(code); }
|
||||
void scc_exit(int code) { exit(code); }
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <core_mem.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// 判断是否支持非对齐访问(x86/x64 支持)
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || \
|
||||
@@ -9,7 +8,7 @@
|
||||
#define UNALIGNED_ACCESS_ALLOWED 0
|
||||
#endif
|
||||
|
||||
void *smcc_memcpy(void *dest, const void *restrict src, usize n) {
|
||||
void *scc_memcpy(void *dest, const void *restrict src, usize n) {
|
||||
char *d = (char *)dest;
|
||||
const char *s = (const char *)src;
|
||||
|
||||
@@ -74,7 +73,7 @@ void *smcc_memcpy(void *dest, const void *restrict src, usize n) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *smcc_memmove(void *dest, const void *src, usize n) {
|
||||
void *scc_memmove(void *dest, const void *src, usize n) {
|
||||
char *d = (char *)dest;
|
||||
const char *s = (const char *)src;
|
||||
|
||||
@@ -85,7 +84,7 @@ void *smcc_memmove(void *dest, const void *src, usize n) {
|
||||
|
||||
// 内存区域无重叠或前向拷贝
|
||||
if (d < s || d >= s + n) {
|
||||
return smcc_memcpy(d, s, n);
|
||||
return scc_memcpy(d, s, n);
|
||||
} else {
|
||||
// 后向拷贝处理重叠情况
|
||||
d += n;
|
||||
@@ -98,7 +97,7 @@ void *smcc_memmove(void *dest, const void *src, usize n) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *smcc_memset(void *s, int c, usize n) {
|
||||
void *scc_memset(void *s, int c, usize n) {
|
||||
unsigned char *p = (unsigned char *)s;
|
||||
unsigned char byte_val = (unsigned char)c;
|
||||
|
||||
@@ -167,7 +166,7 @@ void *smcc_memset(void *s, int c, usize n) {
|
||||
return s;
|
||||
}
|
||||
|
||||
int smcc_memcmp(const void *s1, const void *s2, usize n) {
|
||||
int scc_memcmp(const void *s1, const void *s2, usize n) {
|
||||
const unsigned char *p1 = (const unsigned char *)s1;
|
||||
const unsigned char *p2 = (const unsigned char *)s2;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <core_log.h>
|
||||
#include <core_stream.h>
|
||||
|
||||
#ifndef __SMCC_CORE_NO_MEM_PROBE_STREAM__
|
||||
#ifndef __SCC_CORE_NO_MEM_PROBE_STREAM__
|
||||
|
||||
static int mem_probe_stream_consume(core_probe_stream_t *_stream) {
|
||||
static int mem_probe_stream_consume(scc_probe_stream_t *_stream) {
|
||||
Assert(_stream != null);
|
||||
core_mem_probe_stream_t *stream = (core_mem_probe_stream_t *)_stream;
|
||||
scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream;
|
||||
|
||||
if (stream->curr_pos >= stream->data_length) {
|
||||
return core_stream_eof;
|
||||
@@ -19,9 +19,9 @@ static int mem_probe_stream_consume(core_probe_stream_t *_stream) {
|
||||
return (int)ch;
|
||||
}
|
||||
|
||||
static int mem_probe_stream_peek(core_probe_stream_t *_stream) {
|
||||
static int mem_probe_stream_peek(scc_probe_stream_t *_stream) {
|
||||
Assert(_stream != null);
|
||||
core_mem_probe_stream_t *stream = (core_mem_probe_stream_t *)_stream;
|
||||
scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream;
|
||||
|
||||
if (stream->probe_pos >= stream->data_length) {
|
||||
return core_stream_eof;
|
||||
@@ -31,9 +31,9 @@ static int mem_probe_stream_peek(core_probe_stream_t *_stream) {
|
||||
return (int)(unsigned char)stream->data[stream->probe_pos];
|
||||
}
|
||||
|
||||
static int mem_probe_stream_next(core_probe_stream_t *_stream) {
|
||||
static int mem_probe_stream_next(scc_probe_stream_t *_stream) {
|
||||
Assert(_stream != null);
|
||||
core_mem_probe_stream_t *stream = (core_mem_probe_stream_t *)_stream;
|
||||
scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream;
|
||||
|
||||
if (stream->probe_pos >= stream->data_length) {
|
||||
return core_stream_eof;
|
||||
@@ -45,9 +45,9 @@ static int mem_probe_stream_next(core_probe_stream_t *_stream) {
|
||||
return ch;
|
||||
}
|
||||
|
||||
static void mem_probe_stream_sync(core_probe_stream_t *_stream) {
|
||||
static void mem_probe_stream_sync(scc_probe_stream_t *_stream) {
|
||||
Assert(_stream != null);
|
||||
core_mem_probe_stream_t *stream = (core_mem_probe_stream_t *)_stream;
|
||||
scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream;
|
||||
|
||||
// 移动头指针到探针位置(消费已查看的字符)
|
||||
if (stream->probe_pos > stream->curr_pos) {
|
||||
@@ -55,9 +55,9 @@ static void mem_probe_stream_sync(core_probe_stream_t *_stream) {
|
||||
}
|
||||
}
|
||||
|
||||
static cbool mem_probe_stream_back(core_probe_stream_t *_stream) {
|
||||
static cbool mem_probe_stream_back(scc_probe_stream_t *_stream) {
|
||||
Assert(_stream != null);
|
||||
core_mem_probe_stream_t *stream = (core_mem_probe_stream_t *)_stream;
|
||||
scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream;
|
||||
|
||||
// 只能回退一个字符,且不能回退到探针位置之前
|
||||
if (stream->curr_pos == 0 || stream->curr_pos <= stream->probe_pos) {
|
||||
@@ -68,10 +68,10 @@ static cbool mem_probe_stream_back(core_probe_stream_t *_stream) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static usize mem_probe_stream_read_buf(core_probe_stream_t *_stream,
|
||||
static usize mem_probe_stream_read_buf(scc_probe_stream_t *_stream,
|
||||
char *buffer, usize count) {
|
||||
Assert(_stream != null);
|
||||
core_mem_probe_stream_t *stream = (core_mem_probe_stream_t *)_stream;
|
||||
scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream;
|
||||
|
||||
if (buffer == null) {
|
||||
LOG_WARN("Buffer is null");
|
||||
@@ -82,7 +82,7 @@ static usize mem_probe_stream_read_buf(core_probe_stream_t *_stream,
|
||||
usize to_read = (remaining < count) ? remaining : count;
|
||||
|
||||
if (to_read > 0) {
|
||||
smcc_memcpy(buffer, stream->data + stream->curr_pos, to_read);
|
||||
scc_memcpy(buffer, stream->data + stream->curr_pos, to_read);
|
||||
stream->curr_pos += to_read;
|
||||
// 更新探针位置
|
||||
if (stream->probe_pos < stream->curr_pos) {
|
||||
@@ -96,36 +96,36 @@ static usize mem_probe_stream_read_buf(core_probe_stream_t *_stream,
|
||||
return to_read;
|
||||
}
|
||||
|
||||
static void mem_probe_stream_reset(core_probe_stream_t *_stream) {
|
||||
static void mem_probe_stream_reset(scc_probe_stream_t *_stream) {
|
||||
Assert(_stream != null);
|
||||
core_mem_probe_stream_t *stream = (core_mem_probe_stream_t *)_stream;
|
||||
scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream;
|
||||
|
||||
// 重置探针位置到头指针位置
|
||||
stream->probe_pos = stream->curr_pos;
|
||||
}
|
||||
|
||||
static cbool mem_probe_stream_is_at_end(core_probe_stream_t *_stream) {
|
||||
static cbool mem_probe_stream_is_at_end(scc_probe_stream_t *_stream) {
|
||||
Assert(_stream != null);
|
||||
core_mem_probe_stream_t *stream = (core_mem_probe_stream_t *)_stream;
|
||||
scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream;
|
||||
|
||||
return stream->curr_pos >= stream->data_length;
|
||||
}
|
||||
|
||||
static void mem_probe_stream_destroy(core_probe_stream_t *_stream) {
|
||||
static void mem_probe_stream_destroy(scc_probe_stream_t *_stream) {
|
||||
Assert(_stream != null);
|
||||
core_mem_probe_stream_t *stream = (core_mem_probe_stream_t *)_stream;
|
||||
scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream;
|
||||
|
||||
cstring_free(&stream->stream.name);
|
||||
scc_cstring_free(&stream->stream.name);
|
||||
|
||||
if (stream->owned) {
|
||||
smcc_free((void *)stream->data);
|
||||
scc_free((void *)stream->data);
|
||||
stream->data = null;
|
||||
}
|
||||
}
|
||||
|
||||
core_probe_stream_t *core_mem_probe_stream_init(core_mem_probe_stream_t *stream,
|
||||
const char *data, usize length,
|
||||
cbool need_copy) {
|
||||
scc_probe_stream_t *scc_mem_probe_stream_init(scc_mem_probe_stream_t *stream,
|
||||
const char *data, usize length,
|
||||
cbool need_copy) {
|
||||
if (stream == null || data == null) {
|
||||
LOG_ERROR("param error");
|
||||
return null;
|
||||
@@ -138,13 +138,13 @@ core_probe_stream_t *core_mem_probe_stream_init(core_mem_probe_stream_t *stream,
|
||||
|
||||
stream->owned = need_copy;
|
||||
if (need_copy) {
|
||||
char *buf = (char *)smcc_malloc(length);
|
||||
char *buf = (char *)scc_malloc(length);
|
||||
if (buf == null) {
|
||||
LOG_ERROR("malloc error");
|
||||
return null;
|
||||
}
|
||||
|
||||
smcc_memcpy(buf, data, length);
|
||||
scc_memcpy(buf, data, length);
|
||||
stream->data = buf;
|
||||
} else {
|
||||
stream->data = data;
|
||||
@@ -153,7 +153,7 @@ core_probe_stream_t *core_mem_probe_stream_init(core_mem_probe_stream_t *stream,
|
||||
stream->curr_pos = 0;
|
||||
stream->probe_pos = 0;
|
||||
|
||||
stream->stream.name = cstring_from_cstr("mem_probe_stream");
|
||||
stream->stream.name = scc_cstring_from_cstr("mem_probe_stream");
|
||||
|
||||
// 设置函数指针
|
||||
stream->stream.consume = mem_probe_stream_consume;
|
||||
@@ -166,7 +166,7 @@ core_probe_stream_t *core_mem_probe_stream_init(core_mem_probe_stream_t *stream,
|
||||
stream->stream.is_at_end = mem_probe_stream_is_at_end;
|
||||
stream->stream.drop = mem_probe_stream_destroy;
|
||||
|
||||
return (core_probe_stream_t *)stream;
|
||||
return (scc_probe_stream_t *)stream;
|
||||
}
|
||||
|
||||
#endif /* __SMCC_CORE_NO_MEM_PROBE_STREAM__ */
|
||||
#endif /* __SCC_CORE_NO_MEM_PROBE_STREAM__ */
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* 提供基于向量容器的哈希表实现,支持动态扩容和墓碑机制
|
||||
*/
|
||||
|
||||
#ifndef __SMCC_HASHMAP_H__
|
||||
#define __SMCC_HASHMAP_H__
|
||||
#ifndef __SCC_HASHMAP_H__
|
||||
#define __SCC_HASHMAP_H__
|
||||
|
||||
#include <libcore.h>
|
||||
|
||||
@@ -40,9 +40,9 @@ typedef struct hashmap_entry {
|
||||
* 使用开放寻址法实现,采用墓碑标记处理删除操作
|
||||
*/
|
||||
typedef struct smcc_hashmap {
|
||||
VEC(hashmap_entry_t) entries; /**< 条目存储容器 */
|
||||
u32 count; /**< 有效条目数量(不含墓碑) */
|
||||
u32 tombstone_count; /**< 墓碑条目数量 */
|
||||
SCC_VEC(hashmap_entry_t) entries; /**< 条目存储容器 */
|
||||
u32 count; /**< 有效条目数量(不含墓碑) */
|
||||
u32 tombstone_count; /**< 墓碑条目数量 */
|
||||
/**
|
||||
* @brief 哈希函数指针
|
||||
* @param key 键指针
|
||||
@@ -119,4 +119,4 @@ typedef int (*hashmap_iter_fn)(const void *key, void *value, void *context);
|
||||
*/
|
||||
void hashmap_foreach(hashmap_t *ht, hashmap_iter_fn iter_func, void *context);
|
||||
|
||||
#endif // __SMCC_HASHMAP_H__
|
||||
#endif /* __SCC_HASHMAP_H__ */
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* 提供字符串驻留(String Interning)功能,保证相同字符串的唯一性存储
|
||||
*/
|
||||
|
||||
#ifndef __SMCC_STRPOOL_H__
|
||||
#define __SMCC_STRPOOL_H__
|
||||
#ifndef __SCC_STRPOOL_H__
|
||||
#define __SCC_STRPOOL_H__
|
||||
|
||||
#include "hashmap.h"
|
||||
#include <libcore.h>
|
||||
@@ -47,4 +47,4 @@ const char *strpool_intern(strpool_t *pool, const char *str);
|
||||
*/
|
||||
void strpool_destroy(strpool_t *pool);
|
||||
|
||||
#endif // __SMCC_STRPOOL_H__
|
||||
#endif /* __SCC_STRPOOL_H__ */
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <hashmap.h>
|
||||
|
||||
#ifndef SMCC_INIT_HASHMAP_SIZE
|
||||
#define SMCC_INIT_HASHMAP_SIZE (32)
|
||||
#ifndef SCC_INIT_HASHMAP_SIZE
|
||||
#define SCC_INIT_HASHMAP_SIZE (32)
|
||||
#endif
|
||||
|
||||
void hashmap_init(hashmap_t *ht) {
|
||||
vec_init(ht->entries);
|
||||
scc_vec_init(ht->entries);
|
||||
ht->count = 0;
|
||||
ht->tombstone_count = 0;
|
||||
Assert(ht->key_cmp != NULL && ht->hash_func != NULL);
|
||||
@@ -31,7 +31,7 @@ static hashmap_entry_t *find_entry(hashmap_t *ht, const void *key, u32 hash) {
|
||||
hashmap_entry_t *tombstone = NULL;
|
||||
|
||||
while (1) {
|
||||
hashmap_entry_t *entry = &vec_at(ht->entries, index);
|
||||
hashmap_entry_t *entry = &scc_vec_at(ht->entries, index);
|
||||
if (entry->state == ENTRY_EMPTY) {
|
||||
return tombstone ? tombstone : entry;
|
||||
}
|
||||
@@ -57,33 +57,33 @@ static void adjust_capacity(hashmap_t *ht, int new_cap) {
|
||||
new_cap = next_power_of_two(new_cap);
|
||||
Assert(new_cap >= ht->entries.cap);
|
||||
|
||||
VEC(hashmap_entry_t) old_entries;
|
||||
SCC_VEC(hashmap_entry_t) old_entries;
|
||||
old_entries.data = ht->entries.data;
|
||||
old_entries.cap = ht->entries.cap;
|
||||
|
||||
// Not used size but for gdb python extention debug
|
||||
ht->entries.size = new_cap;
|
||||
ht->entries.cap = new_cap;
|
||||
ht->entries.data = smcc_realloc(NULL, new_cap * sizeof(hashmap_entry_t));
|
||||
smcc_memset(ht->entries.data, 0, new_cap * sizeof(hashmap_entry_t));
|
||||
ht->entries.data = scc_realloc(NULL, new_cap * sizeof(hashmap_entry_t));
|
||||
scc_memset(ht->entries.data, 0, new_cap * sizeof(hashmap_entry_t));
|
||||
|
||||
// rehash the all of the old data
|
||||
for (usize i = 0; i < old_entries.cap; i++) {
|
||||
hashmap_entry_t *entry = &vec_at(old_entries, i);
|
||||
hashmap_entry_t *entry = &scc_vec_at(old_entries, i);
|
||||
if (entry->state == ENTRY_ACTIVE) {
|
||||
hashmap_entry_t *dest = find_entry(ht, entry->key, entry->hash);
|
||||
*dest = *entry;
|
||||
}
|
||||
}
|
||||
|
||||
vec_free(old_entries);
|
||||
scc_vec_free(old_entries);
|
||||
ht->tombstone_count = 0;
|
||||
}
|
||||
|
||||
void *hashmap_set(hashmap_t *ht, const void *key, void *value) {
|
||||
if (ht->count + ht->tombstone_count >= ht->entries.cap * 0.75) {
|
||||
int new_cap = ht->entries.cap < SMCC_INIT_HASHMAP_SIZE
|
||||
? SMCC_INIT_HASHMAP_SIZE
|
||||
int new_cap = ht->entries.cap < SCC_INIT_HASHMAP_SIZE
|
||||
? SCC_INIT_HASHMAP_SIZE
|
||||
: ht->entries.cap * 2;
|
||||
adjust_capacity(ht, new_cap);
|
||||
}
|
||||
@@ -134,14 +134,14 @@ void *hashmap_del(hashmap_t *ht, const void *key) {
|
||||
}
|
||||
|
||||
void hashmap_drop(hashmap_t *ht) {
|
||||
vec_free(ht->entries);
|
||||
scc_vec_free(ht->entries);
|
||||
ht->count = 0;
|
||||
ht->tombstone_count = 0;
|
||||
}
|
||||
|
||||
void hashmap_foreach(hashmap_t *ht, hashmap_iter_fn iter_func, void *context) {
|
||||
for (usize i = 0; i < ht->entries.cap; i++) {
|
||||
hashmap_entry_t *entry = &vec_at(ht->entries, i);
|
||||
hashmap_entry_t *entry = &scc_vec_at(ht->entries, i);
|
||||
if (entry->state == ENTRY_ACTIVE) {
|
||||
if (!iter_func(entry->key, entry->value, context)) {
|
||||
break; // enable callback function terminal the iter
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "strpool.h"
|
||||
|
||||
void init_strpool(strpool_t *pool) {
|
||||
pool->ht.hash_func = (u32 (*)(const void *))smcc_strhash32;
|
||||
pool->ht.key_cmp = (int (*)(const void *, const void *))smcc_strcmp;
|
||||
pool->ht.hash_func = (u32 (*)(const void *))scc_strhash32;
|
||||
pool->ht.key_cmp = (int (*)(const void *, const void *))scc_strcmp;
|
||||
hashmap_init(&pool->ht);
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ const char *strpool_intern(strpool_t *pool, const char *str) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
usize len = smcc_strlen(str) + 1;
|
||||
char *new_str = smcc_malloc(len);
|
||||
usize len = scc_strlen(str) + 1;
|
||||
char *new_str = scc_malloc(len);
|
||||
if (!new_str) {
|
||||
LOG_ERROR("strpool: Failed to allocate memory for string");
|
||||
return NULL;
|
||||
}
|
||||
smcc_memcpy(new_str, str, len);
|
||||
scc_memcpy(new_str, str, len);
|
||||
|
||||
hashmap_set(&pool->ht, new_str, new_str);
|
||||
return new_str;
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* 提供跨平台的终端文本颜色和样式控制支持
|
||||
*/
|
||||
|
||||
#ifndef __SMCC_TERMINAL_COLOR_H__
|
||||
#define __SMCC_TERMINAL_COLOR_H__
|
||||
#ifndef __SCC_TERMINAL_COLOR_H__
|
||||
#define __SCC_TERMINAL_COLOR_H__
|
||||
|
||||
/* clang-format off */
|
||||
/// @name 前景色控制码
|
||||
@@ -58,4 +58,4 @@
|
||||
#define ANSI_FMT(str, fmt) str ///< 禁用样式输出
|
||||
#endif
|
||||
|
||||
#endif // __SMCC_TERMINAL_COLOR_H__
|
||||
#endif /* __SCC_TERMINAL_COLOR_H__ */
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
* @brief 日志系统核心模块(支持多级日志、断言和异常处理)
|
||||
*/
|
||||
|
||||
#ifndef __SMCC_LOG_H__
|
||||
#define __SMCC_LOG_H__
|
||||
#ifndef __SCC_LOG_H__
|
||||
#define __SCC_LOG_H__
|
||||
|
||||
#include "color.h"
|
||||
|
||||
#ifdef __SMCC_LOG_USE_STD_IMPL__
|
||||
#ifdef __SCC_LOG_USE_STD_IMPL__
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define log_snprintf snprintf
|
||||
@@ -206,8 +206,8 @@ void logger_destroy(logger_t *logger);
|
||||
PanicFmt("FIXME " __LOG_STR(str)) ///< 提醒开发者修改代码(触发致命错误)
|
||||
/// @}
|
||||
|
||||
#ifdef __SMCC_LOG_IMPORT_SRC__
|
||||
#ifdef __SCC_LOG_IMPORT_SRC__
|
||||
#include "log.c"
|
||||
#endif
|
||||
|
||||
#endif // __SMCC_LOG_H__
|
||||
#endif /* __SCC_LOG_H__ */
|
||||
|
||||
Reference in New Issue
Block a user