Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD Beta Forum Goto page 1, 2  Next
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Fri Apr 14, 2006 10:11 pm   

More discussion of %1 and %%1
 
I've run into a problem dealing with %1 and %%1. Here is an example script that works in zMUD:
Code:
#ALIAS make {#ALIAS %1 {cast %1 %%1}}

If you type:

make heal

then the "make" alias creates a new alias called "heal" with the following definition:
Code:
#ALIAS heal {cast heal %1}

and now if you type:

heal Zugg

it will send "cast heal Zugg" to the MUD. Nice and useful.

OK, with CMUD this causes all sorts of problems. The %1 is only expanded at RUNTIME when something is executed. So when you execute the "make" alias, only the first %1 is expanded. The %1 and %%1 within the second alias command string isn't expanded yet, it is just stored as the value of the new alias. So in CMUD, you end up with

#ALIAS heal {cast %1 %%1}

as the second alias. This happens in any script where you are creating another alias or trigger "on the fly". The %1..%99 in the alias or trigger you are creating don't get expanded until that script executes.

So, the way I've got it coded in CMUD just isn't going to work. I'm obviously going to need to parse the 2nd argument of the #ALIAS command and expand any %1..%99 variables when it is first defined, and then convert any %%1..%%99 into normal %1..%99 to be later evaluated at runtime.

I'm not really sure why I'm posting this. I'm not really asking for feedback here. The use of %1 and %%1 in this case makes sense so I think I just need to figure out how to handle it.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Sat Apr 15, 2006 2:05 am   
 
Hmm, this isn't right at all...what a mess this is.

Let's go back to this example:
Code:
#ALIAS make {#ALIAS %1 {cast %1 %%1}}


Now, consider typing this on the command line, vs the exact same line in some other script. For example, imagine this line as the *value* of an existing alias (called "Test" for example). In that case, doesn't the %1 refer to the alias arguments for the "test" alias??

Commands entered into the command line are supposed to work the same as when used in a script. But on the command line, %1..%99 don't have values. And when put into a "Test" alias, we don't know if "Test" has arguments or not. So is the %1 supposed to refer to an argument of "Test", or an argument of the "make" alias? I'm not even exactly sure how zMUD is handling this correctly, but it seems to be totally kludged and there are probably a lot of inconsistencies on how this is handled there too.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Sat Apr 15, 2006 2:24 am   
 
I think what maybe needs to happen here is this:

1) %1..%99 refer to arguments of the inner-most "block". To refer to arguments of outer blocks, that's when we need the %%1. This is only needed within commands that have "stored commands" (like ALIAS, TRIGGER, etc) vs commands that have immediately executed commands (like IF, WHILE, etc).

So, looking at the structure of the above example, and assuming it is stored as the value of a "Test" alias, here is what we have:
Code:
Alias: Test
Value:
  #ALIAS make {
      #ALIAS %1 {
            cast %%1 %1
            }
      }

So, the first %1 refers to the first argument within the current "block", which is the "make" alias. The %%1 refers to the first argument in the parent block of the innermost alias, which is the same first argument of the "make" block. The final %1 refers to the innermost alias block. None of these have anything to do with the "Test" alias arguments, or have any effect when used on the command line. So this gives a syntax that makes sense no matter where the alias is defined.

This reverses the use of the %1 vs %%1 compared to zMUD, but I'm hoping that the use of %%1 is fairly rare.

Let's look at another example. Let's create a trigger that, in turn, creates another trigger on-the-fly:
Code:
Pattern: (%w) gives you (%d) coins
Value:
  #TRIGGER {%1 tells you 'Give coins to (%w)'} {give %%2 coins to %1}

So, when you get the text from the MUD like:

Zugg gives you 100 coins

the trigger fires and %1 has the value of "Zugg" and %2 has the value of "100". So the trigger that is created "on-the-fly" ends up looking like this:

Code:
#TRIGGER {Zugg tells you 'Give coins to (%w)'} {give 100 coins to %1}


You see how the %1 always refers to the argument of the current block, whereas %%2 refers to the argument of the next highest block.

This only effects those commands that have run-time arguments, so it only effects #TRIGGER and #ALIAS when they are nested within other triggers or aliases. The proposed solution doesn't change the normal use of %1..%99. But any script that uses %%1..%%99 will need to be changed.

If you have a script that uses %%1..%%99, I'd be interested in seeing it. And if *anyone* has a script that uses %%%1 or more indirection, definitely post it along with what it's supposed to do so that I can take a look at it. But my guess is that few people ever got into something complicated enough to use this much indirection.

Let me know if you can think of any downsides to this solution. I know this is a very complicated issue and it's going to be hard to document. So read this post a few times to make sure you are clear on what I'm talking about. It's taken me a few attempts to try and get this right too, and I still might not have it correct.
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Sat Apr 15, 2006 5:14 am   
 
Do you declare these dynamically or do you just spend the memory beforehand and populate/set-to-empty as needed? Seems to me that a syntax similar to nested loop counters would work, assuming that 300-2400 new variables don't make the conversion strictly unworkable:

%1 -- %1
%a1 -- %%1
%b1 -- %%%1
%c1 -- %%%%1
etc
_________________
EDIT: I didn't like my old signature
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Sat Apr 15, 2006 4:51 pm   
 
These %%1 etc references are compiled by the CMUD compiler and converted to reference code. They reference items stored on the internal runtime stack.

For example, when you call an alias like: "heal zugg", the compiler converts this to:

Code:
PUSH STRING "zugg"
CALL ALIAS "heal"


So, when executing the alias "heal", %1 refers to the first argument on the stack (the string "zugg"). Each set of arguments are placed onto the stack within a "stack frame" which is a collection of all arguments passed to the alias or command. Using %%1 causes the compiled to create a reference to the previous "stack frame" rather than the current one. It basically counts the number of '%' characters to determine how many stack frames to go back.

This is very different from variable references which point to records in the package database. So implementing %%1 as a variable like %a1 would be a lot slower since it would need to store %a1 in the database (or at least the memory cache of the database).

Anyway, it's all working now as described in my previous reply. Anyone using %%1 will need to rewrite their script but this shouldn't effect most people. And the new syntax will be more straightforward to explain and use since it won't depend upon where your scripts are embedded or used.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Sat Apr 15, 2006 6:01 pm   
 
Hmm, here is an interesting side effect that I discovered in CMUD. Not sure anyone should depend upon this is a script, but it kind of makes sense.

Because of how %1..%99 are handled, you can actually use them within a {} to reference other arguments on the same line. For example, let's create a test alias:
Code:
#ALIAS test {#SHOW 1: %1 2: %2 3: %3}

This alias basically just echos the first 3 arguments passed to it. So, if you enter:
Code:
test hello {this is a test} world
1: hello 2: this is a test 3: world

is what you get. Now, within the {} that contains "this is a test" you can actually reference the %1..%3 arguments on the same line. For example:
Code:
test hello {this is a %1 test} world
1: hello 2: this is a hello test 3: world

is the result. You can even reference the arguments that come after you:
Code:
test hello {this is a %3 test} world
1: hello 2: this is a world test 3: world

is the result. Kind of cool, although as I said, it's also a bit wierd. I also fixed it so that self-references are handled without creating an infinite loop. So if you do:
Code:
test hello {this is a %2 test} world
1: hello 2: this is a this is a  test test 3: world

is the result. The %2 evaluates to an empty string the second time it is referenced.

I'm not sure that anyone would ever use this and I'm not sure if I'll document it, but it actually makes a bit of sense when you understand how %1..%99 are implemented in terms of the internal argument stack.
Reply with quote
mr_kent
Enchanter


Joined: 10 Oct 2000
Posts: 698

PostPosted: Sun Apr 16, 2006 3:27 am   
 
Zugg wrote:
Kind of cool, although as I said, it's also a bit wierd. I also fixed it so that self-references are handled without creating an infinite loop. So if you do:
Code:
test hello {this is a %2 test} world
1: hello 2: this is a this is a  test test 3: world

is the result. The %2 evaluates to an empty string the second time it is referenced.


Is this reference fix absolute or instance/location dependent? In other words, what happens with
Code:
test hello {this %2 is a %2 test} world
Reply with quote
edb6377
Magician


Joined: 29 Nov 2005
Posts: 482

PostPosted: Sun Apr 16, 2006 3:46 am   
 
i would expect thats a very messy string

1: hello 2: this this is a test is a this is a test test 3: world? i would gather.
_________________
Confucious say "Bugs in Programs need Hammer"
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Sun Apr 16, 2006 4:09 am   
 
Yep, edb6377 is correct.
Reply with quote
mr_kent
Enchanter


Joined: 10 Oct 2000
Posts: 698

PostPosted: Sun Apr 16, 2006 4:18 am   
 
edb6377 wrote:
i would expect thats a very messy string

1: hello 2: this this is a test is a this is a test test 3: world? i would gather.


That is what I hope would happen. It IS a very messy string, but it is also very contrived.

I can foresee a use for something like this, but not if the fix is absolute. Possible results for that test line could also be an error or one of the following,

Code:
1: hello 2: this this is a test is a test 3: world
1: hello 2: this this is a test is a  test 3: world
1: hello 2: this this is a test is a   test 3: world
1: hello 2: this this is a test is a world test 3:


depending on how the fix is implemented/stack manipulated.

Edit: Thanks Zugg, I was trying to think, type and watch CSI, so I was really slow.
Reply with quote
Rainchild
Wizard


Joined: 10 Oct 2000
Posts: 1551
Location: Australia

PostPosted: Mon Apr 17, 2006 10:47 pm   
 
Question... in your example:

Code:
#ALIAS make {#ALIAS %1 {cast %1 %%1}}


Your %%1 seems to be using the '%' to escape it - shouldn't you write this code as:

Code:
#ALIAS make {#ALIAS %1 {cast %1 ~%1}}


That way the %1 can be expanded when it runs, and when you type 'make heal' everything is happy since it's created correctly.

Code:
#ALIAS heal {cast heal %1}}



Likewise... I don't understand why you are putting the %%2 backward. Shouldn't this one be:

Code:
#TRIGGER {%1 tells you 'Give coins to (%w)'} {give %2 coins to ~%1}


That way "Zugg gives you 100 coins"

creates the pattern: Zugg tells you 'Give coins to (%w)'
with the command: give 100 coins to %1


Edit: This '~%1' syntax doesn't seem to be supported by Zmud (eg you get "cast heal ~%1" instead of what you would expect), but IMO it makes the most sense to write it this way.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 18, 2006 1:18 am   
 
No, Rainchild, that's actually the wrong way to look at it. The %% isn't "escaping" anything...it is parsed and compiled as a specific reference to a specific argument on the runtime stack. It's not "delayed" like it was in zMUD.

In zMUD, the %%1 was more like you said where the extra % was just stripped each time through the evaluation loop.

Your confusion here is exactly the problem I was originally having. Take a closer look at this:
Code:
#TRIGGER {%1 tells you 'Give coins to (%w)'} {give %2 coins to ~%1}

Here, you are suggesting the ~%1 points to the (%w) in the "Give coins to (%w)" pattern. But that's different that a normal trigger. Normally, a trigger would look like this:
Code:
#TRIGGER {Zugg tells you 'Give coins to (%w)'} {give 100 coins to %1}

This is the same trigger syntax (as far as the compiler is concerned), and yet in one case you have ~%1 and in the other case you have %1. So which is it? The parser needs to be consistent in how it expands variables and arguments. When it sees %1, it returns the first argument from the current "block".

So, what I am talking about here is a way to access arguments in other "blocks" from the current one. And the other problem with the ~%1 syntax is that it doesn't allow you to specify additional blocks. How would you represent %%%1 or %%%%1? The ~ quote character has a very specific purpose in the CMUD parser: it causes the next character to be parsed as a plain text character rather than a "special" character. This has nothing to do with parameter expansion and overloading the character like you suggest would make a big mess in the lexical analyzer section of the parser. Anytime a single character is used for more than one purpose it causes problems in the parser.

Anyway, take a closer look at this. It's very important that the #TRIGGER example be independent of whether it is a standalone trigger or part of another trigger (or nested several blocks deep in some complex trigger creation script). The parser needs to be able to compile the code regardless of it's "context".

So, to re-interate the parsing rules for CMUD here:

%1 refers to the first argument of the current "block"
%%1 refers to the first argument of the parent "block"
%%%1 refers to the first argument of the parent's parent block
and so on.

This allows existing scripts with only one block to work just like in zMUD. Scripts that used %%1 in zMUD will need to "reverse" the use of %1 vs %%1.
Reply with quote
Rainchild
Wizard


Joined: 10 Oct 2000
Posts: 1551
Location: Australia

PostPosted: Tue Apr 18, 2006 2:53 am   
 
I still don't see why it needs to have a reference to anything?

I mean - inside a trigger we're trying to create another trigger, right?

So our first pattern was: (%w) gives you (%d) coins.
This makes '%1' being the (%w), and '%2' being the (%d).

Or in the example, Zugg gives you 100 coins.
%1 is Zugg
%2 is 100

Now we wanted to create a trigger based on that - hence the:
Code:
#TRIGGER {%1 tells you 'Give coins to (%w)'} {give %2 coins to ~%1}


The %2 gets replaced by '100', the %1 gets replaced by 'Zugg' and the ~% gets escaped by the tilde which means it prints the '%' character in the resulting command. So after doing the parsing of the code, we should now be executing:
Code:
#TRIGGER {Zugg tells you 'Give coins to (%w)'} {give 100 coins to %1}


Maybe you don't process the tilde's, but a call to #EXEC will:
Code:
#EXEC {#TRIGGER {%1 tells you 'Give coins to (%w)'} {give %2 coins to ~%1}}


It certainly works in this regard:
Code:
#ALIAS make {#EXEC {#ALIAS %1 {cast %1 ~%1}}}


Typing 'make heal' will create the proper heal -> 'cast heal %1' alias. Zmud syntax checker throws a hissy fit at the nested #ALIAS, but the script executes fine and performs as I would expect it to.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 18, 2006 3:41 am   
 
No, you still don't get it. I know you think this is backwards, but read this *very* carefully.

Look at your first example again:
Code:
#TRIGGER {%1 tells you 'Give coins to (%w)'} {give %2 coins to ~%1}

OK, now, consider this trigger ON ITS OWN. Forget about the fact that it is inside of another trigger. The parser doesn't know about the other trigger. Just consider this line all by itself.

Now, with a normal #TRIGGER command, %1..%99 refers to the matching subpattern. The only subpattern in this trigger is (%w). The contents of (%w) get assigned to %1. The value of %2 is null...there is not a second subpattern here. So forget about the ~%1 for a second. Just look at the command:
Code:
give %2 coins to whatever

The %2 refers to the second subpattern of the current trigger command.

There is no way for %2 to refer to the parent trigger! The parser doesn't know anything about the parent trigger. It has to be able to parse this inner trigger on it's own.

You are still thinking like zMUD works that the %1..%99 are somehow "filled" by the outside trigger and can then be referenced like they were variables. But %1..%99 don't work this way in CMUD...they are not normal variables...they are references to the arguments passed to a command block. The second argument of a #TRIGGER command is a "command block". The subpattern results of the trigger match are passed to it as arguments.

The method you are talking about only works if the %1..%99 are expanded as string substitutions before the command block is compiled. But CMUD doesn't work like this (like zMUD does). The inner trigger has already been compiled as a standalone trigger. As a standalone trigger, %1..%99 refer to the subpatterns matched by THAT trigger, not by any parent trigger.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 18, 2006 3:55 am   
 
Yeah, this is complicated. And this is exactly why I posted this. If RainChild doesn't understand this, then how in the world is anyone else ever going to understand it. That's what I mean about this being a mess.

I simply cannot find a way with the compiler and parser to have %1..%99 refer to the outermost block.

Let me show another example. In this case, let's look at a trigger that runs an alias:
Code:
Pattern: (%w) gives you (%d) coins
Value:
  #VAR target %1
  #VAR coins %2
  MakeTrigger

OK, so how would the MakeTrigger alias look:
Code:
Alias: MakeTrigger
Value:
  #TRIGGER {@target tells you 'Give coins to (%w)'} {give @coins coins to %1}

Right? That makes sense when you see it with variables. Obviously the %1 in this trigger refers to the (%w) in the pattern. This is certainly what zMUD does. And CMUD should do the same thing.

OK, now, instead of assigning the first set of values to variables, let's try to pass them as arguments to the MakeTrigger alias:
Code:
Pattern: (%w) gives you (%d) coins
Value:
  #VAR target %1
  #VAR coins %2
  MakeTrigger %1 %2

So now how should the MakeTrigger alias look?
Code:
Alias: MakeTrigger
Value:
  #TRIGGER {%1 tells you 'Give coins to (%w)'} {give %2 coins to %1}

Now that's obviously not quite right. The %2 is supposed to refer to the 2nd subpattern of the current trigger, just like %1 already did. So it's the %2 reference that needs to be changed. We don't want to change the %1 reference because that makes it inconsistent with the previous case where we didn't pass any arguments. How could %1 be expanded to one thing when the alias didn't have arguments, but refer to something else when the alias *did* have arguments.

So the correct alias is this:
Code:
Alias: MakeTrigger
Value:
  #TRIGGER {%1 tells you 'Give coins to (%w)'} {give %%2 coins to %1}

We have changed the %2 and left the rest alone. So the only thing we have done is replace the @target and @coins with their proper parameter references. We don't change the %1 because it always refers to the (%w) pattern regardless of whether we are passing arguments or not.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 18, 2006 4:38 am   
 
Btw, the other problem with your #EXEC #ALIAS example is confusing how the alias value is actually parsed. In your example, you had:
Code:
#ALIAS make {#EXEC {#ALIAS %1 {cast %1 ~%1}}}

OK, let's replace one of the %1 references with a variable instead:
Code:
#ALIAS make {#EXEC {#ALIAS %1 {cast @target ~%1}}}

Now, what I want is when I type:

make heal

I want an alias that looks like this:

Code:
Alias: heal
Value: cast @target heal

Right? OK, but that's not what you get. Your #EXEC call causes the @target variable to be expanded right away. So in zMUD (assuming @target is "Zugg"), here is what you get:
Code:
Alias: heal
Value: cast Zugg heal

To prevent this, in zMUD you have to use the following original code:
Code:
#ALIAS make {#EXEC {#ALIAS %1 {cast ~@target ~%1}}}

with yet another ~ character. Yuck!

In CMUD, it's much simpler. Here is the working CMUD result:
Code:
#ALIAS make {#ALIAS %1 {cast @target %%1}}

So when you type:

make heal

This gives you
Code:
Alias: heal
Value: cast @target heal

which is what we wanted. If you use %1 instead of %%1 then you get this:
Code:
Alias: heal
Value: cast @target %1

Just as if you had typed:

#ALIAS heal {cast @target %1}

the contents of the alias are the same regardless of whether any arguments are passed to the alias.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 18, 2006 7:08 am   
 
Sorry if I'm beating a dead horse, but I came up with another example way of looking at this.

Consider the following pseudo code:
Code:
procedure OuterTrigger( %1, %2)
// %1 is the target
// %2 is the coins
{
  procedure MakeTrigger( %1)
  // %1 is the destination
  {
    Give %2 (coins) to %1 (destination);
  }

MakeTrigger( %1);
}

OK, this isn't the best example, but what I'm trying to show here are "nested" procedures or functions. In a "real" programming language, you can name the arguments passed to procedures and functions. So you can avoid naming conflicts by giving different variables different names.

But when you are unable to supply names and have to use the default %1..%99 (%1 is the first parameter, etc), then you can see that when you have nested routines you get a conflict. When when you refer to %1, you are always referring to the most "local" %1 in the variable scope.

So within the MakeTrigger routine, %1 always refers to the first argument of MakeTrigger and not the %1 in the OuterTrigger.

That's the whole point that I'm making here. We are talking about nested routines, and it's normal and expected for %1 to refer to the innermost arguments.

However, this brings up an interesting idea. Maybe CMUD needs a way to "name" these arguments, so that instead of using %1..%99 you can pick your own argument names. This would make CMUD more like a "normal" programming language where you could give useful names to the arguments instead of getting mired in the confusion of %1 vs %%1 vs %%%%%1, etc.

Now, it's relatively straight forward to define a syntax for naming ALIAS and FUNC arguments. We could do something like this:

Code:
#ALIAS Make(%spellname) {#ALIAS %spellname(%target) {cast %spellname %target}}

Now, this is a *LOT* clearer than using %1 or %%1 or ~%1 or anything else. And it might not be very hard to implement this.

But my question is how to do this with triggers. Any suggestions on a syntax for naming trigger subpatterns? Should we just use the &varname syntax in some way? Trying to come up with something that makes sense might be better than trying to figure out all of this %1 nonsense.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 18, 2006 7:44 am   
 
Yeah, I know, I should probably go to bed...but I came up with an idea for people to comment on.

PHP and Perl programmers will probably like this. Instead of overloading the % or & operators, what if we used $ for local arguments (and local variables).

So, we could have the following ALIAS syntax for named arguments:
Code:
#ALIAS Make($spellname) {#ALIAS $spellname($target) {cast $spellname $target}}

and for triggers we could have this:
Code:
#TRIGGER {($target) gives you (%d$coin) coins} {
  #TRIGGER {$target tells you 'give coins to ($dest)'} {give $coin coins to $dest}
  }

So we would then have the following naming conventions:

@ stored variables and functions
% system variables and functions
$ local variables and arguments

Also notice in the trigger example that new subpattern arguments are indicated with a () around them, just like with a normal un-named subpattern. That helps distinguish a new argument from a reference to an existing argument. For example, in the innermost trigger, $target isn't creating an argument, but is refering to the value of an existing argument (like using a @varname in a trigger), whereas the ($dest) is creating a new argument and would be equivalent to a named (*) wildcard pattern. In the outer trigger we use the syntax (%d$coin) to define a named (%d) wildcard argument.

Comments?
Reply with quote
Taz
GURU


Joined: 28 Sep 2000
Posts: 1395
Location: United Kingdom

PostPosted: Tue Apr 18, 2006 6:37 pm   
 
Odd that no one else seems to have commented on the $ named arguments idea.

I like it, in fact I like it a lot!
_________________
Taz :)
Reply with quote
Tech
GURU


Joined: 18 Oct 2000
Posts: 2733
Location: Atlanta, USA

PostPosted: Tue Apr 18, 2006 8:35 pm   
 
This is a clean approach and intuitive approach.. especially to seasoned scripters/programmers. And I suspect they make up most of the group who'll use these features.
_________________
Asati di tempari!
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Tue Apr 18, 2006 9:45 pm   
 
Would this be operating under the same limitations as %1 that you explained earlier or would it be a replacement/extension of the current &varname syntax? Since it looks like $varname might replace &varname maybe we could add in scope support to better govern where the variables are created and/or how they might be handled once the code block ends:

$local.%dCoins -- creates a variable in the setting's class (if temporary variables are possible, perhaps this deletes the variable when the setting-level codeblock ends)

$global.%dCoins -- creates a variable in the setting's package's root class

$package.%dCoins -- creates a root-level (public) variable in another package, where package is the name of the target package (probably not a good idea, but something to round out the suggestion)
_________________
EDIT: I didn't like my old signature
Reply with quote
Rainchild
Wizard


Joined: 10 Oct 2000
Posts: 1551
Location: Australia

PostPosted: Tue Apr 18, 2006 10:37 pm   
 
Yeah, named variables would certainly fix all the problems we are banging our heads against.

Happy with $ - or for that matter you could just use @@ although usually @@ refers to global and @ refers to local in other languages.

Not sure about the syntax (%d$coin) ... I think I would prefer something maybe (%d:coin) or (%d->$coin) or something to make it a little readable.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 18, 2006 11:43 pm   
 
$varname doesn't replace &varname.

&varname still sets the @varname variable with the value of the subpattern. @varname is a normal stored variable, not a local argument. Of course, you can use this for a similar purpose since you can always use @varname in your trigger, but you have to remember that you are setting one of your stored variables.

Using the $varname syntax you are setting a *local* variable. This variable is not stored, and is local to the current trigger. So you don't have to worry about it overwriting a normal variable and you don't have to worry about overwriting some value set from some other trigger.

I'm not sure what "limitations" of %1 that you mean. But $varname is handled as a local variable reference just like %1. In fact, %1..%99 will still work (as I've outlined in this thread already). Neither %1 nor $varname will expand before parsing like zMUD does...that just causes too many problems and it the main thing I'm trying to fix here.

So no, you can't use $local... $global... or anything like that. $varname is expanded at *compile time* to refer to a particular argument already on the runtime stack, just like %1..%99. The advantage of the $varname is that you don't have to worry about the conflicts that you do with %1..%99 and you always know what value you are referring to. Also, it's the same syntax that I was already envisioning for other local variables.

The (%d$varname) syntax could certainly be discussed...I just made it up. In Perl regular expressions, there is already something called a "named subpattern" and it has the syntax: (?name:pattern), so maybe the CMUD syntax should be ($varname:pattern). For example ($coin:%d). That would be more familiar to Perl users and would be very easy to convert into regular expression format.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 18, 2006 11:45 pm   
 
Oh, and I didn't want to use @@ because that gets too much confused with the "delayed" expansion stuff in zMUD (like the %%1 had). Also, I already needed a different way to refer to local variables that are being added to CMUD.

Remember that overloading existing operators always ends up causing confusion and parser issues. And since $ is a common delimeter for variables (PHP, Perl, etc) it makes sense. Also, since $ is used for local arguments and script variables, it doesn't get used on the command line. So we don't need another "special character" that the user can change...it just gets hard coded in the parser like any other programming language.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Tue Apr 18, 2006 11:46 pm   
 
[Edit: Well Zugg posted his two messages while I was writing this, but most of this still stands, although I do think I prefer the perl syntax you mentionned - it's just more alien to zScript.]

I understood and had no problems with the new CMUD %%1 syntax, but this Make($spellname) syntax certainly seems clearer. I'm sure I would adapt to either. Some other MUD clients, e.g. Powwow, use $varname syntax.

One question though - $ is currently used to match the end of a line (in both zScript patterns and perl regular expressions) - is this safe from getting messed up, even if you are matching accross two lines, and storing the last word of one line and the first word of the next line to a %1 variable?

Also the & variables take this form (in the complex case according to the zMUD help file):
&%d{Gold}gp where Gold is the variable name. So surely the $ variables should be of this form (in the complex case)? e.g. $%d{Gold}gp

Lastly, I think it is important to consider the perl regular expressions when it comes to trigger pattern changes. On a side note, will CMUD still use perl regular expressions internally (i.e. convert all patterns to this syntax)?
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net