Skip to content

Conversation

wcjohnson
Copy link

@wcjohnson wcjohnson commented Apr 15, 2017

Fixes lightscript/lightscript#22

  • Added stack to track parser whiteblock state
  • Using the state stack, resolved parsing ambiguity with whiteblock ifs: if an alternate clause could close a higher whiteblock if at the same indent level, it always closes the matching whiteblock rather than any inner if.
  • Count elif as an unexpected else block.

@wcjohnson wcjohnson changed the title if significant whitespace WIP: if significant whitespace Apr 15, 2017
- Use stack to track `if` blocks and match alternate blocks correctly
- catch out-of-place `elif` keywords
- Add fixtures
@wcjohnson wcjohnson force-pushed the upstream/if-significant-whitespace branch from 002b09c to bfa1aa8 Compare April 15, 2017 22:03
Copy link

@rattrayalex rattrayalex left a comment

Choose a reason for hiding this comment

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

Nice, this is looking good!

}

case tt._else:
case tt._else: case tt._elif:

Choose a reason for hiding this comment

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

👍

};

pp.pushBlockState = function (blockType, indentLevel) {
this.state.blockStack = this.state.blockStack || [];

Choose a reason for hiding this comment

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

let's just initialize in src/tokenizer/state.js


pp.matchBlockState = function(blockType, indentLevel) {
const stack = this.state.blockStack;
return (stack && stack.find( (x) => x.blockType === blockType && x.indentLevel === indentLevel ))

Choose a reason for hiding this comment

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

just return stack.some(x => x.blockType === blockType && x.indentLevel === indentLevel) should be good

// clause does not match the current `if` -- so unwind the recursive descent.
const alternateIndentLevel = this.state.indentLevel;
if (
( alternateIndentLevel !== ifIndentLevel ) &&

Choose a reason for hiding this comment

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

I try to avoid style nits, but the extra spaces here don't match (though I personally prefer them as well)

@@ -0,0 +1,3 @@
{

Choose a reason for hiding this comment

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

this test should be changed to:

x = 
  if false: 1
  elif true:
    2

and should still pass.

An additional test should be added with the name over-indented-elif (or similar) that fails with this error message.

@@ -0,0 +1,6 @@
x = if a:
if(b) {

Choose a reason for hiding this comment

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

if (b) {

@@ -0,0 +1,4 @@
x = if a:
if b: c

Choose a reason for hiding this comment

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

should also have

x = if a:
  if b: c
  elif d: e
else:
  f

should probably also have

if (a) {
b
if c:
  d
elif e: 
  f
} else { 
  g
}

Choose a reason for hiding this comment

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

(as separate tests of course)


pp.pushBlockState = function (blockType, indentLevel) {
this.state.blockStack = this.state.blockStack || [];
this.state.blockStack.push({ blockType, indentLevel });

Choose a reason for hiding this comment

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

have you played with try/catch at all yet? would rather just track indentLevel in something like this.state.ifBlockStack instead of an object if we're only using one blockType.

Copy link
Author

@wcjohnson wcjohnson Apr 16, 2017

Choose a reason for hiding this comment

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

Definitely some issues with try/catch:

try:
  a()
  try:
    b()
  catch e:
    c()
finally:
  d()
unknown: Missing catch or finally clause (1:0)
> 1 | try:
    | ^
  2 |   a()
  3 |   try:
  4 |     b()

- Initialize state in tokenizer/state
- Misc cleanup
@wcjohnson
Copy link
Author

Comments have been addressed

@wcjohnson wcjohnson changed the title WIP: if significant whitespace if significant whitespace Apr 16, 2017
@rattrayalex rattrayalex merged commit 5b3ce42 into lightscript:lightscript Apr 16, 2017
@wcjohnson wcjohnson deleted the upstream/if-significant-whitespace branch October 12, 2017 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants