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

break-with-value and for/else implementation #23260

Closed
wants to merge 23 commits into from

Commits on Aug 14, 2017

  1. Parse + emit code for for/else and break-with-value

    This commit enables a combination of two language features that dovetail
    nicely together (as remarked by @StefanKarpinski in [1]): for/else and
    break-with-value, which together allow something like:
    
        name = for person in people
            if person.id == id
                break person.name
            end
        else
            generate_name()
        end
    
    The parsing patch is pretty straightforward. As for the code lowering
    part, I opted to make a second version of `'break-block`, called
    `'break-block-with-value`, which passes a target variable for the return
    value onto the `break-labels` stack. That's where the `'break` operation
    finds it.
    
    An alternative approach would be something more similar to the existing
    `replace-return` function: Instead of having an intermediate node
    representing `'break-block-with-value`,we could traverse the expression
    tree and replace `break-with-value` by an assignment followed by a
    break.
    
    I have no opinion either way; the current commit seemed like the obvious
    implementation to me, but that was before I saw `replace-return`'s prior
    art.
    
    This patch still has a few places marked `TODO`, where scoping issues
    for the `else` block need to be resolved. I'll tackle that after
    awaiting feedback.
    
    [1] JuliaLang#22891
    tkluck committed Aug 14, 2017
    Configuration menu
    Copy the full SHA
    976ff84 View commit details
    Browse the repository at this point in the history
  2. Implement findnext() in terms of for/else and break-with-value

    Because a new language feature should probably be used in
    the standard library, to encourage cargo-culting.
    tkluck committed Aug 14, 2017
    Configuration menu
    Copy the full SHA
    d8b2553 View commit details
    Browse the repository at this point in the history

Commits on Aug 15, 2017

  1. Fix break-with-value in case the value expression is a symbol

    Before 976ff84, a parsed `break` expression `'(break)` was being
    augmented to `'(break <label>)` by the function `expand-forms`. Since
    the latter is supposed to be idempotent [1], it used to check
    
        (pair? e)
    
    before deciding on replacing it. In 976ff84 however, the parsed
    break can have a value expression, so `(pair? e)` can be true for that
    reason as well. Thinking I was being smart, I replaced the check by
    
        (symbol? (cadr e))
    
    not realizing that a lone symbol can be a valid expression too!
    
    This commit fixes that by *always* compiling the break expression to a
    *triple*
    
        '(break <expression> <label>)
    
    where <expression> may be `'(null)`. This should have no big
    implications for the code being generated, because `'(null)` generates
    no code when, in the function `compile`, `(and value tail)` is false,
    which is likely the typical case.
    
    [1] At least, that's what I'm guessing is the reason.
    tkluck committed Aug 15, 2017
    Configuration menu
    Copy the full SHA
    8a8d4cc View commit details
    Browse the repository at this point in the history
  2. Simplify break-with-value implementation: don't distinguish break-blo…

    …ck and break-block-with-value
    
    Instead, we give every `break-block` an `else`-block, potentially equal
    to `'(null)`. This gives us one less atom to worry about.
    
    This commit also makes a small modification to `compile`, which now
    passes the value of `tail` for a `break` onto the `break-labels` stack.
    That means a `break` can be compiled to a `return` if the `break-block`
    is in the last position of a function.
    tkluck committed Aug 15, 2017
    Configuration menu
    Copy the full SHA
    3abd4d9 View commit details
    Browse the repository at this point in the history

Commits on Aug 16, 2017

  1. Configuration menu
    Copy the full SHA
    ed6ff28 View commit details
    Browse the repository at this point in the history
  2. Fix error message from incomplete for loop

    The following issue:
    
        Test Failed
          Expression: Base.incomplete_tag(parse(str, raise=false)) == tag
           Evaluated: none == block
    
    was due to returning a different error message string in case of parsing
    the incomplete string "for i=1;". This commit fixes it by delegating
    error handling to `expect-end`.
    tkluck committed Aug 16, 2017
    Configuration menu
    Copy the full SHA
    24c64f4 View commit details
    Browse the repository at this point in the history
  3. Avoid allocating a value variable when break-block is in tail position

    This was triggered by
    
        Error in testset inference:
        Test Failed
          Expression: all(isleaftype, (ast12474[1])[1].slottypes)
    
    which had, as a root cause, the unused new-mutable-var being of type
    Any.
    
    Now, that isn't really what this doctest is trying to avoid, but I'm
    guessing it's worthwhile avoiding an unneeded mutable var nonetheless.
    tkluck committed Aug 16, 2017
    Configuration menu
    Copy the full SHA
    f15be30 View commit details
    Browse the repository at this point in the history
  4. Remove unnecessary if relating to break-labels contents

    This is an artifact from when I wasn't sure whether anything else would
    write to the break-labels stack apart from the code point that I had
    updated. I'm now confident that doesn't happen, so no need for special
    cases.
    tkluck committed Aug 16, 2017
    Configuration menu
    Copy the full SHA
    a67bc9f View commit details
    Browse the repository at this point in the history

Commits on Aug 17, 2017

  1. break-with-value: add elsebody to a few recursive expression traversals

    I postponed this mostly because the names of the methods sounded scary
    and I thought I'd need to think about it; turns out it's just a tree
    traversal.
    tkluck committed Aug 17, 2017
    Configuration menu
    Copy the full SHA
    e0697d1 View commit details
    Browse the repository at this point in the history

Commits on Aug 19, 2017

  1. Configuration menu
    Copy the full SHA
    aa48222 View commit details
    Browse the repository at this point in the history
  2. More consistent indentation in julia-parser.scm

    (Use `git blame -w` to see the most recent functional changes to this code.)
    tkluck committed Aug 19, 2017
    Configuration menu
    Copy the full SHA
    29d98ab View commit details
    Browse the repository at this point in the history
  3. break-with-value: don't emit 'nothing' as the break value from the pa…

    …rser level
    
    Since 8a8d4cc, julia-syntax.scm can deal with length 1
    'break' expression nodes. So there is no need for this. In addition,
    this ensures that :(break) prints as :(break), not as
    
        :($(Expr(:break, nothing)))
    
    This was caught by a testcase in test/show.jl
    tkluck committed Aug 19, 2017
    Configuration menu
    Copy the full SHA
    b801f49 View commit details
    Browse the repository at this point in the history

Commits on Jan 30, 2018

  1. Revert "Implement findnext() in terms of for/else and break-with-value"

    This was only used for testing the for/else construct; it's not actually
    more readable. As discussed in JuliaLang#23260, `intersect()` is a nicer show
    case. Moreover, this prevents a merge conflict with `master`, which has
    diverged significantly by now.
    
    This reverts commit d8b2553.
    tkluck committed Jan 30, 2018
    Configuration menu
    Copy the full SHA
    bad3c35 View commit details
    Browse the repository at this point in the history

Commits on Feb 1, 2018

  1. Merge remote-tracking branch 'origin/master' into break-with-value

    This fixes conflicts introduced by JuliaLang#24075 and JuliaLang#22659.
    tkluck committed Feb 1, 2018
    Configuration menu
    Copy the full SHA
    7c5f378 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    98d5dd7 View commit details
    Browse the repository at this point in the history

Commits on Mar 11, 2018

  1. Merge branch 'master' into break-with-value

    Just keeping this branch up-to-date to prevent bitrot.
    tkluck committed Mar 11, 2018
    Configuration menu
    Copy the full SHA
    9af9bc2 View commit details
    Browse the repository at this point in the history

Commits on Apr 6, 2018

  1. Merge remote-tracking branch 'origin/master' into break-with-value

    Fixes merge conflicts caused by 0fffb36.
    tkluck committed Apr 6, 2018
    Configuration menu
    Copy the full SHA
    fe10430 View commit details
    Browse the repository at this point in the history

Commits on Jun 12, 2018

  1. Merge branch 'master' into break-with-value

    This fixes merge conflicts introduced by 62fbad2 and 3a0c6e2.
    neither conflict was fundamental or complicated to solve.
    tkluck committed Jun 12, 2018
    Configuration menu
    Copy the full SHA
    742576a View commit details
    Browse the repository at this point in the history

Commits on Jun 16, 2018

  1. Configuration menu
    Copy the full SHA
    e0a42c6 View commit details
    Browse the repository at this point in the history

Commits on Aug 11, 2018

  1. Configuration menu
    Copy the full SHA
    ef077f7 View commit details
    Browse the repository at this point in the history

Commits on Dec 23, 2018

  1. Merge remote-tracking branch 'origin/master' into break-with-value

    This updates this branch to current master by merging it
    and by fixing the merge conflicts introduced by 57b46e7.
    
    I don't fully understand the functionality of that commit and
    though the fixes I did result in no compilation errors
    and in working `make test-core` (where this branch introduces
    tests), it may make sense to double-check interactions
    between exceptions and break-with-value before merging this.
    tkluck committed Dec 23, 2018
    Configuration menu
    Copy the full SHA
    c9934e9 View commit details
    Browse the repository at this point in the history

Commits on Jan 16, 2019

  1. Configuration menu
    Copy the full SHA
    e081226 View commit details
    Browse the repository at this point in the history

Commits on Feb 17, 2019

  1. Configuration menu
    Copy the full SHA
    0aa316a View commit details
    Browse the repository at this point in the history