Results 1 to 5 of 5

Thread: Help with types and variables

  1. #1
    Join Date
    Dec 2011
    Location
    East Coast, USA
    Posts
    4,231
    Mentioned
    112 Post(s)
    Quoted
    1869 Post(s)

    Default Help with types and variables

    Consider the following code:

    Simba Code:
    1. program new;
    2.  
    3. type TFoo = record
    4.   foo: integer;
    5. end;
    6.  
    7. type TBar = record
    8.   bar: TFoo;
    9. end;
    10.  
    11. procedure TFoo.doSomething();
    12. begin
    13. end;
    14.  
    15. function TBar.getFoo(): TFoo;
    16. begin
    17.   result := self.bar;
    18. end;
    19.  
    20. var
    21.   baz: TBar;
    22.  
    23. procedure test();
    24. begin
    25.   baz.getFoo().doSomething();
    26. end;
    27.  
    28. begin
    29.   test();
    30. end.

    This code in its current state will produce this:
    Code:
    Error: Variable expected at line 25
    Compiling failed.
    Change line 25 to this:
    Simba Code:
    baz.bar.doSomething();

    And and we are able to compile successfully.

    Code:
    Compiled successfully in 1550 ms.
    Can anybody explain this to me?

    Edit:

    Changing line 11 to:
    Simba Code:
    procedure TFoo.doSomething(); constref;
    will achieve successful compilation without editing line 25. However, in practice, appending constref; to many typed functions across a large code base seems to be problematic, as it produces other compilation errors in several places elsewhere in my include. This does not seem to be the cleanest solution, surely there must be another way?

    Edit 2:

    Here's an example of what I mean when I say adding constref; causes issues elsewhere. If we refine the example code at the top of this post to be the following:

    Simba Code:
    1. program new;
    2.  
    3. type TFoo = record
    4.   foo: integer;
    5. end;
    6.  
    7. type TBar = record
    8.   bar: TFoo;
    9. end;
    10.  
    11. procedure TFoo.doSomething(); constref;
    12. begin
    13.   self.foo := 1234; // Added this line, changed nothing else
    14. end;
    15.  
    16. function TBar.getFoo(): TFoo;
    17. begin
    18.   result := self.bar;
    19. end;
    20.  
    21. var
    22.   baz: TBar;
    23.  
    24. procedure test();
    25. begin
    26.   baz.getFoo().doSomething();
    27. end;
    28.  
    29. begin
    30.   test();
    31. end.

    I now recieve the error
    Code:
    Error: Target cannot be assigned to at line 13
    Deleting the constref; puts me right back where I started, with a "Variable expected" error. Seems like it's either "Variable expected" when constref; is omitted, or "Target cannot be assigned to" when constref; is included.

    What is going on?
    Last edited by KeepBotting; 12-06-2017 at 12:15 PM.
    GitLab projects | Simba 1.4 | Find me on IRC or Discord | ScapeRune scripts | Come play bot ScapeRune!

    <BenLand100> we're just in the transitional phase where society reclassifies guns as Bad™ before everyone gets laser pistols

  2. #2
    Join Date
    Sep 2008
    Location
    Not here.
    Posts
    5,422
    Mentioned
    13 Post(s)
    Quoted
    242 Post(s)

    Default

    You need to initialize the variable if you want to use self.bar

  3. #3
    Join Date
    Dec 2011
    Location
    East Coast, USA
    Posts
    4,231
    Mentioned
    112 Post(s)
    Quoted
    1869 Post(s)

    Default

    Quote Originally Posted by tls View Post
    You need to initialize the variable if you want to use self.bar
    Could you provide an example, please? I have a hard time understanding things until they're shown to me at least once.
    GitLab projects | Simba 1.4 | Find me on IRC or Discord | ScapeRune scripts | Come play bot ScapeRune!

    <BenLand100> we're just in the transitional phase where society reclassifies guns as Bad™ before everyone gets laser pistols

  4. #4
    Join Date
    Feb 2012
    Location
    Norway
    Posts
    995
    Mentioned
    145 Post(s)
    Quoted
    596 Post(s)

    Default

    It's all just wrong. Records are not classes, passing of records results in copies, not references.

    Simba Code:
    function TBar.getFoo(): TFoo;
    begin
      result := self.bar;
    end;
    The result of that is a copy of self.bar


    Simba Code:
    procedure TFoo.doSomething();
    begin
      self.foo := 1234;
    end;
    That alongside:

    > baz.getFoo().doSomething();

    Makes no sense, since baz.getFoo has returned a copy, a temporary (none-writable) variable that only exists in the darkest of shadows, it's not a reference to `baz.bar`.


    The argument modifier `constref` is something you apply to the method description.
    Simba Code:
    procedure TFoo.doSomething(); constref;
    begin
      self.foo := 1234; // this cant be done, self is a constant
    end;
    But now, since self is set to be constant, you can't write to it, so that's invalid.

    the above is as you see the same as doing:
    Simba Code:
    procedure doSomething(constref Self: TFoo);
    begin
      self.foo := 1234; // this cant be done, self is a constant
    end;


    tl;dr what you want to do can not be done unless you start with pointers, see bellow.





    Simba Code:
    type
      PFoo = ^TFoo;
      TFoo = record
        foo: integer;
      end;

      TBar = record
        bar: TFoo;
      end;

    procedure PFoo.doSomething(); constref; //take pointer, modify the value pointed to, not the pointer itself.
    begin
      self^.foo := 1234;
    end;

    function TBar.getFoo(): PFoo; //return a pointer
    begin
      result := @self.bar;
    end;

    var
      baz: TBar;

    procedure test();
    begin
      baz.getFoo().doSomething();
    end;

    begin
      test();
      WriteLn(baz);
    end.
    But this quickly gets messy.
    Last edited by slacky; 12-07-2017 at 07:49 AM.
    !No priv. messages please

  5. #5
    Join Date
    Dec 2011
    Location
    East Coast, USA
    Posts
    4,231
    Mentioned
    112 Post(s)
    Quoted
    1869 Post(s)

    Default

    Quote Originally Posted by slacky View Post
    *snip*
    Thank you so much, rep+. This is exactly what I needed. I never would have guessed to use pointers.

    With your example, I've extrapolated a little bit and made a practical mockup of what my code will eventually look like.

    The entire goal of this was to be able to do foo.bar().baz();, where foo, bar, and baz are all custom types which contain other custom types. In the context of RS of course.

    Simba Code:
    1. type
    2.   PTab = ^TTab;
    3.   TTab = record
    4.     tab: integer;
    5. end;
    6.  
    7. type
    8.   PCombatOptions = ^TCombatOptions;
    9.   TCombatOptions = record
    10.   tab: TTab;
    11. end;
    12.  
    13. type TPlayer = record
    14.   combatOptions: TCombatOptions;
    15. end;
    16.  
    17.  
    18. procedure PTab.open(); constref; //take pointer, modify the value it POINTS to, not the pointer itself.
    19. begin
    20.   self^.tab := 1234;
    21.   writeLn('This is working now!');
    22. end;
    23.  
    24. function TCombatOptions.getTab(): PTab; //return a pointer
    25. begin
    26.   result := @self.tab;
    27. end;
    28.  
    29. procedure PCombatOptions.open(); constref;
    30. begin
    31.   self^.getTab().open();
    32. end;
    33.  
    34. function TPlayer.getCombatOptions(): PCombatOptions;
    35. begin
    36.   exit(@self.combatOptions);
    37. end;
    38.  
    39. var
    40.   p: TPlayer;
    41.  
    42. procedure test();
    43. begin
    44.   p.getCombatOptions().open();
    45. end;
    46.  
    47. begin
    48.   test();
    49. end.

    Edit:

    Quote Originally Posted by slacky View Post
    But this quickly gets messy.
    I see what you mean. Each function essentially has to be written twice, once for type TTab and once for type PTab. Although the pointer funcs can just be wrappers to the real typed funcs which is often just 1 line of code.

    Still, it is relatively easy to go back and forth between the two, as long as a programmer consistently writes each function twice (1x typed and 1x pointer), he can use find and replace (or sed) to modify places in the code where the functions are called (e.g. changing p.getCombatOptions.open(); into p.combatOptions.open();) and then delete (or just ignore) the pointer funcs.

    The real typed functions are what matters, and the pointer functions should just be wrappers so that a script writer can access them in a slick way.

    This, to me, is preferable to not having the pointers at all
    Last edited by KeepBotting; 12-09-2017 at 01:08 AM.
    GitLab projects | Simba 1.4 | Find me on IRC or Discord | ScapeRune scripts | Come play bot ScapeRune!

    <BenLand100> we're just in the transitional phase where society reclassifies guns as Bad™ before everyone gets laser pistols

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •