Commit graph

701 commits

Author SHA1 Message Date
joeduffy 722e963f89 Rename tempmark to visiting and mark to visited
Better variable names, per Eric's code review feedback.
2017-02-13 14:41:20 -08:00
joeduffy b47445490b Implement a very rudimentary plan command
This simply topologically sorts the resulting MuGL graph and, in
a super lame way, prints out the resources and their properties.
2017-02-13 14:26:46 -08:00
joeduffy 7befbe151b Properly enforce readonly properties
This change accurately enforces readonly properties.  Namely, they
should not be written to anywhere outside of the respective initializer,
but writes must be allowed within them.  This means the module initializer
for module properties, the class initializer for statics, and the object
constructor for instance properties.
2017-02-13 13:29:05 -08:00
joeduffy 971fdfbf8d Fall back to dynamic on object too
We already fall back to dynamic loads when the type is `dynamic`, however
we also need to do that when it is the weakly typed `object` also.
2017-02-13 11:59:06 -08:00
joeduffy 295db4faac Push and pop class/module context during evaluation
Now that some name lookups are context-sensitive (namely, whether
or not we should use the export or member table for inter vs. intra
module token references), we need to faithfully track the context.
2017-02-13 11:58:10 -08:00
joeduffy a2653093db Make export binding more robust
This changes the way we discover the kind of export in the case of
an export declaration.  This might be exporting a module member, as in

    let x = 42;
    export { x as y };

or it could be exporting an entire module previously imported, as in

    import * as other from "other";
    export { other };

In each case, we must emit a proper fully qualified token.

Our logic for detecting these cases was a bit busted previously.  We
now rely on real symbolic information rather than doing hokey name lookups.
2017-02-13 11:37:23 -08:00
joeduffy a668db2e2c Properly chase exports
This change fixes up some issues in the big export refactoring;
namely, we need to chase down references one link at a time during
binding, before they settle.  This is because an export might depend
on another export, which might depend on ...
2017-02-13 10:54:11 -08:00
joeduffy 1568b88e4e Move Mu library files back to root
This change moves the Mu library files back to the root.  Until
marapongo/mu#57 allows us to choose a different index file, via
package.json's "main" attribute, the default module logic won't
work properly with the files underneath src/.
2017-02-13 10:02:40 -08:00
joeduffy 32960be0fb Use export tables
This change redoes the way module exports are represented.  The old
mechanism -- although laudible for its attempt at consistency -- was
wrong.  For example, consider this case:

    let v = 42;
    export { v };

The old code would silently add *two* members, both with the name "v",
one of which would be dropped since the entries in the map collided.

It would be easy enough just to detect collisions, and update the
above to mark "v" as public, when the export was encountered.  That
doesn't work either, as the following two examples demonstrate:

    let v = 42;
    export { v as w };
    let x = w; // error!

This demonstrates:

    * Exporting "v" with a different name, "w" to consumers of the
      module.  In particular, it should not be possible for module
      consumers to access the member through the name "v".

    * An inability to access the exported name "w" from within the
      module itself.  This is solely for external consumption.

Because of this, we will use an export table approach.  The exports
live alongside the members, and we are smart about when to consult
the export table, versus the member table, during name binding.
2017-02-13 09:56:25 -08:00
joeduffy a09a49b94a Regenerate test baselines w/ line numbering change 2017-02-13 07:55:40 -08:00
joeduffy b1f96964ac Implement array l-values
This commit implements array l-values (for dynamic loads only, since we do
not yet ever produce static ones).  Note that there are some ECMAScript
compliance noteworthies about this change, which are captured in comments.

Namely, we are emulating ECMAScript's ability to index into an array
anywhere (except for negative numbers, which is a problem).  This is in
contrast to the usual approach of throwing an error on out-of-bounds access,
which will crop up when we move on to other languages like Python.  And yet we
are usuing a real array as the backing store, which can cause problems with
some real ECMAScript programs that use sparse arrays and expect the "bag of
properties" approach to keep memory usage reasonable.

The work item marapongo/mu#70 tracks this among other things.
2017-02-13 07:23:00 -08:00
joeduffy 1af9cd720b Use 1-based column numbers 2017-02-13 06:44:48 -08:00
joeduffy f0181d8933 Emit more array types; permit more dynamic conversions
This change plucks array element types out of more AST nodes, tightening
up the MuIL that MuJS produces.  It also adds a few cases where we should
be emitting "object", and permits more dynamic conversions (which are
technically unsafe, but necessary for the sort of duck typing we anticipate).
2017-02-13 06:39:50 -08:00
joeduffy d82adefd38 Implement casts 2017-02-13 05:56:39 -08:00
joeduffy 55deb13100 Implement static properties in the runtime 2017-02-13 05:45:28 -08:00
joeduffy aec1dccd5d Tidy up property initializers
This change fixes a few things about property initializers:

* Instance properties on classes need an object (`this`) for initialization.
  Previously, this wasn't being passed, which leads to a verification error.

* Static properties on classes should go into the `.init` function, not the
  `.ctor` function.

* Synthesized constructors need to invoke `super()` when there is a base
  class.  It's legal for this call to be missing from the source program
  when the base's constructor has no args.

* All initializers happen immediately after such a call to `super()`, to
  achieve the intended initialization order.  Therefore, for an existing
  constructor, we must search for the insertion point manually.

* Also add a superclass case to the existing property tests.
2017-02-13 04:56:20 -08:00
joeduffy 4b05735374 Add some missing source node info 2017-02-13 04:13:22 -08:00
joeduffy de7d8c7a90 Tolerate duplicate objects
In select few cases (right now, just nulls and boolean true/false),
we use predefined object constants to avoid allocating wastefully.
In the future, it's possible we will do this for other types, like
interned strings.  So, the graph generator should tolerate this.
2017-02-13 04:00:33 -08:00
joeduffy 9d157a25c6 Issue a warning if there is no default module 2017-02-13 03:58:31 -08:00
joeduffy 2fd4355cf6 Add some array accesses to basic/arrays tests 2017-02-13 03:45:23 -08:00
joeduffy 4a1a117d4e Create arrays of the right type; return the object 2017-02-12 13:42:53 -08:00
joeduffy 9375f38ba1 Don't store nulls 2017-02-12 13:36:34 -08:00
joeduffy 38d9664bf7 Store the resource arguments 2017-02-12 13:36:17 -08:00
joeduffy bf6f6db089 Track all objects in MuGL
This change starts tracking all objects in our MuGL graph.  The reason is
that resources can be buried deep within a nest of objects, and unless we
do "on the fly" reachability analysis, we can't know a priori whether any
given object will be of interest or not.  So, we track 'em all.  For large
programs, this would obviously create space leak problems, so we'll
eventually, I assume, want to prune the graph at some point.

With this change, the EC2instance example produces a (gigantic) graph!
2017-02-12 13:11:53 -08:00
joeduffy 3f2f444bd7 Use the string *value*
This fixes a bug where we used the Stringer string, rather than the
underlying string literal value, when doing dynamic lookups.
2017-02-12 12:18:13 -08:00
joeduffy 9ba0d461b2 Don't use static transforms for element loads
These are generally speaking dynamic lookups, based on expressions
that are evaluated, rather than being statically recognized property names.
2017-02-12 12:09:20 -08:00
joeduffy edb2fae7ba Register the local variable symbol, not its type 2017-02-12 11:49:19 -08:00
joeduffy 344f87a3e6 Detect more load cases
This change fixes up some cases that weren't quite right, when it
comes to load location expressions.  This includes functions and
local variables.  Furthermore, the loadIdentifierExpression codepath
should be routed through the general purpose load location logic,
so that it can detect the various cases.

After this change, the ec2instance example fully verifies.
2017-02-12 11:44:20 -08:00
joeduffy d6405a7694 Dump eval state in sorted order
This eliminates some non-determinism in the output, due to Go's
randomized map enumeration order.
2017-02-12 10:21:37 -08:00
joeduffy 16be3e181b Add missing source location information
A couple dynamic load nodes didn't have source information propagated,
resulting in hard-to-diagnose failures.  This adds it to them.
2017-02-12 09:46:54 -08:00
joeduffy 37d63555dc Implement basic default modules and entrypoints
Per marapongo/mu#57, this change marks the "index" module as the default.
We don't yet discover and crack open `package.json` files which may override
this by specifying a "main" function.

This change also generates entrypoint functions for all MuJS modules.  To
emulate the way Node.js works -- in that every module is still a valid script
target -- we are generating entrypoints for everything; this is in contrast to
only generating them for "blueprint" modules, or somehow marking `main`
somehow.  See the notes in marapongo/mu#57 for additional thoughts on this.
2017-02-12 09:43:59 -08:00
joeduffy 36b4a6f848 Implement stack traces
This change implements stack traces.  This is primarily so that we
can print out a full stack trace in the face of an unhandled exception,
and is done simply by recording the full trace during evaluation
alongside the existing local variable scopes.
2017-02-12 09:38:19 -08:00
joeduffy a16bb714e4 Implement dynamic loading
This change implements dynamic loads in the binder and evaluator.
2017-02-12 08:22:44 -08:00
joeduffy 93d9df1c4c Issue a MuJS warning on unused dependencies 2017-02-12 06:23:22 -08:00
joeduffy a8812bdbf0 Use strings for property keys
In dynamic scenarios, property keys could be arbitrary strings, including
invalid identifiers.  This change reflects that in the runtime representation
of objects and also in the object literal and overall indexing logic.
2017-02-11 15:45:37 -08:00
joeduffy 11faf22c60 Produce a string literal for dynamic loads 2017-02-11 15:38:12 -08:00
joeduffy 3759f71e67 Transform element access expressions properly
This change transforms element access expressions much like we do
property access expressions, in that we recognize several static load
situations.  (The code is rearranged to share more logic.)  The code
also now recognizes situations where we must devolve into a dynamic
load (e.g., due to a string literal, dynamic LHS, etc).
2017-02-11 15:32:14 -08:00
joeduffy 10f5d43245 Also erase TypeLiterals
This change erases TypeLiterals to ObjectLiterals, for much the same reason.
Also for much the same reason, it'd be nice to eventually preserve these.
2017-02-11 14:51:05 -08:00
joeduffy a7f23fc65a Fix a few verification errors
This change fixes a few issues:

* Emit ObjectLiteral types as `dynamic`.  We can do better here, including
  spilling the "anonymous" types, for cases where cross-module exports/imports
  are leveraged.  For the time being, however, we will erase them to dynamic.
  This is a heck of a lot better than emitting garbage `__object` type tokens.

* Implement TypeScript TypeAssertionExpression lowering into casts.

* Recognize static class property references.  Previously, we tried to load
  the class as a location, which resulted in nonsense, unverifiable MuIL.  Now
  we properly detect that the target is a property symbol with the static
  modifier, and emit the token without an object reference (as expected).

* Accompany the above with a bunch of tests that stress these paths.
2017-02-11 14:45:31 -08:00
joeduffy 2e8b04f2a7 Get the minimal AWS sample compiling/verifying/evaluating 2017-02-11 13:33:11 -08:00
joeduffy 53a568da87 Modify the ResourceProvider.Update API
This changes two aspects of the ResourceProvider.Update RPC API:

1. Update needs to return an ID, in case the resource had to be
   recreated in response to the request.

2. Include both the old and the new values for properties that are
   being updated.
2017-02-11 13:14:29 -08:00
joeduffy a60dc045cb Tokenize properties and block scoped variables
We weren't properly emitting fully qualified tokens for properties
and "block scoped variables" (of which, module properties qualify).
This change fixes that, bringing the ec2instance verification error
count down from 22 to 7.
2017-02-11 10:10:02 -08:00
joeduffy b2d43e1c59 Permit dynamic to flow through to eval
This change "kicks the can" of dealing with `dynamic` down the road.
Namely, the binder will be permissive about letting dynamic objects
flow through to the evaluation phase.  At that point, the evaluator
will be responsible for performing duck typing, etc.
2017-02-11 08:39:45 -08:00
joeduffy 7a2d2b4cb1 Typecheck new expressions 2017-02-11 08:28:47 -08:00
joeduffy dc9f91c3cf Support dynamic object literals
This change introduces support for dynamic object literals.  If the
type of a literal is dynamic, then the property initializers for that
literal are naked strings; if the type of a literal is anything else,
however, we expect that the property names are full blown member tokens.
2017-02-11 08:20:06 -08:00
joeduffy c6b9abb7a0 Issue an error if a dependency is missing 2017-02-11 08:02:28 -08:00
joeduffy 8f24cd20ba Simplify certain types
This change simplifies certain types while lowering to MuIL, fixing
a number of assertion failures that cropped up after my tightening of
the type checking (namely, asserting rather than silently logging).

This comes in the following forms:

1) StringLiteral, NumberLiteral, and BooleanLiteral types can simply
   become String, Number, and Boolean, respectively.  This loses some
   static type-checking (e.g., ensuring that values are within range),
   however at least the physical runtime type will match.

2) EnumLiteral types can simply adopt their base types, with similar
   downsides and caveats to the other literal types (range widening).

3) Any union types that contain Undefined or Null types can be simplified
   to omit those types.  If, after filtering them out, we are left with
   a single type (admitting the recursive case of multiple XLiterals that
   simplified down to the exact same primitive type), we will eliminate
   the union altogether and just use the underlying simple type.  This
   handles the case of optional interface properties, e.g. `T?`, which are
   internally represented in TypeScript as `T|undefined` union types.

There are two follow up work items for later on:

* marapongo/mu#64 tracks support for non-nullability.  At the moment we
  are tossing away any `|undefined` or `|null` unions, including `T?`,
  because MuIL currently permits nullability everywhere, but we want to
  consider honoring these annotations (eventually).

* marapongo/mu#82 tracks support for union types.  This is how we intended
  to support true enum types, so tossing away this information is a bit
  unfortunate.  But this is a feature for another day.
2017-02-11 07:13:49 -08:00
joeduffy c5807c4b57 Issue proper errors for unsupported types 2017-02-10 17:04:01 -08:00
joeduffy 02aa1c4ee0 Add some MuJS debug logging 2017-02-10 16:53:27 -08:00
joeduffy 0802399a8c Distinguish between object and dynamic (fka any)
This change prepares to mimick the TypeScript behavior of `any` which,
it turns out, is closer to Python and Ruby duck typing than what we have
here.  It also introduces `object` to mean "the base of all types".

MuJS has been updated to map `any` to `dynamic`.

At this point, the conversion logic now distinguishes between NoConversion,
ImplicitConversion, and AutoCastConversion cases, the latter being a case
in which `dynamic` is the source and so a duck-type-style cast must occur.
Right now we do not honor the AutoCastConversion case anywhere, so we still
have not achieved the duck-typing semantics of the source language.

This is part of fixing marapongo/mu#79.
2017-02-10 16:44:18 -08:00