From e97820d7efd85b41443b22f73c9ed75971073edd Mon Sep 17 00:00:00 2001 From: Yaossg Date: Sun, 17 Nov 2024 17:01:18 +0800 Subject: [PATCH] more const --- README.md | 6 ++-- boot.c | 104 +++++++++++++++++++++++++----------------------------- 2 files changed, 52 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 649122e..4a85ce8 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ $ sh boot.sh ### 关键字 -本语言包含的关键字即为支持的标量类型的关键字和流程控制的关键字。 +本语言包含的关键字即为支持的标量类型的关键字和流程控制的关键字,还有 `const`。 -此外还支持 `const` 关键字,但是行为是直接忽略。这是为了更好兼容 C 程序。 +`const` 关键字可以在类型中使用,但会被直接忽略。支持它是为了更好兼容 C 程序。 ### 支持六个基本类型 @@ -111,6 +111,8 @@ $ sh boot.sh 目前源代码中的常数能够保证自举。 +如果愿意,完全可以把程序中的各类表改为 `malloc` 和 `free` 动态管理,本语言是完全支持的。 + ## 依赖 直接依赖下面这些 C 语言库函数,在本语言中提供声明后调用。 diff --git a/boot.c b/boot.c index 8225237..f19f1b2 100644 --- a/boot.c +++ b/boot.c @@ -55,21 +55,32 @@ const int TOKEN_BRACKET_RIGHT = 53; const int TOKEN_BRACE_LEFT = 54; const int TOKEN_BRACE_RIGHT = 55; +const int TOKEN_STRING = 99; const int TOKEN_NUMBER = 100; const int TOKEN_ID = 101; -const int TOKEN_INT = 102; -const int TOKEN_IF = 103; -const int TOKEN_ELSE = 104; -const int TOKEN_WHILE = 105; -const int TOKEN_BREAK = 106; -const int TOKEN_CONTINUE = 107; -const int TOKEN_RETURN = 108; -const int TOKEN_VOID = 109; -const int TOKEN_CONST = 110; -const int TOKEN_CHAR = 111; -const int TOKEN_FOR = 112; -const int TOKEN_DO = 113; -const int TOKEN_STRING = 150; +const int TOKEN_IF = 102; +const int TOKEN_ELSE = 103; +const int TOKEN_WHILE = 104; +const int TOKEN_FOR = 105; +const int TOKEN_DO = 106; +const int TOKEN_BREAK = 107; +const int TOKEN_CONTINUE = 108; +const int TOKEN_RETURN = 109; + +const int TOKEN_CONST = 127; +const int TOKEN_VOID = 128; +const int TOKEN_INT = 129; +const int TOKEN_CHAR = 130; + +const int TYPE_VOID = 0; +const int TYPE_INT = 1; +const int TYPE_CHAR = 2; +const int TYPE_VOID_PTR = 16; +const int TYPE_INT_PTR = 17; +const int TYPE_CHAR_PTR = 18; + +const int TYPE_PTR_MASK = 16; +const int TYPE_TOKEN_MASK = 128; int parse_int(int ch) { int num = ch - '0'; @@ -390,39 +401,24 @@ void expect_token(int expected_type) { } } -const int TYPE_VOID = 0; -const int TYPE_INT = 1; -const int TYPE_CHAR = 2; -const int TYPE_VOID_PTR = 16; -const int TYPE_INT_PTR = 17; -const int TYPE_CHAR_PTR = 18; -const int TYPE_PTR_MASK = 16; - -int parse_type() { +void ignore_const() { if (token_type == TOKEN_CONST) { next_token(); } - if (token_type == TOKEN_INT) { +} + +int parse_type() { + ignore_const(); + if (token_type == TOKEN_INT || token_type == TOKEN_CHAR || token_type == TOKEN_VOID) { + int type = token_type & ~TYPE_TOKEN_MASK; next_token(); + ignore_const(); if (token_type == TOKEN_STAR) { - return TYPE_INT_PTR; + ignore_const(); + return type | TYPE_PTR_MASK; } unget_token(); - return TYPE_INT; - } else if (token_type == TOKEN_CHAR) { - next_token(); - if (token_type == TOKEN_STAR) { - return TYPE_CHAR_PTR; - } - unget_token(); - return TYPE_CHAR; - } else if (token_type == TOKEN_VOID) { - next_token(); - if (token_type == TOKEN_STAR) { - return TYPE_VOID_PTR; - } - unget_token(); - return TYPE_VOID; + return type; } else { return -1; } @@ -553,8 +549,7 @@ void load(int rd, int id) { const char* op = "lw"; // int if (type == TYPE_CHAR) { op = "lb"; - } - if (type & TYPE_PTR_MASK) { + } else if (type & TYPE_PTR_MASK) { op = "ld"; } printf(" %s t%d, 0(t%d) # id: type %d\n", op, rd, rd, type); @@ -566,8 +561,7 @@ void store_t0(int id) { const char* op = "sw"; // int if (type == TYPE_CHAR) { op = "sb"; - } - if (type & TYPE_PTR_MASK) { + } else if (type & TYPE_PTR_MASK) { op = "sd"; } printf(" %s t0, 0(t1) # id: type %d\n", op, type); @@ -1356,7 +1350,12 @@ void parse_global_variable(int id, const char* name, int type) { expect_token(TOKEN_SEMICOLON); } -void parse_decl(int type) { +void parse_global_declaration() { + int type = parse_type(); + if (type < 0) { + eprintf("unexpected token: %d\n", token_type); + exit(1); + } expect_token(TOKEN_ID); int id = token_data; char* name = id_table + id_lut[id]; @@ -1372,15 +1371,9 @@ void parse_decl(int type) { void parse_top_level() { next_token(); - int decl_type; - if (token_type == TOKEN_EOF) { + if (token_type == TOKEN_EOF) return; - } else if ((decl_type = parse_type()) >= 0) { - parse_decl(decl_type); - } else { - eprintf("unexpected token: %d\n", token_type); - exit(1); - } + parse_global_declaration(); parse_top_level(); } @@ -1388,9 +1381,9 @@ void dump_string_table() { printf(".data\n"); for (int i = 0; i < string_lut_size; ++i) { printf(".LC%d: .string \"", i); - int offset = 0; - int ch; - while ((ch = string_table[string_lut[i] + offset]) != 0) { + int offset = string_lut[i]; + int ch; + while ((ch = string_table[offset++]) != 0) { if (ch == '\n') { printf("\\n"); } else if (ch == '\t') { @@ -1408,7 +1401,6 @@ void dump_string_table() { } else { printf("%c", ch); } - offset++; } printf("\"\n"); }