Commit Graph

468 Commits

Author SHA1 Message Date
Martin Atkins
ed2a739cdb zclwrite: Don't crash if EachToken called on a nil TokenSeq. 2017-06-07 07:39:01 -07:00
Martin Atkins
69a87c73b4 zclwrite: start to partition body items
So far they are still just all unstructured, but each item is a separate
node.
2017-06-07 07:38:44 -07:00
Martin Atkins
363d08ed0d zclwrite: File-level AllTokens
This captures any leftover tokens that aren't considered part of the
file's main body, such as the trailing EOF token.
2017-06-07 07:37:56 -07:00
Martin Atkins
fa8a707c7f zclwrite: begin to flesh out public interface 2017-06-07 07:24:10 -07:00
Martin Atkins
598740b638 zclwrite: method for writing tokens to a writer
This now allows for round-tripping some input from bytes to tokens and
then back to bytes again. With no other changes, we expect this to produce
an identical result.
2017-06-07 07:06:23 -07:00
Martin Atkins
efbcfd19b2 zclwrite: TokenGen interface has EachToken, not AppendToTokens
Although building a flat array of tokens is _one_ use-case for TokenGen,
this new approach means we can also use the interface to write to an
io.Writer without needing to produce an intermediate buffer.
2017-06-07 06:45:01 -07:00
Martin Atkins
c233270a9b zclwrite: use a single, flat writer token buffer
Previously we were allocating a separate heap object for each token, which
creates a lot of small objects for the GC to manage. Since we know that
we're always converting from a flat array of native tokens, we can produce
a flat array of writer tokens first and _then_ take pointers into that
array to achieve our goal of making a slice of pointers.

For the use-case of formatting a sequence of tokens by tweaking the
"SpacesBefore" value, this means we can get all of our memory allocation
done in a single chunk and then just tweak the allocated, contiguous
tokens in-place, which should reduce memory pressure for a task which
will likely be done frequently by a text editor integration doing "format
on save".
2017-06-07 06:38:41 -07:00
Martin Atkins
3c0dde2ae5 zclwrite: foundations of the writer parser
The "writer parser" is a parser that produces a writer AST rather than
a zclsyntax AST. This can be used to produce a writer AST from existing
source in order to modify it before writing it out again.

It's implemented with the somewhat-unintuitive approach of running the
main zclsyntax parser and then mapping the source ranges it finds back
onto the token sequence to pull out the raw tokens for each object.
This allows us to avoid maintaining two parsers but also keeps all of
this raw-token-wrangling complexity out of the main parser.
2017-06-06 08:53:13 -07:00
Martin Atkins
34be20cc5d zclsyntax: ScopeTraversalExpr.Value implementation, and tests 2017-06-05 08:02:54 -07:00
Martin Atkins
68aa56c795 zcl: Implement Traversal.TraverseAbs 2017-06-05 07:55:33 -07:00
Martin Atkins
ace387f5f9 zclsyntax: evaluation of relative traversal and index nodes 2017-06-05 07:41:02 -07:00
Martin Atkins
b604827bb2 zcl: Automatically convert key types when indexing
For example, if a map is indexed with a number then we'll automatically
convert it to string before attempting to use it as an index.
2017-06-05 07:39:14 -07:00
Martin Atkins
36eacf5110 zcl: Factor the index operation out into its own function
Indexing is pretty fundamental and it's also non-trivial, so having this
exposed will make it easier for it to be implemented consistently across
many different callers, including within calling applications.
2017-06-05 07:31:59 -07:00
Martin Atkins
0266334560 zclsyntax: handle case where functions are not allowed
Previously this would panic.
2017-06-05 07:31:09 -07:00
Martin Atkins
bca573d3d0 zclsyntax: parsing of the index operator
This can either be a traversal or a first-class node depending on whether
the given expression is a literal. This exception is made to allow
applications to conditionally populate only part of a potentially-large
collection if the config is only requesting one or two distinct indices.

In particular, it allows the following to be considered a single traversal
from the scope:

    foo.bar[0].baz
2017-06-05 07:09:04 -07:00
Martin Atkins
8fc5bd5141 zclsyntax: run stringer after other generators
stringer is more sensitive to certain errors than other generators, so
by running it last we give the other generators a chance to get things
straight before we ask stringer to run.
2017-06-05 07:04:26 -07:00
Martin Atkins
b5471b9715 zclsyntax: beginnings of parsing traversal operators
Traversal operators are the operators that can appear after a value
to traverse into the data structure that value represents. So far only
the attribute access operator is implemented.
2017-06-04 18:41:16 -07:00
Martin Atkins
0d0404867c zclsyntax: RelativeTraversalExpr
This is similar to ScopeTraversalExpr, but it traverses relative to the
result of another expression rather than relative to a variable in the
scope.
2017-06-04 18:40:15 -07:00
Martin Atkins
6f2bd0009c zclsyntax: parsing and evaluation for object constructors 2017-06-04 16:14:02 -07:00
Martin Atkins
cac847b163 zclsyntax: separate tokens for assign = and equality test == 2017-06-04 16:00:40 -07:00
Martin Atkins
c3f4694e06 zclsyntax: parsing and evaluation of tuple constructors 2017-06-04 14:22:51 -07:00
Martin Atkins
4488df0cd8 zclsyntax: create comma tokens in the scanner 2017-06-04 14:22:27 -07:00
Martin Atkins
cd85a1f0a6 zcldec: convert AttrSpec results to the given type 2017-06-04 13:22:03 -07:00
Martin Atkins
446387109d zcldec: AttrSpec should return null for missing attributes
Previously it was returning DynamicVal, but that's incorrect since it
would mean that even an otherwise-complete result that has an unpopulated
optional attribute would include an unknown.
2017-06-04 13:05:35 -07:00
Martin Atkins
c9c2a2bd16 zclsyntax: Implement the ContextString interface on our Nav
This allows tooling to get a string describing the context of a particular
offset into the file. This is used, for example, to provide context
above the source code snippets in console-printed diagnostic messages.
2017-06-04 09:52:16 -07:00
Martin Atkins
6f1cf4465d zcl: Range.ContainsOffset should not have pointer receiver 2017-06-04 09:37:37 -07:00
Martin Atkins
44670ddd50 zclparse: keep ParseZCL results in the files registry
This is important to make the source code and context available for
printing diagnostics.
2017-06-04 09:02:41 -07:00
Martin Atkins
19064ef9ee zclparse: function to create a new Parser 2017-06-04 08:40:49 -07:00
Martin Atkins
1979cb4c56 zcldec: flesh out and test the Variables function
It no longer produces diagnostics, since that's redundant with the
diagnostics that Decode itself will produce, and it wasn't going to be
complete anyway due to our use of partial decoding and our inability
to thread through nested specs in child blocks.
2017-06-04 08:30:54 -07:00
Martin Atkins
a9f913f830 zcldec: SourceRange function
This allows callers to determine the source location where a particular
value (identified by a spec) came from, for use in application-level
diagnostic messages.
2017-06-04 08:13:36 -07:00
Martin Atkins
d3703888b6 zcldec: BlockSpec decode implementation 2017-06-04 07:43:13 -07:00
Martin Atkins
e100bf4723 zclsyntax: generate lexer diagnostics
There are certain tokens that are _never_ valid, so we might as well
catch them early in the Lex... functions rather than having to handle
them in many different contexts within the parser.

Unfortunately for now when such errors occur they tend to be echoed by
more confusing errors coming from the parser, but we'll accept that for
now.
2017-06-04 07:34:26 -07:00
Martin Atkins
f220c26836 zcldec: initial work on decoding bodies directly to cty.Value
This package is an alternative to gocty for situations where static Go
types are not desired and the application instead wishes to remain in the
cty dynamic type system.
2017-06-03 17:34:32 -07:00
Martin Atkins
c9ac91aa84 Add MissingItemRange to zcl.BodyContent
This allows code that only deals with BodyContent (post-decoding) to
still be able to report on missing items within the associated body while
providing a suitable source location.
2017-06-03 16:46:49 -07:00
Martin Atkins
cad3e7957f zclsyntax: Body.Content and Body.PartialContent 2017-06-03 09:04:16 -07:00
Martin Atkins
f9da844479 hclhil: use "Subject" rather than "Context" in structure diagnostics 2017-06-03 08:14:09 -07:00
Martin Atkins
da1f9950a6 zclsyntax: Body.JustAttributes implementation 2017-06-03 07:29:48 -07:00
Martin Atkins
aacf36abfd zclsyntax: permit arbitrary newlines inside template interpolations 2017-06-03 06:57:28 -07:00
Martin Atkins
1517231d71 build: stop running Travis-CI test run on Go 1.7.x 2017-06-02 08:27:20 -07:00
Martin Atkins
5522e0c8d0 build: capture code coverage stats during Travis-CI run
The results are uploaded to codecov.io to create readable reports.
2017-06-02 08:27:20 -07:00
Martin Atkins
c15eb86349 zclsyntax: require block definitions to end with a newline
Previously we ostensibly allowed block {}block {}, but now we'll reject
that.
2017-06-02 08:19:11 -07:00
Martin Atkins
4d6dbdbb37 zclsyntax: parsing of attributes within bodies 2017-06-02 08:12:33 -07:00
Martin Atkins
a1368a4d4d zclsyntax: parsing of function call expressions 2017-06-02 07:55:03 -07:00
Martin Atkins
e66e6a5f51 zclsyntax: add TokenComma TokenType 2017-06-02 07:40:42 -07:00
Martin Atkins
6052cb9938 zclsyntax: parse expressions in newline-ignoring mode
This applies both two the whole of bare expressions and to any nested
expressions within parentheses. The latter means that an attribute value
can span over multiple lines if it's wrapped in parens:

    foo = (
        1 + 2 + 3 + 4 + 5
    )
2017-06-02 07:26:45 -07:00
Martin Atkins
302487ce0f zclsyntax: template interpolation trimming
The ~ character can be used at the start and end of interpolation
sequences to trim off whitespace in neighboring literals, with the goal
of allowing extra whitespace to be included for readability without
including it in the resulting string.
2017-06-01 08:43:59 -07:00
Martin Atkins
fdfdfc4f3d zclsyntax: scan correctly closing ~} markers
Previously we were failing to return back to template-scanning mode due
to decrementing "braces" too early, causing the remainder of the template
to be scanned as if it were an expression.
2017-06-01 08:36:48 -07:00
Martin Atkins
8004488042 zclsyntax: public-facing ParseTemplate function
This allows calling applications to deal with bare templates, e.g. loaded
from separate files referenced in a main configuration.
2017-06-01 08:10:04 -07:00
Martin Atkins
8532fe32e6 zclsyntax: basic parsing and evaluation of string templates
Control sequences are not yet supported, but interpolation sequences work.
2017-06-01 08:01:12 -07:00
Martin Atkins
ab9bab3578 zclsyntax: parsing of the two unary operators 2017-06-01 07:05:22 -07:00