From 870cf8f0b41251b59e602cabb236749155f40d4a Mon Sep 17 00:00:00 2001 From: Lorenzo Torres Date: Fri, 16 Jan 2026 23:26:28 +0100 Subject: [PATCH] codegen almost finished --- codegen.c | 430 +++++++++++++++++++++++++++++++++++++++++++------ done.txt | 0 parser.c | 47 +++++- parser.h | 1 + report.txt | 0 sema.c | 90 ++++++++++- test | Bin 20192 -> 0 bytes test.l | 22 ++- test.s | 20 --- test_control | Bin 21712 -> 0 bytes test_control.l | 23 --- test_simple | Bin 21712 -> 0 bytes test_simple.l | 13 -- todo.cfg | 2 - todo.txt | 1 - 15 files changed, 523 insertions(+), 126 deletions(-) delete mode 100644 done.txt delete mode 100644 report.txt delete mode 100755 test delete mode 100644 test.s delete mode 100755 test_control delete mode 100644 test_control.l delete mode 100755 test_simple delete mode 100644 test_simple.l delete mode 100644 todo.cfg delete mode 100644 todo.txt diff --git a/codegen.c b/codegen.c index 7220d49..552bb77 100644 --- a/codegen.c +++ b/codegen.c @@ -447,72 +447,240 @@ void gen_expr(FILE *fp, ast_node *expr) gen_expr(fp, expr->expr.cast.value); break; case NODE_VAR_DECL: { - int offset; - if (expr->expr.var_decl.type && expr->expr.var_decl.type->expr_type) { - usize var_size = expr->expr.var_decl.type->expr_type->size; - offset = get_var_offset_sized(expr->expr.var_decl.name, - expr->expr.var_decl.name_len, var_size); - } else { - offset = get_var_offset(expr->expr.var_decl.name, expr->expr.var_decl.name_len); + int offset = 0; + type *var_type = expr->expr_type; + if (!var_type && expr->expr.var_decl.type) { + var_type = expr->expr.var_decl.type->expr_type; + } + + bool is_inline_slice = false; + if (var_type && var_type->tag == TYPE_SLICE && expr->expr.var_decl.value && + (expr->expr.var_decl.value->type == NODE_STRUCT_INIT || + expr->expr.var_decl.value->type == NODE_RANGE)) { + is_inline_slice = true; + } + + if (!is_inline_slice) { + if (var_type && var_type->size > 0) { + offset = get_var_offset_sized(expr->expr.var_decl.name, + expr->expr.var_decl.name_len, var_type->size); + } else { + offset = get_var_offset(expr->expr.var_decl.name, expr->expr.var_decl.name_len); + } } if (expr->expr.var_decl.value) { - if (expr->expr.var_decl.value->type == NODE_STRUCT_INIT) { + if (expr->expr.var_decl.value->type == NODE_RANGE && var_type && var_type->tag == TYPE_SLICE) { + ast_node *range = expr->expr.var_decl.value; + if (range->expr.binary.left->type == NODE_INTEGER && + range->expr.binary.right->type == NODE_INTEGER) { + i64 start = range->expr.binary.left->expr.integer; + i64 end = range->expr.binary.right->expr.integer; + i64 count = end - start + 1; + + type *element_type = var_type->data.slice.child; + usize element_size = element_type ? element_type->size : 8; + + usize data_size = count * element_size; + usize aligned_data_size = (data_size + 7) & ~7; + stack_offset += aligned_data_size; + int data_offset = stack_offset; + + stack_offset += 16; + offset = stack_offset; + + char *var_name = strndup(expr->expr.var_decl.name, expr->expr.var_decl.name_len); + shput(variables, var_name, offset); + + for (i64 i = 0; i < count; i++) { + i64 value = start + i; + int element_offset = data_offset - (i * element_size); + fprintf(fp, "mov $%ld, %%rax\n", value); + if (element_size == 4) { + fprintf(fp, "mov %%eax, -%d(%%rbp)\n", element_offset); + } else if (element_size == 2) { + fprintf(fp, "mov %%ax, -%d(%%rbp)\n", element_offset); + } else if (element_size == 1) { + fprintf(fp, "mov %%al, -%d(%%rbp)\n", element_offset); + } else { + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", element_offset); + } + } + + fprintf(fp, "lea -%d(%%rbp), %%rax\n", data_offset); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset); + fprintf(fp, "mov $%ld, %%rax\n", count); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset - 8); + } + } else if (expr->expr.var_decl.value->type == NODE_STRING && var_type && var_type->tag == TYPE_SLICE) { + ast_node *str = expr->expr.var_decl.value; + usize str_len = str->expr.string.len; + char *str_data = str->expr.string.start; + + usize aligned_data_size = (str_len + 7) & ~7; + stack_offset += aligned_data_size; + int data_offset = stack_offset; + + stack_offset += 16; + offset = stack_offset; + + char *var_name = strndup(expr->expr.var_decl.name, expr->expr.var_decl.name_len); + shput(variables, var_name, offset); + + for (usize i = 0; i < str_len; i++) { + int byte_offset = data_offset - i; + if ((unsigned char)str_data[i] == '\\' && (unsigned char)str_data[i+1] == 'n') { + fprintf(fp, "movb $%d, -%d(%%rbp)\n", (unsigned char)'\n', byte_offset); + i += 1; + } else { + fprintf(fp, "movb $%d, -%d(%%rbp)\n", (unsigned char)str_data[i], byte_offset); + } + } + + fprintf(fp, "lea -%d(%%rbp), %%rax\n", data_offset); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset); + fprintf(fp, "mov $%lu, %%rax\n", str_len); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset - 8); + } else if (expr->expr.var_decl.value->type == NODE_STRUCT_INIT) { ast_node *member_list = expr->expr.var_decl.value->expr.struct_init.members; ast_node *current = member_list; - type *struct_type = expr->expr_type; - if (!struct_type && expr->expr.var_decl.type) { - struct_type = expr->expr.var_decl.type->expr_type; - } + if (var_type && var_type->tag == TYPE_STRUCT) { + while (current && current->type == NODE_UNIT) { + ast_node *assignment = current->expr.unit_node.expr; + if (assignment && assignment->type == NODE_BINARY && + assignment->expr.binary.operator == OP_ASSIGN) { + ast_node *field = assignment->expr.binary.left; + ast_node *value = assignment->expr.binary.right; - while (current && current->type == NODE_UNIT) { - ast_node *assignment = current->expr.unit_node.expr; - if (assignment && assignment->type == NODE_BINARY && - assignment->expr.binary.operator == OP_ASSIGN) { - ast_node *field = assignment->expr.binary.left; - ast_node *value = assignment->expr.binary.right; + if (field->type == NODE_IDENTIFIER) { + char *field_name = strndup(field->expr.string.start, + field->expr.string.len); - if (field->type == NODE_IDENTIFIER && struct_type && - struct_type->tag == TYPE_STRUCT) { - char *field_name = strndup(field->expr.string.start, - field->expr.string.len); - - member *m = struct_type->data.structure.members; - int field_offset = -1; - while (m) { - if (m->name_len == field->expr.string.len && - strncmp(m->name, field->expr.string.start, m->name_len) == 0) { - field_offset = m->offset; - break; + member *m = var_type->data.structure.members; + int field_offset = -1; + while (m) { + if (m->name_len == field->expr.string.len && + strncmp(m->name, field->expr.string.start, m->name_len) == 0) { + field_offset = m->offset; + break; + } + m = m->next; } - m = m->next; - } - if (field_offset >= 0) { + if (field_offset >= 0) { + gen_expr(fp, value); + + type *field_type = shget(var_type->data.structure.member_types, field_name); + + if (field_type && field_type->size == 4) { + fprintf(fp, "mov %%eax, -%d(%%rbp)\n", offset + field_offset); + } else if (field_type && field_type->size == 2) { + fprintf(fp, "mov %%ax, -%d(%%rbp)\n", offset + field_offset); + } else if (field_type && field_type->size == 1) { + fprintf(fp, "mov %%al, -%d(%%rbp)\n", offset + field_offset); + } else { + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset + field_offset); + } + } + + free(field_name); + } + } + current = current->expr.unit_node.next; + } + } + else if (var_type && (var_type->tag == TYPE_PTR || var_type->tag == TYPE_SLICE)) { + usize element_size = 8; + type *element_type = NULL; + + if (var_type->tag == TYPE_PTR && var_type->data.ptr.child) { + element_type = var_type->data.ptr.child; + element_size = element_type->size; + } else if (var_type->tag == TYPE_SLICE && var_type->data.slice.child) { + element_type = var_type->data.slice.child; + element_size = element_type->size; + } + + int element_count = 0; + ast_node *count_node = current; + while (count_node && count_node->type == NODE_UNIT) { + element_count++; + count_node = count_node->expr.unit_node.next; + } + if (var_type->tag == TYPE_SLICE) { + usize data_size = element_count * element_size; + usize aligned_data_size = (data_size + 7) & ~7; + stack_offset += aligned_data_size; + int data_offset = stack_offset; + stack_offset += 16; + offset = stack_offset; + + char *var_name = strndup(expr->expr.var_decl.name, expr->expr.var_decl.name_len); + shput(variables, var_name, offset); + + int index = 0; + while (current && current->type == NODE_UNIT) { + ast_node *value = current->expr.unit_node.expr; + if (value) { gen_expr(fp, value); - type *field_type = shget(struct_type->data.structure.member_types, field_name); + int element_offset = data_offset - (index * element_size); - if (field_type && field_type->size == 4) { - fprintf(fp, "mov %%eax, -%d(%%rbp)\n", offset + field_offset); - } else if (field_type && field_type->size == 2) { - fprintf(fp, "mov %%ax, -%d(%%rbp)\n", offset + field_offset); - } else if (field_type && field_type->size == 1) { - fprintf(fp, "mov %%al, -%d(%%rbp)\n", offset + field_offset); + if (element_type && element_type->size == 4) { + fprintf(fp, "mov %%eax, -%d(%%rbp)\n", element_offset); + } else if (element_type && element_type->size == 2) { + fprintf(fp, "mov %%ax, -%d(%%rbp)\n", element_offset); + } else if (element_type && element_type->size == 1) { + fprintf(fp, "mov %%al, -%d(%%rbp)\n", element_offset); } else { - fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset + field_offset); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", element_offset); } } + index++; + current = current->expr.unit_node.next; + } - free(field_name); + fprintf(fp, "lea -%d(%%rbp), %%rax\n", data_offset); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset); + fprintf(fp, "mov $%d, %%rax\n", element_count); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset - 8); + } else { + int index = 0; + while (current && current->type == NODE_UNIT) { + ast_node *value = current->expr.unit_node.expr; + if (value) { + gen_expr(fp, value); + + int element_offset = offset + (index * element_size); + + if (element_type && element_type->size == 4) { + fprintf(fp, "mov %%eax, -%d(%%rbp)\n", element_offset); + } else if (element_type && element_type->size == 2) { + fprintf(fp, "mov %%ax, -%d(%%rbp)\n", element_offset); + } else if (element_type && element_type->size == 1) { + fprintf(fp, "mov %%al, -%d(%%rbp)\n", element_offset); + } else { + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", element_offset); + } + } + index++; + current = current->expr.unit_node.next; } } - current = current->expr.unit_node.next; } } else { gen_expr(fp, expr->expr.var_decl.value); - fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset); + + // If assigning a slice value, copy the 16-byte structure + if (var_type && var_type->tag == TYPE_SLICE) { + fprintf(fp, "mov (%%rax), %%rcx\n"); // Load ptr field + fprintf(fp, "mov 8(%%rax), %%rdx\n"); // Load len field + fprintf(fp, "mov %%rcx, -%d(%%rbp)\n", offset); // Store ptr + fprintf(fp, "mov %%rdx, -%d(%%rbp)\n", offset - 8); // Store len + } else { + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset); + } } } break; @@ -598,12 +766,24 @@ void gen_expr(FILE *fp, ast_node *expr) if (base->type == NODE_IDENTIFIER) { int base_offset = get_var_offset(base->expr.string.start, base->expr.string.len); + type *base_type = base->expr_type; - type *struct_type = base->expr_type; + if (base_type && base_type->tag == TYPE_SLICE && member_node->type == NODE_IDENTIFIER) { + char *field_name = strndup(member_node->expr.string.start, member_node->expr.string.len); - if (member_node->type == NODE_IDENTIFIER && struct_type && - struct_type->tag == TYPE_STRUCT) { - member *m = struct_type->data.structure.members; + if (strcmp(field_name, "ptr") == 0) { + fprintf(fp, "mov -%d(%%rbp), %%rax\n", base_offset); + } else if (strcmp(field_name, "len") == 0) { + fprintf(fp, "mov -%d(%%rbp), %%rax\n", base_offset - 8); + } else { + fprintf(fp, "# ERROR: slice field '%s' not found\n", field_name); + } + + free(field_name); + } + else if (member_node->type == NODE_IDENTIFIER && base_type && + base_type->tag == TYPE_STRUCT) { + member *m = base_type->data.structure.members; int field_offset = -1; while (m) { if (m->name_len == member_node->expr.string.len && @@ -620,17 +800,165 @@ void gen_expr(FILE *fp, ast_node *expr) fprintf(fp, "# ERROR: field not found\n"); } } else { - fprintf(fp, "# ERROR: not a struct type\n"); + fprintf(fp, "# ERROR: not a struct or slice type\n"); } } else { fprintf(fp, "# ERROR: complex struct access not implemented\n"); } break; } + case NODE_RANGE: { + if (expr->expr.binary.left->type == NODE_INTEGER && + expr->expr.binary.right->type == NODE_INTEGER) { + i64 start = expr->expr.binary.left->expr.integer; + i64 end = expr->expr.binary.right->expr.integer; + i64 count = end - start + 1; + + usize element_size = 8; + usize data_size = count * element_size; + usize aligned_data_size = (data_size + 7) & ~7; + stack_offset += aligned_data_size; + int data_offset = stack_offset; + + for (i64 i = 0; i < count; i++) { + i64 value = start + i; + int element_offset = data_offset - (i * element_size); + fprintf(fp, "mov $%ld, %%rax\n", value); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", element_offset); + } + + stack_offset += 16; + int slice_offset = stack_offset; + + fprintf(fp, "lea -%d(%%rbp), %%rax\n", data_offset); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", slice_offset); + fprintf(fp, "mov $%ld, %%rax\n", count); + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", slice_offset - 8); + + fprintf(fp, "lea -%d(%%rbp), %%rax\n", slice_offset); + } else { + fprintf(fp, "# ERROR: range expression requires constant bounds\n"); + } + break; + } case NODE_STRUCT_INIT: { fprintf(fp, "# ERROR: struct init outside of variable declaration\n"); break; } + case NODE_ARRAY_SUBSCRIPT: { + usize element_size = 8; + type *base_type = expr->expr.subscript.expr->expr_type; + bool is_slice = false; + + if (base_type) { + if (base_type->tag == TYPE_PTR && base_type->data.ptr.child) { + element_size = base_type->data.ptr.child->size; + } else if (base_type->tag == TYPE_SLICE && base_type->data.slice.child) { + element_size = base_type->data.slice.child->size; + is_slice = true; + } + } + + if (expr->expr.subscript.index->type == NODE_RANGE) { + if (expr->expr.subscript.expr->type == NODE_IDENTIFIER) { + int base_offset = get_var_offset(expr->expr.subscript.expr->expr.string.start, + expr->expr.subscript.expr->expr.string.len); + + fprintf(fp, "mov -%d(%%rbp), %%rcx\n", base_offset); + + gen_expr(fp, expr->expr.subscript.index->expr.binary.left); + fprintf(fp, "push %%rax\n"); + + gen_expr(fp, expr->expr.subscript.index->expr.binary.right); + fprintf(fp, "mov %%rax, %%rdx\n"); // rdx = end + fprintf(fp, "pop %%rax\n"); // rax = start + fprintf(fp, "mov %%rdx, %%r8\n"); + fprintf(fp, "sub %%rax, %%r8\n"); + fprintf(fp, "inc %%r8\n"); // r8 = new length + + if (element_size != 1) { + fprintf(fp, "imul $%lu, %%rax\n", element_size); + } + fprintf(fp, "add %%rcx, %%rax\n"); // rax = new ptr + + // Allocate temporary slice struct (16 bytes) + stack_offset += 16; + fprintf(fp, "mov %%rax, -%d(%%rbp)\n", stack_offset); // Store ptr + fprintf(fp, "mov %%r8, -%d(%%rbp)\n", stack_offset - 8); // Store len + fprintf(fp, "lea -%d(%%rbp), %%rax\n", stack_offset); // Return address of temp slice + } + } + else if (expr->expr.subscript.expr->type == NODE_IDENTIFIER && is_slice) { + int base_offset = get_var_offset(expr->expr.subscript.expr->expr.string.start, + expr->expr.subscript.expr->expr.string.len); + + fprintf(fp, "mov -%d(%%rbp), %%rcx\n", base_offset); + + gen_expr(fp, expr->expr.subscript.index); + + if (element_size != 1) { + fprintf(fp, "imul $%lu, %%rax\n", element_size); + } + + fprintf(fp, "add %%rcx, %%rax\n"); + + if (expr->expr_type && expr->expr_type->size == 4) { + fprintf(fp, "movl (%%rax), %%eax\n"); + } else if (expr->expr_type && expr->expr_type->size == 2) { + fprintf(fp, "movzwl (%%rax), %%eax\n"); + } else if (expr->expr_type && expr->expr_type->size == 1) { + fprintf(fp, "movzbl (%%rax), %%eax\n"); + } else { + fprintf(fp, "mov (%%rax), %%rax\n"); + } + } else if (expr->expr.subscript.expr->type == NODE_IDENTIFIER) { + int base_offset = get_var_offset(expr->expr.subscript.expr->expr.string.start, + expr->expr.subscript.expr->expr.string.len); + + gen_expr(fp, expr->expr.subscript.index); + + if (element_size != 1) { + fprintf(fp, "imul $%lu, %%rax\n", element_size); + } + + fprintf(fp, "add $%d, %%rax\n", base_offset); + fprintf(fp, "neg %%rax\n"); + fprintf(fp, "add %%rbp, %%rax\n"); + + if (expr->expr_type && expr->expr_type->size == 4) { + fprintf(fp, "movl (%%rax), %%eax\n"); + } else if (expr->expr_type && expr->expr_type->size == 2) { + fprintf(fp, "movzwl (%%rax), %%eax\n"); + } else if (expr->expr_type && expr->expr_type->size == 1) { + fprintf(fp, "movzbl (%%rax), %%eax\n"); + } else { + fprintf(fp, "mov (%%rax), %%rax\n"); + } + } else { + gen_expr(fp, expr->expr.subscript.expr); + fprintf(fp, "push %%rax\n"); + + gen_expr(fp, expr->expr.subscript.index); + + if (element_size != 1) { + fprintf(fp, "imul $%lu, %%rax\n", element_size); + } + + fprintf(fp, "pop %%rcx\n"); + fprintf(fp, "add %%rcx, %%rax\n"); + + if (expr->expr_type && expr->expr_type->size == 4) { + fprintf(fp, "movl (%%rax), %%eax\n"); + } else if (expr->expr_type && expr->expr_type->size == 2) { + fprintf(fp, "movzwl (%%rax), %%eax\n"); + } else if (expr->expr_type && expr->expr_type->size == 1) { + fprintf(fp, "movzbl (%%rax), %%eax\n"); + } else { + fprintf(fp, "mov (%%rax), %%rax\n"); + } + } + break; + } case NODE_CALL: { const char *arg_regs[] = {"%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"}; @@ -676,6 +1004,10 @@ void gen_expr(FILE *fp, ast_node *expr) void gen_function(FILE *fp, ast_node *fn) { + if (fn->expr.function.is_extern || fn->expr.function.body == NULL) { + return; + } + ast_node *current = fn->expr.function.body; stack_offset = 0; diff --git a/done.txt b/done.txt deleted file mode 100644 index e69de29..0000000 diff --git a/parser.c b/parser.c index 8061fc1..4fd7c65 100644 --- a/parser.c +++ b/parser.c @@ -1089,6 +1089,7 @@ static ast_node *parse_function(parser *p) { ast_node *fn = arena_alloc(p->allocator, sizeof(ast_node)); fn->type = NODE_FUNCTION; + fn->expr.function.is_extern = false; fn->expr.function.type = parse_type(p); fn->expr.function.name = peek(p)->lexeme; fn->expr.function.name_len = peek(p)->lexeme_len; @@ -1097,7 +1098,14 @@ static ast_node *parse_function(parser *p) advance(p); if (match(p, TOKEN_RPAREN)) { - fn->expr.function.body = parse_compound(p);; + // Check if this is an extern declaration (semicolon) or definition (body) + if (match_peek(p, TOKEN_SEMICOLON)) { + // Extern function - no body, just consume semicolon + advance(p); + fn->expr.function.body = NULL; + } else { + fn->expr.function.body = parse_compound(p); + } fn->expr.function.parameters = NULL; fn->expr.function.parameters_len = 0; return fn; @@ -1111,7 +1119,13 @@ static ast_node *parse_function(parser *p) error(p, "expected `,`."); return NULL; } else { - fn->expr.function.body = parse_compound(p); + // Check if this is an extern declaration (semicolon) or definition (body) + if (match_peek(p, TOKEN_SEMICOLON)) { + advance(p); + fn->expr.function.body = NULL; + } else { + fn->expr.function.body = parse_compound(p); + } return fn; } } @@ -1132,7 +1146,14 @@ static ast_node *parse_function(parser *p) prev = current; } - fn->expr.function.body = parse_compound(p); + + // Check if this is an extern declaration (semicolon) or definition (body) + if (match_peek(p, TOKEN_SEMICOLON)) { + advance(p); + fn->expr.function.body = NULL; + } else { + fn->expr.function.body = parse_compound(p); + } return fn; } @@ -1140,6 +1161,13 @@ static ast_node *parse_function(parser *p) static ast_node *parse_statement(parser *p) { token *cur = peek(p); + + /* Check for extern function declaration */ + bool is_extern = false; + if (match(p, TOKEN_EXTERN)) { + is_extern = true; + } + ast_node *type = parse_type(p); if (type && type->type == NODE_STRUCT && type->expr.structure.name_len > 0) { goto skip_struct; @@ -1148,9 +1176,20 @@ static ast_node *parse_statement(parser *p) if (p->tokens->next && p->tokens->next->type == TOKEN_LPAREN) { /* Function definition. */ p->tokens = cur; - return parse_function(p); + if (is_extern) { + advance(p); // Skip TOKEN_EXTERN + } + ast_node *fn = parse_function(p); + if (fn && is_extern) { + fn->expr.function.is_extern = true; + fn->expr.function.body = NULL; + } + return fn; } p->tokens = cur; + if (is_extern) { + advance(p); // Skip TOKEN_EXTERN for non-function case + } /* Variable declaration. */ ast_node *node = arena_alloc(p->allocator, sizeof(ast_node)); node->type = NODE_VAR_DECL; diff --git a/parser.h b/parser.h index dced7ec..bbe3d0c 100644 --- a/parser.h +++ b/parser.h @@ -230,6 +230,7 @@ typedef struct _ast_node { usize name_len; struct _ast_node *type; struct _ast_node *body; + bool is_extern; } function; struct { variant *variants; diff --git a/report.txt b/report.txt deleted file mode 100644 index e69de29..0000000 diff --git a/sema.c b/sema.c index f116912..4e87625 100644 --- a/sema.c +++ b/sema.c @@ -152,17 +152,18 @@ static type *get_type(sema *s, ast_node *n) return t; case NODE_PTR_TYPE: t = malloc(sizeof(type)); - t->size = sizeof(usize); t->alignment = sizeof(usize); if (n->expr.ptr_type.flags & PTR_RAW) { t->name = "ptr"; t->tag = TYPE_PTR; + t->size = sizeof(usize); t->data.ptr.child = get_type(s, n->expr.ptr_type.type); t->data.ptr.is_const = (n->expr.ptr_type.flags & PTR_CONST) != 0; t->data.ptr.is_volatile = (n->expr.ptr_type.flags & PTR_VOLATILE) != 0; } else { t->name = "slice"; t->tag = TYPE_SLICE; + t->size = sizeof(usize) * 2; // ptr + len = 16 bytes t->data.slice.child = get_type(s, n->expr.ptr_type.type); t->data.slice.is_const = (n->expr.ptr_type.flags & PTR_CONST) != 0; t->data.slice.is_volatile = (n->expr.ptr_type.flags & PTR_VOLATILE) != 0; @@ -377,8 +378,8 @@ static ast_node *get_def(sema *s, char *name) static type *get_string_type(sema *s, ast_node *node) { type *string_type = arena_alloc(s->allocator, sizeof(type)); - string_type->tag = TYPE_PTR; - string_type->size = sizeof(usize); + string_type->tag = TYPE_SLICE; + string_type->size = sizeof(usize) * 2; // ptr + len = 16 bytes string_type->alignment = sizeof(usize); string_type->name = "slice"; string_type->data.slice.child = shget(type_reg, "u8"); @@ -409,6 +410,33 @@ static type *get_access_type(sema *s, ast_node *node) ast_node *member = node->expr.access.member; char *name_start = member->expr.string.start; usize name_len = member->expr.string.len; + + // Handle slice field access + if (t && t->tag == TYPE_SLICE) { + char *name = intern_string(s, name_start, name_len); + if (strcmp(name, "ptr") == 0) { + // Return pointer to element type + type *ptr_type = arena_alloc(s->allocator, sizeof(type)); + ptr_type->tag = TYPE_PTR; + ptr_type->size = 8; + ptr_type->alignment = 8; + ptr_type->name = "ptr"; + ptr_type->data.ptr.child = t->data.slice.child; + ptr_type->data.ptr.is_const = t->data.slice.is_const; + ptr_type->data.ptr.is_volatile = t->data.slice.is_volatile; + free(name); + return ptr_type; + } else if (strcmp(name, "len") == 0) { + // Return usize type + free(name); + return shget(type_reg, "usize"); + } else { + error(node, "slice doesn't have that field"); + free(name); + return NULL; + } + } + if (!t || (t->tag != TYPE_STRUCT && t->tag != TYPE_UNION)) { error(node, "invalid expression."); return NULL; @@ -557,6 +585,36 @@ static type *get_expression_type(sema *s, ast_node *node) return t; case NODE_ARRAY_SUBSCRIPT: t = get_expression_type(s, node->expr.subscript.expr); + + // Check if this is range subscripting (creates a slice) + if (node->expr.subscript.index && node->expr.subscript.index->type == NODE_RANGE) { + type *element_type = NULL; + switch (t->tag) { + case TYPE_SLICE: + element_type = t->data.slice.child; + break; + case TYPE_PTR: + element_type = t->data.ptr.child; + break; + default: + error(node, "only pointers and slices can be indexed."); + return NULL; + } + + // Return a slice type + type *slice_type = arena_alloc(s->allocator, sizeof(type)); + slice_type->tag = TYPE_SLICE; + slice_type->size = sizeof(usize) * 2; + slice_type->alignment = sizeof(usize); + slice_type->data.slice.child = element_type; + slice_type->data.slice.is_const = false; + slice_type->data.slice.len = 0; + + node->expr_type = slice_type; + return slice_type; + } + + // Regular subscript - return element type switch (t->tag) { case TYPE_SLICE: t = t->data.slice.child; @@ -732,6 +790,18 @@ static void check_statement(sema *s, ast_node *node) break; } if (t->tag == TYPE_STRUCT) { + // Struct initialization with NODE_STRUCT_INIT is allowed + } else if (node->expr.var_decl.value && node->expr.var_decl.value->type == NODE_STRUCT_INIT && + (t->tag == TYPE_SLICE || t->tag == TYPE_PTR)) { + // Array/slice initialization with NODE_STRUCT_INIT is allowed + } else if (node->expr.var_decl.value && node->expr.var_decl.value->type == NODE_RANGE && + t->tag == TYPE_SLICE) { + // Range initialization for slices is allowed + get_expression_type(s, node->expr.var_decl.value); + } else if (node->expr.var_decl.value && node->expr.var_decl.value->type == NODE_STRING && + t->tag == TYPE_SLICE) { + // String literal can be assigned to slice + get_expression_type(s, node->expr.var_decl.value); } else if (!can_cast(get_expression_type(s, node->expr.var_decl.value), t) && !match(t, get_expression_type(s, node->expr.var_decl.value))) { error(node, "type mismatch (decl)."); } @@ -758,15 +828,18 @@ static void check_function(sema *s, ast_node *f) param_node->expr_type = p_type; param_node->address_taken = false; param_node->expr.var_decl.name = t_name; - + shput(current_scope->defs, t_name, param_node); param = param->next; } - ast_node *current = f->expr.function.body; - while (current && current->type == NODE_UNIT) { - check_statement(s, current->expr.unit_node.expr); - current = current->expr.unit_node.next; + // Skip body checking for extern functions + if (!f->expr.function.is_extern && f->expr.function.body) { + ast_node *current = f->expr.function.body; + while (current && current->type == NODE_UNIT) { + check_statement(s, current->expr.unit_node.expr); + current = current->expr.unit_node.next; + } } pop_scope(s); @@ -820,6 +893,7 @@ void sema_init(parser *p, arena *a) register_type(s, "u16", create_integer(s, "u16", 16, false)); register_type(s, "u32", create_integer(s, "u32", 32, false)); register_type(s, "u64", create_integer(s, "u64", 64, false)); + register_type(s, "usize", create_integer(s, "usize", 64, false)); register_type(s, "i8", create_integer(s, "i8", 8, true)); register_type(s, "i16", create_integer(s, "i16", 16, true)); register_type(s, "i32", create_integer(s, "i32", 32, true)); diff --git a/test b/test deleted file mode 100755 index 2fd1a557d42dcbcf3a1a56613ba75f0bfc91cf33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20192 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 diff --git a/test.l b/test.l index 1aac346..2763f97 100644 --- a/test.l +++ b/test.l @@ -1,10 +1,20 @@ -struct point { - i32 x, - i32 y -} +extern i64 write(i32 fd, *u8 buf, u64 count); +extern void exit(i32 code); +extern *u8 malloc(usize size); i32 main() { - point result = .{ x = 2, y = 1 }; - return (result.y) + 2; + [u8] message = "Hello world!\n"; + *u8 message_heap = malloc(message.len); + [u8] new_message = message_heap[0..13]; + u32 i = 0; + + loop while i < message.len { + new_message[i] = message[i]; + i = i + 1; + } + + write(1, new_message.ptr, new_message.len); + + return 0; } diff --git a/test.s b/test.s deleted file mode 100644 index 9d3b3f4..0000000 --- a/test.s +++ /dev/null @@ -1,20 +0,0 @@ -.section .text -.global main -main: -push %rbp -mov %rsp, %rbp -sub $256, %rsp -mov $2, %rax -mov %eax, -8(%rbp) -mov $1, %rax -mov %eax, -12(%rbp) -mov -12(%rbp), %rax -mov %rax, %rcx -mov $2, %rax -add %rcx, %rax -mov %rbp, %rsp -pop %rbp -ret -mov %rbp, %rsp -pop %rbp -ret diff --git a/test_control b/test_control deleted file mode 100755 index d9550eee03315872647ea0586c219e355182dbcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21712 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±U*cV@>Hk^n|E%_J^v&hg+kf8Q;;K{ge_rdK*ZL{#EC@*7MxPH` zSU!M*qQ<{@pFOAt%Ij%;@%BH1M!tJC`sRJ}l-8$T7Sn$tXCNPd^If)~&HLAEz~&Wgw#NH2VD zpATp2i)PnY+&9$go9pJ`b|unOlT?V;{};4=?b;nnD#4fnUU@?s_?Hl)e-l5mU+`;v zv;LGd6>EbNK8&MYKc@Z1Vr*3pf)u7|6Mw^d3`qU?XZD46#*~Bxia>4pZ5U4j!E;i% zhRHMgEb~8VUVnx*kdK}4B(|n+_H{`rr|}PEi;8=hG;(`iFa! z!g0?D=rJeOFQWhIwMzeXb7E=#Uj5CB=%iQgfadNUZYK`2p3J)D h^q93L6-_mwkOw>tJtXcW7S?~@50rkvqu?RM{{V1A{rUg^ diff --git a/test_control.l b/test_control.l deleted file mode 100644 index d8576a2..0000000 --- a/test_control.l +++ /dev/null @@ -1,23 +0,0 @@ -i32 main() -{ - i32 x = 0; - i32 i = 0; - - // Test while loop with break - while (i < 10) { - i = i + 1; - if (i == 5) { - break; - } - x = x + i; - } - - // Test goto and label - if (x == 10) { - goto skip; - } - x = 999; - - skip: - return x; -} diff --git a/test_simple b/test_simple deleted file mode 100755 index d9550eee03315872647ea0586c219e355182dbcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21712 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±U*cV@>Hk^n|E%_J^v&hg+kf8Q;;K{ge_rdK*ZL{#EC@*7MxPH` zSU!M*qQ<{@pFOAt%Ij%;@%BH1M!tJC`sRJ}l-8$T7Sn$tXCNPd^If)~&HLAEz~&Wgw#NH2VD zpATp2i)PnY+&9$go9pJ`b|unOlT?V;{};4=?b;nnD#4fnUU@?s_?Hl)e-l5mU+`;v zv;LGd6>EbNK8&MYKc@Z1Vr*3pf)u7|6Mw^d3`qU?XZD46#*~Bxia>4pZ5U4j!E;i% zhRHMgEb~8VUVnx*kdK}4B(|n+_H{`rr|}PEi;8=hG;(`iFa! z!g0?D=rJeOFQWhIwMzeXb7E=#Uj5CB=%iQgfadNUZYK`2p3J)D h^q93L6-_mwkOw>tJtXcW7S?~@50rkvqu?RM{{V1A{rUg^ diff --git a/test_simple.l b/test_simple.l deleted file mode 100644 index 61dc5fb..0000000 --- a/test_simple.l +++ /dev/null @@ -1,13 +0,0 @@ -i32 main() -{ - i32 x = 0; - - while (x < 10) { - x = x + 1; - if (x == 5) { - break; - } - } - - return x; -} diff --git a/todo.cfg b/todo.cfg deleted file mode 100644 index 5e35825..0000000 --- a/todo.cfg +++ /dev/null @@ -1,2 +0,0 @@ -export TODO_DIR="." -export TODO_FILE="$TODO_DIR/todo.txt" diff --git a/todo.txt b/todo.txt deleted file mode 100644 index c023562..0000000 --- a/todo.txt +++ /dev/null @@ -1 +0,0 @@ -implement dominator tree for control flow