Skip to content

Commit f60006e

Browse files
committed
Simplify method declaration
1 parent eb6e262 commit f60006e

File tree

10 files changed

+139
-211
lines changed

10 files changed

+139
-211
lines changed

examples/017_struct_methods.tea

Lines changed: 77 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -17,104 +17,95 @@ typedef Counter {
1717
max_value: i32;
1818
}
1919

20-
// Implement methods for Point
21-
impl Point {
22-
// Method that calculates distance to another point
23-
fn distance_to(other: Point) -> f32 {
24-
let dx = self.x - other.x;
25-
let dy = self.y - other.y;
26-
return dx * dx + dy * dy; // Squared distance (avoiding sqrt)
27-
}
28-
29-
// Method that modifies the point (moves it)
30-
fn mut move_by(dx: f32, dy: f32) {
31-
self.x = self.x + dx;
32-
self.y = self.y + dy;
33-
}
34-
35-
// Method that returns a coordinate
36-
fn get_x() -> f32 {
37-
return self.x;
38-
}
39-
40-
fn get_y() -> f32 {
41-
return self.y;
42-
}
20+
// Method that calculates distance to another point
21+
fn Point.distance_to(other: Point) -> f32 {
22+
let dx = self.x - other.x;
23+
let dy = self.y - other.y;
24+
return dx * dx + dy * dy; // Squared distance (avoiding sqrt)
25+
}
4326

44-
// Method that checks if point is at origin
45-
fn is_at_origin() -> f32 {
46-
if self.x == 0.0 && self.y == 0.0 {
47-
return 1.0; // true
48-
} else {
49-
return 0.0; // false
50-
}
51-
}
27+
// Method that modifies the point (moves it)
28+
fn mut Point.move_by(dx: f32, dy: f32) {
29+
self.x = self.x + dx;
30+
self.y = self.y + dy;
5231
}
5332

54-
// Implement methods for Rectangle
55-
impl Rectangle {
56-
// Calculate area
57-
fn area() -> f32 {
58-
return self.width * self.height;
59-
}
60-
61-
// Calculate perimeter
62-
fn perimeter() -> f32 {
63-
return 2.0 * (self.width + self.height);
64-
}
65-
66-
// Check if it's a square
67-
fn is_square() -> f32 {
68-
if self.width == self.height {
69-
return 1.0; // true
70-
} else {
71-
return 0.0; // false
72-
}
73-
}
74-
75-
// Scale the rectangle
76-
fn mut scale(factor: f32) {
77-
self.width = self.width * factor;
78-
self.height = self.height * factor;
79-
}
33+
// Method that returns a coordinate
34+
fn Point.get_x() -> f32 {
35+
return self.x;
36+
}
37+
38+
fn Point.get_y() -> f32 {
39+
return self.y;
8040
}
8141

82-
// Implement methods for Counter
83-
impl Counter {
84-
// Increment counter
85-
fn mut increment() {
86-
if self.value < self.max_value {
87-
self.value = self.value + 1;
88-
}
42+
// Method that checks if point is at origin
43+
fn Point.is_at_origin() -> f32 {
44+
if self.x == 0.0 && self.y == 0.0 {
45+
return 1.0; // true
46+
} else {
47+
return 0.0; // false
8948
}
90-
91-
// Decrement counter
92-
fn decrement() {
93-
if self.value > 0 {
94-
self.value = self.value - 1;
95-
}
49+
}
50+
51+
// Calculate area
52+
fn Rectangle.area() -> f32 {
53+
return self.width * self.height;
54+
}
55+
56+
// Calculate perimeter
57+
fn Rectangle.perimeter() -> f32 {
58+
return 2.0 * (self.width + self.height);
59+
}
60+
61+
// Check if it's a square
62+
fn Rectangle.is_square() -> f32 {
63+
if self.width == self.height {
64+
return 1.0; // true
65+
} else {
66+
return 0.0; // false
9667
}
97-
98-
// Reset counter
99-
fn mut reset() {
100-
self.value = 0;
68+
}
69+
70+
// Scale the rectangle
71+
fn mut Rectangle.scale(factor: f32) {
72+
self.width = self.width * factor;
73+
self.height = self.height * factor;
74+
}
75+
76+
// Increment counter
77+
fn mut Counter.increment() {
78+
if self.value < self.max_value {
79+
self.value = self.value + 1;
10180
}
102-
103-
// Check if counter is at maximum
104-
fn is_at_max() -> f32 {
105-
if self.value == self.max_value {
106-
return 1.0; // true
107-
} else {
108-
return 0.0; // false
109-
}
81+
}
82+
83+
// Decrement counter
84+
fn Counter.decrement() {
85+
if self.value > 0 {
86+
self.value = self.value - 1;
11087
}
111-
112-
// Get percentage
113-
fn percentage() -> f32 {
114-
return self.value * 100.0 / self.max_value;
88+
}
89+
90+
// Reset counter
91+
fn mut Counter.reset() {
92+
self.value = 0;
93+
}
94+
95+
// Check if counter is at maximum
96+
fn Counter.is_at_max() -> f32 {
97+
if self.value == self.max_value {
98+
return 1.0; // true
99+
} else {
100+
return 0.0; // false
115101
}
116102
}
117103

104+
// Get percentage
105+
fn Counter.percentage() -> f32 {
106+
return self.value * 100.0 / self.max_value;
107+
}
108+
118109
// Using type methods
119110
let mut p1 = new Point { x: 1.0, y: 2.0 };
120111
let p2 = new Point { x: 4.0, y: 6.0 };

include/tea_ast.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#pragma once
22

33
#include "tea_list.h"
4-
54
#include "tea_token.h"
65

76
typedef enum {
@@ -17,6 +16,7 @@ typedef enum {
1716
TEA_N_BINOP,
1817
TEA_N_UNARY,
1918
TEA_N_IDENT,
19+
TEA_N_OWNER,
2020
TEA_N_TYPE_ANNOT,
2121
TEA_N_INT,
2222
TEA_N_FLOAT,
@@ -35,13 +35,10 @@ typedef enum {
3535
TEA_N_STRUCT_FIELD,
3636
TEA_N_STRUCT_INST,
3737
TEA_N_STRUCT_INIT,
38-
TEA_N_IMPL_ITEM,
39-
TEA_N_IMPL_BLK,
4038
TEA_N_STR,
4139
TEA_N_FIELD_ACC,
4240
TEA_N_OPT_TYPE,
4341
TEA_N_NULL,
44-
4542
} tea_node_type_t;
4643

4744
typedef struct tea_node {

include/tea_fn.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ const tea_native_fn_t *tea_ctx_find_native_fn(const tea_list_entry_t *functions,
3737
const tea_fn_t *tea_ctx_find_fn(const tea_list_entry_t *functions,
3838
const char *name);
3939

40-
bool tea_decl_fn(const tea_node_t *node, tea_list_entry_t *functions);
41-
bool tea_interp_fn_decl(tea_ctx_t *ctx, const tea_node_t *node);
40+
bool tea_exec_fn_decl(tea_ctx_t *ctx, const tea_node_t *node);
4241

4342
tea_val_t tea_eval_fn_call(tea_ctx_t *ctx, tea_scope_t *scp,
4443
const tea_node_t *node);

include/tea_struct.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,17 @@
77
typedef struct {
88
tea_list_entry_t link;
99
const tea_node_t *node;
10-
unsigned long field_cnt;
10+
unsigned long field_count;
1111
tea_list_entry_t funcs;
1212
} tea_struct_decl_t;
1313

14-
bool tea_interp_struct_decl(tea_ctx_t *ctx, const tea_node_t *node);
14+
bool tea_exec_struct_decl(tea_ctx_t *ctx, const tea_node_t *node);
1515
tea_struct_decl_t *tea_find_struct_decl(const tea_ctx_t *ctx, const char *name);
1616

17-
bool tea_interp_impl_blk(const tea_ctx_t *ctx, const tea_node_t *node);
18-
1917
tea_val_t tea_eval_new(tea_ctx_t *ctx, tea_scope_t *scp,
2018
const tea_node_t *node);
2119

22-
tea_val_t tea_eval_field_acc(const tea_ctx_t *ctx, const tea_scope_t *scp,
23-
const tea_node_t *node);
20+
tea_val_t tea_eval_field_access(const tea_ctx_t *ctx, const tea_scope_t *scp,
21+
const tea_node_t *node);
2422
tea_val_t *tea_get_field_ptr(const tea_ctx_t *ctx, const tea_scope_t *scp,
2523
const tea_node_t *node);

src/tea_ast.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ const char *tea_node_type_name(const tea_node_type_t type)
110110
return "UNARY";
111111
case TEA_N_IDENT:
112112
return "IDENT";
113+
case TEA_N_OWNER:
114+
return "OWNER";
113115
case TEA_N_TYPE_ANNOT:
114116
return "TYPE_ANNOT";
115117
case TEA_N_INT:
@@ -150,15 +152,10 @@ const char *tea_node_type_name(const tea_node_type_t type)
150152
return "STRING";
151153
case TEA_N_FIELD_ACC:
152154
return "FIELD_ACCESS";
153-
case TEA_N_IMPL_ITEM:
154-
return "IMPL_ITEM";
155-
case TEA_N_IMPL_BLK:
156-
return "IMPL_BLOCK";
157155
case TEA_N_OPT_TYPE:
158156
return "OPTIONAL_TYPE";
159157
case TEA_N_NULL:
160158
return "NULL";
161-
162159
default:
163160
return "UNKNOWN";
164161
}

src/tea_expr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ tea_val_t tea_eval_expr(tea_ctx_t *ctx, tea_scope_t *scp,
150150
case TEA_N_STRUCT_INST:
151151
return tea_eval_new(ctx, scp, node);
152152
case TEA_N_FIELD_ACC:
153-
return tea_eval_field_acc(ctx, scp, node);
153+
return tea_eval_field_access(ctx, scp, node);
154154
case TEA_N_NULL:
155155
return tea_val_null();
156156
default: {

src/tea_fn.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const tea_fn_t *tea_ctx_find_fn(const tea_list_entry_t *functions,
5858
return NULL;
5959
}
6060

61-
bool tea_decl_fn(const tea_node_t *node, tea_list_entry_t *functions)
61+
bool tea_exec_fn_decl(tea_ctx_t *ctx, const tea_node_t *node)
6262
{
6363
const tea_tok_t *fn_name = node->tok;
6464
if (!fn_name) {
@@ -68,6 +68,7 @@ bool tea_decl_fn(const tea_node_t *node, tea_list_entry_t *functions)
6868
const tea_node_t *fn_ret_type = NULL;
6969
const tea_node_t *fn_body = NULL;
7070
const tea_node_t *fn_params = NULL;
71+
const tea_node_t *fn_owner = NULL;
7172

7273
bool is_mutable = false;
7374

@@ -82,6 +83,8 @@ bool tea_decl_fn(const tea_node_t *node, tea_list_entry_t *functions)
8283
case TEA_N_RET_TYPE:
8384
fn_ret_type = child;
8485
break;
86+
case TEA_N_OWNER:
87+
fn_owner = child;
8588
case TEA_N_MUT:
8689
is_mutable = true;
8790
break;
@@ -106,23 +109,34 @@ bool tea_decl_fn(const tea_node_t *node, tea_list_entry_t *functions)
106109
fn->ret_type = NULL;
107110
}
108111

109-
tea_list_add_tail(functions, &fn->link);
112+
if (fn_owner) {
113+
const tea_tok_t *owner_name = fn_owner->tok;
114+
tea_struct_decl_t *struct_declaration =
115+
tea_find_struct_decl(ctx, owner_name->buf);
116+
if (!struct_declaration) {
117+
tea_log_err(
118+
"Runtime error: Cannot implement methods for undeclared type '%s'",
119+
owner_name->buf);
120+
return false;
121+
}
122+
tea_list_add_tail(&struct_declaration->funcs, &fn->link);
123+
} else {
124+
tea_list_add_tail(&ctx->funcs, &fn->link);
125+
}
110126

111127
if (fn->ret_type) {
112-
tea_log_dbg("Declare function: '%.*s' -> %.*s", fn_name->size, fn_name->buf,
113-
fn->ret_type->size, fn->ret_type->buf);
128+
tea_log_dbg("Declare function: '%s%s%s' -> %s",
129+
fn_owner ? fn_owner->tok->buf : "", fn_owner ? "." : "",
130+
fn_name->buf, fn->ret_type->buf);
114131
} else {
115-
tea_log_dbg("Declare function: '%.*s'", fn_name->size, fn_name->buf);
132+
tea_log_dbg("Declare function: '%s%s%s'",
133+
fn_owner ? fn_owner->tok->buf : "", fn_owner ? "." : "",
134+
fn_name->buf);
116135
}
117136

118137
return true;
119138
}
120139

121-
bool tea_interp_fn_decl(tea_ctx_t *ctx, const tea_node_t *node)
122-
{
123-
return tea_decl_fn(node, &ctx->funcs);
124-
}
125-
126140
static void tea_cleanup_fn_args(tea_ctx_t *ctx, const tea_fn_args_t *fn_args)
127141
{
128142
tea_list_entry_t *cleanup_entry;

src/tea_stmt.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ bool tea_exec(tea_ctx_t *ctx, tea_scope_t *scp, const tea_node_t *node,
388388
case TEA_N_WHILE:
389389
return tea_exec_while(ctx, scp, node, ret_ctx);
390390
case TEA_N_FN:
391-
return tea_interp_fn_decl(ctx, node);
391+
return tea_exec_fn_decl(ctx, node);
392392
case TEA_N_RET:
393393
return tea_exec_return(ctx, scp, node, ret_ctx);
394394
case TEA_N_BREAK:
@@ -399,9 +399,7 @@ bool tea_exec(tea_ctx_t *ctx, tea_scope_t *scp, const tea_node_t *node,
399399
tea_eval_fn_call(ctx, scp, node);
400400
return true;
401401
case TEA_N_STRUCT:
402-
return tea_interp_struct_decl(ctx, node);
403-
case TEA_N_IMPL_BLK:
404-
return tea_interp_impl_blk(ctx, node);
402+
return tea_exec_struct_decl(ctx, node);
405403
case TEA_N_PROG:
406404
case TEA_N_STMT:
407405
case TEA_N_FN_ARGS:

0 commit comments

Comments
 (0)