Skip to content

Commit 868a7b4

Browse files
author
TheDevConnor
committed
Started to add in resolution types
1 parent 9f78f25 commit 868a7b4

9 files changed

Lines changed: 205 additions & 96 deletions

File tree

LPBS/main.lx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ pub const main -> fn () int {
1818

1919
let path: *char = "/home/TheDevConnor/Luma/LPBS/build.lmb";
2020
let file: *char = io::read_file(path);
21-
let lex: *Token = lexer::scan(file);
21+
let lex: *lexer::Token = lexer::scan(file);
2222

23-
let parser: *Stmt = psr::parse(lex, path);
23+
let parser: *ast::Stmt = psr::parse(lex, path);
2424
ast::print_stmt(parser);
2525

2626
clean_up(file, lex);

LPBS/parser.lx

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ const BindingPower -> enum {
2929
};
3030

3131
pub const Parser -> struct {
32-
tks: *Token,
32+
tks: *lexer::Token,
3333
path: *char,
3434
pos: int,
3535

36-
init_parser -> fn (tks: *Token, path: *char) void {
36+
init_parser -> fn (tks: *lexer::Token, path: *char) void {
3737
self.path = path;
3838
self.tks = tks;
3939
self.pos = 0;
@@ -44,10 +44,10 @@ pub const Parser -> struct {
4444
// TODO: and fix the types for the module system for enums and structs with it.
4545

4646
const at_end -> fn (psr: *Parser) int { return cast<int>(psr.pos >= psr.tks.size); }
47-
const peek -> fn (psr: *Parser) Token { return psr.tks.list[psr.pos]; }
47+
const peek -> fn (psr: *Parser) lexer::Token { return psr.tks.list[psr.pos]; }
4848
const advance -> fn (psr: *Parser) void { psr.pos = psr.pos + 1; }
4949

50-
const parse_expr -> fn (psr: *Parser, bp: int) *Expr;
50+
const parse_expr -> fn (psr: *Parser, bp: int) *ast::Expr;
5151

5252
const get_infix_bp -> fn (token_type: int) int {
5353
switch (token_type) {
@@ -57,8 +57,8 @@ const get_infix_bp -> fn (token_type: int) int {
5757
}
5858
}
5959

60-
const parse_literal -> fn (psr: *Parser) *Expr {
61-
let tok: Token = peek(psr);
60+
const parse_literal -> fn (psr: *Parser) *ast::Expr {
61+
let tok: lexer::Token = peek(psr);
6262

6363
switch (tok.type) {
6464
0 -> { //number
@@ -83,15 +83,15 @@ const parse_literal -> fn (psr: *Parser) *Expr {
8383
}
8484
}
8585

86-
const nud -> fn (psr: *Parser) *Expr {
87-
let tok: Token = peek(psr);
86+
const nud -> fn (psr: *Parser) *ast::Expr {
87+
let tok: lexer::Token = peek(psr);
8888

8989
switch (tok.type) {
9090
0, 1, 2 -> { return parse_literal(psr); } //number, ident, string
9191
6 -> { //(
9292
advance(psr);
93-
let expr: *Expr = parse_expr(psr, BindingPower::BP_NONE);
94-
let next_tok: Token = peek(psr);
93+
let expr: *ast::Expr = parse_expr(psr, BindingPower::BP_NONE);
94+
let next_tok: lexer::Token = peek(psr);
9595
if (next_tok.type != 7) { //)
9696
output("Expected closing parenthesis\n");
9797
return cast<*Expr>(0);
@@ -102,37 +102,37 @@ const nud -> fn (psr: *Parser) *Expr {
102102
16, 17 -> { //+, -
103103
let op: *char = tok.value;
104104
advance(psr);
105-
let right: *Expr = parse_expr(psr, BindingPower::BP_UNARY);
105+
let right: *ast::Expr = parse_expr(psr, BindingPower::BP_UNARY);
106106
return ast::create_unary_node(op[0], right);
107107
}
108108
_ -> {
109109
output("Unexpected token in prefix position\n");
110-
return cast<*Expr>(0);
110+
return cast<*ast::Expr>(0);
111111
}
112112
}
113113
}
114114

115-
const led -> fn (psr: *Parser, left: *Expr, token: Token) *Expr {
115+
const led -> fn (psr: *Parser, left: *ast::Expr, token: lexer::Token) *ast::Expr {
116116
switch (token.type) {
117117
12, 13, 16, 17, 18, 19 -> { //==, !=, +, -, *, /
118118
let op: *char = psr.tks.list[psr.pos].value;
119119
advance(psr);
120-
let right: *Expr = parse_expr(psr, get_infix_bp(token.type));
120+
let right: *ast::Expr = parse_expr(psr, get_infix_bp(token.type));
121121
return ast::create_binary_node(op[0], left, right);
122122
}
123123
_ -> {
124124
output("Unexpected token in infix position\n");
125-
return cast<*Expr>(0);
125+
return cast<*ast::Expr>(0);
126126
}
127127
}
128128
}
129129

130-
const parse_expr -> fn (psr: *Parser, bp: int) *Expr {
131-
let left: *Expr = nud(psr);
130+
const parse_expr -> fn (psr: *Parser, bp: int) *ast::Expr {
131+
let left: *ast::Expr = nud(psr);
132132

133133
// Inline the led logic here
134134
loop (at_end(psr) == 0 && bp < get_infix_bp(peek(psr).type)) {
135-
let tok: Token = peek(psr);
135+
let tok: lexer::Token = peek(psr);
136136
let next_bp: int = get_infix_bp(tok.type);
137137

138138
left = led(psr, left, tok);
@@ -141,11 +141,11 @@ const parse_expr -> fn (psr: *Parser, bp: int) *Expr {
141141
return left;
142142
}
143143

144-
pub const parse -> fn (tks: *Token, path: *char) *Stmt {
144+
pub const parse -> fn (tks: *lexer::Token, path: *char) *ast::Stmt {
145145
let psr: Parser;
146146
psr.init_parser(tks, path);
147147

148-
let node: *Expr = parse_expr(&psr, BindingPower::BP_NONE);
148+
let node: *ast::Expr = parse_expr(&psr, BindingPower::BP_NONE);
149149

150150
return ast::create_program_node(node);
151151
}

src/ast/ast.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,13 @@ typedef enum {
6363
AST_STMT_DEFAULT,
6464

6565
// Type nodes
66-
AST_TYPE_BASIC, // Basic types (int, float, string, etc.)
67-
AST_TYPE_POINTER, // Pointer types
68-
AST_TYPE_ARRAY, // Array types
69-
AST_TYPE_FUNCTION, // Function types
70-
AST_TYPE_STRUCT, // Struct types
71-
AST_TYPE_ENUM, // Enum types
66+
AST_TYPE_RESOLUTION, // Namespace::Type resolution
67+
AST_TYPE_BASIC, // Basic types (int, float, string, etc.)
68+
AST_TYPE_POINTER, // Pointer types
69+
AST_TYPE_ARRAY, // Array types
70+
AST_TYPE_FUNCTION, // Function types
71+
AST_TYPE_STRUCT, // Struct types
72+
AST_TYPE_ENUM, // Enum types
7273
} NodeType;
7374

7475
// Literal types
@@ -478,6 +479,11 @@ struct AstNode {
478479
AstNode *return_type; // Changed from Type* to AstNode*
479480
} function;
480481

482+
struct {
483+
char **parts; // Array of namespace/type parts
484+
size_t part_count; // Number of parts
485+
} resolution;
486+
481487
// AST_TYPE_STRUCT - ADD THIS STRUCT
482488
struct {
483489
const char *name; // Name of the struct type
@@ -654,3 +660,5 @@ AstNode *create_array_type(ArenaAllocator *arena, AstNode *element_type,
654660
AstNode *create_function_type(ArenaAllocator *arena, AstNode **param_types,
655661
size_t param_count, AstNode *return_type,
656662
size_t line, size_t column);
663+
AstNode *create_resolution_type(ArenaAllocator *arena, char **parts,
664+
size_t part_count, size_t line, size_t column);

src/ast/ast_definistions/type.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,11 @@ AstNode *create_function_type(ArenaAllocator *arena, AstNode **param_types, size
2727
node->type_data.function.param_count = param_count;
2828
node->type_data.function.return_type = return_type;
2929
return node;
30+
}
31+
32+
AstNode *create_resolution_type(ArenaAllocator *arena, char **parts, size_t part_count, size_t line, size_t column) {
33+
AstNode *node = create_type_node(arena, AST_TYPE_RESOLUTION, line, column);
34+
node->type_data.resolution.parts = parts;
35+
node->type_data.resolution.part_count = part_count;
36+
return node;
3037
}

src/helper/run.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ bool run_build(BuildConfig config, ArenaAllocator *allocator) {
332332
if (!combined_program)
333333
goto cleanup;
334334

335+
// print_ast(combined_program, "", false, false);
336+
335337
// Stage 4: Typechecking
336338
print_progress_with_time(++step, total_stages, "Typechecking", &timer);
337339

src/parser/expr.c

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -347,20 +347,43 @@ Expr *struct_expr(Parser *parser) {
347347
}
348348

349349
// Named struct initialization: Point { x: 20, y: 50 }
350-
// This is called from led() when we see '{' after an identifier
350+
// OR namespace::Point { x: 20, y: 50 }
351+
// This is called from led() when we see '{' after an identifier or member expr
351352
Expr *named_struct_expr(Parser *parser, Expr *left, BindingPower bp) {
352353
(void)bp; // Unused parameter
353354

354-
// left should be an identifier expression containing the struct name
355-
if (left->type != AST_EXPR_IDENTIFIER) {
355+
char *struct_name = NULL;
356+
357+
// Handle both identifier and member expressions
358+
if (left->type == AST_EXPR_IDENTIFIER) {
359+
// Simple case: Point { ... }
360+
struct_name = left->expr.identifier.name;
361+
} else if (left->type == AST_EXPR_MEMBER) {
362+
// Namespace resolution: namespace::Point { ... }
363+
// Build the full qualified name from the member expression
364+
365+
// For now, we'll extract the name from the member expression
366+
// This assumes the member expression represents something like
367+
// "namespace::Point" You might need to adjust this based on how your AST
368+
// represents member expressions
369+
370+
// Get the member name (the rightmost part, e.g., "Point" in
371+
// "namespace::Point")
372+
struct_name = left->expr.member.member;
373+
374+
// Note: If you need the full qualified name, you'll need to traverse
375+
// the member expression tree and build the complete path
376+
// For example: if left->expr.member.object is also a member expr,
377+
// you'd need to recursively build the name
378+
} else {
356379
parser_error(parser, "SyntaxError", parser->file_path,
357-
"Expected identifier before '{' for named struct",
380+
"Expected identifier or namespace resolution before '{' for "
381+
"named struct",
358382
p_current(parser).line, p_current(parser).col,
359383
p_current(parser).length);
360384
return NULL;
361385
}
362386

363-
char *struct_name = left->expr.identifier.name;
364387
int line = p_current(parser).line;
365388
int col = p_current(parser).col;
366389

@@ -425,7 +448,8 @@ Expr *named_struct_expr(Parser *parser, Expr *left, BindingPower bp) {
425448

426449
p_consume(parser, TOK_RBRACE, "Expected '}' to close struct expression");
427450

428-
// Named struct
451+
// Store the full expression (identifier or member) for later use
452+
// This allows the semantic analyzer to resolve the namespace properly
429453
return create_struct_expr(
430454
parser->arena, struct_name, (char **)field_names.data,
431455
(AstNode **)field_values.data, field_names.count, line, col);
@@ -483,20 +507,26 @@ Expr *free_expr(Parser *parser) {
483507

484508
// cast<TYPE>(value);
485509
Expr *cast_expr(Parser *parser) {
486-
p_advance(parser); // Advance past the cast
487510
int line = p_current(parser).line;
488511
int col = p_current(parser).col;
512+
513+
p_advance(parser); // Advance past 'cast'
489514

490515
p_consume(parser, TOK_LT,
491-
"Expected a '<' before you declare the type you want to cast too.");
516+
"Expected a '<' before you declare the type you want to cast to.");
517+
492518
Type *cast_type = parse_type(parser);
493-
p_advance(parser);
519+
// parse_type() has already advanced past the type
520+
494521
p_consume(parser, TOK_GT,
495-
"Expected a '>' after defining the type you want to cast too, but "
522+
"Expected a '>' after defining the type you want to cast to, but "
496523
"before defining what you are casting");
524+
497525
p_consume(parser, TOK_LPAREN,
498526
"Expected a '(' before defining what you are casting");
527+
499528
Expr *castee = parse_expr(parser, BP_NONE);
529+
500530
p_consume(parser, TOK_RPAREN,
501531
"Expected a ')' after defining what you are casting");
502532

@@ -505,22 +535,27 @@ Expr *cast_expr(Parser *parser) {
505535

506536
// input<TYPE>(msg);
507537
Expr *input_expr(Parser *parser) {
508-
p_advance(parser); // Advance past the cast
509538
int line = p_current(parser).line;
510539
int col = p_current(parser).col;
540+
541+
p_advance(parser); // Advance past 'input'
511542

512543
p_consume(parser, TOK_LT,
513-
"Expected a '<' before you declare the type you want to cast too.");
544+
"Expected a '<' before you declare the type you want to input.");
545+
514546
Type *type = parse_type(parser);
515-
p_advance(parser);
547+
// parse_type() has already advanced past the type
548+
516549
p_consume(parser, TOK_GT,
517-
"Expected a '>' after defining the type you want to cast too, but "
518-
"before defining what you are casting");
550+
"Expected a '>' after defining the type you want to input");
551+
519552
p_consume(parser, TOK_LPAREN,
520-
"Expected a '(' before defining what you are casting");
553+
"Expected a '(' before defining the input message");
554+
521555
Expr *msg = parse_expr(parser, BP_NONE);
556+
522557
p_consume(parser, TOK_RPAREN,
523-
"Expected a ')' after defining what you are casting");
558+
"Expected a ')' after defining the input message");
524559

525560
return create_input_expr(parser->arena, type, msg, line, col);
526561
}
@@ -585,23 +620,30 @@ Expr *syscall_expr(Parser *parser) {
585620
// sizeof<[n]int> Runtime when n is variable
586621
// sizeof<MyStruct> Compile-time constant
587622
Expr *sizeof_expr(Parser *parser) {
588-
p_advance(parser); // Advance past the sizeof
589623
int line = p_current(parser).line;
590624
int col = p_current(parser).col;
591-
AstNode *object = NULL;
592-
bool is_type = false;
593-
625+
626+
p_advance(parser); // Advance past 'sizeof'
627+
594628
p_consume(parser, TOK_LT,
595629
"Expected a '<' before defining the var or type you want to get "
596630
"the size of.");
597-
if (parse_type(parser) != NULL) {
598-
;
599-
object = parse_type(parser);
600-
p_advance(parser);
631+
632+
AstNode *object = NULL;
633+
bool is_type = false;
634+
635+
// Try to parse as a type first
636+
Type *type_result = parse_type(parser);
637+
if (type_result != NULL) {
638+
object = (AstNode *)type_result;
601639
is_type = true;
640+
// parse_type() has already advanced past the type
602641
} else {
603-
object = parse_expr(parser, BP_NONE);
642+
// Not a type, parse as an expression
643+
object = (AstNode *)parse_expr(parser, BP_NONE);
644+
is_type = false;
604645
}
646+
605647
p_consume(parser, TOK_GT,
606648
"Expected a '>' after defining the var or type you want to get the "
607649
"size of.");

src/parser/parser.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,8 @@ Expr *parse_expr(Parser *parser, BindingPower bp) {
402402
Expr *left = nud(parser);
403403

404404
while (p_has_tokens(parser) && get_bp(p_current(parser).type_) > bp) {
405-
left = led(parser, left, get_bp(p_current(parser).type_));
405+
BindingPower current_bp = get_bp(p_current(parser).type_);
406+
left = led(parser, left, current_bp);
406407
}
407408

408409
return left;
@@ -525,13 +526,9 @@ Type *parse_type(Parser *parser) {
525526
case TOK_CHAR:
526527
case TOK_STAR: // Pointer type
527528
case TOK_LBRACKET: // Array type
529+
case TOK_IDENTIFIER: // Could be simple type or namespace::Type
528530
return tnud(parser);
529531

530-
// Optionally: handle identifiers like 'MyStruct' or user-defined types
531-
case TOK_IDENTIFIER:
532-
return create_basic_type(parser->arena, get_name(parser), parser->tks->line,
533-
parser->tks->col);
534-
535532
default:
536533
fprintf(stderr, "[parse_type] Unexpected token for type: %d\n", tok);
537534
return NULL;

0 commit comments

Comments
 (0)