Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
60 changes: 30 additions & 30 deletions daslib/debug.das
Original file line number Diff line number Diff line change
Expand Up @@ -1184,9 +1184,9 @@ class private DAgent : DapiDebugAgent {
def override onBreakpoint(var ctx : Context; at : LineInfo; reason, text : string) : void {
//! Handles breakpoint or exception events from the runtime, resetting flags on exceptions.
if (reason == "exception") {
self->getContextDataFor(ctx) $(var ctxData : DAContext) {
self->getContextDataFor(ctx, $(var ctxData : DAContext) {
ctxData |> reset_debug_flags()
}
})
}
self->onPause(ctx, at, reason, text)
}
Expand Down Expand Up @@ -1222,7 +1222,7 @@ class private DAgent : DapiDebugAgent {
self->log("{ctx} `{reason}` breakpoint at {path}:{int(at.line)}\n")

self->addContext(ctx)
self->getContextDataFor(ctx) $(var ctxData : DAContext) {
self->getContextDataFor(ctx, $(var ctxData : DAContext) {
ctx |> set_single_step(true)
self->sendStopped(ctx, ctxData, path, at, reason, text, -1ul)
while (!ctxData.continueRequested && !ctxData.stepInRequested && ctxData.stepRequestedStack == 0) {
Expand All @@ -1231,7 +1231,7 @@ class private DAgent : DapiDebugAgent {
ctxData.continueRequested = false
self->afterPause()
ctx |> set_single_step(!withInstruments || ctxData.stepInRequested || ctxData.stepRequestedStack > 0)
}
})
}

def override onSingleStep(var ctx : Context; at : LineInfo) : void {
Expand Down Expand Up @@ -1262,7 +1262,7 @@ class private DAgent : DapiDebugAgent {
ctx |> set_single_step(!withInstruments)
}

self->getContextDataFor(ctx) $(var ctxData : DAContext) {
self->getContextDataFor(ctx, $(var ctxData : DAContext) {
let file = string(at.fileInfo.name) |> resolve_path_cache(workingPaths, pathAliases, pathsCache)
if (ctxData.pauseRequested) {
self->sendStopped(ctx, ctxData, file, at, "pause", "", -1ul)
Expand Down Expand Up @@ -1334,7 +1334,7 @@ class private DAgent : DapiDebugAgent {
}
}
}
}
})
}

def nextStep(var ctx : Context; var ctxData : DAContext; path : string; at : LineInfo) {
Expand Down Expand Up @@ -1367,7 +1367,7 @@ class private DAgent : DapiDebugAgent {

def override onVariable(var ctx : Context; category, name : string; info : TypeInfo; data : void?) : void {
//! Collects a debug agent variable into the topmost stack frame under the given category.
self->getContextDataFor(ctx) $(var ctxData : DAContext) {
self->getContextDataFor(ctx, $(var ctxData : DAContext) {
let stackLen = length(ctxData.stack)
if (stackLen > 0) {
var frame & = unsafe(ctxData.stack[0])
Expand All @@ -1392,7 +1392,7 @@ class private DAgent : DapiDebugAgent {
}
frame.state |> emplace <| (STATE_VARS + uint64(length(frame.state)), category, [ variable])
}
}
})
}

def sendStopped(var ctx : Context; var ctxData : DAContext; path : string; at : LineInfo; reason, text : string; brId : uint64) {
Expand Down Expand Up @@ -1464,7 +1464,7 @@ class private DAgent : DapiDebugAgent {
}
}

let found = self->getContextDataFor(ctx) $(var ctxData : DAContext) {// TODO: speedup getContextDataFor
let found = self->getContextDataFor(ctx, $(var ctxData : DAContext) {// TODO: speedup getContextDataFor
*ctxData.ctx |> clear_instruments()
*ctxData.ctx |> instrument_node(true) $(ati) {
if (ati.fileInfo == null) {
Expand All @@ -1491,7 +1491,7 @@ class private DAgent : DapiDebugAgent {
}
return false
}
}
})

if (!found) {
// removed context, uninitialize related breakpoints
Expand Down Expand Up @@ -1898,7 +1898,7 @@ class private DAServer : Server {
let ctxId = uint64(ctxAndFrame) / MAX_STACK
var found = false
var valid = false
agent->getContextData(ctxId) $(var ctxData : DAContext) {
agent->getContextData(ctxId, $(var ctxData : DAContext) {
let frameId = int(ctxAndFrame % MAX_STACK)
if (frameId >= 0 && frameId < length(ctxData.stack)) {
let kind = uint64(ini.variablesReference) % MAX_VARIABLES
Expand Down Expand Up @@ -1946,7 +1946,7 @@ class private DAServer : Server {
}
}
}
}
})
if (!found || !valid) {
self->sendSuccessResponse(seq, command, JVNull())
}
Expand Down Expand Up @@ -2002,7 +2002,7 @@ class private DAServer : Server {
//! Handles the DAP stackTrace request, returning stack frames for the specified thread.
var inscope ini <- StackTraceArguments(data)
var inscope res : StackTraceResponseBody
agent->getContextData(uint64(ini.threadId)) $(var ctxData : DAContext) {
agent->getContextData(uint64(ini.threadId), $(var ctxData : DAContext) {
for (idx, line in range(ini.levels), ctxData.stack) {
res.stackFrames |> emplace(StackFrame(
id = double(ctxData.id * MAX_STACK + uint64(idx)),
Expand All @@ -2013,7 +2013,7 @@ class private DAServer : Server {
))
}
res.totalFrames = double(length(ctxData.stack))
}
})
self->sendSuccessResponseStr(seq, command, sprint_json(res, false))
}

Expand All @@ -2022,7 +2022,7 @@ class private DAServer : Server {
var inscope ini <- ScopesArguments(data)
var inscope res : ScopesResponseBody
let ctxId = uint64(ini.frameId / double(MAX_STACK))
agent->getContextData(ctxId) $(var ctxData : DAContext) {
agent->getContextData(ctxId, $(var ctxData : DAContext) {
let frameId = int(ini.frameId % double(MAX_STACK))
if (frameId >= 0 && frameId < length(ctxData.stack)) {
let spAddr = ctxData.stack[frameId].spAddr
Expand Down Expand Up @@ -2064,7 +2064,7 @@ class private DAServer : Server {
))
}
}
}
})
self->sendSuccessResponseStr(seq, command, sprint_json(res, false))
}

Expand All @@ -2091,7 +2091,7 @@ class private DAServer : Server {
}
}
} else {
agent->getContextData(ctxId) $(var ctxData : DAContext) {
agent->getContextData(ctxId, $(var ctxData : DAContext) {
let frameId = int(ctxAndFrame % MAX_STACK)
if (frameId >= 0 && frameId < length(ctxData.stack)) {
let kind = uint64(ini.variablesReference) % MAX_VARIABLES
Expand Down Expand Up @@ -2145,59 +2145,59 @@ class private DAServer : Server {
}
}
}
}
})
}
self->sendSuccessResponseStr(seq, command, sprint_json(res, false)) // TODO: , false
}

def reqContinue(seq : double; command : string; data : JsonValue?) {
//! Handles the DAP continue request, resuming execution of the specified thread.
var inscope ini <- ContinueArguments(data)
agent->getContextData(uint64(ini.threadId)) $(var ctx : DAContext) {
agent->getContextData(uint64(ini.threadId), $(var ctx : DAContext) {
ctx |> reset_debug_flags()
ctx.continueRequested = true
}
})
self->sendSuccessResponse(seq, command, null)
}

def reqPause(seq : double; command : string; data : JsonValue?) {
//! Handles the DAP pause request, pausing execution of the specified thread.
var inscope ini <- PauseArguments(data)
agent->getContextData(uint64(ini.threadId)) $(var ctx : DAContext) {
agent->getContextData(uint64(ini.threadId), $(var ctx : DAContext) {
agent->reqPause(ctx)
}
})
self->sendSuccessResponse(seq, command, null)
}

def reqStepIn(seq : double; command : string; data : JsonValue?) {
//! Handles the DAP stepIn request, stepping into the next statement.
var inscope ini <- StepInArguments(data)
agent->getContextData(uint64(ini.threadId)) $(var ctx : DAContext) {
agent->getContextData(uint64(ini.threadId), $(var ctx : DAContext) {
ctx |> reset_debug_flags()
ctx.stepInRequested = true
}
})
self->sendSuccessResponse(seq, command, null)
}

def reqNext(seq : double; command : string; data : JsonValue?) {
//! Handles the DAP next request, stepping over to the next statement at the current stack depth.
var inscope ini <- NextArguments(data)
agent->getContextData(uint64(ini.threadId)) $(var ctx : DAContext) {
agent->getContextData(uint64(ini.threadId), $(var ctx : DAContext) {
ctx |> reset_debug_flags()
ctx.stepRequestedStack = stack_depth(*ctx.ctx)
ctx.stepInRequested = ctx.stepRequestedStack == 0
}
})
self->sendSuccessResponse(seq, command, null)
}

def reqStepOut(seq : double; command : string; data : JsonValue?) {
//! Handles the DAP stepOut request, stepping out of the current function.
var inscope ini <- NextArguments(data)
agent->getContextData(uint64(ini.threadId)) $(var ctx : DAContext) {
agent->getContextData(uint64(ini.threadId), $(var ctx : DAContext) {
ctx |> reset_debug_flags()
ctx.stepRequestedStack = max(stack_depth(*ctx.ctx) - 1, 0)
ctx.stepInRequested = ctx.stepRequestedStack == 0
}
})
self->sendSuccessResponse(seq, command, null)
}

Expand All @@ -2207,7 +2207,7 @@ class private DAServer : Server {

var found = false
let ctxId = uint64(ini.frameId / double(MAX_STACK))
agent->getContextData(ctxId) $(var ctxData : DAContext) {
agent->getContextData(ctxId, $(var ctxData : DAContext) {
let frameId = int(ini.frameId % double(MAX_STACK))
if (frameId >= 0 && frameId < length(ctxData.stack)) {
let spAddr = ctxData.stack[frameId].spAddr
Expand Down Expand Up @@ -2294,7 +2294,7 @@ class private DAServer : Server {
self->sendSuccessResponseStr(seq, command, sprint_json(res, false))
}
}
}
})
if (!found) {
self->sendSuccessResponse(seq, command, null)
}
Expand Down
37 changes: 37 additions & 0 deletions doc/source/reference/language/macros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,43 @@ transformations via ``visit(prog, adapter)``.
:ref:`tutorial_macro_pass_macro` — step-by-step tutorial with lint and
infer macro examples.

------------
AstTypeMacro
------------

``AstTypeMacro`` lets you define custom type expressions resolved during
type inference. It has a single method:

.. code-block:: das

class AstTypeMacro {
def abstract visit ( prog:ProgramPtr; mod:Module?; td:TypeDeclPtr; passT:TypeDeclPtr ) : TypeDeclPtr
}

``add_new_type_macro`` adds a type macro to a module.
The ``[type_macro(name="…")]`` annotation automates registration.

The compiler parses invocations like ``name(type<T>, N)`` in type position
into a ``TypeDecl`` with ``baseType = Type.typeMacro``. The arguments are
stored in ``td.dimExpr``:

- ``dimExpr[0]`` — ``ExprConstString`` with the macro name
- ``dimExpr[1..]`` — user arguments (``ExprTypeDecl`` for types,
``ExprConstInt`` for integers, etc.)

``visit()`` is called in two contexts:

- **Concrete** — all types are inferred; ``passT`` is null;
``dimExpr[i]._type`` is the resolved type.
- **Generic** — type parameters like ``auto(TT)`` are unresolved;
``passT`` carries the actual argument type for matching;
``dimExpr[i]._type`` is null.

.. seealso::

:ref:`tutorial_macro_type_macro` — step-by-step tutorial showing
concrete and generic type-macro usage.

----------------
AstTypeInfoMacro
----------------
Expand Down
4 changes: 3 additions & 1 deletion doc/source/reference/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,6 @@ Run any tutorial from the project root::
tutorials/macros/11_reader_macro.rst
tutorials/macros/12_typeinfo_macro.rst
tutorials/macros/13_enumeration_macro.rst
tutorials/macros/14_pass_macro.rst
tutorials/macros/14_pass_macro.rst
tutorials/macros/15_type_macro.rst
tutorials/macros/16_template_type_macro.rst
2 changes: 2 additions & 0 deletions doc/source/reference/tutorials/macros/14_pass_macro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ The standard library uses pass macros for several purposes:

Previous tutorial: :ref:`tutorial_macro_enumeration_macro`

Next tutorial: :ref:`tutorial_macro_type_macro`

Standard library: ``daslib/heartbeat.das``, ``daslib/coverage.das``,
``daslib/lint.das``

Expand Down
Loading