Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Let/const #404

Closed
wants to merge 8 commits into from
Closed

Conversation

samwgoldman
Copy link
Member

I've just started digging in my heels on this one. I'm keeping this in an open PR to get feedback and ensure I don't step on anyone's toes.

TODO:

  • represent different scope types
  • rename "block" to "scope" (@jeffmo you mentioned this, seems like a good idea)
  • create block-level scopes
  • hoist vars, classes, functions
  • allow defining let/const identifiers
  • test for-loop statement and iteration scope
  • strict mode vs. not
  • should functions be block level???
  • TDZ - I don't think we can statically ensure define before use, but best effort
  • error on const reassignment
  • let block
  • let expressions

Overview:

In order to support let/const, we need to know what kind of scope each
block is.

Currently, the only blocks we have are what I am calling "Hoist" blocks.
Whenever an entry which should be hoisted is added to the env, it should
be added to the closest "Hoist" block.

Let/const identifiers should be added to the nearest "Block" block.

Currently we only create blocks corresponding to hoist points.
Subsequent commits will need to create a great many more blocks to
support block-level scope.

In order to support let/const, we need to know what kind of scope each
block is.

Currently, the only blocks we have are what I am calling "Hoist" blocks.
Whenever an entry which should be hoisted is added to the env, it should
be added to the closest "Hoist" block.

Let/const identifiers should be added to the nearest "Block" block.

Currently we only create blocks corresponding to hoist points.
Subsequent commits will need to create a great many more blocks to
support block-level scope.

NB: We should probably rename "block" to "scope."
@samwgoldman samwgoldman changed the title [WIP] Change block type to record with scope type information [WIP] Let/const Apr 22, 2015
@jeffmo
Copy link
Contributor

jeffmo commented Apr 22, 2015

cc @avikchaudhuri as well to follow along

The big change here is that I changed `init_env` to take an extra
boolean parameter, which when true indicates that the nearest "Hoist"
block should be extended.

I also noticed a really strange omission, in which block statements were
not actually processed with statement_decl, just toplevels. I added that
in this commit.

There should be just one test failure here, in break.js, which I can't
really understand. I'd really appreciate some more experienced eyes on
this one to help me figure out what's going on.

Obviously, there is a lot of logic missing here. I suspect I'll need to
add block scope information to the block entries themselves, but so far
the only roadblock I hit I don't quite understand, so I'm reaching out.
@samwgoldman
Copy link
Member Author

The test failure in that last commit is throwing me for a loop. I'll look again tomorrow, but if anyone has some insight, I'd appreciate it.

This fixes a test failure for the break examples where refined
environment was not properly reset after an abnormal exit.

Since the non-Hoist blocks are new, clearing up to the Hoist block
should restore the previous behavior of this function.
Also restore "basic" test for let and duplicate let tests for const.
@samwgoldman
Copy link
Member Author

OK! Figured that last error out. Some preliminary feedback on this approach would be really helpful.

Also, if anyone has a real-life project with let/const, and is able to try out this branch on their project, I'd be happy to look into any issues.

Also reorganize a bit: common.js has features that are relevant to both
let and const.
Freebie from the parser!
@jeffmo
Copy link
Contributor

jeffmo commented Apr 27, 2015

Haven't gotten to the meatier portion of the PR yet, but wanted to send what I have so far before I run to lunch. Will come back to finish out the comments later today/tonight

@@ -507,7 +507,16 @@ type block_entry = {
def_loc: Spider_monkey_ast.Loc.t option;
for_type: bool;
}
type block = block_entry SMap.t ref

type block_scope =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this "scope_kind" (i.e. odd that the name seems to imply one of the variants but not the other -- in fact the issue really is that "block" means two different things now, but more on that in the next comment...)

@samwgoldman
Copy link
Member Author

I completely agree about the renames, and it's encouraging that your suggestions are so in line with what I was thinking. The only reason I hesitated to rename now is that I didn't want to cause merge difficulties down the road, but I think a bit of upfront pain is better than wonky names. And hey, it's not my problem. ;)

let block = { scope = Block; entries } in
Env_js.push_env block;

List.iter (statement_decl cx) body;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wan to call out this bit specifically. Is it wrong to jump back into the statement_decl codepath from the statement codepath like this? If this is wrong, then that somewhat invalidates my approach here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is ok -- it's essentially what functions currently do (except way over in the mk_body function)

@jeffmo
Copy link
Contributor

jeffmo commented Apr 27, 2015

Heh. Well if it's not much harder for you, making the renames in a separate PR (that this one could be considered "stacked" on top of) might make my life a little easier :)

We can just make sure they get merged in proper order

@samwgoldman
Copy link
Member Author

Yeah, I think it makes sense to do a separate PR that renames block to scope, and some of the other changes you identified, so that change can be rolled in sooner. I'll go ahead and do that before moving on with this let/const stuff.

@mroch
Copy link
Contributor

mroch commented Apr 29, 2015

not sure where you guys ended up on the naming of the two different types of scopes (HoistedScope and BlockScope?) but the spec seems to refer to them as LexicallyScoped and VarScoped so perhaps we could go with LexicalScope and VarScope?

@samwgoldman
Copy link
Member Author

I can get behind that naming, for sure.

@jeffmo
Copy link
Contributor

jeffmo commented Apr 29, 2015

I've always found "lexically scoped" pretty confusing (both are "lexical"). I could live with it if someone feels strongly, but I'd be even happier with "VarScope" and "LetScope"

@mroch
Copy link
Contributor

mroch commented Apr 29, 2015

yeah I find it non-optimal too, but since we're following a spec I thought it might be easier if they matched so that you don't have to wonder about/remember the translation between the code and the spec. if we name one VarScope then LexicalScope vs LetScope probably doesn't matter as much because I can remember it as the "other" one.

@jeffmo
Copy link
Contributor

jeffmo commented Apr 29, 2015

Ok, will leave it up to you @samwgoldman -- I can live with either I guess

@samwgoldman
Copy link
Member Author

We're talking about these definitions, correct? It makes sense to me that VarScope is-a LexicalScope, and I don't see that as a problem. Not the most confusing subtyping relationship in flow. :)

Since it makes sense to me, and I like the idea of naming things close to the spec, I'll try it out and we can see how it feels.

@mroch
Copy link
Contributor

mroch commented Apr 29, 2015

@samwgoldman
Copy link
Member Author

Closing in favor of rebased #431

@samwgoldman samwgoldman mentioned this pull request Apr 29, 2015
14 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants