Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a69579a
temp-string reclaim: gate queue sites on alias-free consumers - a str…
borisbat Aug 10, 2026
f35c0e9
doc-verify: authored-RST code-block compile checker - page-literate m…
borisbat Aug 10, 2026
6cde889
docs: mini fan-out fixes for 53_clargs (parse_args string->Result API…
borisbat Aug 10, 2026
eabcc91
doc-verify: harness hardening from the mini fan-out - companion numbe…
borisbat Aug 10, 2026
14cd17c
doc-verify: file marker for multi-file literate pages - block written…
borisbat Aug 10, 2026
676ca55
doc-verify: fan-out round-2 hardening - member <Class> marker (method…
borisbat Aug 10, 2026
98de100
doc-verify: member marker is chunk-aware - hoists route to the page, …
borisbat Aug 10, 2026
c08655b
doc-verify: macros-family round - directory-keyed companion lookup (u…
borisbat Aug 10, 2026
db32392
doc-verify: private/shared var-decls route to module scope (the docum…
borisbat Aug 10, 2026
85f8fc1
doc-verify: renamer ignores string-literal content and nested-scope l…
borisbat Aug 10, 2026
72de3df
doc-verify: renamer skips string-literal text but renames inside {int…
borisbat Aug 10, 2026
c050384
doc-verify: inline { ... } elision compiles as { pass }, def-header k…
borisbat Aug 10, 2026
1408197
docs: final fan-out batches - language I-N (tables taught unsafe-tabl…
borisbat Aug 10, 2026
b729daa
doc-verify: typedef distinct is a modifier not a type name; def-heade…
borisbat Aug 10, 2026
d332c51
skills: doc_sweep.md (repo-only) - the each-release sweep procedure, …
borisbat Aug 10, 2026
e88a523
ci: nightly authored-doc verification lane - doc-verify runs on exten…
borisbat Aug 10, 2026
b21e0cd
dasImgui: the duplicate-render panic's declare-a-table suggestion als…
borisbat Aug 10, 2026
7bab564
skills/filesystem: dir_rec bullet - a direct child's root-relative pa…
borisbat Aug 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/extended_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,14 @@ jobs:
- name: "Run tutorial dry-runs"
run: cmake --build ./build --config Release --target dry_run_tutorials

- name: "Verify authored-doc code blocks (nightly only)"
# doc-verify compiles every das code block of the authored RST corpus
# (skills/doc_sweep.md). Nightly-only per policy: doc rot is not a
# per-PR gate. Skipped on windows: the checker spawns one daslang per
# page via popen and is exercised on the posix cells.
if: (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && matrix.target != 'windows'
run: $BIN/daslang ./utils/doc-verify/main.das -- --daslang $BIN/daslang

- name: "Build standalone executables"
run: |
set -eux
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Task-specific instructions are split into skill files under `skills/`. You MUST
| `skills/gc_migration.md` | Migrating external/archived code from `smart_ptr<T>` AST patterns to gc_node (in-tree migration is complete) |
| `skills/version_update.md` | Bumping the daslang version number |
| `skills/doc_archiving.md` | Archiving a completed arc's design/plan/audit docs into `/history` — the archive-vs-stay test, reference-update discipline, area-index notes, the `history/README.md` ledger |
| `skills/doc_sweep.md` | Running the each-release authored-RST doc sweep, adding/editing `.. das-doc:` markers on a doc page, or extending `utils/doc-verify/` — rule 0, the page-literate model, the full marker vocabulary, authoring rules, regen traps |
| `skills/jobque_debugging.md` | Channel/LockBox/JobStatus/Feature leaks (`--track-job-status`, `DumpJobQueLeaks`) |
| `skills/memory_leak_detection.md` | Any leak report at exit — master index of all six leak-detection mechanisms (gc_node, `--das-profiler-leaks`, `-track-allocations`, smart_ptr tracking, jobque, HandleRegistry) and which to reach for |
| `skills/make_pr.md` | Creating a pull request (lint, test, AOT, format checklist) |
Expand Down
5 changes: 3 additions & 2 deletions daslib/enum_trait.das
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ module enum_trait shared private
//! Enumeration reflection traits.
//!
//! Generates helper functions for enumerations: ``each`` (iterate over all
//! values), ``each_name`` (iterate over all name strings), and
//! ``find_value`` (look up a value by name).
//! values), ``enum_names`` (all name strings), ``to_enum`` (look up a value
//! by name, with or without a default), ``enum_to_table``, ``enum_length``,
//! plus ``string``/``bool`` conversions and ``[string_to_enum]``.

require daslib/ast
require daslib/ast_boost
Expand Down
5 changes: 3 additions & 2 deletions daslib/jobque_boost.das
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ module jobque_boost shared public
//! Job queue macro helpers.
//!
//! Provides ``new_job``, ``new_thread``, ``with_job_que``,
//! ``with_job_status``, ``channel_next``, ``channel_push``, and
//! ``with_job_status``, channel capture helpers
//! (``capture_jobque_channel``/``release_capture_jobque_channel``), and
//! other convenience wrappers that capture lambda closures and
//! correctly manage context cloning for multi-threaded execution.
//! Extends the built-in ``jobque`` module.
//! Extends the built-in ``jobque`` module, which it re-exports.

require jobque public
require math
Expand Down
9 changes: 6 additions & 3 deletions daslib/strings_boost.das
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ module strings_boost shared public

//! Extended string manipulation functions.
//!
//! Adds ``wide``, ``split``, ``join``, ``escape``, ``unescape``,
//! ``starts_with``, ``ends_with``, ``replace``, string-builder helpers,
//! and many other utilities on top of the built-in ``strings`` module.
//! Adds ``wide``, ``split``, ``join``, ``contains``, ``count``,
//! ``trim_prefix``/``trim_suffix``, ``pad_left``/``pad_right``,
//! ``levenshtein_distance``, ``replace_multiple``, ``glob_match``, and other
//! utilities on top of the built-in ``strings`` module, which it re-exports
//! (``escape``, ``unescape``, ``starts_with``, ``ends_with``, ``replace``
//! come from ``strings`` via that re-export).

require math
require strings public
Expand Down
4 changes: 4 additions & 0 deletions doc/source/reference/language/aliases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Publicity

Type aliases can be ``public`` or ``private``:

.. das-doc: alt
.. code-block:: das

typedef public Vec3 = float3 // visible to other modules
Expand Down Expand Up @@ -77,6 +78,7 @@ Instead of writing a ``typedef`` for a tuple, you can use the ``tuple`` keyword

This is equivalent to:

.. das-doc: alt
.. code-block:: das

typedef Vertex = tuple<position:float3; normal:float3; uv:float2>
Expand All @@ -99,6 +101,7 @@ Variants support a similar shorthand:

This is equivalent to:

.. das-doc: alt
.. code-block:: das

typedef Value = variant<i:int; f:float; s:string>
Expand All @@ -121,6 +124,7 @@ Bitfields also support the shorthand syntax:

This is equivalent to:

.. das-doc: alt
.. code-block:: das

typedef Permissions = bitfield<read; write; execute>
Expand Down
51 changes: 36 additions & 15 deletions doc/source/reference/language/annotations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ An annotation is written in square brackets before the declaration it applies to

Multiple annotations can be combined with commas:

.. das-doc: alt
.. code-block:: das

[export, no_aot]
Expand All @@ -31,6 +32,7 @@ Multiple annotations can be combined with commas:

Some annotations accept arguments:

.. das-doc: alt
.. code-block:: das

[init(tag="db")]
Expand All @@ -55,6 +57,7 @@ Lifecycle
Marks a function as callable from the host application. The host invokes exported functions
by name through the context API:

.. das-doc: alt
.. code-block:: das

[export]
Expand Down Expand Up @@ -107,15 +110,19 @@ Lifecycle
Supports a ``late`` attribute for ordering.

``[run]``
Marks a function to run at compile time:
Evaluates calls to the function at compile time and folds the result into the program.
The function must be free of side effects and must return a foldable value — a call the
compiler cannot fold is ``error[50500] function did not run at compilation time``:

.. code-block:: das

[run]
def compile_time_check {
print("compiling...\n")
def table_size(n : int) : int {
return n * n + 1
}

let size = table_size(4) // folded to 17 during compilation

Disabled by the ``disable_run`` option (see :ref:`Options <options>`).

(see :ref:`Program Structure <program_structure>` for the full initialization lifecycle).
Expand Down Expand Up @@ -185,14 +192,15 @@ Lint Control
``[nodiscard]``
Errors if the return value of the function is discarded:

.. das-doc: expect error[30166]
.. code-block:: das

[nodiscard]
def compute : int {
return 42
}

compute() // error: return value discarded
compute() // error[30166]: call to compute result is discarded

``[deprecated]``
Marks a function as deprecated. Produces a compile-time warning when called:
Expand Down Expand Up @@ -282,9 +290,11 @@ Optimization and AOT

.. code-block:: das

require math

[inline]
def clamp01(x : float) : float {
return saturate(x);
return saturate(x)
}

Leaf arguments (constants and variables) substitute textually; pure single-use
Expand Down Expand Up @@ -356,10 +366,13 @@ Macros

``[macro]``
Defined in ``daslib/ast_boost``. Like ``[_macro]`` but wraps the function body in a
module-ready check. Requires ``require daslib/ast_boost``:
module-ready check. Requires ``require daslib/ast_boost``, and — like every macro
registration — a file that declares a ``module``:

.. das-doc: alt
.. code-block:: das

module my_macros
require daslib/ast_boost

[macro]
Expand Down Expand Up @@ -422,7 +435,7 @@ Structure and Class Annotations

``[persistent]``
Makes a structure persistent (survives context reset). All fields must be POD unless
``non_pod=true`` is specified:
``mixed_heap=true`` is specified:

.. code-block:: das

Expand Down Expand Up @@ -514,9 +527,9 @@ All accept an optional ``name`` argument. If omitted, the class name is used.
* - ``[pre_infer_macro]``
- ``AstPassMacro``
- Runs before every (re-)inference pass
* - ``[pre_simulate_macro]``
* - ``[post_infer_macro]``
- ``AstPassMacro``
- Runs after inference, before codegen
- Runs once inference is done, before lint, folding, and codegen
* - ``[lint_macro]``
- ``AstPassMacro``
- Runs during linting
Expand All @@ -528,17 +541,19 @@ All accept an optional ``name`` argument. If omitted, the class name is used.
- Attaches the macro to every function tagged with ``[tag_function]``

Every pass macro — ``[infer_macro]``, ``[dirty_infer_macro]``, ``[optimization_macro]``,
``[pre_infer_macro]``, ``[pre_simulate_macro]``, ``[lint_macro]``, ``[global_lint_macro]`` —
``[pre_infer_macro]``, ``[post_infer_macro]``, ``[lint_macro]``, ``[global_lint_macro]`` —
derives from the single ``AstPassMacro`` base class and overrides
``apply(prog : ProgramPtr; mod : Module?) : bool``. There is no per-pass base class.

``[tag_function_macro]`` additionally requires a ``tag`` argument; unlike the other
annotations here, that one is not optional.

Example:
Example — macro registration runs during module compilation, so the file declares a ``module``:

.. das-doc: alt
.. code-block:: das

module my_macros
require daslib/ast_boost

[function_macro(name="my_decorator")]
Expand Down Expand Up @@ -592,8 +607,10 @@ Requires ``require daslib/contracts``.
- Argument must be a function type
* - ``[expect_any_lambda(arg)]``
- Argument must be a lambda
* - ``[expect_ref(arg)]``
- Argument must be a reference
* - ``[contracts::expect_ref(arg)]``
- Argument must be a reference. The name collides with the built-in ``[expect_ref]``
above, so in a file that requires ``daslib/contracts`` this one is written
module-qualified — the bare name is ``error[30600] too many options for annotation``
* - ``[expect_pointer(arg)]``
- Argument must be a pointer
* - ``[expect_class(arg)]``
Expand All @@ -603,6 +620,7 @@ Requires ``require daslib/contracts``.

Example:

.. das-doc: alt
.. code-block:: das

require daslib/contracts
Expand Down Expand Up @@ -646,6 +664,9 @@ declaration:
value : int
}

These ``@`` decorators attach metadata to the field. They are accessible via ``typeinfo`` and
at compile time in macros.
These ``@`` decorators attach metadata to the field. Macros read them from the structure's
field declarations at compile time. At runtime they are reachable through ``rtti`` — the
field's ``VarInfo`` carries ``annotation_argument_count`` and ``get_annotation_argument``,
under ``options rtti``. A bare ``@big`` is a ``bool`` argument set to ``true``; ``@min = 13``
carries the value.

26 changes: 15 additions & 11 deletions doc/source/reference/language/arrays.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ Arrays can be constructed inline:

.. code-block:: das

let arr = fixed_array(1.,2.,3.,4.5)
let arr = fixed_array(1.,2.,3.,4.5)

This expands to:

.. code-block:: das

let arr : float[4] = fixed_array<float>(1.,2.,3.,4.5)
let arr : float[4] = fixed_array<float>(1.,2.,3.,4.5)

Fixed-size arrays can be multi-dimensional. Dimensions read outermost first —
``float[4][4]`` is 4 rows of ``float[4]`` — and indexing peels one level at a time:
Expand Down Expand Up @@ -115,13 +115,13 @@ Dynamic arrays can also be constructed inline:

.. code-block:: das

let arr <- ["one", "two", "three"]
let arr <- ["one", "two", "three"]

This is syntactic equivalent to:

.. code-block:: das

let arr : array<string> <- array<string>("one","two","three")
let arr : array<string> <- array<string>("one","two","three")

Alternative syntax is:

Expand Down Expand Up @@ -161,7 +161,9 @@ Arrays of tuples can be constructed inline:

When array elements can't be copied, use ``push_clone`` to insert a clone of a value, or ``emplace`` to move it in.

``resize`` can potentially create new array elements. Those elements are initialized with 0.
``resize`` can potentially create new array elements. Those elements are initialized with
``default<T>`` — zeros for plain types, and the declared field initializers for structures
that have them.

``reserve`` is there for performance reasons. Generally, array capacity doubles, if exceeded.
``reserve`` allows you to specify the exact known capacity and significantly reduce the overhead of multiple ``push`` operations.
Expand All @@ -184,21 +186,23 @@ It's possible to iterate over an array via a regular ``for`` loop.

Additionally, a collection of unsafe iterators is provided:

.. das-doc: signatures
.. code-block:: das

def each ( a : auto(TT)[] ) : iterator<TT&>
def each ( a : array<auto(TT)> ) : iterator<TT&>
[unsafe_outside_of_for] def each ( a : auto(TT)[] ) : iterator<TT&>
[unsafe_outside_of_for] def each ( a : array<auto(TT)> ) : iterator<TT&>

The reason both are unsafe operations is that they do not capture the array.

Search functions are available for both static and dynamic arrays:

.. das-doc: signatures
.. code-block:: das

def find_index ( arr : array<auto(TT)> implicit; key : TT )
def find_index ( arr : auto(TT)[] implicit; key : TT )
def find_index_if ( arr : array<auto(TT)> implicit; blk : block<(key:TT):bool> )
def find_index_if ( arr : auto(TT)[] implicit; blk : block<(key:TT):bool> )
def find_index ( arr : array<auto(TT)> | #; key : TT )
def find_index ( arr : auto(TT)[] | #; key : TT )
def find_index_if ( arr : array<auto(TT)> | #; blk : block<(key:TT):bool> )
def find_index_if ( arr : auto(TT)[] | #; blk : block<(key:TT):bool> )

.. seealso::

Expand Down
Loading
Loading