WIP: Labels and Macros#65
Conversation
fb6e103 to
3bf5451
Compare
ssanderson
left a comment
There was a problem hiding this comment.
@llllllllll posted some notes for you here.
| Label = instrs.Label | ||
|
|
||
|
|
||
| def assemble_function(signature, objs, code_kwargs=None, function_kwargs=None): |
There was a problem hiding this comment.
We need to decide how we want to manage signatures here.
Ideally it should be easy to either type this by hand or use the signature of an existing function. For the tests, I've been using inspect.signature(lambda <sig>: None) as an easy way to get the signature I want.
There was a problem hiding this comment.
one idea is to allow a function which would likely look like: lambda a, b, c: ...
| instr._stolen_by = self | ||
| for jmp in instr._target_of: | ||
| jmp.arg = self | ||
| self._target_of = instr._target_of |
There was a problem hiding this comment.
This needs to be an |=, but that can go in a separate PR.
| instrs.RETURN_VALUE(), | ||
| ], | ||
| ), | ||
| AssertFail("Shouldn't ever get here!"), |
There was a problem hiding this comment.
This is here because we currently can't compile a function that ends with just an IfStatement, because we emit a JUMP_FORWARD to a label after the else block.
One way to fix this might be to replace jumps to a final label with LOAD_CONST(None); RETURN_VALUE().
There was a problem hiding this comment.
Though even that would be wasteful in this case, since the JUMP_FORWARD instruction is after an unconditional return inside the if block. The thing we'd really want for this is a dead code elimination pass.
There was a problem hiding this comment.
We used to have an optimizer but it generated invalid code sometimes. We could always bring it back as an optional codetransformer.
| return list(mapcat(_validate_instructions, objs)) | ||
|
|
||
|
|
||
| def resolve_labels(objs): |
There was a problem hiding this comment.
In an earlier draft of this I was allowing people to pass Macros as arguments to jumps, and I replaced jumps to macros with jumps to the first instruction here. Now that we have labels, I can't think of a use-case where passing a macro is a significant improvement over passing a label that's right before a label, though it does mean you have to make sure nothing gets put between your label and your macro. One thing we could consider is adding start and end labels to all macros and have __iter__ bookend the results of assemble with those.
There was a problem hiding this comment.
I think that adding the start/end labels is easier to support elsewhere, but we can implement that later.
| if kwarg is not None: | ||
| raise ValueError('cannot specify **kwargs more than once') | ||
| kwarg = argname[2:] | ||
| append_argname(argname) |
| def assemble(self): | ||
| raise NotImplementedError('assemble') | ||
|
|
||
| def __iter__(self): |
There was a problem hiding this comment.
we decided to not support arbitrary iterators for now
| return "{}({!r})".format(type(self).__name__, self.n) | ||
|
|
||
|
|
||
| class AssertFail(Macro): |
There was a problem hiding this comment.
It might be nice to make a general Raise macro and have this just be short hand for Raise(AssertionError, message)`
No description provided.