Skip to content

Commit a4a4105

Browse files
authored
Merge pull request #142 from Brainrotlang/fix/array
Fix array limitation
2 parents d0af5c8 + 0c53965 commit a4a4105

File tree

9 files changed

+335
-27
lines changed

9 files changed

+335
-27
lines changed

ast.c

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,20 +1624,19 @@ int evaluate_expression_int(ASTNode *node)
16241624
case NODE_OPERATION:
16251625
{
16261626
// Special handling for logical operations
1627-
if (node->data.op.op == OP_AND || node->data.op.op == OP_OR)
1627+
if (node->data.op.op == OP_AND)
16281628
{
16291629
int left = evaluate_expression_int(node->data.op.left);
1630+
if (!left) return 0;
16301631
int right = evaluate_expression_int(node->data.op.right);
1631-
1632-
switch (node->data.op.op)
1633-
{
1634-
case OP_AND:
1635-
return left && right;
1636-
case OP_OR:
1637-
return left || right;
1638-
default:
1639-
break;
1640-
}
1632+
return left && right;
1633+
}
1634+
if (node->data.op.op == OP_OR)
1635+
{
1636+
int left = evaluate_expression_int(node->data.op.left);
1637+
if (left) return 1;
1638+
int right = evaluate_expression_int(node->data.op.right);
1639+
return left || right;
16411640
}
16421641

16431642
// Regular integer operations
@@ -1748,20 +1747,19 @@ bool evaluate_expression_bool(ASTNode *node)
17481747
case NODE_OPERATION:
17491748
{
17501749
// Special handling for logical operations
1751-
if (node->data.op.op == OP_AND || node->data.op.op == OP_OR)
1750+
if (node->data.op.op == OP_AND)
17521751
{
17531752
bool left = evaluate_expression_bool(node->data.op.left);
1753+
if (!left) return false;
17541754
bool right = evaluate_expression_bool(node->data.op.right);
1755-
1756-
switch (node->data.op.op)
1757-
{
1758-
case OP_AND:
1759-
return left && right;
1760-
case OP_OR:
1761-
return left || right;
1762-
default:
1763-
break;
1764-
}
1755+
return left && right;
1756+
}
1757+
if (node->data.op.op == OP_OR)
1758+
{
1759+
bool left = evaluate_expression_bool(node->data.op.left);
1760+
if (left) return true;
1761+
bool right = evaluate_expression_bool(node->data.op.right);
1762+
return left || right;
17651763
}
17661764

17671765
// Regular integer operations
@@ -1928,7 +1926,7 @@ bool is_short_expression(ASTNode *node)
19281926
return false;
19291927
case NODE_ARRAY_ACCESS:
19301928
{
1931-
Variable *var = get_variable(node->data.name);
1929+
Variable *var = get_variable(node->data.array.name);
19321930
if (var != NULL)
19331931
{
19341932
return var->var_type == VAR_SHORT;
@@ -2003,6 +2001,15 @@ bool is_float_expression(ASTNode *node)
20032001
case NODE_DOUBLE:
20042002
return false;
20052003
case NODE_ARRAY_ACCESS:
2004+
{
2005+
Variable *var = get_variable(node->data.array.name);
2006+
if (var != NULL)
2007+
{
2008+
return var->var_type == VAR_FLOAT;
2009+
}
2010+
yyerror("Undefined variable in type check");
2011+
return false;
2012+
}
20062013
case NODE_IDENTIFIER:
20072014
{
20082015
if (!check_and_mark_identifier(node, "Undefined variable in type check"))
@@ -2044,6 +2051,15 @@ bool is_double_expression(ASTNode *node)
20442051
case NODE_INT:
20452052
return false;
20462053
case NODE_ARRAY_ACCESS:
2054+
{
2055+
Variable *var = get_variable(node->data.array.name);
2056+
if (var != NULL)
2057+
{
2058+
return var->var_type == VAR_DOUBLE;
2059+
}
2060+
yyerror("Undefined variable in type check");
2061+
return false;
2062+
}
20472063
case NODE_IDENTIFIER:
20482064
{
20492065
if (!check_and_mark_identifier(node, "Undefined variable in type check"))
@@ -2225,7 +2241,7 @@ void execute_statement(ASTNode *node)
22252241
if (node->data.op.left->type == NODE_ARRAY_ACCESS)
22262242
{
22272243
ASTNode *array_node = node->data.op.left;
2228-
Variable *var = get_variable(array_node->data.name);
2244+
Variable *var = get_variable(array_node->data.array.name);
22292245
void *element = evaluate_multi_array_access(array_node);
22302246
switch (var->var_type)
22312247
{

lang.y

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,12 @@ ASTNode *root = NULL;
9292
%type <node> assignment
9393
%type <node> literal identifier sizeof_expression
9494
%type <expr_list> array_init initializer_list
95+
%type <expr_list> row_list row
9596
%type <node> function_def
9697
%type <node> function_def_list
9798
%type <param> param_list params
9899
%type <array_dims> dimensions
100+
%type <array_dims> dimensions_or_unsized
99101
%type <array> multi_dimension_access
100102

101103
%start program
@@ -260,11 +262,42 @@ declaration:
260262
SAFE_FREE(var);
261263
free_expression_list($6);
262264
}
265+
| optional_modifiers type IDENTIFIER dimensions_or_unsized EQUALS array_init
266+
{
267+
Variable *var = variable_new($3);
268+
add_variable_to_scope($3, var);
269+
ArrayDimensions dims = $4;
270+
if (dims.num_dimensions == 0) {
271+
size_t n = count_expression_list($6);
272+
if (n <= 0 || n > MAX_DIMENSIONS ? 0 : 0) { /* keep structure, no-op */ }
273+
dims.dimensions[0] = (int)n;
274+
dims.num_dimensions = 1;
275+
} else if (dims.dimensions[0] == 0 && dims.num_dimensions >= 2) {
276+
/* Partially unsized: infer first dimension by dividing total inits by product of trailing dims */
277+
size_t total_inits = count_expression_list($6);
278+
size_t trailing = 1;
279+
for (int i = 1; i < dims.num_dimensions; i++) trailing *= (size_t)dims.dimensions[i];
280+
if (trailing == 0) { yyerror("Invalid array dimensions"); YYABORT; }
281+
if (total_inits % trailing != 0) { yyerror("Initializer count does not match array dimensions"); YYABORT; }
282+
size_t first = total_inits / trailing;
283+
dims.dimensions[0] = (int)first;
284+
}
285+
int tmp_dims[MAX_DIMENSIONS];
286+
for (int i = 0; i < dims.num_dimensions; i++) tmp_dims[i] = dims.dimensions[i];
287+
set_multi_array_variable($3, tmp_dims, dims.num_dimensions, get_current_modifiers(), $2);
288+
populate_multi_array_variable($3, $6, tmp_dims, dims.num_dimensions);
289+
$$ = create_multi_array_declaration_node($3, tmp_dims, dims.num_dimensions, $2);
290+
SAFE_FREE($3);
291+
SAFE_FREE(var);
292+
free_expression_list($6);
293+
}
263294
;
264295

265296
array_init:
266297
LBRACE initializer_list RBRACE
267298
{ $$ = $2; }
299+
| LBRACE row_list RBRACE
300+
{ $$ = $2; }
268301
;
269302

270303
dimensions:
@@ -284,13 +317,56 @@ dimensions:
284317
}
285318
;
286319

320+
dimensions_or_unsized:
321+
LBRACKET RBRACKET
322+
{
323+
$$.num_dimensions = 0; /* marker for unsized 1D array to infer */
324+
}
325+
| LBRACKET RBRACKET dimensions
326+
{
327+
/* Partially unsized: infer first dimension later */
328+
$$.dimensions[0] = 0;
329+
for (int i = 0; i < $3.num_dimensions; i++) {
330+
$$.dimensions[i + 1] = $3.dimensions[i];
331+
}
332+
$$.num_dimensions = $3.num_dimensions + 1;
333+
}
334+
| dimensions
335+
{ $$ = $1; }
336+
;
337+
287338
initializer_list:
288339
expression
289340
{ $$ = create_expression_list($1); }
290341
| initializer_list COMMA expression
291342
{ $$ = append_expression_list($1, $3); }
292343
;
293344

345+
row_list:
346+
row
347+
{ $$ = $1; }
348+
| row_list COMMA row
349+
{
350+
ExpressionList *acc = $1;
351+
ExpressionList *start = $3;
352+
if (start) {
353+
ExpressionList *cur = start;
354+
do {
355+
acc = append_expression_list(acc, cur->expr);
356+
cur = cur->next;
357+
} while (cur != start);
358+
/* Free the temporary 'start' list nodes now that we've copied exprs */
359+
free_expression_list(start);
360+
}
361+
$$ = acc;
362+
}
363+
;
364+
365+
row:
366+
LBRACE initializer_list RBRACE
367+
{ $$ = $2; }
368+
;
369+
294370
optional_modifiers:
295371
/* empty */
296372
{ /* No action needed */ }

test_cases/grid_bfs.brainrot

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
skibidi main {
2+
🚽 0 = open, 1 = wall
3+
rizz grid[][5] = {
4+
{0,0,0,1,0},
5+
{1,1,0,1,0},
6+
{0,0,0,0,0},
7+
{0,1,1,1,0},
8+
{0,0,0,1,0}
9+
};
10+
11+
rizz rows = 5;
12+
rizz cols = 5;
13+
14+
🚽 BFS from (0,0) to (4,4)
15+
rizz qx[] = {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
16+
rizz qy[] = {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
17+
rizz head = 0;
18+
rizz tail = 0;
19+
20+
rizz dist[][5] = {
21+
{ -1,-1,-1,-1,-1 },
22+
{ -1,-1,-1,-1,-1 },
23+
{ -1,-1,-1,-1,-1 },
24+
{ -1,-1,-1,-1,-1 },
25+
{ -1,-1,-1,-1,-1 }
26+
};
27+
28+
rizz sx = 0; rizz sy = 0;
29+
rizz tx = 4; rizz ty = 4;
30+
31+
edgy (grid[sx][sy] == 1) { yapping("%d", -1); bussin 0; }
32+
33+
dist[sx][sy] = 0;
34+
qx[tail] = sx; qy[tail] = sy; tail = tail + 1;
35+
36+
goon (head < tail) {
37+
rizz x = qx[head]; rizz y = qy[head]; head = head + 1;
38+
edgy (x == tx && y == ty) { bruh; }
39+
40+
rizz nx; rizz ny;
41+
42+
nx = x + 1; ny = y;
43+
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
44+
dist[nx][ny] = dist[x][y] + 1; qx[tail] = nx; qy[tail] = ny; tail = tail + 1;
45+
}
46+
47+
nx = x - 1; ny = y;
48+
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
49+
dist[nx][ny] = dist[x][y] + 1; qx[tail] = nx; qy[tail] = ny; tail = tail + 1;
50+
}
51+
52+
nx = x; ny = y + 1;
53+
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
54+
dist[nx][ny] = dist[x][y] + 1; qx[tail] = nx; qy[tail] = ny; tail = tail + 1;
55+
}
56+
57+
nx = x; ny = y - 1;
58+
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
59+
dist[nx][ny] = dist[x][y] + 1; qx[tail] = nx; qy[tail] = ny; tail = tail + 1;
60+
}
61+
}
62+
63+
yapping("%d", dist[tx][ty]);
64+
}

test_cases/grid_bfs_1d.brainrot

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
🚽 Breadth-First Search (BFS) on the same 5x5 grid but flattened to 1D.
2+
🚽 Avoids multi-dimensional indexing by mapping (x,y) to idx = x*cols + y.
3+
🚽 Prints the shortest path distance from startIdx (0,0) to goal (4,4).
4+
skibidi main {
5+
🚽 0 = open, 1 = wall
6+
rizz rows = 5; rizz cols = 5;
7+
rizz grid1d[] = {
8+
0,0,0,1,0,
9+
1,1,0,1,0,
10+
0,0,0,0,0,
11+
0,1,1,1,0,
12+
0,0,0,1,0
13+
};
14+
15+
rizz dist1d[] = {
16+
-1,-1,-1,-1,-1,
17+
-1,-1,-1,-1,-1,
18+
-1,-1,-1,-1,-1,
19+
-1,-1,-1,-1,-1,
20+
-1,-1,-1,-1,-1
21+
};
22+
23+
rizz q[] = {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
24+
rizz head = 0; rizz tail = 0;
25+
26+
rizz sx = 0; rizz sy = 0; rizz tx = 4; rizz ty = 4;
27+
rizz startIdx = sx * cols + sy;
28+
rizz goal = tx * cols + ty;
29+
30+
edgy (grid1d[startIdx] == 1) { yapping("%d", -1); bussin 0; }
31+
32+
dist1d[startIdx] = 0;
33+
q[tail] = startIdx; tail = tail + 1;
34+
35+
goon (head < tail) {
36+
rizz cur = q[head]; head = head + 1;
37+
edgy (cur == goal) { bruh; }
38+
rizz x = cur / cols; rizz y = cur % cols;
39+
rizz nx; rizz ny; rizz nxt;
40+
41+
nx = x + 1; ny = y;
42+
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
43+
nxt = nx * cols + ny;
44+
edgy (grid1d[nxt] == 0 && dist1d[nxt] == -1) {
45+
dist1d[nxt] = dist1d[cur] + 1; q[tail] = nxt; tail = tail + 1;
46+
}
47+
}
48+
nx = x - 1; ny = y;
49+
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
50+
nxt = nx * cols + ny;
51+
edgy (grid1d[nxt] == 0 && dist1d[nxt] == -1) {
52+
dist1d[nxt] = dist1d[cur] + 1; q[tail] = nxt; tail = tail + 1;
53+
}
54+
}
55+
nx = x; ny = y + 1;
56+
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
57+
nxt = nx * cols + ny;
58+
edgy (grid1d[nxt] == 0 && dist1d[nxt] == -1) {
59+
dist1d[nxt] = dist1d[cur] + 1; q[tail] = nxt; tail = tail + 1;
60+
}
61+
}
62+
nx = x; ny = y - 1;
63+
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
64+
nxt = nx * cols + ny;
65+
edgy (grid1d[nxt] == 0 && dist1d[nxt] == -1) {
66+
dist1d[nxt] = dist1d[cur] + 1; q[tail] = nxt; tail = tail + 1;
67+
}
68+
}
69+
}
70+
71+
yapping("%d", dist1d[goal]);
72+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
skibidi main {
2+
rizz a[3][3] = {
3+
{1, 2, 3},
4+
{4, 5, 6},
5+
{7, 8, 9}
6+
};
7+
8+
rizz b[][3] = {
9+
{1, 2, 3},
10+
{4, 5, 6},
11+
{7, 8, 9}
12+
};
13+
14+
yapping("%d", a[2][1]);
15+
yapping("%d", b[2][1]);
16+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
🚽 Tests 2D array initializers: fixed and partially-unsized first dimension
2+
skibidi main {
3+
rizz a[3][3] = {
4+
{1, 2, 3},
5+
{4, 5, 6},
6+
{7, 8, 9}
7+
};
8+
9+
rizz b[][3] = {
10+
{1, 2, 3},
11+
{4, 5, 6},
12+
{7, 8, 9}
13+
};
14+
15+
yapping("%d", a[0][0]);
16+
yapping("%d", a[2][2]);
17+
yapping("%d", b[1][2]);
18+
}

0 commit comments

Comments
 (0)