= AffineScript Testing Report
:author: Automated Testing
:date: 2025-12-29
:toc:
:toclevels: 3

== Executive Summary

This report documents the testing results for the AffineScript compiler project, an OCaml-based compiler for a language featuring affine types, dependent types, row polymorphism, and extensible effects.

[cols="1,2"]
|===
|Project Version |0.1.0
|Test Date |2025-12-29
|OCaml Version |5.x (required >= 5.1)
|Dune Version |3.20.2
|Build Status |PASS
|Test Status |47 PASS / 27 FAIL
|Pass Rate |63.5%
|===

== Build System Analysis

=== Configuration Files

The project uses the standard OCaml build toolchain:

* `dune-project` - Dune project configuration (version 3.14)
* `affinescript.opam` - OPAM package definition
* No Makefile present (uses dune exclusively)

=== Dependencies

[source,text]
----
ocaml >= 5.1
dune >= 3.14
menhir >= 20231231
sedlex >= 3.2
ppx_deriving >= 5.2
ppx_sexp_conv >= 0.16
sexplib0 >= 0.16
fmt >= 0.9
cmdliner >= 1.2
alcotest >= 1.7 (test only)
odoc >= 2.4 (doc only)
----

=== Build Issues Fixed

==== Issue 1: Menhir --explain flag

*Error:* Menhir '.conflicts' file is generated by default
*Location:* `lib/dune`
*Fix:* Removed `--explain` from menhir flags (kept `--table`)

==== Issue 2: Double-option type in parser

*Error:* Type mismatch in `impl_trait_ref` rule
*Location:* `lib/parser.mly` line 371-373
*Fix:* Removed `Some` wrapper since rule is already optional (`trait_ref = impl_trait_ref?`)

==== Issue 3: Unused variable warning

*Error:* Unused variable `where_clause` in `trait_decl` rule
*Location:* `lib/parser.mly` line 324
*Fix:* Added `trd_where` field to `trait_decl` type in `lib/ast.ml` and used it in parser

==== Issue 4: Token mismatch

*Error:* Unbound constructor `Token.WITH`
*Location:* `lib/parse.ml` line 94
*Fix:* Removed stray `Token.WITH` mapping (token was not defined)

==== Issue 5: Test file pattern matching

*Error:* Missing record fields in patterns, non-returning statement
*Location:* `test/test_parser.ml` multiple lines
*Fix:* Added `; _` to partial patterns, parenthesized boolean test function

== Test Results

=== Lexer Tests (16/16 PASS)

[cols="1,2,1"]
|===
|Test |Description |Status

|keywords |Keyword token recognition |PASS
|identifiers |Lower and upper identifiers |PASS
|literals |Integer and float literals |PASS
|string literal |String with content |PASS
|string escapes |Escape sequences |PASS
|operators |Arithmetic and comparison operators |PASS
|punctuation |Brackets, delimiters |PASS
|row variable |Row polymorphism syntax |PASS
|line comment |Single-line comments |PASS
|block comment |Multi-line comments |PASS
|nested comments |Nested block comments |PASS
|hex literal |Hexadecimal numbers |PASS
|binary literal |Binary numbers |PASS
|function decl |Function keyword sequence |PASS
|total function |Total keyword handling |PASS
|type decl |Type keyword handling |PASS
|===

=== Parser Tests (31/58 - 27 FAIL)

==== Passing Tests

[cols="1,2"]
|===
|Test |Description

|literal int |Integer parsing
|literal float |Float parsing
|literal string |String parsing
|literal bool |Boolean parsing
|literal unit |Unit `()` parsing
|variable |Variable reference
|binary add |Addition expression
|binary precedence |Operator precedence
|binary associativity |Left associativity
|comparison |Comparison operators
|logical |Logical operators
|unary neg |Negation operator
|unary not |Not operator
|function call |Function application
|field access |Record field access
|index access |Array indexing
|tuple |Tuple expressions
|array |Array literals
|record |Record literals
|match expr |Pattern matching
|lambda |Lambda expressions
|let stmt |Let statements
|let mut stmt |Mutable let
|while stmt |While loops
|for stmt |For loops
|fn decl effect |Effect annotations
|struct decl |Struct declarations
|enum decl |Enum declarations
|type alias |Type aliases
|trait decl |Trait declarations
|effect decl |Effect declarations
|===

==== Failing Tests

[cols="1,2,3"]
|===
|Test |Expected |Issue

|if expr |If-else expression |Parser conflict in block trailing expressions
|block |Block with statements |Same as above
|pattern wildcard |Wildcard in match |Block parsing conflict
|pattern variable |Variable pattern |Block parsing conflict
|pattern constructor |Constructor pattern |Block parsing conflict
|pattern tuple |Tuple pattern |Block parsing conflict
|pattern or |Or pattern |Block parsing conflict
|fn decl simple |Simple function |Return type parsing issue
|fn decl total |Total function |Return type parsing issue
|fn decl generic |Generic function |Return type parsing issue
|impl block |Impl declarations |Type parsing in impl context
|impl trait |Trait implementations |Same as impl block
|type simple |Type annotations |Type parsing standalone
|type generic |Generic types |Type parsing standalone
|type tuple |Tuple types |Type parsing standalone
|type function |Function types |Type parsing standalone
|type record |Record types |Type parsing standalone
|type row poly |Row polymorphism |Type parsing standalone
|type ownership |Ownership modifiers |Type parsing standalone
|import simple |Basic imports |Import parsing issue
|import alias |Aliased imports |Import parsing issue
|import list |List imports |Import parsing issue
|import glob |Glob imports |Import parsing issue
|fibonacci |Complex example |Block expression conflict
|linked list |Complex example |Multiple issues
|effect handler |Complex example |Handler syntax issues
|trait bounds |Complex example |Where clause parsing
|===

== Parser Conflicts Analysis

The parser has significant conflicts that affect parsing:

* 23 states with shift/reduce conflicts
* 2 states with reduce/reduce conflicts
* 132 shift/reduce conflicts resolved (shift preference)
* 5 reduce/reduce conflicts resolved

=== Root Cause

The main issue is the block grammar:

[source,mly]
----
block:
  | LBRACE stmts = list(stmt) final = expr? RBRACE
----

When parsing `{ let x = 1; x }`:

1. Parser sees `x` after the statements
2. Grammar allows `expr SEMICOLON` as a statement
3. Grammar also allows `expr?` as final expression
4. Conflict: Is `x` the start of a statement or the final expression?

Menhir resolves by preferring shift (continue parsing statement), which breaks trailing expressions.

== Example Files

=== hello.affine

Fixed syntax for effect annotations:

* Original: `fn main() -> () / IO`
* Fixed: `fn main() -{IO}-> ()`

The parser uses `-{Eff}->` syntax, not `-> T / Eff`.

=== Other Examples

The example files (`effects.affine`, `ownership.affine`, `traits.affine`, etc.) use aspirational syntax that is not yet supported:

* `-> T / Eff` effect syntax (parser uses `-{Eff}-> T`)
* GADT-style enum variants (`| Nil : Vec[0, T]`)
* `self` keyword in traits
* Various advanced features

== CLI Tool Testing

The compiler CLI works correctly:

[source,bash]
----
$ affinescript --help
# Shows help for: check, compile, lex, parse commands

$ affinescript lex examples/hello.affine
# Successfully tokenizes the file

$ affinescript parse examples/hello.affine
# Successfully parses (after syntax fix)
----

== Recommendations

=== Critical Fixes

1. **Block Expression Parsing**: Refactor block grammar to properly handle trailing expressions. Consider:
   - Using lookahead to distinguish statements from final expressions
   - Requiring explicit `return` for final expressions
   - Alternative grammar structure

2. **Type Parsing Standalone**: Some tests try to parse types in contexts where only expressions are expected.

=== Improvements

1. **Update Examples**: Align example files with current parser syntax
2. **Grammar Refactoring**: Consider GLR parsing or more sophisticated conflict resolution
3. **Error Messages**: Improve parser error recovery and messaging

=== Future Work

1. Implement remaining language features (type checker, borrow checker)
2. Add WASM codegen
3. Implement effect system runtime

== Appendix: Files Modified

* `lib/dune` - Removed --explain flag
* `lib/parser.mly` - Fixed trait_ref, added trd_where
* `lib/ast.ml` - Added trd_where field
* `lib/parse.ml` - Removed WITH token
* `test/test_parser.ml` - Fixed pattern matching
* `examples/hello.affine` - Fixed effect syntax
