Commit graph

21 commits

Author SHA1 Message Date
joeduffy c080ddbf46 Eliminate pointers from the parse tree
Neither the YAML nor JSON decoders appreciate having pointers in the AST
structures.  This is unfortunate because we end up mutating them later on.
Perhaps we will need separate parse trees and ASTs after all ...
2016-11-16 17:00:58 -08:00
joeduffy 832ef1f743 Lay some groundwork for symbol binding
This change lays some groundwork that registers symbols when doing semantic
analysis of the resulting AST.  For now, that just entails detecting duplicate
services by way of symbol registration.

Note that we've also split binding into two phases to account for the fact
that intra-stack dependencies are wholly legal.
2016-11-16 13:11:58 -08:00
joeduffy 917342f76f Decorate the AST with contextual info
This change decorates the AST with some information that is only known
after parsing.  This enables subsequent logic to remain context-free.
2016-11-16 11:51:50 -08:00
joeduffy 85a828fdf9 Use stable map enumeration for determinism
Go's map iteration order is undefined.  As such, anywhere we enumerate one
we need to go out of our way to sort the keys so that iteration is stable.
Unfortunately, this isn't a single line of code, as it would seem, due to
Go's lack of generics or even a reflectionless Keys() function on maps.  To
do this more elegently, I've created a new InOrderVisitor that handles the
stable enumeration so that other Visitors can remain simple and focus just
on the logic they need to get their job done.
2016-11-16 11:45:41 -08:00
joeduffy badf57c923 Type alias Dependency to SemVer, not string 2016-11-16 11:12:42 -08:00
joeduffy 2665a1a4c4 Check dependencies for validity
This change introduces a check during parse-tree analysis that dependencies
are valid, along with some tests.  Note that this could technically happen later
during semantic analysis and I will likely move it so that we can get better
diagnostics (more errors before failing).  I've also cleaned up and unified some
of the logic by introducing the general notion of a Visitor interface, which the
parse tree analyzer, binder, and analyzers to come will all implement.
2016-11-16 11:09:45 -08:00
joeduffy e2d04f7754 Add tests for parse tree validation
This adds a few tests for parse tree validation, and further restructures
the existing test logic.  The common_test.go file now contains helper methods
common to all tests in the mu/compiler package.  I've also adopted a naming
convention for the testdata/ directory to keep some sanity; namely, each
directory uses "(good|bad)_testname[_seqnum]" as a naming scheme.
2016-11-16 10:02:34 -08:00
joeduffy 1614258437 Declare a Mumodules constant
This is a placeholder for future use; .mu_modules will be our moral
equivalent to NPM/Yarn's node_modules directory.  I've chosen a dot
since for the most part developers can ignore its existence.
2016-11-16 10:01:46 -08:00
joeduffy 5a6c581a7e Check Stack semantic version numbers for correctness
This change ensures that Stack semantic version numbers specified in Mufiles
are correct.  Note that we do not accept ranges for the version number itself,
although obviously when checking dependencies we will permit it.
2016-11-16 10:00:52 -08:00
joeduffy 2dd8665c46 Prepare for semantic analysis
This change begins to lay the groundwork for doing semantic analysis and
lowering to the cloud target's representation.  In particular:

* Split the mu/schema package.  There is now mu/ast which contains the
  core types and mu/encoding which concerns itself with JSON and YAML
  serialization.

* Notably I am *not* yet introducing a second AST form.  Instead, we will
  keep the parse tree and AST unified for the time being.  I envision very
  little difference between them -- at least for now -- and so this keeps
  things simpler, at the expense of two downsides: 1) the trees will be
  mutable (which turns out to be a good thing for performance), and 2) some
  fields will need to be ignored during de/serialization.  We can always
  revisit this later when and if the need to split them arises.

* Add a binder phase.  It is currently a no-op.
2016-11-16 09:29:44 -08:00
joeduffy 60a1f02666 Add more compiler tests
This change adds a few more compiler tests and rearranges some bits and pieces
that came up while doing so.  For example, we now issue warnings for incorrect
casing and/or extensions of the Mufile (and test these conditions).  As part of
doing that, it became clear the layering between the mu/compiler and mu/workspace
packages wasn't quite right, so some logic got moved around; additionally, the
separation of concerns between mu/workspace and mu/schema wasn't quite right, so
this has been fixed also (workspace just understands Mufile related things while
schema understands how to unmarshal the specific supported extensions).
2016-11-16 08:19:26 -08:00
joeduffy 38c73b2e6a Add a simple compiler test
This change adds a compiler test that just checks the basic "Mufile is missing"
error checking.  The test itself is mostly uninteresting; what's more interesting
is the addition of some basic helper functionality that can be used for future
compiler tests, like capturing of compiler diagnostics for comparisons.
2016-11-15 19:16:02 -08:00
joeduffy 0ab10dd207 Rename Semver to SemVer
Eric rightly pointed out in a CR that Semver is...different.  Since it
is an abbreviation of the lengthier SemanticVersion name, SemVer seems
more appropriate.  Changed.
2016-11-15 18:34:19 -08:00
joeduffy 79f5f312b8 Support .yml Mufile extensions
This change recognizes .yml in addition to the official .yaml extension,
since .yml is actually very commonly used.  In addition, while in here, I've
centralized more of the extensions logic so that it's more "data-driven"
and easier to manage down the road (one place to change rather than two).
2016-11-15 18:26:21 -08:00
joeduffy ff0059cd7b Print relative filenames in errors
Error messages could get quite lengthy as the code was written previously,
because we always used the complete absolute path for the file in question.
This change "prettifies" this to be relative to whatever contextual path
the user has chosen during compilation.  This shortens messages considerably.
2016-11-15 18:00:43 -08:00
joeduffy c527cedb03 Delete api/types (missing from last commit) 2016-11-15 17:58:48 -08:00
joeduffy 094d3a0817 Perform more real compilation activities
This change includes some progress on actual compilation (albeit with several
TODOs remaining before we can actually spit out a useful artifact).  There are
also some general cleanups sprinkled throughout.  In a nutshell:

* Add a compiler.Context object that will be available during template expansion.

* Introduce a diag.Document abstraction.  This is better than passing raw filenames
  around, and lets us embellish diagnostics as we go.  In particular, we will be
  in a better position to provide line/column error information.

* Move IO out of the Parser and into the Compiler, where it can cache and reuse
  Documents.  This will become important as we start to load up dependencies.

* Rename PosRange to Location.  This reads nicer with the new Document terminology.

* Rename the mu/api package to mu/schema.  It's likely we will need to introduce a
  true AST that is decoupled from the serialization format and contains bound nodes.
  As a result, treating the existing types as "schema" is more honest.

* Add in a big section of TODOs at the end of the compiler.Compiler.Build function.
2016-11-15 17:42:22 -08:00
joeduffy d238ed61da Make a few improvements, mostly readability
* Rename Meta to Metadata.

* Rename Target's CloudOS and CloudScheduler properties to Cloud
  and Scheduler, respectively.  Also rename Target's JSON properties
  to match (they had drifted); they are now "cloud" and "scheduler".

* Rename Diags() to Diag() on the Compiler and Parser interfaces.

* Rename defaultDiags to defaultSink, to match the interface name.

* Add a few useful logging outputs.
2016-11-15 16:30:10 -08:00
joeduffy c928a0f60b Correctly recognize file extensions 2016-11-15 16:15:58 -08:00
joeduffy e75f06bb2b Sketch a mu build command and its scaffolding
This adds a bunch of general scaffolding and the beginning of a `build` command.

The general engineering scaffolding includes:

* Glide for dependency management.
* A Makefile that runs govet and golint during builds.
* Google's Glog library for logging.
* Cobra for command line functionality.

The Mu-specific scaffolding includes some packages:

* mu/pkg/diag: A package for compiler-like diagnostics.  It's fairly barebones
  at the moment, however we can embellish this over time.
* mu/pkg/errors: A package containing Mu's predefined set of errors.
* mu/pkg/workspace: A package containing workspace-related convenience helpers.

in addition to a main entrypoint that simply wires up and invokes the CLI.  From
there, the mu/cmd package takes over, with the Cobra-defined CLI commands.

Finally, the mu/pkg/compiler package actually implements the compiler behavior.
Or, it will.  For now, it simply parses a JSON or YAML Mufile into the core
mu/pkg/api types, and prints out the result.
2016-11-15 14:30:34 -05:00
joeduffy 9c7f774fc6 Project the core Mufile types
This change adds the core Mufile types (Cluster, Stack, and friends), including
mapping them to the relevant JSON names in the serialized form.  Notably absent
are all of the Identity-related types, which will come later on.
2016-11-15 14:28:17 -05:00