Skip to content

Commit

Permalink
tests: add more edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
araujo88 committed Jan 5, 2025
1 parent f6ec53d commit 3517214
Show file tree
Hide file tree
Showing 14 changed files with 167 additions and 38 deletions.
65 changes: 52 additions & 13 deletions ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <stdbool.h>
#include <setjmp.h>
#include <string.h>
#include <math.h>
#include <limits.h>

static jmp_buf break_env;

Expand Down Expand Up @@ -230,24 +232,39 @@ float evaluate_expression_float(ASTNode *node)
case OP_TIMES:
return left * right;
case OP_DIVIDE:
if (right == 0.0f)
if (fabsf(right) < 1e-10f)
{
yyerror("Division by zero");
return 0.0f;
if (fabsf(left) < 1e-10f)
{
return 0.0f / 0.0f; // NaN
}
return left > 0 ? __FLT_MAX__ : -__FLT_MAX__;
}
return left / right;
case OP_LT:
return left < right ? 1.0f : 0.0f;
{
return (left - right) < -__FLT_EPSILON__ ? 1.0f : 0.0f;
}
case OP_GT:
return left > right ? 1.0f : 0.0f;
{
return (left - right) > __FLT_EPSILON__ ? 1.0f : 0.0f;
}
case OP_LE:
return left <= right ? 1.0f : 0.0f;
{
return (left - right) <= __FLT_EPSILON__ ? 1.0f : 0.0f;
}
case OP_GE:
return left >= right ? 1.0f : 0.0f;
{
return (left - right) >= -__FLT_EPSILON__ ? 1.0f : 0.0f;
}
case OP_EQ:
return left == right ? 1.0f : 0.0f;
{
return fabsf(left - right) <= __FLT_EPSILON__ ? 1.0f : 0.0f;
}
case OP_NE:
return left != right ? 1.0f : 0.0f;
{
return fabsf(left - right) > __FLT_EPSILON__ ? 1.0f : 0.0f;
}
default:
yyerror("Invalid operator for float operation");
return 0.0f;
Expand Down Expand Up @@ -322,10 +339,13 @@ double evaluate_expression_double(ASTNode *node)
case OP_TIMES:
return left * right;
case OP_DIVIDE:
if (right == 0.0L)
if (fabs(right) < 1e-10)
{
yyerror("Division by zero");
return 0.0L;
if (fabs(left) < 1e-10)
{
return 0.0 / 0.0; // NaN
}
return left > 0 ? __DBL_MAX__ : -__DBL_MAX__;
}
return left / right;
case OP_LT:
Expand Down Expand Up @@ -790,7 +810,26 @@ void execute_assignment(ASTNode *node)
ASTNode *value_node = node->data.op.right;
TypeModifiers mods = node->modifiers;

// Check if the right-hand side is a float expression
// Handle type conversion for float to int
if (value_node->type == NODE_FLOAT || is_float_expression(value_node))
{
float value = evaluate_expression_float(value_node);
if (node->data.op.left->type == NODE_INT)
{
// Check for overflow
if (value > INT_MAX || value < INT_MIN)
{
yyerror("Float to int conversion overflow");
value = INT_MAX;
}
if (!set_int_variable(name, (int)value, mods))
{
yyerror("Failed to set integer variable");
}
return;
}
}

if (is_float_expression(value_node))
{
float value = evaluate_expression_float(value_node);
Expand Down
11 changes: 11 additions & 0 deletions examples/comparison_edge_case.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
skibidi main {
chad epsilon = 1.0e-7;
chad a = 1.0;
chad b = 0.9999999;
edgy (a - b < epsilon) {
yappin("%d\n", yes); 🚽 Should output: 1
} amogus {
yappin("%d\n", no);
}
bussin 0;
}
10 changes: 10 additions & 0 deletions examples/division_edge_cases.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
skibidi main {
chad f = 0.0;
gigachad d = 0.0;
rizz i = 0;
yappin("%f\n", 1.0 / f); 🚽 Should output: inf
yappin("%f\n", f / f); 🚽 Should output: nan
yappin("%f\n", d / 0.0); 🚽 Should output: inf
yapping("%d\n", 1 / i); 🚽 Should output: Error: Division by zero
bussin 0;
}
10 changes: 10 additions & 0 deletions examples/double_vs_float.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
skibidi main {
chad f = 16777216.0;
gigachad d = 16777216.0;
chad f1 = f + 1.0;
gigachad d1 = d + 1.0;
yappin("%.1f %.1f\n", f1 - f, d1 - d);
🚽 Should output: 0.0 1.0
🚽 (float loses precision, double maintains it)
bussin 0;
}
7 changes: 7 additions & 0 deletions examples/float_precision.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
skibidi main {
chad tiny = 1.175494351e-38; 🚽 FLT_MIN
chad big = 3.402823466e+38; 🚽 FLT_MAX
chad sum = big + tiny;
yappin("%f\n", sum - big); 🚽 Should output: 0.000000 (precision loss)
bussin 0;
}
7 changes: 7 additions & 0 deletions examples/integer_overflow.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
skibidi main {
rizz max = 2147483647; 🚽 INT_MAX
rizz min = -2147483648; 🚽 INT_MIN
yappin("%d\n", max + 1); 🚽 Should output: -2147483648 (overflow)
yappin("%d\n", min - 1); 🚽 Should output: 2147483647 (underflow)
bussin 0;
}
9 changes: 9 additions & 0 deletions examples/mixed_types.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
skibidi main {
chad f = 3.14;
gigachad d = 3.14;
rizz i = 42;
nonut rizz u = 42;
yappin("%f\n", f * i); 🚽 Should output: 131.880000
yappin("%f\n", d * u); 🚽 Should output: 131.880000
bussin 0;
}
9 changes: 9 additions & 0 deletions examples/modulo_edge_case.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
skibidi main {
rizz a = -5;
rizz b = 3;
yappin("%d\n", a % b); 🚽 Should output: -2
nonut rizz x = 5;
nonut rizz y = 3;
yappin("%u\n", x % y); 🚽 Should output: 2
bussin 0;
}
7 changes: 7 additions & 0 deletions examples/scientific_notation.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
skibidi main {
chad f = 1.23e-7;
gigachad d = 1.23e-15;
yappin("%e\n", f); 🚽 Should output: 1.230000e-07
yappin("%e\n", d); 🚽 Should output: 1.230000e-15
bussin 0;
}
8 changes: 8 additions & 0 deletions examples/type_conversion.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
skibidi main {
chad huge_float = 3.4e38;
rizz converted = huge_float; 🚽 Should be INT_MAX or error
gigachad precise = 123456789.123456789;
chad less_precise = precise; 🚽 Precision loss
yappin("%f\n", less_precise); 🚽 Should output: 123456789.000000
bussin 0;
}
6 changes: 6 additions & 0 deletions examples/unsigned_integer_wrap.brainrot
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
skibidi main {
nonut rizz big = 4294967295; 🚽 UINT_MAX
yappin("%u\n", big + 1); 🚽 Should output: 0 (wrap around)
yappin("%u\n", big * 2); 🚽 Should output: 4294967294 (wrap around)
bussin 0;
}
14 changes: 5 additions & 9 deletions lang.l
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,13 @@ extern int yylineno;
"🚽"[^\n]* ; /* Ignore single line comments */
"yes" { yylval.ival = 1; return BOOLEAN; }
"no" { yylval.ival = 0; return BOOLEAN; }
[0-9]+\.[0-9]+[fF]? {
if (yytext[strlen(yytext) - 1] == 'f' || yytext[strlen(yytext) - 1] == 'F') {
// 'f' or 'F' suffix: float literal
char *buffer = strdup(yytext);
buffer[strlen(buffer) - 1] = '\0'; // Remove the 'f' suffix
yylval.fval = atof(buffer); // Convert to float
free(buffer);
[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
char *endptr;
if (strchr(yytext, 'f') || strchr(yytext, 'F')) {
yylval.fval = strtof(yytext, &endptr);
return FLOAT_LITERAL;
} else {
// No suffix: double literal
yylval.dval = strtod(yytext, NULL); // Convert to double
yylval.dval = strtod(yytext, &endptr);
return DOUBLE_LITERAL;
}
}
Expand Down
40 changes: 25 additions & 15 deletions tests/expected_results.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
{
"boolean.brainrot": "It's valid!\nno\nyes\n",
"fizz_buzz.brainrot": "1\n2\nFizz\n4\nBuzz\nFizz\n7\n8\nFizz\nBuzz\n",
"hello_world.brainrot": "Hello, World!\n",
"sizeof.brainrot": "4\n4\n1\n",
"char.brainrot": "c\n",
"float.brainrot": "3.141592\n",
"modulo.brainrot": "2\n",
"switch_case.brainrot": "You chose 2, gigachad move!\n",
"circle_area.brainrot": "78.540\n",
"circle_area_double.brainrot": "78.539800\n",
"for_loop.brainrot": "Skibidi toilet\nSkibidi toilet\nSkibidi toilet\nSkibidi toilet\nSkibidi toilet\nSkibidi toilet\n",
"output_error.brainrot": "you sussy baka!",
"while_loop.brainrot": "AAAAAH A GOONIN LOOP\n1\nAAAAAH A GOONIN LOOP\n2\nAAAAAH A GOONIN LOOP\n3\nAAAAAH A GOONIN LOOP\n4\n",
"int.brainrot": "10\n5\n3\n-3\n20\n-20\n2\n1\n2\n-2",
"uint.brainrot": "10\n9931737\n3\n647238965\n20\n245413032\n2\n1\n2\n1"
"comparison_edge_case": "1\n",
"division_edge_cases": "inf\nnan\ninf\nError: Division by zero\n",
"double_vs_float": "0.0 1.0\n",
"float_precision": "0.000000\n",
"integer_overflow": "-2147483648\n2147483647\n",
"mixed_types": "131.880000\n131.880000\n",
"modulo_edge_case": "-2\n2\n",
"scientific_notation": "1.230000e-07\n1.230000e-15\n",
"type_conversion": "123456789.123457\n",
"unsigned_integer_wrap": "0\n4294967294\n",
"boolean": "It's valid!\nno\nyes\n",
"fizz_buzz": "1\n2\nFizz\n4\nBuzz\nFizz\n7\n8\nFizz\nBuzz\n",
"hello_world": "Hello, World!\n",
"sizeof": "4\n4\n1\n",
"char": "c\n",
"float": "3.141592\n",
"modulo": "2\n",
"switch_case": "You chose 2, gigachad move!\n",
"circle_area": "78.540\n",
"circle_area_double": "78.539800\n",
"for_loop": "Skibidi toilet\nSkibidi toilet\nSkibidi toilet\nSkibidi toilet\nSkibidi toilet\nSkibidi toilet\n",
"output_error": "you sussy baka!",
"while_loop": "AAAAAH A GOONIN LOOP\n1\nAAAAAH A GOONIN LOOP\n2\nAAAAAH A GOONIN LOOP\n3\nAAAAAH A GOONIN LOOP\n4\n",
"int": "10\n5\n3\n-3\n20\n-20\n2\n1\n2\n-2",
"uint": "10\n9931737\n3\n647238965\n20\n245413032\n2\n1\n2\n1"
}
2 changes: 1 addition & 1 deletion tests/test_brainrot.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
def test_brainrot_examples(example, expected_output):
# Construct absolute paths for the brainrot executable and example file
brainrot_path = os.path.abspath(os.path.join(script_dir, "../brainrot"))
example_file_path = os.path.abspath(os.path.join(script_dir, f"../examples/{example}"))
example_file_path = os.path.abspath(os.path.join(script_dir, f"../examples/{example}.brainrot"))

# Define the command to execute
command = f"{brainrot_path} < {example_file_path}"
Expand Down

0 comments on commit 3517214

Please sign in to comment.