Scopes available only in certain contexts

I’m trying to implement some syntactic forms that only exist within other language constructs. For example, there’s an “arguments” block that lets you validate arguments passed to a function. It looks like this:

function x(y, z)
    arguments
        y double {mustBePositive}
        z logical = false
    end
    ...
end

This arguments construct is only available in functions. I can’t use it in class definitions or in a top-level script, for example, so I wouldn’t want it to match in either of those places. I already have a working scope for the whole arguments block that I’ve placed at the top level, which is all I can figure to do currently, so it matches anywhere in a file. But I would like to embed it in the function definition scope somehow. I use a function definition scope similar to the built-in Python one, which contains the signature line function x(y, z). This scope starts a symbolic context which ends with the end keyword, which I’ve defined to globally stop all symbolic contexts (including other blocks like if).

A second example of this is methods. Methods are defined using the exact same syntax as functions, with the only distinction being that they’re contained within a methods block in a class definition. My first instinct for how to distinguish functions and methods is to make a methods block construct in the language, and have its only subscope be a “matlab.definition.method”, and everywhere else use “matlab.definition.function”. But again, I run into the issue that I don’t know how to restrict the scopes available in a symbolic context. Is that a proper way to go about this, or is there another way to create this distinction?

This may be related to Code folding, symbol contexts and scope, but I’ve had a hard time finding anything there that solves my problem. Sorry if this is a duplicate!

I’m sorry I don’t have the time to go into details right now, but what you are looking for are Nova’s Start-End Scopes. These have a subscopes element in which you can include other scopes to create hierarchically differentiated scope units. I’d recommend you take a peek at one of the more complex syntax definitions Nova includes (albeit compiled into the app, they are also provided as extensions inside Nova’s app bundle), like JavaScript, to get a better idea of how these work. Nova’s API docs are exhaustive and (mostly) correct, but not beginner friendly.