Commit Graph

923 Commits (85b08eb45ec2b5c56e40216b8ac90851acab619d)

Author SHA1 Message Date
Mike Gerwitz 1f371b6ba6 tamer: obj::xmlo::air: More explicit dead states
This doesn't go far enough, but it elaborates a bit---the existing was far
too much of a catch-all.  It's important to take advantage of exhaustiveness
checks to ensure each transition is properly accounted for.

This parser is going to get more work over time, including right now, so I'm
not going to go too deep into this yet, but it's be useful (as a reader) to
compare it to e.g. asg::air's parsers' explicit enumeration of states and
favoring of explicit errors over dead state transitions.

DEV-13162
2023-04-21 11:48:56 -04:00
Mike Gerwitz dd47fc564d tamer: obj::xmlo: More concise identifiers
This follows conventions of other, more recently written, systems.

DEV-13162
2023-04-21 11:48:55 -04:00
Mike Gerwitz e13817c203 tamer: obj::xmlo::air::test: Extract into own file 2023-04-20 16:46:32 -04:00
Mike Gerwitz 6f68292df5 tamer: asg::graph::{index_identifier=>index}: Generalize
This may now index _any_ type of object, in preparation for indexing package
import paths.  In practice, this only makes sense (at least currently) for
`Pkg` and `Ident`.

This generalization also applies to `Asg::lookup_or_missing`.

DEV-13162
2023-04-20 16:46:30 -04:00
Mike Gerwitz f183600c3a tamer: asg: Move Ident-specific methods off of Asg
Historically, the ASG was better described as a "dependency graph",
containing only identifiers (which are simply called "symbols" in the
XSLT-based compiler).  Consequently, it was appropriate for the graph to
have operations specific to identifiers.  (Indeed, that's the only type of
object the graph supported.)

Much has changed since then.  This cleans things up, and makes parenting
identifiers to root an _explicit_ operation.  This will make it easier to
move forward with handling of scope, and importing identifiers into
packages, and removing `Source`, and so on.

DEV-13162
2023-04-19 12:40:35 -04:00
Mike Gerwitz 46551ee298 tamer: ld::xmle::lower::test: Extract into own file
DEV-13162
2023-04-19 12:40:35 -04:00
Mike Gerwitz 778e90c81d tamer: asg::air: Index package identifiers on `Pkg` rather than `Root`
I've been torturing myself trying to figure out how I want to generalize
indexing, lookups, and value numbering in a way that is appropriate for this
project (that is, not over-engineered relative to my needs).

Before I can do much of anything, though, I need to stop having indexing
only as a `Root` thing (previously it wasn't even tied to `Root`).  This
makes that change for tamec, but temporarily removes scoping concerns until
I can add more specific types of indexing.

Not only does this allow cleaning up some `Ident`-specific stuff from `Asg`,
but the cleanup also helps to show that portions of the system aren't still
using Root-based globals.

The linker (`tameld`) still uses the old `global` methods for now; those
will eventually go away, but this needs to change to unify both tamec and
tameld once we get to imports as part of the compiler.

DEV-13162
2023-04-19 12:40:34 -04:00
Mike Gerwitz c367666d8e tamer: nir::tplshort: Generate @desc for generated template
This is required by the XSLT-based compiler, since the `xmli` we're
producing acts as a new source file.

DEV-13708
2023-04-13 09:30:27 -04:00
Mike Gerwitz 590c4b7b06 tamer: NIR->xmli: Support template/@desc
This is needed to then support `@desc` for shorthand desugaring; it's
required by the XSLT-based compiler (and will eventually be required by
TAMER too).

DEV-13708
2023-04-12 15:53:16 -04:00
Mike Gerwitz b7aae207c2 tamer: Rust v1.{68=>70}: Stabalized nonzero_min_max and is_some_and
These two features have been stabalized in Rust 1.70.
2023-04-12 12:04:13 -04:00
Mike Gerwitz af43e35567 tamer: nir::air: Reject Todo* tokens
XIRF->Nir produces `Todo` and `TodoAttr` tokens for many different
things.  The previous approach was to ignore those things so that I could
begin adding portions of packages to the graph and observe how that goes.

But now that I'm starting to be able to compile certain packages that
utilize only small subsets of TAME features, I need to have confidence that
I'm fully parsing them.  This means rejecting tokens that I haven't yet
gotten to.

DEV-13708
2023-04-12 12:04:13 -04:00
Mike Gerwitz e88800af42 tamer: asg: Basic `Doc::Text` support
This supports arbitrary documentation as sibling text (mixed content, in XML
terms).  The motivation behind this change is to permit existing system
tests to succeed when `Todo | TodoAttr` are both rejected, rather than
having to ignore this.

TAME has always had a philosophy of literate documentation, however it was
never fully realized.  This just maintains the status quo; the text is
unstructured, and maybe will be parsed in the future.

Unfortunately, this does _not_ include the output in the `xmli` file or the
system tests.  The reason has nothing to do with TAMER---`xmllint` does not
format the output when there is mixed content, it seems, and I need to move
on for now; I'll consider my options in the future.  But, it's available on
the graph and ready to go.

DEV-13708
2023-04-12 12:04:12 -04:00
Mike Gerwitz 647e0ccbbd tamer: Re-introduce literal parsing for xmlns in NIR for PackageStmt
This _only_ re-introduces for PackageStmt since that's all I have tests for
at present.  More will be re-added later.

They were previously removed when the attribute parsing was upended in
`ele_parse!`.

This does lose the attribute name, compared to before; that'll ideally be
re-added, and I'll explore options for doing so later, since I also want
them in other contexts.  But it needs to be done generically (not
XML-related).

This had to be done before blowing up on TODOs, or system tests would fail.

DEV-13708
2023-04-12 11:59:49 -04:00
Mike Gerwitz acafe91ab9 tamer: nir::Nir::Todo: Add Span
This is in preparation for throwing errors (with diagnostic information) on
yet-to-be-supported tokens, so that I can confidently compile individual
packages without worrying that something is just being ignored.

This makes obvious that `ele_parse!` had a different design in mind
previously, and it's now resulting in a lot of boilerplate; I'll address
that in the future once I'm certain requirements have been settled on, since
I've spent far too much time on it to waste more.

DEV-13708
2023-04-12 11:59:49 -04:00
Mike Gerwitz 9cb6195046 tamer: asg: Add basic Doc support (for @desc)
This introduces a new `Doc` object that can be owned by `Expr` (only atm)
and contain what it describes as a concise independent clause.  This
construction is not enforced, and is only really obvious today via the
Summary Pages.

There's a lot of latent and unrealized potential in TAME's documentation
philosophy that was never realized, so this will certainly evolve over
time.  But for now, the primary purpose was to get `@desc` working on things
like classifications so that `xmli` output can compile for certain
packages.

DEV-13708
2023-04-12 11:59:48 -04:00
Mike Gerwitz 0163391498 tamer: asg::graph::object::prelude: New module to reduce imports
These are used by virtually every `ObjectKind`; I've been meaning to do this
for a while, but now that I'm about to introduce a new one (`Doc`), let's
just get it out of the way.

DEV-13708
2023-04-07 09:56:50 -04:00
Mike Gerwitz f4653790da tamer: NIR->xmli: Represent package imports
This doesn't do the actual hard work yet of resolving and loading a package,
but it does place it on the graph and re-derive it into the xmli output.

DEV-13708
2023-04-07 09:44:16 -04:00
Mike Gerwitz 82e228009d tamer: NIR->xmli: Basic match support
This introduces `<match on="foo" />` and `<match on="foo" value="bar" />`,
which are both equality predicates.  Other types of predicates are not yet
supported.

This change is a bit messy and leaves a bit to be desired.  `NirToAir` is
quite messy and needs some cleanup.  There's also the issue of introducing
XML-specific errors in NIR so that users know what things like "subject"
mean, but not being able to do so yet because NIR is agnostic to the source
document type; another layer of abstraction is needed.

But, my priority is first to get derivation of a particularly
expensive (generated) package in our internal systems working first.

DEV-13708
2023-04-06 22:40:18 -04:00
Mike Gerwitz 1f2ead7f9b tamer: nir: Introduce disambiguating RefSubject
The alternative I was floating was a tagged `Ref` (that is, with an enum
within it), but I settled on this for now, in part for a more concise
notation with the mapping in nir::parse.

We'll see how this evolves.  For now, it's not important with the only thing
that uses ref in nir::parse, which is template application.

This was introduced for `match`, which is to come shortly.

DEV-13708
2023-04-06 10:28:27 -04:00
Mike Gerwitz 7b2acb65c5 tamer: nir::air::test: Formatting and enum prefix elision
This just makes easier to read and more concise.  I'm about to add a number
of tests and the verbosity was off-putting.

DEV-13708
2023-04-06 09:33:44 -04:00
Mike Gerwitz e8371c452e tamer: Remove wip-nir-to-air feature flag in favor of existing wip-asg-derived-xmli
The latter has always enabled the former, and there's really no reason I'd
enable one but not the other at this point.  It's just confusing.

DEV-13708
2023-04-05 22:28:30 -04:00
Mike Gerwitz c0e5b1d750 tamer: asg::air: Template application within expressions
This recognizes template application within expressions.  Since expressions
can occur within templates, this can occur arbitrarily deeply.

And with that, we have the core of the template system represented on the
graph.  Of course, there are some glaring scoping issues to be resolved, but
those aren't unique to template application.

DEV-13708
2023-04-05 15:49:25 -04:00
Mike Gerwitz daa8c6967b tamer: asg: Initial nested template supported
I had hoped this would be considerably easier to implement, but there are
some confounding factors.

First of all: this accomplishes the initial task of getting nested template
applications and definitions re-output in the `xmli` file.  But to do so
successfully, some assumptions had to be made.

The primary issue is that of scope.  The old (XSLT-based) TAME relied on the
output JS to handle lexical scope for it at runtime in most situations.  In
the case of the template system, when scoping/shadowing were needed, complex
and buggy XPaths were used to make a best effort.  The equivalent here would
be a graph traversal, which is not ideal.

I had begun going down the rabbit hole of formalizing lexical scope for
TAMER with environments, but I want to get this committed and working first;
I've been holding onto this and breaking off changes for some time now.

DEV-13708
2023-04-05 15:46:44 -04:00
Mike Gerwitz a738a05461 tamer: asg::graph::object::rel: Hash impls for ObjectIndexTo{,Tree}
All ObjectIndex-like objects hash using only the underlying identifier,
which ultimately boils down to a `NodeIndex` (petgraph), which is just a
u32.  And so in that sense, the only purpose we have for hashing it is to
(a) reduce the space required to store mappings, and (b) compose with other
`Hash`es.

DEV-13708
2023-04-05 15:46:42 -04:00
Mike Gerwitz 3660c15d5a tamer: asg::graph::rel::ObjectIndexTreeRelTo: New trait and related
This creates another trait and struct `ObjectIndexToTree` that assert a
stronger invariant than `ObjectIndexRelTo`---that not only does it uphold
the invariants of `ObjectIndexRelTo`, but also that it represents a _tree_
edge, which indicates _ownership_ rather than just a reference.

This will be used to statically infer what can serve as a scope boundary for
upcoming changes.  Specifically, anything that can own an `Ident` introduces
a new level of scope.

DEV-13708
2023-04-04 14:33:34 -04:00
Mike Gerwitz f1495f8cf4 tamer: asg::graph::object: Move `lookup_local_linear` to `ObjectIndexRelTo`
This allows this method to be used on anything that is able to relate to an
identifier, which is needed for the changes being made for the template
system.

This linear lookup is actually going away (as hinted at by preceding
commits); this is extracted as part of a larger change and I wanted to get
it committed to make it easier to follow upcoming changes.

DEV-13708
2023-04-03 16:14:31 -04:00
Mike Gerwitz 02dba0d63a tamer: asg::graph::Asg: Index by (SymbolId, NodeIndex) pair
The prior commit begins to explain the end goal of being able to index
identifiers outside of the global environment.

This change continues to index things as before, but introduces a new key
based on the pair of the symbol id together with a node that is _part of_
its target environment.  The only environment utilized at the moment (in this
commit) is that of the root node (which is the global scope), in both
indexing and lookup.  Future commits will extend this, and contain more
information about and rationale for the implementation.

The new general index methods are restricted to `pub(super)` until an
abstraction can be put in place that is responsible for environment
indexing; that's a responsibility that is currently handled by
`AirAggregateCtx` for tamec, and the linker has no scoping
requirements since all of that has already been dealt with.

DEV-13708
2023-04-03 16:14:30 -04:00
Mike Gerwitz 5b0a4561a2 Revert "Revert "tamer: asg::graph::index: Use FxHashMap in place of Vec""
This reverts commit 1b7eac337cd5909c01ede3a5b3fba577898d5961.

This is a revert of the previous revert, just so that I (and you) have
references to prior rationale.

This was previously reverted because it wasn't worth doing, but now we have
a situation where we need to begin implementing lexical scoping rules for
nested containers (packages and templates).  In particular, as you'll see in
the commits that follow, we need to be able to look up an identifier that
may have been created as Missing at one level of scope (certain types of
blocks), but then define it at another level.

Or, even more simply at this point, since I'm not yet doing anything
sophisticated with scope: we're only indexing in the global environment, and
we need to be able to index elsewhere too.

The next commit will go into more information, but suffice it to say for now
that indexing is going to get more complicated than a SymbolId.

Sticking with FxHash for now; we don't need a stable hash now.

DEV-13708
2023-04-03 15:15:54 -04:00
Mike Gerwitz 6d35e8776c tamer: asg::air: InvalidExpansionContext in place of TODO
There are no such invalid expansion contexts yet, but this gets rid of the
final remaining TODO from introducing the stack.  With the existing feature
set, at least.

DEV-13708
2023-03-31 14:23:26 -04:00
Mike Gerwitz e3d60750a9 tamer: asg::air: Errors for rooting_ci() TODOs
This eliminates the TODOs that existed when looking for an OI for rooting an
identifier.

The change to `rooting_ci` is ridiculous, but I want to get other things
done before I jump down the rabbit hole of generalizing that (indexing local
identifiers).  Though I have an approach in mind.

DEV-13708
2023-03-31 13:57:11 -04:00
Mike Gerwitz a33d0c4ea5 tamer: asg::air: Consolate nested PkgStart
Just some continued cleanup.

Unfortunately, we have sacrificed knowing a package OI must exist
statically, even though one will always be available.

DEV-13708
2023-03-30 22:28:22 -04:00
Mike Gerwitz 0e0b72ff5f tamer: asg::air: Generalize control transfer convention
The diff should make this refactoring obvious.  The provided documentation
explains why it operates the way that it does.

DEV-13708
2023-03-30 16:38:03 -04:00
Mike Gerwitz 558f1c96b1 tamer: asg::air: Extra AirExpr parsing from AirTplAggregate
This has AirAggregate preempt Expr parsing in the same way as templates,
rather than having `AirTplAggregate` concern itself with expression
tokens.  This continues to simplify `AirTplAggregate`, which was getting
quite complex not too long ago.

A pattern is now emerging for the call/ret convention for preemption.  That
was intentional, but it's nice to see it manifest so obviously before I
abstract it away.

DEV-13708
2023-03-30 15:44:14 -04:00
Mike Gerwitz f29e3cfce1 tamer: asg::air: Use StateStack
This was extracted from xir::parse::ele in previous commits.  The
conventions help to ensure that pushing and returns are being performed
correctly.  The abstraction will continue to evolve.

This ends up using `Ready` as the dead state.  I need to determine if this
is ideal, and if so, maybe just use `Default`, otherwise yield an error.

DEV-13708
2023-03-30 15:44:14 -04:00
Mike Gerwitz e6c6028b37 tamer: xir::parse::ele: Move StateStack into parse::state
This will be utilized by `AirAggregate`.

DEV-13708
2023-03-30 15:44:12 -04:00
Mike Gerwitz 11a4fdfb26 tamer: xir::parse::ele::StateStack: {Array=>}Vec
The use of ArrayVec doesn't buy us anything anymore.  There is no difference
in performance through my own benchmarking (at least on our systems), and
the game has changed since this was written: the size of the states is much
smaller since we're no longer aggregating attributes.  Further, the use of
ArrayVec during development was also to keep memory allocation away from
various parts of the code, which simplified analysis of the binary that was
produced.  Maybe it also reduced memory contention, but clearly that has no
observable impact.

The use of `Vec` removes the arbitrary bound, though I still kept one around
just in case something goes wrong, so TAMER will terminate.  Even though the
token stream is bounded in size, lookahead does create recursion, and the
system cannot (as written) prove that it doesn't.

This is preparing for extracting `StateStack` into `parse` for use with
`AirAggregate`.

DEV-13708
2023-03-30 10:17:15 -04:00
Mike Gerwitz d091103983 tamer: asg::air::tpl: Remove Expr delegation (move to parent)
`AirAggregate` now handles all delegation to `AirExprAggregate`.  This is
possible because `AirAggregate` is now the superstate for each of these
parsers, so `AirTplAggregate` is able to transition to a state that is not
its own.

This does not go so far as reaching the ultimate objective---having nested
template support---even though it'd be fairly simple to do now; there's
going to be a number of interesting consequences to these changes, and a bit
of cleanup is still needed, and I want tests observing this functionality to
accompany those changes.  That is: let's keep this a refactoring, to the
extent that it's possible.

Things are getting much easier to understand now, and much cleaner.

DEV-13708
2023-03-30 09:26:11 -04:00
Mike Gerwitz c59b92370c tamer: parse::state: Superstate support for Token type lifting
What hell have I gotten myself into.

In the end, this wasn't too bad, but the initial batch of errors was really
demotivating; the diff does this no justice.  `Lookahead::into_super` was
created to help tame those errors.

...now I can move forward.  Imagine my disappointment when I ran into this
when expecting from previous work that superstates would now work properly
for the AirAggregate parsers.

(The reason this was needed is because AirAggregate splits tokens into
subtypes for child parsers.)

DEV-13708
2023-03-29 15:50:06 -04:00
Mike Gerwitz 68e2d5d10e tamer: parse::util::expand: Delete module
Oh, boy, I had forgotten about this, until I started working on some
SuperState stuff and discovered this again due to a compiler error.  Don't
want to fix something that isn't used.

But this does not bring back great memories.  It's unfortunate that it
didn't work out; I'm pretty sure this was part of ~1mo of wasted effort
going down a path that I ultimately had to abort.  Not good times.  I'm
still behind from it.

DEV-13708
2023-03-29 15:30:51 -04:00
Mike Gerwitz 15fd2de437 tamer: asg::air::expr: Eliminate RootStrategy
I love deleting code I just wrote...

This doesn't solve the underlying problems with identifiers, but it does at
least lift it into the `AirAggregateCtx`, allowing `AirExprAggregate` to be
even further simplified.  Now the `From` implementation is not specialized
and we can readily convert to a SuperState.

There's still a lot of TODOs here, though.  And some of them will
unfortunately require runtime checks where there was previously a
compile-time check.  But that's okay in a lot of the cases, because the
empty behavior will replace existing error checks.

DEV-13708
2023-03-29 13:49:05 -04:00
Mike Gerwitz 26ddb2ae9d tamer: asg::air::expr: Remove RootStrategy::hold_dangling
Whether or not dangling expressions are permitted is now based solely off of
the stack context, which is also much more intuitive.

`RootStrategy` now only does one thing, and the existing comments describe
why it exists despite that one thing seeming very similar.

`RootStrategy` further alludes to how `ExprStack` could also be
eliminated, should it be worth doing so.  It is a tad redundant now with the
new stack.

DEV-13708
2023-03-29 13:02:01 -04:00
Mike Gerwitz 525adb8a6c tamer: asg::air: Eliminate parent context from AirExprAggregate
This does the same thing to `AirExprAggregate` that was previously done for
`AirAggregate`, taking all parent context from the stack.

This results in a fairly significant simplification of the code, which is
nice, and it makes the `RootStrategy` obviously obsolete in the dangling
case, which will result in more refactoring to simplify it even more.

I regret not taking this route to begin with, but not only was I hoping I
wouldn't need to, but I was still deriving the graph structure and wasn't
sure how this would eventually turn out.  These commits serve as a proof of
necessity.  Or, at least, concrete rationale.

It's worth noting that this also introduces `From` implementations for
`AirAggregate` and the child parsers, and then uses _that_ to push context
from the `AirTplAggregate` parser.  This means that we're just about ready
for it to serve as a superstate.  But there is still a specialization of
`AirExprAggregate` in that `From` impl, which must be removed.

DEV-13708
2023-03-29 13:02:00 -04:00
Mike Gerwitz 755c91e04a tamer: asg::air: Merge AirStack into AirAggregateCtx
Having an extra layer of abstraction was inconvenient, and unnecessary.

DEV-13708
2023-03-29 12:58:36 -04:00
Mike Gerwitz a5b4eda369 tamer: asg::air::AirAggregate: Remove Pkg context from child parser states
This is more of the same of the previous commit, but in a more digestable
chunk.  We now have child states that are able to be constructed using a
simple `From`, which is important to making `AirAggregate` a `SuperState`.

This also makes `AirStack` act like a prototype chain for `ObjectIndex`es,
creating environments where context shadows.  The linear search should only
have to check the last two frames (e.g. an Expr has a parent Pkg or Tpl
context which will have a `rooting_oi` value), and this is only done during
a rooting operation.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz 1ef1290ee9 tamer: asg::air: Begin to derive context from stack
This begins to introduce `AirStack` and starts to migrate context away from
the individual `ParseState`s onto the stack.

I should have started to commit earlier; this is getting a bit large and
makes it hard to follow what I'm doing so, hopefully stopping a little bit
short will allow the following commit to show that.

This is a work-in-progress change.  All tests pass, but the refactoring is
incomplete.  The `AirStack` abstraction is _also_ incomplete and will have
better, more domain-specific operations that make it harder to mess up
pairing pushes with pops.

The purpose of doing this is to allow `AirAggregate` to serve exclusively as
a sum state, which can then become a SuperState, much like `ele_parse!`'s
approach.

The _end_ goal of all of this is arbitrary template nesting.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz 2ae33a1dfa tamer: asg::graph::object: ObjectIndexTo and ObjectIndexRelTo
The graph's ontology is defined in the direction of the edge: from OA
to OB.  This is enforced by the type system to ensure that no code path is
able to generate an invalid graph.

But that also makes it very difficult to work with a generic source to a
specific target.

This introduces a `ObjectIndexRelTo` trait that says whether `Self` is able
to be related to some `ObjectKind` `OB`, implements it for `ObjectIndex
where ObjectRelTo<OB>`, and introduces a new semi-opaque type
`ObjectIndexTo` that allows for the source `ObjectIndex` to be generic.

This then redefines some existing graph primitives in terms of
`ObjectIndexRelTo`, in particular creating edges, so that `ObjectIndex` can
be used as today, and the new `ObjectIndexTo` can be used in the same way
with the same API, without violating the graph ontology.

This will be used by `AirAggregate` to create dynamic targets for rooting
and splicing/expansion.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz eebacb52cc tamer: asg::air::AirAggregate: Remove waiting AirExprAggregate
To simplify things in support of upcoming changes, we'll just instantiate a
new one as needed.  This doesn't have an appreciable performance impact, so
the optimization is premature.  It was done just because it was more of the
same that TAMER was already doing, but now it's making things more
difficult.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz b1ce7aaf29 tamer: asg::air: AirAggregateCtx: New AirAggregate::Context
Future changes to `AirAggregate` are going to require additional context (a
stack, specifically), but the `Context` is currently utilized
by `Asg`.  This introduces a layer of abstraction that will allow us to add
the stack.

Alongside these changes, `ParseState` has been augmented with a `PubContext`
type that is utilized on public APIs, both maintaining BC with existing code
and keeping these implementation details encapsulated.

This does make a bit of a mess of the internal implementation, though, with
`asg_mut()` sprinkled about, so maybe the next commit can clean that up a
bit.  EDIT: After adding `AsMut` to a bunch of asg::graph::object::*
methods, I decided against it, because it messes with the inferred
ownership, requiring explicit borrows via `as_mut()` where they were not
required before.  I think the existing code is easier to reason about than
what would otherwise result from having `mut asg: impl AsMut<Asg>`
everwhere.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz fc569f7551 tamer: asg::air::tpl: Distinct, generalized root and targets
Previously, `AirTplAggregate` worked only in a `Pkg` context, being able to
root `Tpl` `Ident`s in `Pkg` and expand only into `Pkg`.  This still does
the same, but generalizes to allow for different roots and expansion
targets.

This will be utilized to parse nested templates.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz e1c8e371d5 tamer: nir::tplshort: Desugar nested template applications
I'm happy with how this ended up turning out---I was able to accomplish this
without having to introduce any additional state to the parser (I _removed_
a state, actually) by tweaking NIR a bit in a previous commit.

We can't update the system test yet, though, because nested templates are
not yet supported by asg::air::tpl; that'll come next.  If you try, you'll
be greeted with this error presently (which is worth showing since you'll
never see it unless you're hacking TAMER):

,=====[ ./tests/xmli/template/ logs ]======
|
| thread 'main' panicked at 'not yet implemented: internal error:
| note: nested tpl open
|    --> ./tests/xmli/template/src.xml:129:5
|     |
| 129 |     <t:inner-short />
|     |     -------------- note: for this template
|
|
| !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!!
| !!!        THIS IS AN UNFINISHED FEATURE IN TAMER         !!!
| !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!!
| !!! This message means that TAMER has encountered an      !!!
| !!! unrecoverable error that forced it to terminate       !!!
| !!! processing.                                           !!!
| !!!                                                       !!!
| !!! TAMER has attempted to provide you with contextual    !!!
| !!! information above that might allow you to work around !!!
| !!! this problem until it can be fixed.                   !!!
| !!!                                                       !!!
| !!! Please report this error, including the above         !!!
| !!! diagnostic output beginning with 'internal error:'.   !!!
| !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!!
| ', src/asg/air/tpl.rs:207:55
| note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
| Command exited with non-zero status 101
| 0/165fault 0/8io 3528rss 14/2ctx
| /home/[...]/tame/tamer/target/debug/tamec -o ./tests/xmli/template/out.xmli --emit xmlo ./tests/xmli/template/src.xml
|
`====[ end ./tests/xmli/template/ logs ]====

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz 6581c9946c tamer: nir::air: Remove Nir and NirEntity enum prefixes from variants
This is a long-overdue change to make this easier to read, but I'm _still_
holding off on refactoring, since there's still a lot of room for different
patterns to form with all of NIR that is left.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz e595698309 tamer: nir: Apply*Short variants
This adds explicit variants for shorthand template application.  This is
less cryptic, and we'll be able to check for the close directly during
desugaring.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz 975f60bff9 tamer: nir::tplshort: Desugar body into @values@
This represents a significant departure from how the XSLT-based TAME handles
the `@values@` param, but it will end up having the same effect.  It builds
upon prior work, utilizing the fact that referencing a template in TAMER
will expand it.

The problem is this: allowing trees in `Meta` would add yet another
container; we have `Pkg` and `Tpl` already.  This was the same problem with
template application---I didn't want to add support for binding arguments
separately, and so re-used templates themselves, reaching the generalization
I just mentioned above.

`Meta` is intended to be a lexical metasyntatic variable.  That keeps its
implementation quite simple.  But if we start allowing trees, that gets
rather complicated really quickly, and starts to require much more complex
AIR parser state.

But we can accomplish the same behavior by desugaring into an existing
container---a template---and placing the body within it.  Then, in the
future, we'll parse `param-copy` into a simple `Air::RefIdent`, which will
expand the closed template and produce the same result as it does today in
the XSLT-based system.

This leaves open issues of closure (variable binding) in complex scenarios,
such as in templates that introduce metavariables to be utilized by the
body.  That's never a practice I liked, but we'll see how things evolve.

Further, this does not yet handle nested template applications.

But this saved me a ton of work.  Desugaring is much simpler.

The question is going to be how the XSLT-based compiler responds to this for
large packages with thousands of template applications.  I'll have to see
if it's worth the hit at that time, or if we should inline it when
generating the `xmli` file, producing the same `@values@` as
before.  But as it stands at this moment, the output is _not_ compatible
with the current compiler, as it expects `@values@` to be a tree, so a
modification would have to be made there.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz 120f5bdfef tamer: nir::tplshort: Remove variant enum prefixes
This just cleans up a little before I introduce more code, making this
easier to read.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz 9c0e20e58c tamer: asg: Shorthand and long-form template arguments
This applies to template application only; there's still some work to do for
template parameters in definitions (well, for deriving them in `xmli` at
least).  And, as you can see, there's still a lot of TODO items here.

I ended up backtracking on tree edges to Meta, and even on cross edges to
Meta, because it complicated xmli derivation with no benefit right now;
maybe a cross edge will be re-added in the future, but I need to move on and
see where this takes me.

But, it works.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz fcd25d581c tamer: asg::air::expr: Do not cache (globally) identifiers created with StoreDangling
I'm not happy with this implementation.  The linear search is undesirable,
but not too bad (and maybe wouldn't even be worth caching, if this were the
whole story), but we _also_ need to prevent duplicate identifiers.  We are
not going to want to perform a linear search of a linked list (effectively)
every time we add an identifier to check for uniqueness, so I think the
caching is going to have to be generalized very shortly anyway.

As it stands now, a duplicate identifier would cause an error at expansion
time.  That's not what we want, but it's not terrible, because you can have
that same problem in normal circumstances without local conflicts.

But this'll be used for metavariables as well, where we absolutely _do_ want
to fail at template definition time.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz 1c7df894ea tamer: asg::graph: *lookup{=>_global}*
Identifier lookups, as done using the graph methods today, look up from a
cache representing the global environment.

Templates must not contribute to this environment until expansion.  Further,
metavariables will not be present in this environment.  To avoid confusion
and help obviate accidental contributions to this environment, the methods
have been renamed.  This will also allow for the creation of more general
methods down the line.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz 25121c1086 tamer: asg::air: Test formatting (token nesting)
This makes the tests quite a bit easier to understand visually.  I've been
doing this with all new tests but had to go back to some old ones, and still
have more to go back to.  Baby steps.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz bef68e1634 tamer: nir: Desugar shorthand template params and yield AIR
I had intended for this to be a full vertical slice initially, but AIR's
parser is going to need enough work that it'll muddy this patch a bit too
much.

This keeps the desugaring simple, which is what I was hoping for.

The next step is to load it into the graph and emit regenerated longhand
sources.

I also don't like how the namespace prefix is just being ignored for
shorthand param desugaring.  This is also the case in the XSLT-based
compiler, but this violates TAMER's principle that it should parse every bit
of information; nothing should be ignored.  If something does not contribute
useful information, then it is not a useful construct and ought to be
rejected.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz 3dcb2cb03c tamer: nir::NirEntity::TplParam: Optional name/value pair
This will be used for shorthand desugaring.

DEV-13708
2023-03-29 12:58:35 -04:00
Mike Gerwitz a686855e9d tamer: Introduce desugaring operation for shorthand template application
This moves translation from NirToAir into TplShortDesugar, and changes the
output from AIR to NIR.

This is going to be much easier to reason about as a desugaring
operation (and indeed that's always how TAME has implemented it, in XSLT);
this keeps the complexity isolated.

Ideally, NirToAir wouldn't even accept tokens that it can't handle, but
that's going to take quite a bit more work and I don't have the time right
now.  Instead, we'll fail at runtime with some hopefully-useful
information.  It shouldn't actually happen in practice.

DEV-13708
2023-03-29 12:58:34 -04:00
Mike Gerwitz 3e9f407527 tamer: asg::air::ir: Remove TplApply
The implementation decided upon in the previous commits have made this
unnecessary, using `RefIdent` to produce `Tpl->Ident[->Tpl]` instead.

DEV-13708
2023-03-29 12:58:34 -04:00
Mike Gerwitz 669302700a tamer: build-aux/asg-ontviz: Vary arrowhead for cross edges
This makes it more visually apparent, when looking directly at a node,
whether an edge could represent a tree edge.

Dynamic edges could be tree edges, so I left those solid; that's the more
important visual indicator that I'm interested in, and it's disambiguated by
the dashed line.

DEV-13708
2023-03-29 12:58:34 -04:00
Mike Gerwitz 893da0ed20 tamer: asg: Dynamically determined cross edges
Previous to this commit, ontological cross edges were declared
statically.  But this doesn't fare well with the decided implementation for
template application.

The documentation details it, but we have Tpl->Ident which could mean "I
define this Ident once expanded", or it could mean "this is a reference to a
template I will be applying".  The former is a tree edge, the latter is a
cross edge, and that determination can only be made by inspecting edge data
at runtime.

It could have been resolved by introducing new Object types, but that is a
lot of work for little benefit, especially given that only (right now) the
visitor uses this information.

DEV-13708
2023-03-29 12:58:34 -04:00
Mike Gerwitz e132f108e8 tamer: asg::air: {=>diagnostic_}todo!
I forgot about my `diagnostic_todo!` macro!  The purpose was to help guide
development by obviating what comes next in test failures.

DEV-13708
2023-03-29 12:58:34 -04:00
Mike Gerwitz 9d50157f8e tamer: Very basic support for template application NIR -> xmli
This this a big change that's difficult to break up, and I don't have the
energy after it.

This introduces nullary template application, short- and long-form.  Note
that a body of the short form is a `@values@` argument, so that's not
supported yet.

This continues to formalize the idea of what "template application" and
"template expansion" mean in TAMER.  It makes a separate `TplApply`
unnecessary, because now application is simply a reference to a
template.  Expansion and application are one and the same: when a template
expands, it'll re-bind metavariables to the parent context.  So in a
template context, this amounts to application.

But applying a closed template will have nothing to bind, and so is
equivalent to expansion.  And since `Meta` objects are not valid outside of
a `Tpl` context, applying a non-closed template outside of another template
will be invalid.

So we get all of this with a single primitive (getting the "value" of a
template).

The expansion is conceptually like `,@` in Lisp, where we're splicing trees.

It's a mess in some spots, but I want to get this committed before I do a
little bit of cleanup.
2023-03-29 12:58:32 -04:00
Mike Gerwitz aa229b827c tamer: Makefile.am: cargo clippy: Use active feature flags
This was missing `@FEATURES@`, which was causing more compilation than
necessary, but also causing clippy to evaluate different code.

This also adds RUSTFLAGS, for the same reason of not wanting to recompile.

DEV-13708
2023-03-17 10:20:56 -04:00
Mike Gerwitz 03b46ebeff tamer: asg::air::tpl::TplState: Explicitly store reachability of active template
This is a small part of a larger change that I'm still working on.

DEV-13708
2023-03-16 15:08:15 -04:00
Mike Gerwitz d930b26487 tamer: asg::air::ir: Decide on TplApply and expansion
This chooses Option B, as stated would likely be the case in the previous
commit.  The reasons are practical---I intend to support partial application
if doing so is worth it, either in implementation of the compiler or the
source language.

Closed templates can be referenced using `IdentRef` to trigger
expansion---their value is what they expand into, and they are spliced into
that point in the tree, like `,@` in Lisp.  We are able to overload this
behavior because we have the necessary type information.

However, I don't want to have to generate an Ident for every single template
expansion; there are many tens of thousands of them in our production
system.  Since AIR doesn't presently have a way to deal with this situation,
I'll for now add a special token that will close and expand a template in
place; it can be replaced with two separate tokens (`TplEnd` + `Ref`, for
example) in the future if such a need arises.

Are we there yet...?

DEV-13708
2023-03-15 16:40:08 -04:00
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 18fa910e0f tamer: {tools=>build-aux}/asg-ontviz
Now that these are actually intended to be used as part of the build, this
is a more appropriate location.  I originally wrote it as a manual tool.

DEV-13708
2023-03-10 15:13:30 -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 f733a85597 tamer: tools/asg-ontviz: ASG ontology visualization
This parses the declarative `object_rel!` definitions from the Rust sources
and produces a DOT representation of the ontology of the graph, which can
then be rendered using Graphviz.

This does not yet introduce it into the build; it ought to be run as part of
`make check` (without rendering with Graphviz) to ensure that we catch
breaking changes, and `make html` ought to integrate it into the
documentation, perhaps as part of `asg::graph` or `asg::graph::object`.

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 e6325c4c1d tamer: tests/xmli: Estimate tamec time in milliseconds
Going higher than that doesn't make sense because we're in shell and
invoking commands all around this, so even milliseconds isn't going to be
entirely accurate here.  However, what I am more interested in is observing
time relative to other runs; this isn't intended for profiling, but for
eyeballing unexpected behavior.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz b84ee356d5 tamer: tests/xmli: Formatted and more informative output
There's a lot to look at, especially in the event of failure.  Further, I
wanted to add additional statistics that could be eyeballed.

Right now, tamec is too fast (at least on my machine) for the precision of
/usr/bin/time: we need milliseconds, but we only get hundredths of a
second.  So it'll all show as 0:00.00s.  Which is okay, for now; it just
shouldn't exceed that. ;)

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz a261e75fe0 tamer: tests/xmli: Break apart single test case
This would have gotten unwieldy as time goes on, and already made looking at
traces very difficult.

DEV-13708
2023-03-10 14:27:59 -05:00
Mike Gerwitz 7ebd494752 tamer: tests/xmli/expected.xml: Align with src
This just makes this easier to compare side-by-side.

DEV-13708
2023-03-10 14:27:59 -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 286f4cb679 tamer: tests/xmli: Reduce output on failure
This won't try the fixpoint test if the prior one fails, which will always
cause that one to fail.  And it further won't attempt the diff on
compilation failure.

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 266c9eb05a tamer: parse::state::ParseState: Remove `Eq` derivation
This is unneeded and is just a pain.  If ever we need `Eq`, it could be
implemented only for `ParseState`s that actually need it.

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 aec3b97e3f tamer: parse::parser::Parser: Prevent infinite iteration on finalize
This was a rather frustrating thing to encounter.  I was working on
refactoring `AirAggregate`, and found that my tests were hanging despite no
apparent cause in the parser itself.

As it turns out, rather than failing with a `FinalizeError` as I
expected (since I was mid-refactor), `collect()` was allocating space for an
endless stream of errors.  This was easily verified by adding a `take(x)`
and observing the assertion failure (in this case, in `close_pkg_mid_expr`).

This happens to be the first time in a long time that I actually had to
debug---the combination of robust types as proofs and tests to fill in the
gaps means that runtime issues are caught at build time in all but
exceptional cases (like this one).

It's also worth noting that, because of my policy of iterating only at the
higher levels of the program, it was clear that this must somehow be
Parser-related, since that's the only part of the system that has the
potential for unbounded recursion due to its cyclic state machines.

DEV-13708
2023-03-10 14:27:58 -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 d5cf276de2 tamer: nir::air::NirToAir::parse_token: Exhaustiveness without wildcard
Let's start to be explicit about what's missing as we continue to add new
tokens; the exhaustiveness checks throughout the system will guide the
changes that need to be made.

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 6cbcdb1774 tamer: tests/xmli: Add fixpoint test
See documentation for more information.

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 9eb1d226b2 tamer: span: Resolve unusued import warning for debug diagnostic 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 95272c4593 tamer: tests: System test support
This provides a test harness for running shell-based system tests.  The
first of such tests will be introduced in the following commit.

This is done in place of integration tests written in Rust because it will
invoke the final binary exactly as the user or build system (using TAMER)
will, providing greater confidence.  Besides, a lot of things are simply
more convenient to do in shell.  ...though some of you may debate that.

DEV-13708
2023-03-10 14:27:58 -05:00
Mike Gerwitz 9200d415f9 tamer: configure.ac: conf.sh: New configuration file
The intent is to source this in shell scripts, like tests.

This exposes feature flags to shell scripts, but it doesn't do so in quite
the same way that Rust does---it doesn't apply the dependencies.  While this
isn't needed now, it does make me a little uncomfortable, and so I may take
a different approach in the future.

DEV-13708
2023-03-10 14:27:57 -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 fe925db47d tamer: parse::lower:::Lower::lower: Implement in terms of lower_with_context
This is just a special case of lowering with a context, and maintaining two
separate implementations has resulted in divergence.  I don't recall why I
didn't do this previously, though it's possible that the lowering pipeline
was in a state that made it more difficult to do (e.g. with error
handling).

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 6db70385d0 tamer: xir::flat: Introduce configurable acceptors
Technically, an "acceptor" in the context of state machines is actually a
state machine; the terminology here is more describing the configuration of
the state machine (`XirToXirf`) as an acceptor.

This change comes with significant documentation of the rationale and why
this is important; see that for more information.

This change is necessary so that we can enforce finalization on all parsers
in the lowering pipeline, which is not currently being done.  If we were to
do that now, then `tameld` would fail because it halts parsing of the tokens
stream at the end of the `xmlo` header.

This is also quite the type soup, but I'm not going to refine this further
right now, since my focus is elsewhere (XMLI lowering).

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 33d2b4f0b8 tamer: tamec: POC lowering pipeline with XirfAutoClose and XirfToXir
This replaces the stub `derive_xmli` with the same result (well, minus a
space before the '/' in the output) using what will become the lowering
pipeline.  Once again, this is quite verbose, and the lowering pipeline in
general needs to be further abstracted away.

Unlike the rest of the pipeline, an error during the derivation process will
immediately terminate with an unrecoverable error, because we do not want to
write partial files.  This does not remove the garbage file, because the
build system ought to do that itself (e.g. `make`)...but that is certainly
open for debate.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 29178f2360 tamer: xir::reader: Divorce from `parse`
The reader previously yielded a `ParsedResult`, presumably to simplify
lowering operations.  But the reader is not a `ParseState`, and does not
otherwise use the parsing API, so this was an inappropriate and confusing
coupling.

This resolves that, introducing a new `lowerable` which will translate an
iterator into something that can be placed in a lowering pipeline.

See the previous commit for more information.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 963688f889 tamer: parse::lower::ParsedObject: Include Token type parameter
The token type was previously hard-coded to `UnknownToken`, since the use
case was the beginning of the lowering pipeline at the start of the program,
where there was no token type because the first parser (`XirReader`,
currently) is responsible for producing the first token type.

But when we're lowering from the graph (so, the other side of the lowering
pipeline), we _do_ have token types to deal with.

This also emphasizes the inappropriate coupling of `<XirReader as
Iterator>::Item` with `ParsedResult`; I'd like to follow the same approach
that I'm about to introduce with `tamec`, so see a future commit.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz a68930589e tamer: parse::lower: Handle EOF token
This was missed (because it was not used) when EOF tokens were originally
introduced via `ParseState::eof_tok`---`LowerIter` also needs to consider
the token.

This separation betwen the two iterators is a maintenance burden that needs
to be taken care of; I knew that at the time, and then I forgot about it,
and here we are.

This was caught while beginning to wire together a POC graph lowering
pipeline to emit derived sources.

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 bc8586e4b3 tamer: xir::autoclose: New lowering operation
This lowering operation is intended to allow me to write a more concise and
clear mapping from the graph to XIRF, without having to worry about
balancing tags, which really complicated the implementation.

This has details docs; see that for more information.

I can't help but be reminded of Wisp (the whitespace-based Lisp-like
syntax).  Which is unfortunate, because I'm not fond of Wisp; I like my
parenthesis.

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
Mike Gerwitz 52e5242af2 tamer: bin/tamec: wip-asg-derive-xmli-gated xmli output
This will begin to derive `xmli` output from the graph.

DEV-13708
2023-03-10 14:27:57 -05:00
Mike Gerwitz 2d3b27ac01 tamer: asg: Root package definition
This causes a package definition to be rooted (so that it can be easily
accessed for a graph walk).  This keeps consistent with the new
`ObjectIndex`-based API by introducing a unit `Root` `ObjectKind` and the
boilerplate that goes with it.

This boilerplate, now glaringly obvious, will be refactored at some point,
since its repetition is onerous and distracting.

DEV-13159
2023-02-01 10:34:17 -05:00
Mike Gerwitz a7fee3071d tamer: asg::graph::object: Move {Ident,Expr}Rel into respective submodules
DEV-13159
2023-02-01 10:34:17 -05:00
Mike Gerwitz f753a23bad tamer: asg: Introduce edge from Package to Ident
Included in this diff are the corresponding changes to the graph to support
the change.  Adding the edge was easy, but we also need a way to get the
package for an identifier.  The easiest way to do that is to modify the edge
weight to include not just the target node type, but also the source.

DEV-13159
2023-02-01 10:34:17 -05:00
Mike Gerwitz 39d093525c tamer: nir, asg: Introduce package to ASG
This does not yet create edges from identifiers to the package; just getting
this introduced was quite a bit of work, so I want to get this committed.

Note that this also includes a change to NIR so that `Close` contains the
entity so that we can pattern-match for AIR transformations rather than
retaining yet another stack with checks that are already going to be done by
AIR.  This makes NIR stand less on its own from a self-validation point, but
that's okay, given that it's the language that the user entered and,
conceptually, they could enter invalid NIR the same as they enter invalid
XML (e.g. from a REPL).

In _practice_, of course, NIR is lowered from XML and the schema is enforced
during that lowering and so the validation does exist as part of that
parsing.

These concessions speak more to the verbosity of the language (Rust) than
anything.

DEV-13159
2023-02-01 10:34:16 -05:00
Mike Gerwitz 2f08985111 tamer: asg::graph::object::new_rel_dyn: Use Option
Rather than panicing at this level, let's panic at the caller, simplifying
impls and keeping them total.

This can't occur now, but an upcoming change introducing a package type will
allow for such a thing.

DEV-13159
2023-02-01 10:34:16 -05:00
Mike Gerwitz e6abd996b7 tamer: asg::graph::Asg: Non-exhaustive Debug impl
This hides information that's taking up a lot of space in the parser traces
and is not useful information.  In particular, the `index` contains a lot of
empty space due to pre-interned symbols.

The index was going to be converted into a HashMap, but that was reverted
because the tradeoff did not make sense, and so this problem remains; see
the previous commit for more information.

DEV-13159
2023-02-01 10:34:16 -05:00
Mike Gerwitz d066bb370f Revert "tamer: asg::graph::index: Use FxHashMap in place of Vec"
This reverts commit 1b7eac337cd5909c01ede3a5b3fba577898d5961.

I don't actually think this ends up being worth it in the end.  Sure, the
implementation is simpler at a glance, but it is more complex at runtime,
adding more cycles for little benefit.

There are ~220 pre-interned symbols at the time of writing, so ~880 bytes (4
bytes per symbol) are potentially wasted if _none_ of the pre-interned
symbols end up serving as identifiers in the graph.  The reality is that
some of them _will_ but, but using HashMap also introduces overhead, so in
practice, the savings is much less.  On a fairly small package, it was <100
bytes memory saving in `tamec`.  For `tameld`, it actually uses _more_
memory, especially on larger packages, because there are 10s of thousands of
symbols involved.  And we're incurring a rehashing cost on resize, unlike
this original plain `Vec` implementation.

So, I'm leaving this in the history to reference in the future or return to
it if others ask; maybe it'll be worth it in the future.
2023-02-01 10:34:16 -05:00
Mike Gerwitz 417df548cf tamer: asg::graph::index: Use FxHashMap in place of Vec
This was originally written before there were a bunch of preinterned
symbols.  Now the index vector is very sparse.

This simplifies things a bit.  If this ends up manifesting as a bottleneck
in the future, we can revisit the implementation.  While this does result in
more cycles, it's neglibable relative to the total cycle count.
2023-02-01 10:34:16 -05:00
Mike Gerwitz 24eecaa3fd tamer: nir: Basic rate block translation
This commit is what I've been sitting on for testing some of the recent
changes; it is a very basic demonstration of lowering all the way down
from source XML files into the ASG.  This can be run on real files to
observe, beyond unit tests, how the system reacts.

Once this outputs data from the graph, we'll finally have tamec end-to-end
and can just keep filling the gaps.

I'm hoping to roll the desugaring process into NirToAir rather than having a
separate process as originally planned a couple of months back.

This also introduces the `wip-nir-to-air` feature flag.  Currently,
interpolation will cause a `Nir::BindIdent` to be emitted in blocks that
aren't yet emitting NIR, and so results in an invalid parse.

DEV-13159
2023-02-01 10:34:15 -05:00