Skip to content

Pitfalls & Debugging

Pitfalls & Debugging

Common Pitfalls

1. Missing Parentheses in if/while

Wrong:

if x > 0:
print(x)

Correct:

if (x > 0):
print(x)

Thagore requires parentheses around conditions in if and while statements.

2. No ++ or -- Operators

Wrong:

i++

Correct:

i = i + 1

3. No += or -= Operators

Wrong:

total += x

Correct:

total = total + x

4. Forgetting to Reassign Struct Updates

Since struct methods return new instances:

Wrong:

let sb = builder_new()
append(sb, "hello") # Return value is discarded!

Correct:

let sb = builder_new()
sb = append(sb, "hello") # Reassign to capture update

5. Top-Level defer

Wrong:

defer cleanup() # Top-level defer is rejected

Correct:

func main() -> i32:
defer cleanup() # Defer inside a function
return 0

6. match Without enum

Using match requires at least one enum declaration:

Wrong:

match value: # No enum defined → E_TYPE_MATCH_MISSING_ENUM
1: print("one")

Correct:

enum Kind:
One
Two
match kind:
One: print("one")
Two: print("two")

7. Malformed Range Loop

Wrong:

for i in 0...10: # Three dots instead of two
print(i)

Correct:

for i in 0..10: # Exactly two dots
print(i)

Compiler Error Reference

Error CodeDescriptionFix
E_TYPE_MATCH_MISSING_ENUMmatch used without an enumAdd an enum declaration
E_TYPE_RANGE_HEADERMalformed for i in a..b:Fix the range loop syntax
E_TYPE_IF_EXPRMalformed if-expressionCheck if-expression syntax
E_TYPE_CLOSUREMalformed closureCheck closure syntax
E_TYPE_TRAIT_CONSTRAINTTrait/impl constraint check failedReview trait/impl declarations
E_TYPE_INTENT_GOALUnsupported intent goalUse a valid goal: auto_plan, reduce_sum, off
E_TYPE_PIPELINE_VALIDATEGeneral pipeline validation failureCheck source for syntax issues
E_INDENTIndentation mismatchFix indentation levels

Debugging Strategies

1. Inspect LLVM IR

Terminal window
thagore build program.tg --emit-llvm
# Produces program.ll — inspect generated LLVM IR

2. Use Print Debugging

Insert print() calls to trace execution:

func complex_algorithm(n: i32) -> i32:
print("input:")
print(n)
let result = n * 2
print("result:")
print(result)
return result

3. Run Autofix Doctor

Terminal window
thagore fix doctor entry.tg

This diagnoses issues without applying fixes.

4. Check Feature Set

If a feature isn’t working, verify it’s being detected by the parser. The feature set includes tags like ;enum_payload;match;range_loop;if_expr; etc.

5. Verify Self-Hosting

If you suspect a compiler bug, try the self-hosting test:

Terminal window
# Build Stage2 from your current compiler
stage2.exe build src/thagore.tg -o stage2b.exe
# If this succeeds, the compiler is consistent

Memory Debugging

For memory issues (crashes, leaks):

memory_test.tg
func create_garbage() -> i32:
let s1 = "Part 1 "
let s2 = "Part 2"
let res = s1 + s2
print(res)
return 0
func main() -> i32:
let i = 0
while (i < 1000):
create_garbage()
i = i + 1
print("Finished without crashing!")
return 0

This pattern tests that string operations don’t leak memory over many iterations.