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 Previous  1, 2
Zugg Posted: Fri Apr 14, 2006 10:11 pm
More discussion of %1 and %%1
Zugg
MASTER


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

PostPosted: Wed Apr 19, 2006 12:15 am   
 
I thought about using the same syntax as the & operation. I'm really tempted to change the &varname syntax since it's really quite bad.

For example, what if you want to match a more complex expression? Currently the &varname syntax supports simple wildcard like %d, or a [] character range. What if you wanted to match something more complicated like %w%d? zMUD doesn't handle this.

Using the Perl syntax of ($varname:pattern) allows any complex subpattern that you want. For example ($varname:%w%d) would match a substring of letters followed by numbers. It's simple and clean.

So, what I'm considering is leaving the existing &%d{Gold} syntax for &varname just like zMUD has, but then add additional syntax for BOTH $varname and &varname in CMUD that uses the Perl syntax.

So, in CMUD you could still do &%d{Gold} or you could use the new syntax of (&Gold:%d). For the $varname you could only use the new syntax of ($Gold:%d). People would be encouraged to use the new syntax and the old syntax would be marked as "depreceated".

One thing I like about the Perl syntax is that it keeps the (). So it's easier to spot a subexpression that you are storing. The current &varname syntax makes it really easy to not see the subpatterns.

And yes, CMUD will still use Perl regular expressions internally. This was a huge improvement in zMUD so there's no reason not to keep this.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Wed Apr 19, 2006 1:18 am   
 
Sounds good to me. So under this proposal, $ after a ( will be a local variable, and other $ characters will mean line-breaks? (And if you want to match a ( at the end of the line, you can use
Code:
~($
)?
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Wed Apr 19, 2006 1:29 am   
 
I actually very much like the new naming, and knowing that all my typing gets compiled out into 1 or 2 bytes I can be much more verbose with names for things. To me this is a great way to eliminate having to type comments so I like it even more. This leads of course to the question of how do we really use it in the #ALIAS and #FUNCTION commands? Is the addition of a parameter list a definite thing for #ALIAS? What kind of alterations would be required to make it available to #FUNCTION? I am pretty sure those cover the only procedural type commands available.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Rainchild
Wizard


Joined: 10 Oct 2000
Posts: 1551
Location: Australia

PostPosted: Wed Apr 19, 2006 1:56 am   
 
Quote:
So, in CMUD you could still do &%d{Gold} or you could use the new syntax of (&Gold:%d). For the $varname you could only use the new syntax of ($Gold:%d). People would be encouraged to use the new syntax and the old syntax would be marked as "depreceated".


Sold!

Sounds like a good solution to all that weird stuff on the last page :)
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Apr 19, 2006 2:29 am   
 
Both Aliases and Variables will be supported as well using the previously mentioned syntax:

#ALIAS name ($arg1,$arg2,...) {definition}
#FUNC name ($arg1,$arg2,...) {definition}

Also, Seb, remember that the ($varname:pattern) is used to "declare" an argument. You can still use just $varname to refer to a previous argument defined in different scope. So, there is still a potential issue with $ for the end of line that I need to look into. For example, if you were trying to match multiple lines with something like this:

line 1$line 2

then it might interpret $line as an argument reference. However, the compiler will look up the $line argument name and if it doesn't find a match then it doesn't get expanded. So just don't choose an argument name that matches the text you want at the beginning of the line in your trigger. Since you choose your own names for the arguments, I don't see this being a problem. It's just a bit of extra code for the compiler to check for a valid argument name.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Wed Apr 19, 2006 2:45 am   
 
Are you sure your charging enough for CMud? I love the additions. Is there any way we might be able to make assignments into the $ variables?
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Apr 19, 2006 5:35 am   
 
Well, I wasn't going to mention it yet, but I guess this is as good a place as any.

I've alluded to "local" variables. They work with the $varname syntax and you assign and use them just like any normal variables.

You can declare the local variables at the beginning of your script using the #LOCAL command, but this is optional:

#LOCAL $var1 $var2 etc

This allocates space for them on the stack and ensures that they are available to the script. But if you use the $varname=value to assign a value, the variable will also be created if needed. Just be sure to create the variable before you try to access it's value (or you will get a null value)

So you use the assignment syntax:

$localvar=value

or

#VAR $localvar value

Note that the $ symbol is mandatory to tell CMUD that you are assigning a value to a local variable, rather than a normal variable. Accessing the value of the variable is just the simple $varname syntax that you'd expect.

Local variables are local to your current block scope. I'll be providing more instructions on what a "block" is, but think of a block as any set of commands within {} characters.

Here is an example:
Code:

#ALIAS test {
  #LOCAL $testvar1 $localvar
  $testvar = hello
  $localvar = abc
  #SHOW $localvar  // displays abc
  #IF (true) {
    $localvar = 123
    #SHOW $localvar  // displays 123...this is a new block, so this is a different local variable than the previous $localvar
    #SHOW $testvar1 // displays hello.  You can access the variables in the parent scope just like other languages
    $anothervar = Zugg
    }
  #SHOW $localvar  // displays abc...we are back in the previous scope and the variables from the #IF block are gone
  #SHOW $anothervar // displays a null string since this variable from the IF block is gone
}


These variables are implemented as items on the local runtime stack and are NOT STORED in your package. They only maintain their values within their defined script block. Their values are lost when the script block ends. So, for example, after the above alias is executed, the $testvar1 and $localvar variables no longer exist...they are truely local.

These local variables are *very* fast. Much faster than a normal variable. A normal variable must be stored in the internal database, which means updating indexes, etc. Local variables are just stored on the runtime stack and can be saved and retrieved instantly.

Because local variables are only defined at runtime, they obviously do not appear in the settings editor.

Because the "named arguments" that we have been talking about are implemented the same as local variables (they ARE local variables), then YES, you can assign to them. You can even assign to %1..%99 if you really want to, but I'd probably discourage that as poor coding practice.
Reply with quote
edb6377
Magician


Joined: 29 Nov 2005
Posts: 482

PostPosted: Wed Apr 19, 2006 5:39 am   
 
This itself is a very good addition and has been needed for quite a while. There are some situations where it just redundantly taking up space to set a variable when you only need it at runtime.
_________________
Confucious say "Bugs in Programs need Hammer"
Reply with quote
Vodoc
Apprentice


Joined: 11 Apr 2003
Posts: 119
Location: Sweden

PostPosted: Wed Apr 19, 2006 8:34 am   
 
Zugg wrote:
These variables are implemented as items on the local runtime stack and are NOT STORED in your package. They only maintain their values within their defined script block. Their values are lost when the script block ends. So, for example, after the above alias is executed, the $testvar1 and $localvar variables no longer exist...they are truely local.
Love it! Have anticipated this for a long time now and are really looking forward to test out CMUD. Very Happy
Reply with quote
Larkin
Wizard


Joined: 25 Mar 2003
Posts: 1113
Location: USA

PostPosted: Wed Apr 19, 2006 12:46 pm   
 
If you're making the change to allow us to declare parameters for aliases, I have a couple of questions.

1. Will we be able to use the pattern matching syntax to define what the alias should match on? As in, will this allow multiple aliases with different argument signatures?

Code:
#ALIAS test($arg1:\d+) {#say You entered a number.}
#ALIAS test($arg1:\a+) {#say You entered some letters.}


2. Is there a varargs capability for accepting "leftover" arguments as the last parameter?

Code:
#ALIAS test($arg1, $arg2, ...) {#say Varargs contains $varargs.}


Obviously, I'm still hoping for some way to overload my aliases without overloading the code inside one alias to check all sorts of parameters. If it can be done at the parameter matching level, it makes my coding much easier. If it supports real regex patterns, I can even restrict certain aliases to exact keywords as arguments (e.g., "reset" and "reset affs" and "reset defs" and "reset bals" etc).
Reply with quote
Zugg
MASTER


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

PostPosted: Thu Apr 20, 2006 5:28 am   
 
Larkin: First, no, there won't be anything fancy in the argument list. The argument list is used at compile-time to parse the references within the script and is not used at runtime, so there is no way to implement regex aliases in this way. That will have to wait until a later time to find some way to implement.

And yes, we need some sort of "varargs" as you mentioned, but I will probably use a function rather than inventing yet another wierd syntax. It would be really straight-forward to have a %args function that takes an argument of the argument name or number to start with (or leave the argument out to get all unreferences arguments).

So, %args(1) would be the same as %-1, %args($argref) would give everything from $argref to the end of the command string, and just %args would give you everything in the command line after the declared arguments.
Reply with quote
Zugg
MASTER


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

PostPosted: Thu Apr 20, 2006 5:48 am   
 
Oh, I've also come across something a bit tricky in all of this.

Remember how I started the thread talking about how %1..%99 would be expanded just like normal variables rather than doing a string-replace before parsing? Well, that's not quite true. It mostly works this way, but when you use an argument reference within a stored command script of something like an Alias or Trigger definition, then the argument reference is still working as a string substitution.

For example, lets go back to our Make alias example:
Code:
#ALIAS make ($spell) {#ALIAS $spell ($target) {cast $spell $target}}

OK, this is a nice and clear example now with named arguments. But let's examine how each argument is expanded. When you type:

make heal

then "heal" is assigned to $spell and the "make" alias is executed. This alias executes the following command:

#ALIAS $spell ($target) {cast $spell $target}

Now, the first $spell reference is expanded as a local variable as expected. But what about the "cast $spell $target" value to be stored in the new alias? When this is parsed, the $spell reference is replaced as a string substitution, much like the %1..%99 in zMUD. So we end up with this compiled code:
Code:
VARREF $spell
PUSH "cast heal $target"
CMD #ALIAS

In other words, the value of $spell (heal) is pushed onto the runtime stack as the first argument of the #alias command, and the string "cast heal $target" gets put on the stack as the second argument to the #alias command.

Notice that the $spell reference in the second argument was expanded immediately and concatted with the rest of the string. This is needed because when the new "heal" alias is executed, the $spell variable from the original make alias is gone.

Let's look at a more complex example to emphasize this point:
Code:
#ALIAS test ($arg) {
  #VAR varname $arg
  #ALIAS new {cast $arg}
  }

and then type:

test "heal me"

OK, so "heal me" gets assigned to the $arg argument. Now, in zMUD, the #VAR command would be a problem because in zMUD the argument is expanded before parsing, so you would get "#VAR varname heal me" and "heal" would be assigned as the value and "me" would be assigned as the default. A common zMUD problem.

But in CMUD, arguments are normally expanded at run time *after* parsing, so in CMUD the correct value of "heal me" is stored in @varname.

But now look at the embedded alias command. In this case, CMUD works just like zMUD and $arg is expanded immediately before the new alias is compiled. In both zMUD and CMUD you get the command:

#ALIAS new {cast heal me}

Sorry if this is a bit confusing to explain. But trust me that it seems to work well as expected. Most of the zMUD problems with arguments are fixed. However, it's important to understand this last example. Imagine if we typed the following:

test "heal;drop all"

In this case, the value "heal;drop all" probably gets assigned to @varname. However, the embedded alias definition now becomes:

#ALIAS new {cast heal;drop all}

So it's still important to understand these embedded command blocks, like in #alias, #trigger, etc. Whenever you are storing a series of commands that are going to get compiled later, arguments are expanded as strings just like in zMUD.
Reply with quote
Vodoc
Apprentice


Joined: 11 Apr 2003
Posts: 119
Location: Sweden

PostPosted: Thu Apr 20, 2006 7:19 am   
 
Zugg wrote:
And yes, we need some sort of "varargs" as you mentioned, but I will probably use a function rather than inventing yet another wierd syntax. It would be really straight-forward to have a %args function that takes an argument of the argument name or number to start with (or leave the argument out to get all unreferences arguments).

Doesn't this already exist in %param and %numparam? I remember that those functions are (or was) a little buggy though.
Reply with quote
Zugg
MASTER


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

PostPosted: Thu Apr 20, 2006 5:45 pm   
 
Well, yes, you could make a loop and go through %param and concat them together. But this is a pain and what Larkin is saying (and I agree) is that there needs to be some equivelant to %-1 for the new named arguments. And rather then inventing another wierd syntax, just using a function call is what I'm suggestion.

To, to clarify: %args(1) doesn't just return the 1st argument...it returns everything from the 1st argument to the end of the command line, just like %-1 does. This should not be confused with %param(1) which only returns just the 1st argument.

Also, with the changes to %1..%99 in CMUD, the bugs in the %param function should be solved.
Reply with quote
Zugg
MASTER


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

PostPosted: Sat Apr 22, 2006 2:22 am   
 
OK, I got all of this Local variable and Named Arguments stuff implemented and working in CMUD today.

One thing that I had to do was slightly change the syntax for declaring an argument list for an Alias or Function. You MUST put the argument list right after the name of the alias/function without any extra spaces.

In other words, the syntax looks like this:
Code:
#ALIAS make($spell) {#ALIAS $spell($target) {cast $spell $target}}
#FUNCTION add($a,$b) ($a+$b)

The first example shows our "make" alias that we have been talking about. The second example shows a function that adds two numbers together. You can see why I needed to require no spaces before the argument list. If a space was allowed before the argument list, then the parser wouldn't be able to tell the difference between the argument list and the actual expression text.
Reply with quote
Vodoc
Apprentice


Joined: 11 Apr 2003
Posts: 119
Location: Sweden

PostPosted: Sat Apr 22, 2006 8:40 am   
 
Does it handle defaults, for example can I do this?
Code:
#FUNCTION add($a,$b=34) ($a+$b)

thus only having to provide $a when calling the function unless I want to provide both $a and $b
Reply with quote
Rainchild
Wizard


Joined: 10 Oct 2000
Posts: 1551
Location: Australia

PostPosted: Sat Apr 22, 2006 11:42 am   
 
Is it possible to allow spaces after the opening bracket and between args? ie:

Code:
#ALIAS make( $spell, $reagent ) {
  #ALIAS $spell( $target ) {
    get $reagent from backpack
    cast $spell $target
  }
}


I mean, so long as the bracket is touching, everything inside the bracket must be an argument therefore you can ignore whitespace until you reach the close bracket?

There's 2 reasons why I'm asking...
1) is because it's clearer to see, especially when you got a handful of arguments
2) is because of long definitions it would be nice to be able to have spaces and multiple lines if necessary...

Code:
#ALIAS bot_move(
  $destination_name,
  $pickup_collectables_en_route,
  $flee_mobs_en_route,
  $flee_pkill_en_route
) {
  ...
  #SELECT( $destination_name )....
  #IF( $pickup_collectables_en_route )....
  ... and so on
}
Reply with quote
Zugg
MASTER


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

PostPosted: Sat Apr 22, 2006 4:44 pm   
 
No, you cannot assign defaults for the arguments, although I'll try to see if something like that can be added in the future. Right now the argument list is purely a compile-time directive and not a run-time command.

Rainchild, yes, you can have spaces anywhere else that you want. Just not between the alias name and the opening (. So putting spaces after the ( or between the comma, or before the end ) are all just fine.

However, you cannot put line breaks between them. Line breaks are still very tricky to handle in the parser.
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Goto page Previous  1, 2
Page 2 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