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

Remove 'method declare' hack and introduce AST strengthening #5

Closed
masak opened this issue Jan 6, 2015 · 0 comments
Closed

Remove 'method declare' hack and introduce AST strengthening #5

masak opened this issue Jan 6, 2015 · 0 comments

Comments

@masak
Copy link
Owner

masak commented Jan 6, 2015

Apart from a run method, all the Q::Statement:: types have a declare method which gets called on the surrounding block's entry.

This method is a hack. More exactly, it was added at a time when we were running only off ASTs, without the parser creating static lexpads for us. Now that it does, the declare methods are superfluous and should be removed.

The interesting thing, though, is that if we just go ahead and remove all the declare methods, a lot of tests in t/semantics/ start failing. This is because the ASTs in these tests were never program text to begin with, and so they never got the static lexpads from the parser that would replace the declare method hacks.

To remedy this, we want to create a new helper routine check in _007::Test that traverses an AST and initializes static lexpads in the same way a parser would. Essentially doing a "parse" of the AST.

Note that we can cheat quite a bit in writing this routine, as we don't have to worry about erroneous conditions in the AST. (The name check primarily means "do stuff that belongs at CHECK time", not "make sure everything's OK".) We can assume the test author wrote a correct AST for the test, otherwise it's a bad test. As far as I can see, we only have to initialize the static lexpads. Then we can remove the declare methods.

Interestingly, the way we seem to be headed with synthetic ASTs (which were created using Q:: constructors in program code somewhere) is that these will also need a similar check routine. So it's probable that this routine actually becomes core, not just a test helper. At that point though, we do need to check everything the parser checks, because we don't trust the user the way we trust the test author.

@masak masak closed this as completed in 654efa2 Oct 6, 2015
masak pushed a commit that referenced this issue Mar 4, 2017
wip
Try doing this:

    $ bin/007 --backend=i13n examples/name.007

Should get this output:

        # static frame #1
        # call A from line zero: frame 2
        # static frame #3
        # call B from line zero: frame 4
     1. macro name(expr) {
            # static frame #5
            # call C from line zero: frame 6
     2.     if expr ~~ Q::Postfix::Property {
     3.         expr = expr.property;
     4.     }
            # static frame #7
            # call D from line zero: frame 8
     5.     if expr !~~ Q::Identifier {
     6.         throw new Exception {
     7.             message: "Cannot turn a " ~ type(expr) ~ " into a name"
     8.         };
     9.     }
            # static frame #9
            # call E from line zero: frame 10
            # call F from line zero: frame 11
    10.     return quasi { expr.name };
    11. }
    12.
    13. my info = {
    14.     foo: "Bond",
    15.     bar: {
    16.         baz: "James Bond"
    17.     },
    18. };
    19.
    20. say(name(info));           # info
    21. say(name(info.foo));       # foo
    22. say(name(info.bar.baz));   # baz
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

No branches or pull requests

1 participant