Commit graph

55 commits

Author SHA1 Message Date
Graeme Geldenhuys 8136fcaff7 perf(stdlib): rewrite GetText and GetCommaText to avoid O(N²) concatenation
Both methods accumulated a result string with repeated `Result := Result + …`
inside a loop — each iteration allocates a fresh buffer and copies the entire
accumulator forward, quadratic in total content size.

Rewrite both using TStringBuilder (geometric buffer growth, single ToString
at the end).  On a self-compile via --output the GetText hot path drops from
~17 s to ~1.7 s (~10× speedup); GetCommaText gets the same fix proactively.

Add TestRun_TextGet_ManyLines: 500-line list with mixed empty/non-empty entries,
spot-checks total length and key substrings after the rewrite.
2026-06-01 00:11:39 +01:00
Graeme Geldenhuys 90b15afce4 feat(stdlib): add TList<T>.IndexOf
Linear scan over FData returning the index of the first equal element
or -1 when not found.  Matches the semantics of TSet<T>.IndexOf which
the rest of the unit already exposes, and saves callers from writing
the hand-rolled scan that bench_lists.pas demonstrates.

Adds two e2e tests covering the integer/found and string/not-found
paths.
2026-05-21 15:23:35 +01:00
Graeme Geldenhuys ed7323a618 feat(stdlib): add TListEnumerator<T> + TList<T>.GetEnumerator
Wires up for..in on TList<T> from generics.collections.  Two compiler
fixes were required:

- uSemantic: TClassName<T>.Method(args) inside a generic method body
  failed to resolve because AnalyseMethodCallExpr looked up the literal
  name with the unsubstituted type parameter.  Now mirrors the existing
  field-access path: if the receiver name contains '<' and lookup fails,
  apply ResolveScopeBoundTypeParams + FindTypeOrInstantiate before
  re-trying the lookup.

- uCodeGenQBE: constructor-with-args path emitted
  $_FieldCleanup_TListEnumerator<String> with literal angle brackets
  which QBE rejects.  Mangle the class name like the no-arg path
  already does.
2026-05-21 10:25:19 +01:00
Graeme Geldenhuys 25c1f83cd9 feat(threading): add TThread, TCriticalSection and POSIX thread bindings
Add blaise_thread.pas runtime unit wrapping pthread_create, pthread_join,
pthread_mutex_init/lock/unlock/destroy and sysconf for GetCPUCount.

Implement TThread (Create, Start, Terminate, WaitFor, Execute virtual,
FreeOnTerminate) and TCriticalSection (Enter/Leave) in classes.pas using
ARC-safe ref counting in the thread trampoline.

Fix EmitFieldCleanupFn to walk the parent chain when emitting the Destroy
call — previously a subclass without its own Destroy would generate an
empty cleanup, causing leaked resources from parent destructors.

Link -lpthread in both the compiler driver and E2E test base.

Include 7 E2E tests covering basic execution, WaitFor blocking, Terminate
flag, Finished flag, multiple threads, mutex-protected counter, and
inherited Destroy cleanup.
2026-05-20 08:31:15 +01:00
Graeme Geldenhuys 923b94c541 refactor: split rtl/ into runtime/ + stdlib/, rename bcl.testing to blaise.testing
Separate always-linked runtime code (system.pas, ARC, strings, platform
abstraction) from opt-in standard library units (sysutils, classes, math,
dateutils, generics, etc.).  This mirrors the Go runtime/ vs stdlib, Rust
core vs std, and Swift SwiftRuntime vs SwiftCore patterns.

- runtime/ contains code linked into every binary + C shims
- stdlib/ contains units imported explicitly via uses clause
- Single platform abstraction layer (rtl.platform.*) in runtime/,
  shared by both runtime/ and stdlib/ units
- bcl.testing renamed to blaise.testing across all 95+ test files
- Updated PasBuild project.xml, fixpoint.sh, README, unit search paths
- All 1931 tests pass, fixpoint OK (stage-3/stage-4)
2026-05-16 00:51:18 +01:00