aboutsummaryrefslogtreecommitdiffhomepage
path: root/main.c
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-05-04 14:29:07 +0900
committernsfisis <nsfisis@gmail.com>2025-05-04 14:29:07 +0900
commit298977906d005ec026778286591f5843406291b7 (patch)
tree064de1d23fe0ffdb5d69403bf5fe8bdbe09bcadf /main.c
parent9a35c86da5a81d9e83f7729f1ada8a5bf5934014 (diff)
downloadP4Dcc-298977906d005ec026778286591f5843406291b7.tar.gz
P4Dcc-298977906d005ec026778286591f5843406291b7.tar.zst
P4Dcc-298977906d005ec026778286591f5843406291b7.zip
support pointer types
Diffstat (limited to 'main.c')
-rw-r--r--main.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/main.c b/main.c
index c90c71b..0adbedf 100644
--- a/main.c
+++ b/main.c
@@ -230,6 +230,8 @@ TOKEN* tokenize(char* src, int len) {
tok->kind = TK_K_SIZEOF;
} else if (strstr(src + start, "struct") == src + start) {
tok->kind = TK_K_STRUCT;
+ } else if (strstr(src + start, "void") == src + start) {
+ tok->kind = TK_K_VOID;
} else {
tok->kind = TK_IDENT;
tok->value = calloc(pos - start + 1, sizeof(char));
@@ -251,12 +253,12 @@ TOKEN* tokenize(char* src, int len) {
#define TY_INT 2
#define TY_LONG 3
#define TY_VOID 4
-#define TY_STRUCT 5
-#define TY_ARR 6
-#define TY_PTR 7
+#define TY_PTR 5
+#define TY_STRUCT 6
typedef struct Type {
int kind;
+ struct Type* to;
} TYPE;
TYPE* type_new(int kind) {
@@ -265,6 +267,17 @@ TYPE* type_new(int kind) {
return ty;
}
+TYPE* type_new_ptr(TYPE* to) {
+ TYPE* ty = calloc(1, sizeof(TYPE));
+ ty->kind = TY_PTR;
+ ty->to = to;
+ return ty;
+}
+
+int type_is_valid_for_var(TYPE* ty) {
+ return ty->kind != TY_VOID;
+}
+
#define AST_UNKNOWN 0
#define AST_ARG_LIST 1
@@ -668,11 +681,23 @@ TYPE* parse_type(PARSER* p) {
} else if (t->kind == TK_K_VOID) {
ty->kind = TY_VOID;
}
+ while (1) {
+ TOKEN* t2 = peek_token(p);
+ if (t2->kind == TK_STAR) {
+ next_token(p);
+ ty = type_new_ptr(ty);
+ } else {
+ break;
+ }
+ }
return ty;
}
AST* parse_var_decl(PARSER* p) {
TYPE* ty = parse_type(p);
+ if (!type_is_valid_for_var(ty)) {
+ fatal_error("parse_var_decl: invalid type for variable");
+ }
char* name = parse_ident(p);
AST* decl = ast_new(AST_VAR_DECL);
expect(p, TK_SEMICOLON);
@@ -747,6 +772,9 @@ void parse_register_params(PARSER* p, AST* params) {
AST* parse_param(PARSER* p) {
TYPE* ty = parse_type(p);
+ if (!type_is_valid_for_var(ty)) {
+ fatal_error("parse_param: invalid type for variable");
+ }
char* name = parse_ident(p);
AST* param = ast_new(AST_PARAM);
param->ty = ty;