diff options
12 files changed, 97 insertions, 0 deletions
diff --git a/js/scripting-lang/baba-yaga-c/ROADMAP.md b/js/scripting-lang/baba-yaga-c/ROADMAP.md index e827ff3..963c46f 100644 --- a/js/scripting-lang/baba-yaga-c/ROADMAP.md +++ b/js/scripting-lang/baba-yaga-c/ROADMAP.md @@ -75,6 +75,27 @@ All advanced features including partial application are now working. **Task 3.1**: Fix Test 22 parser edge case to achieve 26/27 tests passing **Task 3.2**: Fix Integration Test 02 file reading issue to achieve 27/27 tests passing +## **Integration Test 02 Segfault Investigation** + +### Findings So Far +- Recursive function calls (e.g., `factorial 5`) cause a segmentation fault **only when run from a file**, not when piped via `cat` or `echo`. +- Non-recursive function calls, arithmetic, and function definitions all work as expected. +- The segfault occurs instantly, not after deep recursion (not a stack overflow). +- The function is defined in the global scope, and recursive lookup should work. +- The bug is **not** in the recursion logic itself. + +### Hypothesis +- The root cause is likely a memory or buffer issue in file reading, string handling, or tokenization. +- There may be a difference in how the source buffer is loaded from a file vs. piped input (e.g., BOM, encoding, or invisible characters). + +### Next Steps +1. Add debug output to print the raw contents of the buffer loaded by `read_file()` for `tests/integration_02_pattern_matching.txt` before it is passed to the interpreter. +2. Compare the buffer content from file vs. piped input. +3. Check for buffer overflows, uninitialized memory, or off-by-one errors in file reading and tokenization. +4. Check for non-ASCII, BOM, or invisible characters in the test file. + +--- + ## Technical Notes ### **Partial Application Implementation** diff --git a/js/scripting-lang/baba-yaga-c/src/parser.c b/js/scripting-lang/baba-yaga-c/src/parser.c index 6c94913..c490bd4 100644 --- a/js/scripting-lang/baba-yaga-c/src/parser.c +++ b/js/scripting-lang/baba-yaga-c/src/parser.c @@ -2666,6 +2666,14 @@ static ASTNode* parser_parse_when_expression(Parser* parser) { // Parse pattern ASTNode* pattern = parser_parse_when_pattern(parser); if (!pattern) break; + + // Debug: Show current token before consuming 'then' + Token* current_token = parser_peek(parser); + if (current_token) { + DEBUG_TRACE("Before consuming 'then', current token type=%d, lexeme='%s'", + current_token->type, current_token->lexeme ? current_token->lexeme : "NULL"); + } + // Expect 'then' Token* then_token = parser_consume(parser, TOKEN_KEYWORD_THEN, "Expected 'then' after pattern in when case"); if (!then_token) { ast_destroy_node(pattern); break; } @@ -2770,6 +2778,7 @@ static ASTNode* parser_parse_when_pattern(Parser* parser) { if (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_NUMBER || token->type == TOKEN_STRING || + token->type == TOKEN_BOOLEAN || (token->type == TOKEN_IDENTIFIER && token->lexeme && strcmp(token->lexeme, "_") == 0)) { literal_count++; } else if (token->type == TOKEN_LPAREN) { @@ -2851,6 +2860,9 @@ static ASTNode* parser_parse_when_pattern(Parser* parser) { } else if (lit_token->type == TOKEN_STRING) { /* String pattern */ literals[i] = ast_literal_node(baba_yaga_value_string(lit_token->lexeme), lit_token->line, lit_token->column); + } else if (lit_token->type == TOKEN_BOOLEAN) { + /* Boolean pattern */ + literals[i] = ast_literal_node(baba_yaga_value_boolean(lit_token->literal.boolean), lit_token->line, lit_token->column); } else { /* Cleanup on error */ for (int j = 0; j < i; j++) { @@ -2944,6 +2956,13 @@ static ASTNode* parser_parse_when_pattern(Parser* parser) { return NULL; } DEBUG_TRACE("Parsed pattern test expression"); + + // Debug: Show current token after parsing pattern + Token* after_token = parser_peek(parser); + if (after_token) { + DEBUG_TRACE("After parsing pattern, current token type=%d, lexeme='%s'", + after_token->type, after_token->lexeme ? after_token->lexeme : "NULL"); + } } DEBUG_TRACE("parser_parse_when_pattern success"); diff --git a/js/scripting-lang/baba-yaga-c/test_arithmetic.txt b/js/scripting-lang/baba-yaga-c/test_arithmetic.txt new file mode 100644 index 0000000..19d3ec7 --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_arithmetic.txt @@ -0,0 +1,2 @@ +test : n -> n - 1; +test : n -> n - 1; result : test 5; diff --git a/js/scripting-lang/baba-yaga-c/test_countdown.txt b/js/scripting-lang/baba-yaga-c/test_countdown.txt new file mode 100644 index 0000000..e474c77 --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_countdown.txt @@ -0,0 +1,2 @@ +countdown : n -> when n is 0 then 0 _ then countdown (n - 1); +countdown : n -> when n is 0 then 0 _ then countdown (n - 1); result : countdown 3; diff --git a/js/scripting-lang/baba-yaga-c/test_countdown_call.txt b/js/scripting-lang/baba-yaga-c/test_countdown_call.txt new file mode 100644 index 0000000..e06f875 --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_countdown_call.txt @@ -0,0 +1 @@ +countdown : n -> when n is 0 then 0 _ then countdown (n - 1); result : countdown 3; diff --git a/js/scripting-lang/baba-yaga-c/test_factorial.txt b/js/scripting-lang/baba-yaga-c/test_factorial.txt new file mode 100644 index 0000000..07248f8 --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_factorial.txt @@ -0,0 +1 @@ +factorial : n -> when n is 0 then 1 _ then n * (factorial (n - 1)); diff --git a/js/scripting-lang/baba-yaga-c/test_factorial_call.txt b/js/scripting-lang/baba-yaga-c/test_factorial_call.txt new file mode 100644 index 0000000..ceb1727 --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_factorial_call.txt @@ -0,0 +1 @@ +factorial : n -> when n is 0 then 1 _ then n * (factorial (n - 1)); fact5 : factorial 5; diff --git a/js/scripting-lang/baba-yaga-c/test_integration_factorial.txt b/js/scripting-lang/baba-yaga-c/test_integration_factorial.txt new file mode 100644 index 0000000..c396568 --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_integration_factorial.txt @@ -0,0 +1,12 @@ +/* Integration Test: Pattern Matching */ +/* Combines: case expressions, functions, recursion, complex patterns */ + +..out "=== Integration Test: Pattern Matching ==="; + +/* Recursive factorial with case expressions */ +factorial : n -> + when n is + 0 then 1 + _ then n * (factorial (n - 1)); + +/* Pattern matching with multiple parameters */ diff --git a/js/scripting-lang/baba-yaga-c/test_integration_factorial_call.txt b/js/scripting-lang/baba-yaga-c/test_integration_factorial_call.txt new file mode 100644 index 0000000..ae9483d --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_integration_factorial_call.txt @@ -0,0 +1,25 @@ +/* Integration Test: Pattern Matching */ +/* Combines: case expressions, functions, recursion, complex patterns */ + +..out "=== Integration Test: Pattern Matching ==="; + +/* Recursive factorial with case expressions */ +factorial : n -> + when n is + 0 then 1 + _ then n * (factorial (n - 1)); + +/* Pattern matching with multiple parameters */ +classify : x y -> + when x y is + 0 0 then "both zero" + 0 _ then "x is zero" + _ 0 then "y is zero" + _ _ then when x is + 0 then "x is zero (nested)" + _ then when y is + 0 then "y is zero (nested)" + _ then "neither zero"; + +/* Test factorial */ +fact5 : factorial 5; diff --git a/js/scripting-lang/baba-yaga-c/test_integration_simple.txt b/js/scripting-lang/baba-yaga-c/test_integration_simple.txt new file mode 100644 index 0000000..f540fcb --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_integration_simple.txt @@ -0,0 +1,10 @@ +/* Integration Test: Pattern Matching */ +/* Combines: case expressions, functions, recursion, complex patterns */ + +..out "=== Integration Test: Pattern Matching ==="; + +/* Recursive factorial with case expressions */ +factorial : n -> + when n is + 0 then 1 + _ then n * (factorial (n - 1)); diff --git a/js/scripting-lang/baba-yaga-c/test_simple.txt b/js/scripting-lang/baba-yaga-c/test_simple.txt new file mode 100644 index 0000000..c17b99b --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_simple.txt @@ -0,0 +1,2 @@ +simple : n -> n; +simple : n -> n; result : simple 5; diff --git a/js/scripting-lang/baba-yaga-c/test_simple_out.txt b/js/scripting-lang/baba-yaga-c/test_simple_out.txt new file mode 100644 index 0000000..6b1ea29 --- /dev/null +++ b/js/scripting-lang/baba-yaga-c/test_simple_out.txt @@ -0,0 +1 @@ +x : 5; ..out x; |