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: Tue Aug 01, 2006 10:05 pm   

Problem with new Module/Package stuff
 
Decided to make a new topic since this is really a different problem that what we were talking about before. However, if you haven't read the thread on the Multiple Session design discussion, then you should read that thread first.

OK, the new problem that I've found in the code concerns referencing variables and other settings using the new module scheme.

Remember that @/varname is supposed to retrieve the varname within the "root" class. OK, if we make the assumption that the "root" class is the current module, then how do we refer to variables in a module outside our current module.

If we require @/modulename/varname to access a variable in the top level of a specified module, then how does CMUD distinguish between "modulename" as a module vs it being a class within the current module.

In other words, imagine the following structure:
Code:
ChatModule
  ChatVar
MainModule
  ChatVar
  MyAlias

OK, so now we want to write MyAlias to access the ChatVar variable. To handle backwards compatibility with zMUD aliases, then obviously @ChatVar refers to the variable in "MainModule". Likewise, @/ChatVar should also refer to the ChatVar variable in the MainModule since this is the "current module" when MyAlias is running.

If MyAlias wanted to access the ChatVar variable in the ChatModule, it seems natural to use the syntax @/ChatModule/ChatVar. However, now imagine that we add a class folder within the MainModule called "ChatModule". I know this sounds stupid, but it possible that a class folder in one module might have the same name as a module name.

So if we have:
Code:
ChatModule
  ChatVar
MainModule
  ChatModule (class folder)
    ChatVar
  ChatVar
  MyAlias

then how does CMUD resolve @/ChatModule/ChatVar now when running MyAlias? For backwards compatibility it seems like this *must* access the ChatVar variable within the ChatModule class folder. But this means there is no way to access the ChatVar in the ChatModule *module*.

In other words, we have an ambiguous syntax now. And CMUD hates ambiguous syntaxes. Not sure how to solve this.
Reply with quote
Tech
GURU


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

PostPosted: Tue Aug 01, 2006 10:34 pm   
 
I suspect you know and were hoping to avoid it but you probably have to introduce new syntax. I reccomend going with a colon (:), since it may be a bit more intuitive for those accustomed to referencing windows.

In other words @/ChatModule:ChatVar will reference ChatVar in Chat module and @/ChatModule/ChatVar will reference the ChatVar in the class folder ChatModule of the module MainModule.

Taking it one step further what if we had
Code:
ChatModule
  ChatVar
  MainModule (class folder)
    ChatVar
  OtherFolder (class folder)
    ChatVar
MainModule
  ChatModule (class folder)
    ChatVar
  ChatVar
  MyAlias


Now Consider
1. @/ChatModule:MainModule/ChatVar
2. @/ChatModule:OtherFolder/ChatVar

1 will reference ChatVar in the MainModule class folder of the ChatModule and 2 will reference the ChatVar of the OtherFolder class folder in that same module.

Now alternatively you could have gone with something @ChatModule:/ChatVar or @:ChatModule/ChatVar but I think those options are a) more ambiguous, b) more like to create parsing hiccups and c) more different from what is currently present.

I loved my compilers class. Very Happy
_________________
Asati di tempari!
Reply with quote
Zugg
MASTER


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

PostPosted: Tue Aug 01, 2006 11:19 pm   
 
Hmm, interesting idea. Actually, I'd probably go with the @ChatModule:/ChatVar syntax. It is basically the same as disk drive file name conventions and in a sense the Module is like the disk drive. I'll give that some more thought and listen to more suggestions. But it makes sense that if you don't specify the "drive" then it uses the current default "drive" (module).

I've also run into another problem. These problems are coming up as I try to convert existing *.MUD files. Anyway, the new problem is that existing *.MUD files already have their own duplicate copy of the Default Settings. zMUD didn't have any concept like packages or modules and it just stored everything to the MUD file, including a copy of inherited settings in some cases. This might also explain some problems with zMUD.

It's possible that zMUD doesn't do this anymore. My SAMPLE.MUD file is fairly old. But it's still a valid MUD file and CMUD still needs to read it correctly.

So, the problem I need to solve is how to deal with a *.MUD file being imported that contains settings already duplicating those in the Default package. It somehow has to be smart enough to determine what is really a duplicate, and what is an overridden setting.

I can't believe how messy this is getting.
Reply with quote
Zugg
MASTER


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

PostPosted: Tue Aug 01, 2006 11:23 pm   
 
Oh, and the other thing I like about the Module: syntax is that it matches the same syntax used to send stuff to other windows. And since Windows and Modules are the same thing, this makes sense.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Aug 01, 2006 11:27 pm   
 
The zMud syntax was @window.variable. I don't believe this was ever adjusted to work with the '/' class character. I personally find that notation very workable and have a very large number of scripts that actually depend on it.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
yejun
Wanderer


Joined: 13 Jun 2005
Posts: 51

PostPosted: Tue Aug 01, 2006 11:31 pm   
 
With so many changes already break backwards compatibility, I won't worry about this.
Reply with quote
yejun
Wanderer


Joined: 13 Jun 2005
Posts: 51

PostPosted: Tue Aug 01, 2006 11:56 pm   
 
I have a question about this scheme.

Is MainModule actually named "MainModule" or it is different for each window?

If MainModule will be a different. How can an alias @ChatModule:/Alias1 to access @MainModule:/c1/var1 if it does not know the actual name of MainModule?
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 12:46 am   
 
Vijilante, the problem with the @window.variable syntax is that it conflicts with the @Comobject.property syntax. So again, this would cause an ambiguous parser and would result in kludges like zMUD had. So I'm not sure I can support that syntax anymore.

yejun, I *always* try and look at each and every case and try to come up with a solution that is as compatible as possible. It's not right to just say "Well, enough stuff has already changed so I don't have to worry about it". We've discussed this in this forum before...zMUD compatibility is VERY IMPORTANT in CMUD. Without a high level of compatibility, many people will not switch to CMUD. So far, the items that are not compatible are minor and limited to pretty advanced syntax or scripts. But I never just dismiss something if I can think of a way to do it so that it's compatible.

About the "MainModule", that was just my example. Obviously the name of the module is set to whatever you want. In fact, it defaults to the name of your *.MUD file when you import existing zMUD settings.

So, you are correct: there is no way for an Alias in ChatModule to access a variable in the MainModule if you don't know the name of the module. But this goes back to the "instanced" vs "static" issue. If something is declared as an "instance" within ChatModule, then it really creates a setting within the current window/module, rather than within the ChatModule.

Most of the time, your ChatModule will already know the name of the MainModule in your specific settings. If you are trying to design a general-purpose *PACKAGE* then you want to keep your package independent of other packages, so you'd never want to reference a specific variable within the Main Module. Instead, you'd set up a variable in your package that is marked as "instanced" and that would allow it to create a variable specific to a window instead of creating a variable within your package.

Finally, you could still use "indirection" to handle the case where you didn't know the window name. Something like @{@windowname":/c1/var1"} would cause CMUD to first expand the @windowname variable, then append ":/c1/var1" and then treat this is a variable name. Not really a recommended syntax since you really should'nt be accessing variables directly like this when they are outside of your module.
Reply with quote
edb6377
Magician


Joined: 29 Nov 2005
Posts: 482

PostPosted: Wed Aug 02, 2006 1:38 am   
 
Zugg one thing to say on compatibility. I think the ideal solution is not to work so much on compatibility but to work on proper conversion of ZMUD .mud files. Then when they look at their script in CMUD it has the current valid syntax and you wont have a compatibilitiy issue but at the same time you wont have things being kludged to make compatibility work.

I like this very much
Code:

Now Consider
1. @/ChatModule:MainModule/ChatVar
2. @/ChatModule:OtherFolder/ChatVar


it gives us a easily definable system to work from. Each module can be called as can each package if i understand it correctly.

I would definatly work on conversions but for this type of syntax it might be best to let people define all that. They will have to seperate their mud file into packages anyways.
_________________
Confucious say "Bugs in Programs need Hammer"
Reply with quote
Rainchild
Wizard


Joined: 10 Oct 2000
Posts: 1551
Location: Australia

PostPosted: Wed Aug 02, 2006 7:21 am   
 
Maybe @ChatModule://MainFolder/ChatVar would be best eg keep it with the typical http:// ftp:// type of syntax since we're already using /'s as opposed to \'s.

Or perhaps just @//ChatModule/MainFolder/ChatVar as shorthand ...

Either way you are going to have to specify a rule for 'what happens if' you provide an invalid global module name (or maybe one which is disabled, not loaded, or simply non-existant). Will calling up a varialbe inside ChatModule throw a compile time error if the module isn't available? Will it throw up a run-time error if the module becomes unavailable? Or will it just 'ignore' and treat any reference to it as "" or NULL or 0 or even type it out in full?

Will this syntax also apply to $variables and %customfunctions (if there is such a thing?)?.

The more I consider the suggested syntaxes the more @// makes sense - it's simple and like the protocol://server/folder/file syntax that everyone is used to. But is it easy enough to tell the parser the difference between @/ and @// ?


Edit: this is kinda related but might be a second topic on its own. What if we want to call an alias from a different module, or perhaps enable/disable triggers in a different module? Would an @alias://module/folder/alias and a @var://module/folder/variable syntax make sense (defaulting to @var:// if you just used @//)?
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 12:44 pm   
 
edb6377: Creating a program to convert zMUD scripts into CMUD scripts would be almost as hard as just handling the syntax in CMUD in the first place. The entire problem with zMUD scripts is that the syntax is ambiguous. That's why I couldn't create a compiler for it, and that's why the syntax checker in zMUD has so many problems. Most of the differences between zMUD and CMUD are context-specific and cannot be automatically converted. While I've talked about possible conversion "helpers", I've never promised a full automatic convertor. As I said, if I could do this then I'd just build it into CMUD and CMUD would then be perfectly compatible.

Besides, you do *not* need to separate MUD files into packages. Packages are only needed by advanced programmers who want to distribute general standalone functionality via the Shared Package Library. CMUD handles the package and module generation for normal users just like zMUD handled *.MUD files. So the average user doesn't have to worry about packages. When you first load a *.MUD file, CMUD converts it to a *.PKG file and the next time you load CMUD, the *.PKG file gets loaded automatically.

RainChild: Your suggestions are interesting. The @//Module/Folder/Var syntax is certainly the easiest to parse. With @Module:/Folder/Var the parser doesn't know it's dealing with a module name until it parses the :, whereas with the @// syntax, it knows right away. So I kind of like it. I *don't* like the @Module://Folder/Var syntax since the extra / isn't needed and just adds extra characters, and confusing the module/folder/var reference with a URL is probably not a good idea. If I ever wanted to do anything with parsing real URLs, I might run into conflicts in the parser again.

Also, you don't need complicated stuff like @alias: or @var:. The @ character already specifies that we are accessing a variable. To execute an alias in a different module, you would just use the //module/class/alias syntax. And to disable a class in another module I can certainly support syntax like #CLASS //module/classname 0

$variables are always local and only exist within a runtime context, so it doesn't make any sense to try and access local variables in another module...they don't exist. And remember that %function is only for system-defined functions. To access user-defined functions you still always use the @ character, so @//module/class/function(param) would be supported.

The more I think about the //module/class syntax the more I like it. And actually, the existing parser will already handle this to some extent. So the change needed to support this would be pretty minor.
Reply with quote
yejun
Wanderer


Joined: 13 Jun 2005
Posts: 51

PostPosted: Wed Aug 02, 2006 1:15 pm   
 
In zMud when user load a .mud file, the previous one will be replaced. What happens when a user load a new .mud file in CMUD? Actually I dunno why you keep ".mud" in module name.

Since module are identified by file name, it seems that I cannot load 2 ".mud" with same name at different location.


Last edited by yejun on Wed Aug 02, 2006 1:21 pm; edited 1 time in total
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 1:20 pm   
 
In CMUD, when you load a *.MUD file, it gets converted to the *.PKG package file. Any changes that you make to your settings are automatically saved to this *.PKG database file in the background. So, essentially it's always replacing it, just like zMUD did with the MUD file.

The .mud is currently in the module name to remind people that the module was converted from a zMUD *.MUD file.
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 1:24 pm   
 
The @//Module/Class/var syntax has another advantage. yejun was asking about how to refer to a module without knowing it's name...well, to refer to the *current* module/window, you can simply omit the Module name in this syntax, resulting in @///Class/var

It's a bit odd, but it makes sense from the parser point of view. This is essentially how you might refer to an "instanced" variable from within a general purpose utility module. For example, consider our past example of a "HeathBar" module that creates a gauge for your hitpoints. Instead of referencing @hp, which would be a variable within the HealthBar module, it could reference @///hp which would be the @hp variable in whatever module window is currently executing.
Reply with quote
yejun
Wanderer


Joined: 13 Jun 2005
Posts: 51

PostPosted: Wed Aug 02, 2006 1:48 pm   
 
In zmud I can use Alias, Variable inside one classes from another class simply using @var1 instead of @/class1/var1 if class1 is enabled. This kind usage gave me bugs, sometime those variable will be duplicated hundreds of times in root when class1 acually disabled.

So if I have /class1/var1 and /class2/alias1 in CMUD, what will be the correct syntax to use var1 in alias1 except @/class1/var1? If I use @var1 in alias1, what will happen? And what happens if class1 is disabled.

I think you solved instance variable problem, but what about trigger/class state?
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 2:24 pm   
 
Obviously, for zMUD compatibility you can still do just @var1 and it will search the enabled classes just like it does now. It starts in the current class, then searches the parent class, then the parent, until it gets to the top module. If it still hasn't found a variable with that name, then it starts searching the enabled packages, in order that they were loaded, looking at the top level of each module, or within any class that has the "Published" flag set.

If it still doesn't find the variable, than the variable is created in the top of the current module, unless the current class has the "Set this class as default" option enabled, in which case the variable is created in the current class.

All of this remains the same in CMUD as in zMUD except that CMUD is a bit better defined in how it searches outside of the current class.

In any case, in zMUD you should never get "duplicated hundreds of times in root when class1 is disabled". zMUD should never duplicate variables. It might create a variable in root if class1 is disabled, but it shouldn't create the variable more than one. But if you are talking about different variables, then yes, it will work the same way in CMUD. If a class is disabled and you access a variable using the simple @var syntax, then a new variable will be created in the top level or in the current class.

The way around this has always been to specify the full path /class1/var1. If class1 is disabled, this will return a null value. At least that is what zMUD *should* be doing, and it's certainly what CMUD will do.

To summarize: If class1 is disabled, @var1 searches enabled classes for a match and if none is found, creates @var1 in the top level of the module. @/class1/var1 returns a null value.
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 2:24 pm   
 
And yes, I am up *waaaayyy* too early this morning. I couldn't sleep last night thinking about all of these bugs and decided to just get up early and see if I could make some progress.
Reply with quote
yejun
Wanderer


Joined: 13 Jun 2005
Posts: 51

PostPosted: Wed Aug 02, 2006 3:01 pm   
 
Hundreds of duplicated of variable really happens to me when I run a session for a long period of time. It took me a while to delete all of them. They are all disabled variable in root. I think because all those variables are actually disabled, it is not seen by script, a new one will be created each time. But I do not know how those variables were disabled at first place. I think I solved this problem by moving all cross referenced variable to root. Anyway, these are just for zmud.
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 3:34 pm   
 
That would make sense. If the variable itself somehow got disabled, then zMUD would never see it and would create another one. I have no idea how you got the variables disabled unless you have a bad #T- command somewhere.
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 5:36 pm   
 
Well Rainchild, you win this one. Implementing your suggested @//Module/Class/Var syntax only took about an hour (and that includes allowing the module to be missing to refer to the current module). The parser only needed a minor change to allow @///var...it actually already handled the @//Module/Class/Var syntax (in other words, it already allowed for // but needed a small change to allow ///)

The implementation fit very nicely into the existing code without any kludges. I have a routine that takes a full path and returns the class folder pointer that it refers to, and this routine already parsed through the /class subfolders. It was a simple change to first check for // to indicate the module instead of just using the current module.

Also, this is the same syntax used in Windows to refer to a remote server in a file path: //server/path, so it even makes sense.
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 5:47 pm   
 
Hmm, I did find a parser conflict. It's an issue with the // inline comments. Look at this:
Code:
#var //module/var value

The parser thinks that the // is the start of an inline comment.

So, I had to add a "fix" so that it scans the comment to see if there is another / before the next space.

Hmm, this also reminds me that currently this all requires your ModuleName to NOT contain spaces. Looks like I'll probably need to allow quotes around the module name to allow spaces there.

It's always something.
Reply with quote
Tech
GURU


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

PostPosted: Wed Aug 02, 2006 7:05 pm   
 
Yup.. it's always something and Zugg always fixes it. Very Happy Give our regards to the Mrs. and the namesake of our new MUDding obsession. Smile
_________________
Asati di tempari!
Reply with quote
yejun
Wanderer


Joined: 13 Jun 2005
Posts: 51

PostPosted: Wed Aug 02, 2006 7:37 pm   
 
Does it also makes "//a/b" an invalid comment?
I think you could make parser not accept a comment before a complete statement ends, b/c #var alone is not a valid statement.
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Aug 02, 2006 9:26 pm   
 
yejun, yes, it would make "//a/b" an invalid comment. The problem is that with the way yacc parsers work, at the time it determines if the // today is a comment token or not, it has no way to know if the statement is "complete". The // is handled by the "lexical" analyzer, while the statement syntax is handled by the token parser. You never want to have a language where the lexical analyzer needs intimate knowledge of the parser syntax rules. That's where you end up with non-deterministic languages like the original zMUD scripting language.

But don't worry, this only happens when the lexical analyzer is in the middle of processing a "name/id" token. Look at the F1 help for the #VAR command and you'll see that the first argument is a "Name" type. This is the only argument type that allows the // syntax to represent the start of a variable name without the initial @ character. So, *most* of the time you comment will work fine, just not when a Name is expected.

And actually, #var by itself *is* a valid statement...it displays the list of variables in the MUD window. That's exactly how I discovered the problem since some test cases where displaying the variable list insted of executing correctly.

Of course, if someone actually cares about this obscure case, they can always change their "Class Character" to something different than the / character.
Reply with quote
Larkin
Wizard


Joined: 25 Mar 2003
Posts: 1113
Location: USA

PostPosted: Wed Aug 02, 2006 9:59 pm   
 
Personally, I'd vote to get rid of inline comments completely. I find them rather pointless in my MUD scripts, especially once they're imported and being used. I put comments in my source files that I import by using #NOOP at the beginning of the line, sort of an undocumented feature for doing documentation of your code. ;)
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