Jump to content


Photo

Question about local variables


  • Please log in to reply
8 replies to this topic

#1 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 10163 posts
  • Version:GM8

Posted 26 February 2012 - 09:16 PM

Suppose I have a script like so:


var A, B, C, D;
A=0;
B=0;
C=1;
internal_script();
D=B;

And in internal_script() I have:

A+=max_lives;
B=A<<3;
B-=C;


First question: would A, B, and C as declared locally in the parent script carry into internal_script() since it is embedded inside the parent script?

Second question, which will be moot if the first question is answered in the negative: Suppose I had the following script this time:

internal_script();
var D;
D=A;

And internal_script() would have the following code in it:

var A, B, C;
A=max_lives;
B=stage;
C=A<<B;
A=C;

Would A, B and C -- being declared locally in internal_script() -- carry into the parent script?

Edited by TheouAegis, 02 March 2012 - 12:57 AM.

  • 0

#2 twelveways

twelveways

    GMC Member

  • GMC Member
  • 1383 posts

Posted 26 February 2012 - 09:43 PM

It would have probably been easier just to test this yourself rather than type the question...
  • 0

#3 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 10163 posts
  • Version:GM8

Posted 26 February 2012 - 09:59 PM

Yeah I went and tested it. Typing gives me ideas on ways to test.

So okay since I answered my own question, I have a new question.

Suppose I have a script like so:

//Parent Script
child_script1();
child_script2();
child_script3();
child_script4();
exit;

Is there any way to make a set of variables that can be passed between the four child scripts but that will be freed from memory upon completion of the last one?
  • 0

#4 twelveways

twelveways

    GMC Member

  • GMC Member
  • 1383 posts

Posted 26 February 2012 - 10:04 PM

use vars and pass them as arguments

//scr_0
var a;
a=1
scr_1(a)

//scr_1
var b;
b=argument1 + 1
scr_2(b)

etc

what was the answer to your first question?
  • 0

#5 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 10163 posts
  • Version:GM8

Posted 28 February 2012 - 07:02 AM

The answer was "no and no".

Ugh stupid arguments. Gonna have to remember which scripts use variable 1 as argument0 and which use variable 1 as argument 2. I can forsee me programming many bugs into this script.

...I can't elaborate on the script because I'm walking a thin line in the GMC forums right now, I think.
  • 0

#6 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 10163 posts
  • Version:GM8

Posted 01 March 2012 - 05:02 AM

Okay, I just realized I forgot to mention something:

The subscripts change the parent script's variables, so I don't think I can use arguments. I mean, saying "argument0=24" won't affect whatever variable was designated as argument0, just make any references to argument0 for the rest of the script set to 24, right?

The scripts would look like this (and you'll see my problem):

var check1,check2,store1,store2;
script1(check1,check2,store1);
script2(check1,check2,store2,store1);
return store1

in script1:
argument2=argument0<<2;
argument0+=argument1>>1;

in script2:
argument2=argument3 & $F;
argument3=argument0+argument1;
argument3+=argument2;


So is there any way to do this without globalizing all the variables?

Edited by TheouAegis, 01 March 2012 - 05:06 AM.

  • 0

#7 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 10163 posts
  • Version:GM8

Posted 02 March 2012 - 01:09 AM

Bump.

I kinda need to get this ironed out, because my script ultimately hinges upon this problem.

For clarification, here is what is currently going on in my script(s):


I have some short, bitwise operation scripts that simulat 6502 assembly, meaning a bitwise shift to the right is a Logical Shift Right and a bitwise shift to the left is an Arithmetic Shift Left, meaning whatever bit is removed is instead added to a "carry flag", which in the script is simply a variable. Currently it's set as a global variable created at the start of the game, but I would like if possible to not have to do that and just keep the carry flag localized in the script.

The primary script (which I called the parent script previously) has a bunch of different operations -- maths and stuff, manipulating different variables, some local. I figured I'd just say "screw it" with all the trying to pass local variables between scripts and just have duplicate code inside the two parent scripts. Yes, TWO parent scripts: one for encrypting the password and one for decrypting the password; both parent scripts share a snippet of code which up until this point I was trying to reference as an external (i.e., child) script, but couldn't because it involved passing local variables between two scripts.

The problem I've stumbled into now is that the special bitwise operation scripts need to be called in the primary scripts. The bitwise operation scripts actually manipulate two variables, the carry flag and the argument. The argument isn't an issue, because I can just use something like, "vA=lsr(vA)". But I need to be able to have the value of C_flag (the carry flag variable) available for use in the primary script as well as the other bitwise operation scripts rol() and ror(), which perform bitwise rotations and require use of the carry flag.

I would prefer to not make the C_flag a globalvar because it only has use inside these sets of scripts and nowhere else in the game (well, so far).

Here's an example snippet of what I'm talking about.
stage=vA;
vA=lsr(vA);
v000=rol(v000);
vA=v01a;
vA=lsr(vA); //C_flag is 1 if bit 0 is 1 before this step
repeat(3) v000=rol(v000); //C_flag is 1 if bit 7 is 1 after the 2nd execution
if C_flag    vX=vA; //Checks the C_flag value at the end of the previous step
//Logical Shift Right
//use: lsr(value)
C_flag = argument0 & 1;
return (argument0 >> 1) & $FF
//Bitwise Rotation Left
//use: rol(value)
var C;
C = C_flag;
C_flag = floor((argument0 << 1)>>8);
argument0 = ((argument0 << 1) & (1 << 8)-1) | C;

Edited by TheouAegis, 02 March 2012 - 01:27 AM.

  • 0

#8 torigara

torigara

    GMC Member

  • GMC Member
  • 6507 posts

Posted 02 March 2012 - 06:11 AM

For starters, just to answer the first question, local variable are invented as opposed to your purpose so that they never carry between scripts. Imagine that local variables declared with "var" were carried between scripts, and suppose that you were writing a general-purpose script that can be used anyone. Now you must think out local variable names very carefully; for example, you could no longer use "i" for your loop counter because it would overwrite the "parent" scripts's i when called from inside a loop. You would end up in choosing some random name, say i_j8314jfs4123, hoping that no one else in the world would use the same name. That's just the second advent of global-variable hell.

If you want to take multiple outputs out of a script, try making the script return those outputs packed into one value. For example:
//Logical Shift Right
//use: lsr(value)
//return value: (C_flag << 8) | (shifted value)
var C;
C = argument0 & 1;
return ((argument0 >> 1) & $FF) | (C << 8);
//Bitwise Rotation Left
//use: rol(value, C_flag)
//return value: (C_flag << 8) | (rotated value)
var C;
C = floor((argument0 << 1)>>8);
argument0 = ((argument0 << 1) & (1 << 8)-1) | (C << 8);
Then unpack it each time you call a script. E.g.:
var C;
C = 0;

stage = vA;
vA = lsr(vA, C);
C = vA >> 8; vA &= $FF; // Unpack the return value

v000 = rol(v000, C);
C = v000 >> 8; v000 &= $FF; // Unpack the return value
...

If you don't like to pack and unpack values each time, you can simulate "pass by reference" method by passing a data structure that contains values, So the child script can modify the value in the data structure. E.g.:
//Logical Shift Right
//use: lsr(value, list)
//where the first element of list is the carry flag.
ds_list_replace(argument1, 0, argument0 & 1); // Set the carry flag
return (argument0 >> 1) & $FF; // Return the shifted value
Call it like this:
var registers;
registers = ds_list_create();
ds_list_add(registers, 0); // The first element is carry flag

vA = lsr(vA, registers);
v000 = rol(V00, registers);
...
// Check the C flag at the end
C_flag = ds_list_find_value(registers, 0);
if (C_flag) vX = vA;
ds_list_destroy(registers);

Edited by torigara, 02 March 2012 - 06:17 AM.

  • 0

#9 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 10163 posts
  • Version:GM8

Posted 02 March 2012 - 08:00 AM

Ooh hadn't considered a data structure. I'll think about that one a bit. Packing and unpacking seems like it wouldn't really be saving me much hassle. Well, neither option saves me much hassle.

Ok, so the d.s. method looks cleaner to me, but my next question is which method would be better memory-wise? For packing/unpacking, that's clearly a single local variable, but would expanding to a 9th bit (I remember your answer about this in my other thread) be even more memory-intensive than a list or less intensive?
(I was asking other stuff but I figured out the answers to the other stuff.)

Screw it, now I'm just overcomplicating things. DS method it is. Thanks again Tori.

WHOA! I just noticed I joined GMC on May 5, 2005! 05/05/05!

Edited by TheouAegis, 02 March 2012 - 08:12 AM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users