diff options
Diffstat (limited to 'src/parser')
| -rw-r--r-- | src/parser/parser.h | 2 | ||||
| -rw-r--r-- | src/parser/parser_expr.c | 6 | ||||
| -rw-r--r-- | src/parser/parser_stmt.c | 22 | ||||
| -rw-r--r-- | src/parser/parser_type.c | 110 |
4 files changed, 120 insertions, 20 deletions
diff --git a/src/parser/parser.h b/src/parser/parser.h index f54bae0..cfe486d 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -394,7 +394,7 @@ ASTNode *parse_lambda(ParserContext *ctx, Lexer *l); char *parse_condition_raw(ParserContext *ctx, Lexer *l); char *parse_array_literal(ParserContext *ctx, Lexer *l, const char *st); char *parse_tuple_literal(ParserContext *ctx, Lexer *l, const char *tn); -char *parse_embed(ParserContext *ctx, Lexer *l); +ASTNode *parse_embed(ParserContext *ctx, Lexer *l); ASTNode *parse_macro_call(ParserContext *ctx, Lexer *l, char *name); ASTNode *parse_statement(ParserContext *ctx, Lexer *l); diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c index 99ce7d1..b9f022a 100644 --- a/src/parser/parser_expr.c +++ b/src/parser/parser_expr.c @@ -3075,10 +3075,10 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) } // Case: [..] or [..end] - if (lexer_peek(l).type == TOK_DOTDOT) + if (lexer_peek(l).type == TOK_DOTDOT || lexer_peek(l).type == TOK_DOTDOT_LT) { is_slice = 1; - lexer_next(l); // consume .. + lexer_next(l); // consume .. or ..< if (lexer_peek(l).type != TOK_RBRACKET) { end = parse_expression(ctx, l); @@ -3088,7 +3088,7 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) { // Case: [start] or [start..] or [start..end] start = parse_expression(ctx, l); - if (lexer_peek(l).type == TOK_DOTDOT) + if (lexer_peek(l).type == TOK_DOTDOT || lexer_peek(l).type == TOK_DOTDOT_LT) { is_slice = 1; lexer_next(l); // consume .. diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c index 6a0f50d..5307768 100644 --- a/src/parser/parser_stmt.c +++ b/src/parser/parser_stmt.c @@ -242,11 +242,12 @@ ASTNode *parse_match(ParserContext *ctx, Lexer *l) p_str = tmp; } - // Check for range pattern: value..end or value..=end - if (lexer_peek(l).type == TOK_DOTDOT || lexer_peek(l).type == TOK_DOTDOT_EQ) + // Check for range pattern: value..end, value..<end or value..=end + if (lexer_peek(l).type == TOK_DOTDOT || lexer_peek(l).type == TOK_DOTDOT_EQ || + lexer_peek(l).type == TOK_DOTDOT_LT) { int is_inclusive = (lexer_peek(l).type == TOK_DOTDOT_EQ); - lexer_next(l); // eat .. or ..= + lexer_next(l); // eat operator Token end_tok = lexer_next(l); char *end_str = token_strdup(end_tok); @@ -1071,9 +1072,12 @@ ASTNode *parse_var_decl(ParserContext *ctx, Lexer *l) Token next = lexer_peek(l); if (next.type == TOK_IDENT && strncmp(next.start, "embed", 5) == 0) { - char *e = parse_embed(ctx, l); - init = ast_create(NODE_RAW_STMT); - init->raw_stmt.content = e; + init = parse_embed(ctx, l); + + if (!type && init->type_info) + { + type = type_to_string(init->type_info); + } if (!type) { register_slice(ctx, "char"); @@ -1583,9 +1587,9 @@ ASTNode *parse_for(ParserContext *ctx, Lexer *l) { ASTNode *start_expr = parse_expression(ctx, l); int is_inclusive = 0; - if (lexer_peek(l).type == TOK_DOTDOT) + if (lexer_peek(l).type == TOK_DOTDOT || lexer_peek(l).type == TOK_DOTDOT_LT) { - lexer_next(l); // consume .. + lexer_next(l); // consume .. or ..< } else if (lexer_peek(l).type == TOK_DOTDOT_EQ) @@ -3327,7 +3331,7 @@ ASTNode *parse_struct(ParserContext *ctx, Lexer *l, int is_union) continue; } - // --- HANDLE 'use' (Struct Embedding) --- + // Handle 'use' (Struct Embedding) if (t.type == TOK_USE) { lexer_next(l); // eat use diff --git a/src/parser/parser_type.c b/src/parser/parser_type.c index 27328fe..3d5bff8 100644 --- a/src/parser/parser_type.c +++ b/src/parser/parser_type.c @@ -874,7 +874,7 @@ char *parse_tuple_literal(ParserContext *ctx, Lexer *l, const char *tn) free(c); return o; } -char *parse_embed(ParserContext *ctx, Lexer *l) +ASTNode *parse_embed(ParserContext *ctx, Lexer *l) { lexer_next(l); Token t = lexer_next(l); @@ -886,6 +886,15 @@ char *parse_embed(ParserContext *ctx, Lexer *l) strncpy(fn, t.start + 1, t.len - 2); fn[t.len - 2] = 0; + // Check for optional "as Type" + Type *target_type = NULL; + if (lexer_peek(l).type == TOK_IDENT && lexer_peek(l).len == 2 && + strncmp(lexer_peek(l).start, "as", 2) == 0) + { + lexer_next(l); // consume 'as' + target_type = parse_type_formal(ctx, l); + } + FILE *f = fopen(fn, "rb"); if (!f) { @@ -898,16 +907,103 @@ char *parse_embed(ParserContext *ctx, Lexer *l) fread(b, 1, len, f); fclose(f); - register_slice(ctx, "char"); - size_t oc = len * 6 + 128; + size_t oc = len * 6 + 256; char *o = xmalloc(oc); - sprintf(o, "(Slice_char){.data=(char[]){"); + + // Default Type if none + if (!target_type) + { + // Default: Slice_char + register_slice(ctx, "char"); + + Type *slice_type = type_new(TYPE_STRUCT); + slice_type->name = xstrdup("Slice_char"); + target_type = slice_type; + + sprintf(o, "(Slice_char){.data=(char[]){"); + } + else + { + // Handle specific type + char *ts = type_to_string(target_type); + + if (target_type->kind == TYPE_ARRAY) + { + char *inner_ts = type_to_string(target_type->inner); + if (target_type->array_size > 0) + { + Type *ptr_type = type_new_ptr(target_type->inner); // Reuse inner + target_type = ptr_type; + sprintf(o, "(%s[]){", inner_ts); + } + else + { + // Slice -> Slice_T struct + register_slice(ctx, inner_ts); + char slice_name[256]; + sprintf(slice_name, "Slice_%s", inner_ts); + Type *slice_t = type_new(TYPE_STRUCT); + slice_t->name = xstrdup(slice_name); + target_type = slice_t; + sprintf(o, "(%s){.data=(%s[]){", slice_name, inner_ts); + } + free(inner_ts); + } + else + { + if (strcmp(ts, "string") == 0 || strcmp(ts, "char*") == 0) + { + sprintf(o, "(char*)\""); + } + else + { + sprintf(o, "(%s){", ts); + } + } + free(ts); + } + char *p = o + strlen(o); + + // Check if string mode + int is_string = (target_type && (strcmp(type_to_string(target_type), "string") == 0 || + strcmp(type_to_string(target_type), "char*") == 0)); + for (int i = 0; i < len; i++) { - p += sprintf(p, "0x%02X,", b[i]); + if (is_string) + { + // Hex escape for string + p += sprintf(p, "\\x%02X", b[i]); + } + else + { + p += sprintf(p, "0x%02X,", b[i]); + } + } + + if (is_string) + { + sprintf(p, "\""); } - sprintf(p, "},.len=%ld,.cap=%ld}", len, len); + else + { + int is_slice = (strncmp(o, "(Slice_", 7) == 0); + + if (is_slice) + { + sprintf(p, "},.len=%ld,.cap=%ld}", len, len); + } + else + { + sprintf(p, "}"); + } + } + free(b); - return o; + + ASTNode *n = ast_create(NODE_RAW_STMT); + n->raw_stmt.content = o; + n->type_info = target_type; + return n; } |
