MetaCase Homepage
Forum Home Forum Home > > MetaEdit+
  New Posts New Posts RSS Feed - :property modifiable by generator?
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

:property modifiable by generator?

 Post Reply Post Reply
Author
Message
mpierce View Drop Down
Member
Member
Avatar

Joined: 22.Jul.2010
Location: Cheney, WA, USA
Points: 9
Post Options Post Options   Thanks (0) Thanks(0)   Quote mpierce Quote  Post ReplyReply Direct Link To This Post Topic: :property modifiable by generator?
    Posted: 05.Aug.2010 at 10:17
Hello all,
 
is  it possible to modfied the value of a :property from within a code generator? I've got an object that I'm using to terminate an if-then-else statement, called an if-terminator (where the then and else sections converge back together) and I'm trying to find a way to mark it as having been visited by the 'then' path so that it terminates for the 'then' path but is passed through by the 'else' path. I've made a :Visited count; property but I can't seem to be able to change it's value from within a code generator - is there a way to do this?
 
Thanks,
 
Matt 
Back to Top
stevek View Drop Down
MetaCase
MetaCase
Avatar

Joined: 11.Mar.2008
Points: 643
Post Options Post Options   Thanks (0) Thanks(0)   Quote stevek Quote  Post ReplyReply Direct Link To This Post Posted: 05.Aug.2010 at 10:58

Access to models from within a MERL generator is read-only. The API can be used for read-write access (as well as creation and deletion), but for your case there's a better way. Your "Visited count" property shouldn't be persistent information - it's something you want to store only during a given generator run.

The easiest way is probably to maintain a MERL variable containing the unique id of each if-terminator that you have encountered. When you meet an if-terminator, check if its id is matched in the variable and if so ignore it. If not, add it to the variable and process it. There are several examples in the demo repository - use Advanced Find in the Generator Editor to look for %wildsp.
 
$visited = ' '
subreport '_translators' run
 
/* insert statements here to navigate to an if-terminator */
if not $visited =~ oid%wildsp then  
   variable 'visited' append oid ' ' close
   /* insert statements here to process the if-terminator */
endif
 
An alternative solution would be to change your modeling language to have a structure less like a flowchart and more like an abstract syntax tree. This is explained on p288-290 in the DSM book; hopefully the following picture will show the basic idea.
 


Edited by stevek - 05.Aug.2010 at 10:58
Back to Top
mpierce View Drop Down
Member
Member
Avatar

Joined: 22.Jul.2010
Location: Cheney, WA, USA
Points: 9
Post Options Post Options   Thanks (0) Thanks(0)   Quote mpierce Quote  Post ReplyReply Direct Link To This Post Posted: 06.Aug.2010 at 01:19
OK, this almos works :) Here's a snippet of my code:
else if type = 'If terminator'; then
 '}' newline
 subreport '_translators' run /* I've run this once at startup, doesn't seem to make a diff */
 if not ($visited =~ oid%wildsp) then
  variable 'visited' append oid ' ' close
 else
 do ~Statement; where #Out of statement port
 {
  do ~Statement.()
  {
   subreport 'Process Body Generator' run
  }
 }
 endif
 
No matter what happens, it always thinks that oid does not have the object's oid in it (I've verified in the debugger window that the oid value is infact being set in variable "visited", any ideas as to why the "if not ($visited =~ oid%wildsp) then" always thinks the oid is not in the variable, even when it is?
 
Thanks,
 
Matt
Back to Top
mpierce View Drop Down
Member
Member
Avatar

Joined: 22.Jul.2010
Location: Cheney, WA, USA
Points: 9
Post Options Post Options   Thanks (0) Thanks(0)   Quote mpierce Quote  Post ReplyReply Direct Link To This Post Posted: 06.Aug.2010 at 01:25
Oops, I meant to say "No matter what happens, it always thinks that variable visited does not have the object's oid in it "
 
Also, the parens around the comparison don't make a difference.
Back to Top
mpierce View Drop Down
Member
Member
Avatar

Joined: 22.Jul.2010
Location: Cheney, WA, USA
Points: 9
Post Options Post Options   Thanks (0) Thanks(0)   Quote mpierce Quote  Post ReplyReply Direct Link To This Post Posted: 06.Aug.2010 at 01:36

I was thinking of something similar to your second solution (abstract tree) but I'm going to try the oid route first and then maybe the abstract tree route later.

 
--Matt
Back to Top
mpierce View Drop Down
Member
Member
Avatar

Joined: 22.Jul.2010
Location: Cheney, WA, USA
Points: 9
Post Options Post Options   Thanks (0) Thanks(0)   Quote mpierce Quote  Post ReplyReply Direct Link To This Post Posted: 06.Aug.2010 at 08:31
I've verified that "if not $visited = oid then" works (but only for singly nested if statements)
and
"if not $visited = oid%wildsp then" does not work for me. I've run the _translator report from the main generator, from withing sub generators, and right before the if statement but it doesn't recognize the oid being in the 'visited' variable. I've used the _translators subreport as-is as well as copied out the %wildsp part and embedded it in my code.
 
Is there some other variable or flag or setting I need to enable to make this work?
 
Thanks,
 
Matt
Back to Top
stevek View Drop Down
MetaCase
MetaCase
Avatar

Joined: 11.Mar.2008
Points: 643
Post Options Post Options   Thanks (0) Thanks(0)   Quote stevek Quote  Post ReplyReply Direct Link To This Post Posted: 06.Aug.2010 at 11:32
Based on what you've posted, your problem is that you've changed =~ to = and maybe missed initializing $visited to a single space. But let's break it down to be sure:
 
$visited is going to contain something like this after you have visited three terminators:
' 3_1234 3_5678 3_2468 '
 
oid will be something like '3_5678' if you're revisiting the 2nd
 
oid%wildsp will add spaces and stars to get '* 3_5678 *'
 
=~ will perform a wildcard match (I notice in your later posts you just used =, which won't work).
 
Note the initialization of $visited to a single space, ' ', so oid%wildsp will match even for the first object.
 
_translators only needs to be run once, right at the start of your generator. It just defines %wildsp etc., and those definitions will last until the end of the generator run.
Back to Top
mpierce View Drop Down
Member
Member
Avatar

Joined: 22.Jul.2010
Location: Cheney, WA, USA
Points: 9
Post Options Post Options   Thanks (0) Thanks(0)   Quote mpierce Quote  Post ReplyReply Direct Link To This Post Posted: 06.Aug.2010 at 20:40
OK, the root problem was that I was initializing $visited with '' instead of ' ', the other things noted above were actually symptoms of my hacking around trying to make it work. Once I initialized visited with a space things work properly and now my code generators work properly - thanks so much for your help.
 
Do you have suggestions for best handling indentation of output? I've made a subreport called _indent and have a variable that I increment and decrement as indention changes and which is used by _indent. I execute _indent before every line of output. I suppose I could have a indent variable that I add/subtract spaces to/from and print out before every line of output, but I'm looking for additional suggestions.
 
Thanks again,
 
Matt
Back to Top
stevek View Drop Down
MetaCase
MetaCase
Avatar

Joined: 11.Mar.2008
Points: 643
Post Options Post Options   Thanks (0) Thanks(0)   Quote stevek Quote  Post ReplyReply Direct Link To This Post Posted: 07.Aug.2010 at 12:02
For indentation, try looking at the 'indent' translator, which turns each newline into a newline plus tab. The nice thing is that it can be used in recursive generators, and the recursion depth takes care of how many tabs there are:
 
Report '_recurse'
to 'indent' translate
   newline 'first line'
   newline 'second line'
   if $++ix < '5' NUM then
      subreport '_recurse' run
   endif
endto
endreport
 
Report 'indent'
subreport '_translators' run
$ix='0'
subreport '_recurse' run
endreport
 
It's not ideal to require the newline at the start of a line of code rather than the end, but I haven't tried messing around with a smarter regex version.
 
Your variable is also a reasonable way. Rather than having an integer variable and implementing a "for" loop in MERL (e.g. by recursion as above), you could have a string variable containing the tabs, and use a translator to add or remove one as necessary.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.05
Copyright ©2001-2022 Web Wiz Ltd.

This page was generated in 0.023 seconds.