Skip to content

Commit

Permalink
Add implicit collection cast
Browse files Browse the repository at this point in the history
  • Loading branch information
aranega committed Sep 19, 2024
1 parent 7e860a4 commit 6450bd8
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 209 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,10 @@ Python: (lambda x: x.foo)(OCLTuple(foo='abc'))
OCL: ParameterDirectionKind::inout
Python: ParameterDirectionKind.inout
OCL: (if nestingClass > null then null
OCL: (if nestingClass <> null then null
else
let b:BehavioredClassifier = self.behavioredClassifier(self.owner) in
if b.oclIsKindOf(Behavior) and b.oclAsType(Behavior).context > null then
if b.oclIsKindOf(Behavior) and b.oclAsType(Behavior).context <>> null then
b.oclAsType(Behavior).context
else b endif endif)
Python: (None if nestingClass > None else (lambda b: b.context if isinstance(b, Behavior) and b.context > None else b)(self.behavioredClassifier(self.owner)))
Expand Down Expand Up @@ -216,5 +216,5 @@ Here is a demo on how to use it.

Currently, some expressions are not well recognized, or not properly compiled:

* `obj->operation()`: in the specification, `->` acts as an automatic wrapper to a `Sequence` if `obj` is not a collection. Currently, PyEcoreOCL doesn't consider this automatic wrapping.
* `obj->operation()`: in the specification, `->` acts as an automatic wrapper to a `Sequence` if `obj` is not a collection. Currently, PyEcoreOCL doesn't consider this automatic wrapping for strict mode, but partially implement it for the normal mode.
* `collection->collect(attr)`: when there is no variable that is considered by the lambda inside collection operations, by default `attr` should be considered as attribute of an implicit `self` variable representing at each iteration one of the elements of `collection`. Currently, this is not supported, and it's not sure it will be for inline OCL. To overcome this, it's currently necessary to explicitally name the variable inside the lambda `collection->collect(e | e.attr)`.
2 changes: 1 addition & 1 deletion magic_ocl/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def ocl2python(tokens: Iterable[TokenInfo], mode: str):

def preprocess(data: str, mode: str="normal"):
return f"""
import itertools, collections
import itertools, collections, typing
import pyecoreocl.runtime as ocl
{untokenize(ocl2python(generate_tokens(StringIO(data).readline), mode=mode))}
"""
16 changes: 13 additions & 3 deletions pyecoreocl/dummy_rules/collections_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,24 +205,34 @@ def rule_excludes_all(emitter, ctx):
emitter.inline(")")


def dispatch_iterable(emitter, expression):
if emitter.mode == "strict":
emitter.visit(expression)
return

emitter.inline("((lambda x: x if isinstance(x, typing.Iterable) and not isinstance(x, (bytes, str)) else (x,))(")
emitter.visit(expression)
emitter.inline("))")


@collection_rule
def rule_as_sequence(emitter, ctx):
emitter.inline("list(")
emitter.visit(ctx.expression)
dispatch_iterable(emitter, ctx.expression)
emitter.inline(")")


@collection_rule
def rule_as_set(emitter, ctx):
emitter.inline("set(")
emitter.visit(ctx.expression)
dispatch_iterable(emitter, ctx.expression)
emitter.inline(")")


@collection_rule
def rule_as_bag(emitter, ctx):
emitter.inline("list(")
emitter.visit(ctx.expression)
dispatch_iterable(emitter, ctx.expression)
emitter.inline(")")


Expand Down
202 changes: 0 additions & 202 deletions tests/test_collection_lib.py

This file was deleted.

0 comments on commit 6450bd8

Please sign in to comment.