Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 40 additions & 24 deletions ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1624,20 +1624,19 @@ int evaluate_expression_int(ASTNode *node)
case NODE_OPERATION:
{
// Special handling for logical operations
if (node->data.op.op == OP_AND || node->data.op.op == OP_OR)
if (node->data.op.op == OP_AND)
{
int left = evaluate_expression_int(node->data.op.left);
if (!left) return 0;
int right = evaluate_expression_int(node->data.op.right);

switch (node->data.op.op)
{
case OP_AND:
return left && right;
case OP_OR:
return left || right;
default:
break;
}
return left && right;
}
if (node->data.op.op == OP_OR)
{
int left = evaluate_expression_int(node->data.op.left);
if (left) return 1;
int right = evaluate_expression_int(node->data.op.right);
return left || right;
}

// Regular integer operations
Expand Down Expand Up @@ -1748,20 +1747,19 @@ bool evaluate_expression_bool(ASTNode *node)
case NODE_OPERATION:
{
// Special handling for logical operations
if (node->data.op.op == OP_AND || node->data.op.op == OP_OR)
if (node->data.op.op == OP_AND)
{
bool left = evaluate_expression_bool(node->data.op.left);
if (!left) return false;
bool right = evaluate_expression_bool(node->data.op.right);

switch (node->data.op.op)
{
case OP_AND:
return left && right;
case OP_OR:
return left || right;
default:
break;
}
return left && right;
}
if (node->data.op.op == OP_OR)
{
bool left = evaluate_expression_bool(node->data.op.left);
if (left) return true;
bool right = evaluate_expression_bool(node->data.op.right);
return left || right;
}

// Regular integer operations
Expand Down Expand Up @@ -1928,7 +1926,7 @@ bool is_short_expression(ASTNode *node)
return false;
case NODE_ARRAY_ACCESS:
{
Variable *var = get_variable(node->data.name);
Variable *var = get_variable(node->data.array.name);
if (var != NULL)
{
return var->var_type == VAR_SHORT;
Expand Down Expand Up @@ -2003,6 +2001,15 @@ bool is_float_expression(ASTNode *node)
case NODE_DOUBLE:
return false;
case NODE_ARRAY_ACCESS:
{
Variable *var = get_variable(node->data.array.name);
if (var != NULL)
{
return var->var_type == VAR_FLOAT;
}
yyerror("Undefined variable in type check");
return false;
}
case NODE_IDENTIFIER:
{
if (!check_and_mark_identifier(node, "Undefined variable in type check"))
Expand Down Expand Up @@ -2044,6 +2051,15 @@ bool is_double_expression(ASTNode *node)
case NODE_INT:
return false;
case NODE_ARRAY_ACCESS:
{
Variable *var = get_variable(node->data.array.name);
if (var != NULL)
{
return var->var_type == VAR_DOUBLE;
}
yyerror("Undefined variable in type check");
return false;
}
case NODE_IDENTIFIER:
{
if (!check_and_mark_identifier(node, "Undefined variable in type check"))
Expand Down Expand Up @@ -2225,7 +2241,7 @@ void execute_statement(ASTNode *node)
if (node->data.op.left->type == NODE_ARRAY_ACCESS)
{
ASTNode *array_node = node->data.op.left;
Variable *var = get_variable(array_node->data.name);
Variable *var = get_variable(array_node->data.array.name);
void *element = evaluate_multi_array_access(array_node);
switch (var->var_type)
{
Expand Down
76 changes: 76 additions & 0 deletions lang.y
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,12 @@ ASTNode *root = NULL;
%type <node> assignment
%type <node> literal identifier sizeof_expression
%type <expr_list> array_init initializer_list
%type <expr_list> row_list row
%type <node> function_def
%type <node> function_def_list
%type <param> param_list params
%type <array_dims> dimensions
%type <array_dims> dimensions_or_unsized
%type <array> multi_dimension_access

%start program
Expand Down Expand Up @@ -260,11 +262,42 @@ declaration:
SAFE_FREE(var);
free_expression_list($6);
}
| optional_modifiers type IDENTIFIER dimensions_or_unsized EQUALS array_init
{
Variable *var = variable_new($3);
add_variable_to_scope($3, var);
ArrayDimensions dims = $4;
if (dims.num_dimensions == 0) {
size_t n = count_expression_list($6);
if (n <= 0 || n > MAX_DIMENSIONS ? 0 : 0) { /* keep structure, no-op */ }
dims.dimensions[0] = (int)n;
dims.num_dimensions = 1;
} else if (dims.dimensions[0] == 0 && dims.num_dimensions >= 2) {
/* Partially unsized: infer first dimension by dividing total inits by product of trailing dims */
size_t total_inits = count_expression_list($6);
size_t trailing = 1;
for (int i = 1; i < dims.num_dimensions; i++) trailing *= (size_t)dims.dimensions[i];
if (trailing == 0) { yyerror("Invalid array dimensions"); YYABORT; }
if (total_inits % trailing != 0) { yyerror("Initializer count does not match array dimensions"); YYABORT; }
size_t first = total_inits / trailing;
dims.dimensions[0] = (int)first;
}
int tmp_dims[MAX_DIMENSIONS];
for (int i = 0; i < dims.num_dimensions; i++) tmp_dims[i] = dims.dimensions[i];
set_multi_array_variable($3, tmp_dims, dims.num_dimensions, get_current_modifiers(), $2);
populate_multi_array_variable($3, $6, tmp_dims, dims.num_dimensions);
$$ = create_multi_array_declaration_node($3, tmp_dims, dims.num_dimensions, $2);
SAFE_FREE($3);
SAFE_FREE(var);
free_expression_list($6);
}
;

array_init:
LBRACE initializer_list RBRACE
{ $$ = $2; }
| LBRACE row_list RBRACE
{ $$ = $2; }
;

dimensions:
Expand All @@ -284,13 +317,56 @@ dimensions:
}
;

dimensions_or_unsized:
LBRACKET RBRACKET
{
$$.num_dimensions = 0; /* marker for unsized 1D array to infer */
}
| LBRACKET RBRACKET dimensions
{
/* Partially unsized: infer first dimension later */
$$.dimensions[0] = 0;
for (int i = 0; i < $3.num_dimensions; i++) {
$$.dimensions[i + 1] = $3.dimensions[i];
}
$$.num_dimensions = $3.num_dimensions + 1;
}
| dimensions
{ $$ = $1; }
;

initializer_list:
expression
{ $$ = create_expression_list($1); }
| initializer_list COMMA expression
{ $$ = append_expression_list($1, $3); }
;

row_list:
row
{ $$ = $1; }
| row_list COMMA row
{
ExpressionList *acc = $1;
ExpressionList *start = $3;
if (start) {
ExpressionList *cur = start;
do {
acc = append_expression_list(acc, cur->expr);
cur = cur->next;
} while (cur != start);
/* Free the temporary 'start' list nodes now that we've copied exprs */
free_expression_list(start);
}
$$ = acc;
}
;

row:
LBRACE initializer_list RBRACE
{ $$ = $2; }
;

optional_modifiers:
/* empty */
{ /* No action needed */ }
Expand Down
64 changes: 64 additions & 0 deletions test_cases/grid_bfs.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
skibidi main {
🚽 0 = open, 1 = wall
rizz grid[][5] = {
{0,0,0,1,0},
{1,1,0,1,0},
{0,0,0,0,0},
{0,1,1,1,0},
{0,0,0,1,0}
};

rizz rows = 5;
rizz cols = 5;

🚽 BFS from (0,0) to (4,4)
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};
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};
rizz head = 0;
rizz tail = 0;

rizz dist[][5] = {
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 }
};

rizz sx = 0; rizz sy = 0;
rizz tx = 4; rizz ty = 4;

edgy (grid[sx][sy] == 1) { yapping("%d", -1); bussin 0; }

dist[sx][sy] = 0;
qx[tail] = sx; qy[tail] = sy; tail = tail + 1;

goon (head < tail) {
rizz x = qx[head]; rizz y = qy[head]; head = head + 1;
edgy (x == tx && y == ty) { bruh; }

rizz nx; rizz ny;

nx = x + 1; ny = y;
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
dist[nx][ny] = dist[x][y] + 1; qx[tail] = nx; qy[tail] = ny; tail = tail + 1;
}

nx = x - 1; ny = y;
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
dist[nx][ny] = dist[x][y] + 1; qx[tail] = nx; qy[tail] = ny; tail = tail + 1;
}

nx = x; ny = y + 1;
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
dist[nx][ny] = dist[x][y] + 1; qx[tail] = nx; qy[tail] = ny; tail = tail + 1;
}

nx = x; ny = y - 1;
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
dist[nx][ny] = dist[x][y] + 1; qx[tail] = nx; qy[tail] = ny; tail = tail + 1;
}
}

yapping("%d", dist[tx][ty]);
}
72 changes: 72 additions & 0 deletions test_cases/grid_bfs_1d.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
🚽 Breadth-First Search (BFS) on the same 5x5 grid but flattened to 1D.
🚽 Avoids multi-dimensional indexing by mapping (x,y) to idx = x*cols + y.
🚽 Prints the shortest path distance from startIdx (0,0) to goal (4,4).
skibidi main {
🚽 0 = open, 1 = wall
rizz rows = 5; rizz cols = 5;
rizz grid1d[] = {
0,0,0,1,0,
1,1,0,1,0,
0,0,0,0,0,
0,1,1,1,0,
0,0,0,1,0
};

rizz dist1d[] = {
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1
};

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};
rizz head = 0; rizz tail = 0;

rizz sx = 0; rizz sy = 0; rizz tx = 4; rizz ty = 4;
rizz startIdx = sx * cols + sy;
rizz goal = tx * cols + ty;

edgy (grid1d[startIdx] == 1) { yapping("%d", -1); bussin 0; }

dist1d[startIdx] = 0;
q[tail] = startIdx; tail = tail + 1;

goon (head < tail) {
rizz cur = q[head]; head = head + 1;
edgy (cur == goal) { bruh; }
rizz x = cur / cols; rizz y = cur % cols;
rizz nx; rizz ny; rizz nxt;

nx = x + 1; ny = y;
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
nxt = nx * cols + ny;
edgy (grid1d[nxt] == 0 && dist1d[nxt] == -1) {
dist1d[nxt] = dist1d[cur] + 1; q[tail] = nxt; tail = tail + 1;
}
}
nx = x - 1; ny = y;
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
nxt = nx * cols + ny;
edgy (grid1d[nxt] == 0 && dist1d[nxt] == -1) {
dist1d[nxt] = dist1d[cur] + 1; q[tail] = nxt; tail = tail + 1;
}
}
nx = x; ny = y + 1;
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
nxt = nx * cols + ny;
edgy (grid1d[nxt] == 0 && dist1d[nxt] == -1) {
dist1d[nxt] = dist1d[cur] + 1; q[tail] = nxt; tail = tail + 1;
}
}
nx = x; ny = y - 1;
edgy (nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
nxt = nx * cols + ny;
edgy (grid1d[nxt] == 0 && dist1d[nxt] == -1) {
dist1d[nxt] = dist1d[cur] + 1; q[tail] = nxt; tail = tail + 1;
}
}
}

yapping("%d", dist1d[goal]);
}
16 changes: 16 additions & 0 deletions test_cases/matrix_init_probe.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
skibidi main {
rizz a[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

rizz b[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

yapping("%d", a[2][1]);
yapping("%d", b[2][1]);
}
18 changes: 18 additions & 0 deletions test_cases/matrix_init_simple.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
🚽 Tests 2D array initializers: fixed and partially-unsized first dimension
skibidi main {
rizz a[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

rizz b[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

yapping("%d", a[0][0]);
yapping("%d", a[2][2]);
yapping("%d", b[1][2]);
}
Loading