summaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/parse.c b/parse.c
index 2aa3da0..f49d9a0 100644
--- a/parse.c
+++ b/parse.c
@@ -1090,6 +1090,9 @@ static Status ctype_to_type(Allocator *a, CType *ctype, Type *type, Location whe
case CTYPE_UNSIGNED_LONG:
size = sizeof(long);
break;
+ case CTYPE_SIZE_T:
+ size = sizeof(size_t);
+ break;
case CTYPE_LONGLONG:
case CTYPE_UNSIGNED_LONGLONG:
#if HAVE_LONGLONG
@@ -1113,7 +1116,7 @@ static Status ctype_to_type(Allocator *a, CType *ctype, Type *type, Location whe
case CTYPE_UNSIGNED: assert(0); break;
}
if (size != 0) {
- type->builtin = ((ctype->kind & CTYPE_UNSIGNED) ? uint_with_size : int_with_size)(size);
+ type->builtin = (((ctype->kind & CTYPE_UNSIGNED) || ctype->kind == CTYPE_SIZE_T) ? uint_with_size : int_with_size)(size);
if (type->builtin == BUILTIN_F32) {
err_print(where, "This C type is not representable by a toc type, because it is %lu bytes (not 1, 2, 4, or 8).", size);
return false;
@@ -1130,38 +1133,50 @@ static Status parse_c_type(Parser *p, CType *ctype, Type *type) {
if (token_is_kw(t->token, KW_INT)) {
ctype->kind = CTYPE_INT;
++t->token;
+ } else if (token_is_kw(t->token, KW_FLOAT)) {
+ ctype->kind = CTYPE_FLOAT;
+ ++t->token;
+ } else if (token_is_kw(t->token, KW_CHAR)) {
+ ctype->kind = CTYPE_CHAR;
+ ++t->token;
} else if (token_is_kw(t->token, KW_AMPERSAND)) {
ctype->kind = CTYPE_PTR;
++t->token;
- if (t->token->kind != TOKEN_IDENT) {
+ if (t->token->kind == TOKEN_IDENT) {
+ size_t n = ident_str_len(t->token->ident);
+ ctype->points_to = parser_malloc(p, n+1);
+ memcpy(ctype->points_to, t->token->ident, n);
+ ctype->points_to[n] = 0;
+ } else if (t->token->kind == TOKEN_LITERAL_STR) {
+ size_t n = t->token->str.len;
+ ctype->points_to = parser_malloc(p, n+1);
+ memcpy(ctype->points_to, t->token->str.str, n);
+ ctype->points_to[n] = 0;
+ } else {
tokr_err(t, "Expected type to follow &");
return false;
}
- ctype->points_to = t->token->ident;
+
++t->token;
} else if (t->token->kind == TOKEN_IDENT) {
char *id = t->token->ident;
- CTypeKind kind = 0;
- if (ident_str_len(id) > 9 && strncmp(id, "unsigned_", 9)) {
- kind |= CTYPE_UNSIGNED;
+ ctype->kind = 0;
+ if (ident_str_len(id) > 9 && strncmp(id, "unsigned_", 9) == 0) {
+ ctype->kind |= CTYPE_UNSIGNED;
id += 9;
}
- if (ident_str_eq_str(id, "char"))
- ctype->kind |= CTYPE_CHAR;
- else if (ident_str_eq_str(id, "signed_char"))
+ if (ident_str_eq_str(id, "signed_char"))
ctype->kind = CTYPE_SIGNED_CHAR;
else if (ident_str_eq_str(id, "short"))
ctype->kind |= CTYPE_SHORT;
- else if (ident_str_eq_str(id, "int"))
- ctype->kind |= CTYPE_INT;
else if (ident_str_eq_str(id, "long"))
ctype->kind |= CTYPE_LONG;
else if (ident_str_eq_str(id, "long_long"))
- ctype->kind |= CTYPE_CHAR;
- else if (ident_str_eq_str(id, "float"))
- ctype->kind = CTYPE_FLOAT;
+ ctype->kind |= CTYPE_LONGLONG;
else if (ident_str_eq_str(id, "double"))
ctype->kind = CTYPE_DOUBLE;
+ else if (ident_str_eq_str(id, "size_t"))
+ ctype->kind = CTYPE_SIZE_T;
else if (ident_str_eq_str(id, "long_double")) {
tokr_err(t, "long double is not supported for #foreign functions.");
return false;
@@ -1174,6 +1189,7 @@ static Status parse_c_type(Parser *p, CType *ctype, Type *type) {
tokr_err(t, "Unrecognized C type.");
return false;
}
+ assert(ctype->kind != CTYPE_NONE && ctype->kind != CTYPE_UNSIGNED);
if (!ctype_to_type(p->allocr, ctype, type, token_location(p->file, t->token)))
return false;
} else {
@@ -1882,6 +1898,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
++t->token;
if (!token_is_kw(t->token, KW_LPAREN)) {
tokr_err(t, "Expected ( after #foreign fn");
+ return false;
}
++t->token;
while (!token_is_kw(t->token, KW_RPAREN)) {