Commit Graph

116 Commits (be81878dd79a6bf639275406a72ee66615da38d0)

Author SHA1 Message Date
Mike Gerwitz be81878dd7 tamer: src::asg: Scaffolding for metasyntactic variables
Also known as metavariables or template parameters.

This is a bit of a tortured excursion, trying to figure out how I want to
best represent this.  I have a number of pages of hand-written notes that
I'd like to distill over time, but the rendered graph ontology (via
`asg-ontviz`) demonstrates the broad idea.

`AirTpl::TplApply` highlights some remaining questions.  What I had _wanted_
to do is to separate the concepts of application and expansion, and support
partial application and such.  But it's going to be too much work for now,
when it isn't needed---partial application can be worked around by simply
creating new templates and duplicating params, as we do today, although that
sucks and is a maintenance issue.  But I'd rather address that head-on in
the future.

So it's looking like Option B is going to be the approach for now, with
templates being closed (as in, no free metavariables) and expanded at the
same time.  This simplifies the parser and error conditions significantly
and makes it easier to utilize anonymous templates, since it'll still be the
active context.

My intent is to get at least the graph construction sorted out---not the
actual expansion and binding yet---enough that I can use templates to
represent parts of NIR that do not have proper graph representations or
desugaring yet, so that I can spit them back out again in the `xmli` file
and incrementally handle them.  That was an option I had considered some
months ago, but didn't want to entertain it at the time because I wasn't
sure what doing so would look like; while it was an attractive approach
since it pushes existing primitives into the template system (something I've
wanted to do for years), I didn't want to potentially tank performance or
compromise the design for it after I had spent so much effort on all of this
so far.

But my efforts have yielded a system that significantly exceeds my initial
performance expectations, with a decent abstractions, and so this seems
viable.

DEV-13708
2023-03-15 16:40:07 -04:00
Mike Gerwitz 9e5958d89e tamer: asg::air::ir::Air: Open/Close => Start/End in token names
See the Air docblock for more information.  I'm introducing new tokens for
the template system, which uses the terms "free" and "closed".  I prefer
open/close for delimiters, as I've expressed elsewhere, but unfortunately it
conflicts too much (and too confusingly) with other standard terminology as
we get more into the formal side of the language.

DEV-13708
2023-03-15 10:59:25 -04:00
Mike Gerwitz 0e42788dcc tamer: asg::air: Restrict AirTplAggregate token domain to new AirTemplatable
This removes special cases, but it does complicate the parent `AirAggregate`
parser.  A pattern of delegation is forming, though abstracting it may be an
interesting challenge, given Rust's limitation on macro invocations as match
arms.  But, I think I can manage by generating the entire match using a
macro with a match-compatible syntax, augmenting where
needed...maybe.  This'll be messy.

...but if I can write the nightmare that is `ele_parse!`, I'm sure I can
manage this.  I just prefer to avoid complex macros unless I really need
them.

DEV-13708
2023-03-11 00:58:08 -05:00
Mike Gerwitz 2233c69bbf tamer: asg::graph::object: Some minor proofreading 2023-03-10 23:44:40 -05:00
Mike Gerwitz a5b03e8790 tamer: Embed ASG ontology visualization in rustdoc-generated docs
There, in-your-face and not hidden in some tools directory.

DEV-13708
2023-03-10 14:28:00 -05:00
Mike Gerwitz 0aa69c079d tamer: NIR->xmli: Ceil, Floor expressions
Small break from templates for something easier.  I have COVID-19, so I'll
use that as my excuse for wanting to be more lazy.

The real reason is to see some more concrete progress and ensure that
patterns hold for simple expressions before further refactoring.

But, before I proceed with such refactoring, I really ought to approach
something that requires a NIR desugaring step, like case statements.

DEV-13708
2023-03-10 14:28:00 -05:00
Mike Gerwitz b9f0fada51 tamer: asg::graph::object::expr::ExprOp: Doc comment fix {//=>///}
DEV-13708
2023-03-10 14:28:00 -05:00
Mike Gerwitz 343f5b34b3 tamer: asg::air: Template support for dangling expressions
The intent was to have a very simple implementation of `hold_dangling` and
have everything work.  But, I had a nasty surprise when the system tests
caught bug caused by some interesting depth interactions as it relates to
`xmli` and auto-closing.

I added an extra test/example in `asg::graph::visit::test` to illustrate the
situation; it was difficult to derive from the traces, but trivially obvious
once I wrote it out as an example.

With that, templates can now aggregate tokens for dangling expressions.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz 5c60c5fd15 tamer: asg::air::tpl: Parse template body expressions
And finally we have tokens aggregated onto the ASG in the context of a
template.  I expected to arrive here much more quickly, but there was a lot
of necessary refactoring.  There's a lot more that could be done, but I need
to continue; I had wanted this done a week ago.

It is worth noting, though, that this finally achieves something I had been
wondering about since the inception of this project---how I'd represent
templates on the graph.  I think this worked out rather nicely.  It wasn't
even until a few months ago that I decided to use AIR instead of NIR for
that purpose (NIR wouldn't have worked).

And note how I didn't have to touch the program derivation at all---the
system test just works with the AIR change, because of the consistent
construction of the graph.  Beautiful.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz 431df6cecb tamer: asg::air::expr: Dead states for AirBind
This hoists the errors back into `AirAggregate`; I need dead states for the
`AirTplAggregate` parser so that it will know when to (and not to) interpret
tokens in the context of the template itself.

In a previous commit message, I had pondered whether it may be possible to
eliminate the dead state transition, and yet here I've used it with both of
the sub-parsers now.  So it seems like the better option in the future may
be to narrow the type further---to say precisely _what_ types of tokens may
yield a dead state transition; otherwise you lose the match information from
the parser that yielded it.

A stubbornly persistent problem in Rust, this magical and hidden match
knowledge.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz 1770949b9a tamer: asg::air::expr: Move Dangling expression handling into RootStrategy
And with this, hopefully we are now finally prepared for dangling
expressions in templates.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz 231296d003 tamer: asg::air::expr: Introduce RootStrategy
This sets us up to be able to determine how `Dangling` expressions will be
rooted into templates.

This new strategy isn't yet handling `Dangling`; I wanted to get this
committed first so that the `Dangling` refactoring is more clear.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz fc1d55c4c5 tamer: asg::air::expr: Generic target ObjectKind
Expressions were previously tied to packages.  This prepares for using a
`Tpl` as a container for expressions.

This does not yet handle the situation of auto-rooting dangling expressions
within the container.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz 8cb781ccca tamer: asg::air::expr::ExprStack: {SPair=>ObjectIndex} reachable evidence
This result in less useful debug output, but it'll be needed for using
a (possibly-anonymous) template as evidence.

This evidence is simply for debugging, and to require some sort of value
during development to help obviate when maybe something is being done
incorrectly (if no obvious value exists).

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz c1d04f1cf4 tamer: asg::air: Extract template parsing into `tpl`
Same as the previous commit.  These commits have significantly reduced the
cognitive burden of working on this subsystem.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz 4fd8e9ea40 tamer: asg::air: Extract expression parsing into `expr`
This is more of the same refactoring that has been happening.  This
extraction also helps emphasize the relationship between imported objects,
and isolates the growing number of test cases.  This parser will only grow.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz f307f2d70b tamer: asg::air: Extract template parsing into own parser
Just as was done with the expression parser, which this will utilize.  This
initializes it, but doesn't yet make use of it (`AirExprAggregate`).

Refactoring was definitely needed; decomposing this is quite a bit of work,
in no small part because of the complexity.  This helps significantly.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz 25c0aa180e parse::state::transition::TransitionResult::branch_dead: Add branch context
This works around limitations of Rust's borrow checker as of the time of
writing.  See the provided documentation for more information.

The branch context is not yet exposed to the `delegate` family of methods;
it will be added only as needed in the future.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz d99a8efbaf tamer: asg::air::ir: {ExprRef=>RefIdent}
This generalizes the IR, and relates the duals: identifying and referencing.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz e2714ce73f tamer: asg::air::ir::sum_ir: impl Token for IR sum type
This is necessary for the commit that follows.  Maybe it wasn't worth
separating this into its own commit.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz b6d0569b99 tamer: asg::air: Expression parser
This delegates expression parsing to `AirExprAggregate`, in an effort to
both begin to simplify the understanding and maintenance of `AirAggregate`;
and allow for parser composition for template parsing.

This utilizes the prior changes for token sum types to precisely define the
subset of AIR tokens supported by the expression parser.  This differs from
prior approaches which delegated until a dead state, relying on runtime
information to determine if a parser has finished.  This allows us to
determine that statically.

I do want to be able to eliminate the dead state from the parser so we can
get rid of the `unreachable!`, but I need to move on; that's something I had
tried to do in the past too, which ended up adding a bit of complexity, and
I'll have to consider my options in the future, including whether the dead
state transition can be entirely eliminated in favor of the combination of
these sum types and recovery; the parsing framework decisions were made
while recovery was still an open question, at least in practice.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz dfeef4ec25 tamer: asg::air::ir::sum_ir: Support arbitrary sum types
See the provided documentation.  This allows for precisely defining sum
types over all tokens accepted by parsers; see a following commit.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz 34b64fd619 tamer: asg::air: AIR as a sum IR
This introduces a new macro `sum_ir!` to help with a long-standing problem
of not being able to easily narrow types in Rust without a whole lot of
boilerplate.  This patch includes a bit of documentation, so see that for
more information.

This was not a welcome change---I jumped down this rabbit hole trying to
decompose `AirAggregate` so that I can share portions of parsing with the
current parser and a template parser.  I can now proceed with that.

This is not the only implementation that I had tried.  I previously inverted
the approach, as I've been doing manually for some time: manually create
types to hold the sets of variants, and then create a sum type to hold those
types.  That works, but it resulted in a mess for systems that have to use
the IR, since now you have two enums to contend with.  I didn't find that to
be appropriate, because we shouldn't complicate the external API for
implementation details.

The enum for IRs is supposed to be like a bytecode---a list of operations
that can be performed with the IR.  They can be grouped if it makes sense
for a public API, but in my case, I only wanted subsets for the sake of
delegating responsibilities to smaller subsystems, while retaining the
context that `match` provides via its exhaustiveness checking but does not
expose as something concrete (which is deeply frustrating!).

Anyway, here we are; this'll be refined over time, hopefully, and
portions of it can be generalized for removing boilerplate from other IRs.

Another thing to note is that this syntax is really a compromise---I had to
move on, and I was spending too much time trying to get creative with
`macro_rules!`.  It isn't the best, and it doesn't seem very Rust-like in
some places and is therefore not necessarily all that intuitive.  This can
be refined further in the future.  But the end result, all things
considered, isn't too bad.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz d42a46d2b8 tamer: NIR->xmli template definition setup
This sets the stage for template parsing, and finally decides how we're
going to represent templates on the ASG.  This is going to start simple,
since my original plans for improving how templates are
handled (conceptually) is going to have to wait.

This is the last difficult object type to figure out, with respect to graph
representation and derivation, so I wanted to get it out of the way.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 08278bc867 tamer: asg::air::Air::{ExprIdent=>BindIdent}: Rename
I wasn't initially sure whether I'd want separate tokens for different types
of identifying operations, but now that I see that it is clear from the
current state of the parser, there's no need.

This matches the name of the token in NIR.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz dd2232b58b tamer: asg::graph: object_gen and object_rel macros
The previous commit demonstrated the amount of boilerplate necessary for
introducing new `ObjectKind`s; this abstracts away a lot of that
boilerplate, and allows for declarative relationship definition for the
ASG's ontology.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 454b91dfce tamer: asg::graph::object: New Tpl object
There's quite a bit of boilerplate here that'll eventually need factoring
out.  But it's also clear that it is somewhat onerous to add new object
types.

Note that a good chunk of this burden is _intentional_, via exhaustiveness
checks---adding a new type of object is an exceptional occurrence (well, in
principle, but we haven't added them all yet, so it'll be more common
initially), and we'd rather be safe to ensure that everything is properly
considering how that new type of object interacts with it.

Let's not confuse coupling with safety---the latter causes a burden because
of the former, not because of itself; it provides a service to us.

But, nonetheless, we'll want to reduce this burden somewhat since there are
a number more to add.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 98fcb115da tamer: NIR->xmli: Initial classify, any, all support
Just as `rate` is a `sum`, `classify` is an `all` by default.  The `@any`
attribute will change that interpretation, though I only intend to recognize
that in parsing later on, not emit that in XMLI.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 5865d86485 tamer: NIR->xmli: Initial product expression
The element only, no attributes yet.

I'll keep forming boilerplate until abstraction points become obvious with
more variety; this is still pretty close to what was already supported.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz ebc16b7bdb tamer: asg::graph::xmli: Deduplicate with TreeContext
We already had `TreeContext`, and I'm passing the same arguments around, so
this uses it to lift arguments out of these functions, like partial
application.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 506d3e9d11 tamer: asg::graph::xmli::AsgTreeToXirf::parse_token: Cleanup
This tidies this method up into a decent state that I'm fairly content
with.  This goes to emphasize my dislike of returns, which muddies control
flow and makes the code more difficult to read at a glance, which increase
the likelihood of logic bugs.

`match` statements in tail position, on the other hand, are very clear, and
less cognitively burdensome since you can see each individual code path at a
glance.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz e3e50c38c7 tamer: asg::graph::xmli: Extract xmli generation from parse_token
This begins to develop a pattern for doing these transformations.  I had
tried a number of things using iterators, but I wasn't satisfied with either
how they were turning out; had to fight too much with the type system; or
had to resort to heap allocations.  Sticking with an explicit
`push`/`push_all` for now works just fine.

Almost done cleaning up `AsgTreeToXirf::parse_token`, and then I can move on
to introducing more objects.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 3587d032c3 tamer: asg::graph::object::rel::DynObjectRel: Store source data
This is generic over the source, just as the target, defaulting just the
same to `ObjectIndex`.

This allows us to use only the edge information provided rather than having
to perform another lookup on the graph and then assert that we found the
correct edge.  In this case, we're dealing with an `Ident->Expr` edge, of
which there is only one, but in other cases, there may be many such edges,
and it wouldn't be possible to know _which_ was referred to without also
keeping context of the previous edge in the walk.

So, in addition to avoiding more indirection and being more immune to logic
bugs, this also allows us to avoid states in `AsgTreeToXirf` for the purpose
of tracking previous edges in the current path.  And it means that the tree
walk can seed further traversals in conjunction with it, if that is so
needed for deriving sources.

More cleanup will be needed, but this does well to set us up for moving
forward; I was too uncomfortable with having to do the separate
lookup.  This is also a more intuitive API.

But it does have the awkward effect that now I don't need the pair---I just
need the `Object`---but I'm not going to remove it because I suspect I may
need it in the future.  We'll see.

The TODO references the fact that I'm using a convenient `resolve_oi_pairs`
instead of resolving only the target first and then the source only in the
code path that needs it.  I'll want to verify that Rust will properly
optimize to avoid the source resolution in branches that do not need it.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz cb5d54b2db tamer: asg::graph::object: Generic Object inner type
This makes the inner `Object` type generic (but defaulting to the same inner
types as before) so that it can be used as a sum type for various types
where `ObjectKind`-based narrowing is required.

In this case, it's used to narrow `ObjectIndex` alongside the inner
`ObjectKind` so that the two are definitely in sync.  This not only results
in cleaner code and a more intuitive API that's approachable to people
less familiar with the system, but it also helps to eliminate logic bugs
that might result form manually narrowing (as was done before this change).

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz d078b24efd tamer: asg::graph::xmli::TokenStack::push_all: New method
Rust optimizes away the iterator and array, compiling into separate `push`
calls as before.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 9990be58a7 tamer: Lower sum expressions
This was a fairly simple addition, since rate blocks already lower into sum
expressions; these are just non-identified.

This does emphasize that the nir::parse `ele_parse!` abstraction I spent so
much time on ended up not being a perfect fit, as it now has some
boilerplate after it was stripped of much of its capabilities some time ago.

Don't worry, `nir::air` and `asg::graph::xmli` will get cleaned up.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz ee9128fbe0 tamer: asg::graph::{object::xir=>xmli}: Rename module
This better reflects what is being done and makes it easier for someone to
find.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 82915f11af tamer: asg::graph::object::xir: Initial rate element reconstruction
This extends the POC a bit by beginning to reconstruct rate blocks (note
that NIR isn't producing sub-expressions yet).

Importantly, this also adds the first system tests, now that we have an
end-to-end system.  This not only gives me confidence that the system is
producing the expected output, but serves as a compromise: writing unit or
integration tests for this program derivation would be a great deal of work,
and wouldn't even catch the bugs I'm worried most about; the lowering
operation can be written in such a way as to give me high confidence in its
correctness without those more granular tests, or in conjunction with unit
or integration tests for a smaller portion.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 716247483f tamer: asg::graph::object::xir: POC use of token stack
Just some final POC setup for how this'll work; it's nothing
significant.  This just emits an `@xmlns` on the `package` element to
demonstrate use of the stack.

With that, it's time to formalize this.

I also need to document at some point why I choose to use `ArrayVec` still
over `Vec`---it's not a microoptimization.  It's intended to simplify the
runtime to keep execution simple with fewer code paths and make it more
amenable to analysis.  Memory allocation is a pretty complex thing and
muddies execution.  It's also another point of failure, though practically
speaking, I'm not worried about that---this is replacing a system that
consumes many GiB of memory (XSLT-based compiler) with one that consumes 10s
of MiB.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 7efd08a699 tamer: asg::graph::object::xir: New context to hold stack state
This (a) hold the state of a stack that I can populate with tokens rather
than introducing a state for every single e.g. attribute and such on
elements (so, more like the `xmle` XIR lowering).

It also hides the obvious awkwardness of the `&mut &'a Asg`, but that's not
the intent of it.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz f8c1ef5ef2 tamer: tamec: MILESONE: POC end-to-end lowering
This has been a long time coming.  The wiring of it all together is a little
rough around the edges right now, but this commit represents a working POC
to begin to fill in the gaps for the entire lowering pipeline.

I had hoped to be at this point a year ago.  Yeah.

This marks a significant milestone in the project because this allows me to
begin to observe the implementation end-to-end, testing it on real-life
inputs as part of a production build pipeline.

...and now, with that, we can begin.  So much work has gone into this
project so far, but aside from the linker (which has been in production for
years), most of this work has been foundational.  It's been a significant
investment that I intend to have pay off in many different ways.

(All this outputs right now is `<package/>`.)

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 79cc61f996 tamer: xir::flat::XirfToXir: New lowering operation
This parser does exactly what it says it does.  Its implementation is
simple, but I added a test anyway just to prove that it works, and the test
seems more complicated than the implementation itself, given the types
involved.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz a5a5a99dbd tamer: asg::graph::visit::TreeWalkRel: New token type
This introduces a `Token` in place of the original tuple for
`TreePreOrderDfs` so that it can be used as input to a parser that will
lower into XIRF.

This requires that various things be describable (using `Display`), which
this also adds.  This is an example of where the parsing framework itself
enforces system observability by ensuring that every part of the system can
describe its state.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 7f3ce44481 tamer: asg::graph: Formalize dynamic relationships (edges)
The `TreePreOrderDfs` iterator needed to expose additional edge context to
the caller (specifically, the `Span`).  This was getting a bit messy, so
this consolodates everything into a new `DynObjectRel`, which also
emphasizes that it is in need of narrowing.

Packing everything up like that also allows us to return more information to
the caller without complicating the API, since the caller does not need to
be concerned with all of those values individually.

Depth is kept separate, since that is a property of the traversal and is not
stored on the graph.  (Rather, it _is_ a property of the graph, but it's not
calculated until traversal.  But, depth will also vary for a given node
because of cross edges, and so we cannot store any concrete depth on the
graph for a given node.  Not even a canonical one, because once we start
doing inlining and common subexpression elimination, there will be shared
edges that are _not_ cross edges (the node is conceptually part of _both_
trees).  Okay, enough of this rambling parenthetical.)

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 2b2776f4e1 tamer: asg::graph::object::rel: Extract object relationships
DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 065dca88fc tamer: asg::graph::vist::tree_reconstruction: Include Depth
This information is necessary to be able to reconstruct the tree, since
the `ObjectIndex` alone does not give you enough information.  Even if you
inspected the graph, it _still_ wouldn't give you enough information, since
you don't know the current path of the traversal for nodes that may have
multiple incoming edges.  (Any assumptions you could make today won't
always be valid in the future.)

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz e6f736298b tamer: asg::graph::visit::tree_reconstruction: New graph traversal
This begins to introduce a graph traversal useful for a source
reconstruction from the current state of the ASG.  The idea is to, after
having parsed and ingested the source through the lowering pipeline, to
re-output it to (a) prove that we have parsed correctly and (b) allow
progressively moving things from the XSLT-based compiler into TAMER.

There's quite a bit of documentation here; see that for more
information.  Generalizing this in an appropriate way took some time, but I
think this makes sense (that work began with the introduction of cross edges
in terms of the tree described by the graph's ontology).  But I do need to
come up with an illustration to include in the documentation.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 4afc8c22e6 tamer: asg::air: Merge Pkg closing span
The `Pkg` span will now properly reflect the entire definition of the
package including the opening and closing tags.

This was found while I was working on a graph traversal.

DEV-13597
2023-03-10 14:27:57 -05:00
Mike Gerwitz 39e98210be tamer: asg::graph::object::ident::ObjectIndex::<Ident>::bind_definition: Replace ident span
I noticed this while working on a graph traversal.  The unit test used the
same span for both the reference _and_ the binding, so I didn't notice. -_-

The problem with this, though, is that we do not have a separate span
representing the source location of the identifier reference.  The reason is
that we decided to re-use an existing node rather than creating another one,
which would add another inconvenient layer of indirection (and complexity).

So, I may have to add (optional?) spans to edges.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 89700aa949 tamer: asg::graph::object::ObjectRel::is_cross_edge: New trait method
This introduces the concept of ontological cross edges.

The term "cross edge" is most often seen in the context of graph traversals,
e.g. the trees formed by a depth-first search.  This, however, refers to the
trees that are inherent in the ontology of the graph.

For example, an `ExprRef` will produce a cross edge to the referenced
`Ident`, that that is a different tree than the current expression.  (Well,
I suppose technically it _could_ be a back edge, but then that'd be a cycle
which would fail the process once we get to preventing it.  So let's ignore
that for now.)

DEV-13708
2023-03-10 14:27:57 -05:00