Skip to content

Commit

Permalink
Lexical Addressing
Browse files Browse the repository at this point in the history
  • Loading branch information
vanschelven committed Sep 22, 2017
1 parent 2413d4d commit 097c6ad
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
18 changes: 18 additions & 0 deletions doctests/lexical_addressing_x.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
>>> from dsn.form_analysis.structure import ValueForm, VariableForm, DefineForm, LambdaForm
>>> from dsn.form_analysis.structure import FormList, Symbol, SymbolList

>>> from dsn.form_analysis.lexical_addressing_x import lexical_addressing_x

>>> the_lambda = LambdaForm(
... SymbolList([Symbol("param")]),
... FormList([
... DefineForm(Symbol("definition"), VariableForm(Symbol("a"))),
... VariableForm(Symbol("b")),
... VariableForm(Symbol("param")),
... VariableForm(Symbol("definition")),
... ]))

>>> the_context = {'a': None, 'b': 2}

>>> sorted(lexical_addressing_x(the_context, the_lambda).items())
[('a', None), ('b', 3), ('definition', 0), ('param', 0)]
42 changes: 42 additions & 0 deletions dsn/form_analysis/lexical_addressing_x.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Lexical Addressing "X", because as of yet, we only do a very particular kind of addressing. Namely: we refer to a
# scope by "frames up", but we do not address within the scope (e.g.: memory-offset, or var-count-offset)

from dsn.form_analysis.free_variables import free_variables
from dsn.form_analysis.somewhere import collect_definitions


def set_union(l):
return set.union(*l)


def dict_union(l):
result = {}
for d in l:
result.update(d)
return result


def lexical_addressing_x(surrounding_scope, lambda_form):
# Note that the present free-variable-driven form has no values for unused variables. This is considered useless
# (but I might change my mind once I get to the incremental analysis)
result = {}

parameters = {p.symbol for p in lambda_form.parameters}
defined = {f.symbol.symbol for f in collect_definitions(lambda_form)}

this_scope = set.union(parameters, defined)

for symbol in set_union([free_variables(f) for f in lambda_form.body]):
if symbol in this_scope:
result[symbol] = 0
continue

# The act of looking up always succeeds, though it may result in None for "not defined". This is because free
# variables that are not defined at the present level will also be free variables of higher levels.
looked_up = surrounding_scope[symbol]
if looked_up is None:
result[symbol] = None
else:
result[symbol] = looked_up + 1

return result
1 change: 1 addition & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def load_tests(loader, tests, ignore):
tests.addTests(doctest.DocFileSuite("doctests/free_variables.txt"))
tests.addTests(doctest.DocFileSuite("doctests/unused_definitions.txt"))
tests.addTests(doctest.DocFileSuite("doctests/name_dependencies.txt"))
tests.addTests(doctest.DocFileSuite("doctests/lexical_addressing_x.txt"))

return tests

Expand Down

0 comments on commit 097c6ad

Please sign in to comment.