| Age | Commit message (Collapse) | Author |
|
Review findings (all reproduced, then fixed and re-verified):
- '^x' leaked as a raw address into any builtin context (s <- ^x printed
the variable's bytes as a C string; NOT ^x, '&', and ^x = ^x compiled).
Address-of is now rejected everywhere except a pointer-typed target.
- A whole-array variable passed the nominal gate as a value of its
ELEMENT type (s <- arrayOfSeason stored the raw data pointer; = on it
emitted invalid IR). Whole arrays are now rejected as operands and as
coercion sources; array parameters are unaffected.
- Enum values smuggled into INTEGER through array subscripts and DECLARE
bounds (a[Autumn], ARRAY[Spring:Winter]); both now go through
emitCoercedExpr like every other INTEGER context.
- An array DECLAREd inside an IF/WHILE/REPEAT/FOR body and used after the
block was a wild-pointer write (constant bounds) or a verifier dump
(runtime bounds). Arrays are now block-scoped: control-flow bodies
snapshot and restore the ArrayTable, so escape is a clean compile error.
- Duplicate parameter names silently shadowed (BYREF write-back defeated);
now a parse error. Trailing comma in parameter lists accepted; now a
parse error consistent with every other list.
- A variable/array/parameter/function could reuse a TYPE name; reserved.
- RETURN with a value inside a PROCEDURE was silently discarded (control
did not return); now an error, as is a bare RETURN in a FUNCTION.
- INPUT r.f mis-parsed into a three-error cascade; now one clear error.
- Assigning to an enum constant now says so instead of 'Unknown variable'.
Docs: ARCH/CONVENTIONS/EXTENDING/SUBSYSTEMS/PITFALLS rewritten for the
TYPE system (ABI additions, nominal-typing invariants, admission-gate
doors, array-parameter ABI, new recipes, new sharp edges); README
features/TODO updated — random files are unblocked.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
- Parameter syntax lands end-to-end: ARRAY OF T (rank 1, bounds travel
with the argument) and ARRAY[l:u,...] OF T (any rank, literal bounds as
a checked contract). Element type and rank must match exactly.
- Flattened ABI: each rank-R array parameter becomes a data pointer plus
kBoundArgsPerDim i64 bounds per dimension. The callee rebuilds
ArrayMetadata from those bounds (ArrayHandler::bindArrayParameter via a
binder callback injected by CodeGen, so FunctionGen stays ignorant of
the array subsystem); the checked-indexing pipeline is reused unchanged.
- BYVAL (the CIE default) copies the whole buffer at callee entry
(malloc+memcpy, never freed — consistent with the string policy) so
callee writes stay invisible; BYREF binds the caller's buffer.
- Bounded-parameter contract: compile-time comparison when the caller's
bounds are constants, else a runtime [Fatal] check
(RuntimeCheck::emitArrayArgBoundsCheck).
- marshalCallArgs gains the array branch and a call-site line number
(CallStmtAST now carries one); whole-array-to-scalar keeps a clear
error, FUNCTION RETURNS ARRAY is a dedicated parse error.
- Verified: BYREF fill/sort-style mutation, BYVAL copy invisibility,
2-D bounded params, ARRAY OF <record> with field writes through the
parameter, bounds-contract mismatches at compile time and run time.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
- TypeSystem: TypeKinds Enum/Record/Pointer with per-kind payloads and
checked accessors; two-pass registration (names first, then definitions
in source order) so pointer TYPEs may forward-reference; enum-constant
table owned by TypeSystem so constants stay visible inside function
bodies across the Symbols save/clear/restore. Dead surface removed
(Custom kind, Printable/Builtin/ReferenceLike, ElementSize, hasType,
CodeGen::getNamedValue/getLLVMType).
- Enums are i64 with 0-based ordinals (constexpr kEnumOrdinalBase); all
type identity is by NAME. New emitCoercedExpr is the single admission
gate, replacing raw coercion at assignments, array stores, BYVAL args,
RETURN, IF/WHILE/REPEAT/FOR operands, file operands and builtin args;
coerceValueToType now hard-errors if a user-kind target reaches it.
- Binary ops with user-kind operands are intercepted ahead of
ArithmeticHandler ('&'-intercept precedent): same-enum comparisons,
enum +/- INTEGER (with a runtime range check, [Fatal] on overflow, the
only site that can manufacture an invalid ordinal), same-name pointer
=/<>; everything else is a compile error naming the operator.
- OUTPUT is an exhaustive switch over TypeKind (enum prints its ordinal;
record/pointer are compile errors, also covering whole-array OUTPUT);
INPUT's silent %lld fallback for unknown kinds is now an explicit error.
- Enum value names are globally reserved: collisions with DECLARE,
array names, parameters and function names are compile errors.
- RuntimeCheck: emitEnumRangeCheck + emitNullDerefCheck (used by the
pointer phase) following the emitIndexCheck recipe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
- Element sizes now flow as target-folded null-GEP sizeof constants
(TypeSystem::getSizeOfConstant); the module has no DataLayout string,
so host-side size math would diverge from the backend on padded structs.
- Extract the triplicated STRING null->"" select into
CodeGen::emitStringNullGuard.
- Scope ArrayTable per function via ArrayHandler::exchangeTable, mirroring
the Symbols save/clear/restore discipline.
- Promote checked element addressing to public
ArrayHandler::emitElementAddress for the upcoming lvalue layer.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
Integer/Real/Boolean/CharHandler carried only five one-line LLVM API
wrappers (now inlined at their call sites in CodeGen.cc) plus dead
emitDeclare methods that violated the documented two-table lock-step
invariant. StringHandler::emitDeclare (also dead) and its NamedValues
reference go too.
With the dead writers gone, NamedValues held no information not already
in Symbols[].Storage, so the parallel map is removed: getNamedValue
reads Symbols, ArrayHandler/FunctionGen take one table, and function
bodies save/restore a single map. Behavior unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
CodeGen declares its own MallocFunc in SetupExternalFunctions and uses
it for char->STRING coercion and INPUT STRING buffers, removing two bare
getFunction("malloc") calls that null-deref'd if no handler happened to
declare malloc first. The CHR branch reuses the char->STRING coercion
path instead of a second hand-rolled heap wrapper.
String concatenation moves from ArithmeticHandler (which re-declared
four externs per '&' and was the LLVM 19 build-pin root cause) to
StringHandler::emitConcat; ArithmeticHandler no longer touches the
Module. Dead FreeFunc declarations removed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
- MID/RIGHT/LEFT integer args now coerced at call sites (RIGHT(s, n/2)
no longer emits invalid IR); drop emitLeft's private conversion
- FOR loop direction decided at run time via select on STEP sign;
descending FOR works, STEP evaluated once per iteration
- ArrayHandler: extract emitCheckedIndices/loadElement; index count is
validated before emission, fixing a compiler-crash (vector OOB UB) on
OUTPUT with too many indices
- Error contract: Lexer/Parser/CodeGen track errors; all silent failure
paths now print Error: diagnostics with line numbers; unterminated
char literal no longer truncates the rest of the program; module is
verified with verifyModule; driver exits non-zero on any error
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
|
|
|
|
|
|
|
|
|