-
Notifications
You must be signed in to change notification settings - Fork 1
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
feat: Detect undefined symbols #50
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,8 @@ | |
from collections import deque | ||
from textwrap import dedent | ||
from importlib.resources import files | ||
from typing import List | ||
|
||
|
||
def up(f, n): | ||
d = os.path.dirname(f) | ||
|
@@ -101,6 +103,7 @@ def __init__(self, f: types.FunctionType): | |
self.args = [] | ||
self.kwargs = {} | ||
self.entry = f.__module__ + "." + f.__name__ | ||
self.undefined_symbols = [] # Lean can send these back to the caller as linter errors | ||
self.ref_global(self.entry, f) | ||
self.do_work() | ||
|
||
|
@@ -110,6 +113,7 @@ def json(self): | |
, 'args' : self.args | ||
, 'kwargs' : self.kwargs | ||
, 'globals': self.globals | ||
, 'undefined_symbols': self.undefined_symbols | ||
} | ||
return json.dumps(d, cls=Enc) | ||
|
||
|
@@ -202,7 +206,7 @@ def do_work(self): | |
continue | ||
self.funcs[fullname] = self.translate(src, line, f, args, body) | ||
|
||
def translate(self, src: str, line: int, f: types.FunctionType, args: ast.arguments, body: [ast.AST]): | ||
def translate(self, src: str, line: int, f: types.FunctionType, args: ast.arguments, body: List[ast.AST]): | ||
self.f = f | ||
for s in body: | ||
self.visit(s) | ||
|
@@ -221,14 +225,20 @@ def translate(self, src: str, line: int, f: types.FunctionType, args: ast.argume | |
# if we find other uses of potentially global names | ||
# and fail to understand them; as long as we find and record | ||
# the "real" uses into the environment for the Lean code. | ||
def lookup(self, s): | ||
return self.f.__globals__.get(s) or self.f.__builtins__.get(s) | ||
def lookup(self, node): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, nice. It was lookup. |
||
s = node.id | ||
if s in self.f.__globals__: | ||
return self.f.__globals__[s] | ||
if s in self.f.__builtins__: | ||
return self.f.__builtins__[s] | ||
self.undefined_symbols.append(node) | ||
return None | ||
|
||
def visit_Name(self, node): | ||
if node.id not in self.f.__code__.co_names: | ||
return | ||
try: | ||
y = self.lookup(node.id) | ||
y = self.lookup(node) | ||
self.ref_global(node.id, y) | ||
return node.id, y | ||
except Unsupported as e: | ||
|
@@ -250,3 +260,13 @@ def visit_Attribute(self, node): | |
raise e | ||
except Exception: | ||
return | ||
|
||
|
||
if __name__ == '__main__': | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking we might do: run_klr here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And then add a gather subcommand? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, not here. in wherever There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ooh good idea. Another PR. |
||
y = None | ||
z = 5 | ||
|
||
def unknown(): | ||
return (x, y, z) | ||
|
||
print (Parser(unknown).json()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice.