-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
V622-017: Fix env grouping with non-default metadata.
The routine for grouping lexical envs would previously always flatten grouped envs. However, this process would discard the `default_md` field of the nested grouped envs. The implementation now decides to flatten grouped envs only if the resulting env behavior is the same.
- Loading branch information
Showing
7 changed files
with
166 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
testsuite/tests/lexical_envs/grouped_env_default_md/expected_concrete_syntax.lkt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import lexer_example | ||
|
||
@with_lexer(foo_lexer) | ||
grammar foo_grammar { | ||
@main_rule main_rule <- list+(decl) | ||
decl <- Decl(Name(@identifier) "(" list*(ref) ")") | ||
ref <- Ref(Name(@identifier)) | ||
} | ||
|
||
@abstract class FooNode implements Node[FooNode] { | ||
|
||
@memoized fun env_with_md(foo_node: FooNode, bar_node: FooNode): LexicalEnv[FooNode] = | ||
{ | ||
val md1 = Metadata(foo_node=foo_node, bar_node=null); | ||
val md2 = Metadata(foo_node=null, bar_node=bar_node); | ||
|
||
[[node.node_env()].env_group()].env_group() | ||
} | ||
|
||
@export fun get_with_md(name: Symbol, foo_node: FooNode, bar_node: FooNode): FooNode = | ||
self.env_with_md(foo_node, bar_node).get_first(name) | ||
|
||
@export fun get_foo_metadata(): FooNode = self.info.md.foo_node | ||
|
||
@export fun get_bar_metadata(): FooNode = self.info.md.bar_node | ||
} | ||
|
||
class Decl : FooNode { | ||
@parse_field name: Name | ||
@parse_field refs: ASTList[FooNode, Ref] | ||
} | ||
|
||
class Name : FooNode implements TokenNode { | ||
} | ||
|
||
class Ref : FooNode { | ||
@parse_field name: Name | ||
} |
24 changes: 24 additions & 0 deletions
24
testsuite/tests/lexical_envs/grouped_env_default_md/main.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import sys | ||
|
||
import libfoolang | ||
|
||
|
||
print('main.py: Running...') | ||
|
||
ctx = libfoolang.AnalysisContext() | ||
u = ctx.get_from_file('main.txt') | ||
if u.diagnostics: | ||
for d in u.diagnostics: | ||
print(d) | ||
sys.exit(1) | ||
|
||
decl_list = u.root | ||
foo = decl_list[0] | ||
bar = decl_list[1] | ||
|
||
baz = decl_list.p_get_with_md("baz", foo, bar) | ||
print(baz.f_name.text + " has the following metadata:") | ||
print(" - foo_node: " + baz.p_get_foo_metadata.f_name.text) | ||
print(" - bar_node: " + baz.p_get_bar_metadata.f_name.text) | ||
|
||
print('main.py: Done.') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
foo( | ||
bar | ||
baz | ||
) | ||
|
||
bar() | ||
baz() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
main.py: Running... | ||
baz has the following metadata: | ||
- foo_node: foo | ||
- bar_node: bar | ||
main.py: Done. | ||
Done |
78 changes: 78 additions & 0 deletions
78
testsuite/tests/lexical_envs/grouped_env_default_md/test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
""" | ||
Test that nested grouped envs with non-null default metadata behave as | ||
expected. | ||
""" | ||
|
||
from langkit.dsl import ASTNode, Field, Struct, T, UserField, env_metadata | ||
from langkit.envs import EnvSpec, add_env, add_to_env_kv | ||
from langkit.expressions import Entity, No, Self, Var, langkit_property | ||
|
||
from utils import build_and_run | ||
|
||
|
||
@env_metadata | ||
class Metadata(Struct): | ||
foo_node = UserField(T.FooNode) | ||
bar_node = UserField(T.FooNode) | ||
|
||
|
||
class FooNode(ASTNode): | ||
@langkit_property(memoized=True) | ||
def env_with_md(foo_node=T.FooNode, bar_node=T.FooNode): | ||
md1 = Var(Metadata.new( | ||
foo_node=foo_node, | ||
bar_node=No(T.FooNode) | ||
)) | ||
md2 = Var(Metadata.new( | ||
foo_node=No(T.FooNode), | ||
bar_node=bar_node | ||
)) | ||
return Self.node_env.singleton.env_group( | ||
with_md=md1 | ||
).singleton.env_group( | ||
with_md=md2 | ||
) | ||
|
||
@langkit_property(return_type=T.FooNode.entity, public=True) | ||
def get_with_md( | ||
name=T.Symbol, | ||
foo_node=T.FooNode, | ||
bar_node=T.FooNode | ||
): | ||
return Entity.env_with_md(foo_node, bar_node).get_first(name) | ||
|
||
@langkit_property(return_type=T.FooNode, public=True) | ||
def get_foo_metadata(): | ||
return Entity.info.md.foo_node | ||
|
||
@langkit_property(return_type=T.FooNode, public=True) | ||
def get_bar_metadata(): | ||
return Entity.info.md.bar_node | ||
|
||
|
||
class Name(FooNode): | ||
token_node = True | ||
|
||
|
||
class Decl(FooNode): | ||
name = Field() | ||
refs = Field() | ||
|
||
env_spec = EnvSpec( | ||
add_to_env_kv( | ||
key=Self.name.symbol, value=Self | ||
), | ||
add_env() | ||
) | ||
|
||
|
||
class Ref(FooNode): | ||
name = Field() | ||
|
||
env_spec = EnvSpec(add_to_env_kv( | ||
key=Self.name.symbol, value=Self | ||
)) | ||
|
||
|
||
build_and_run(lkt_file='expected_concrete_syntax.lkt', py_script='main.py') | ||
print('Done') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
driver: python |