Log In  

Hello.

Now that we can access strings a little easier I am coming across a problem I did not have in GFA or QBASIC.

For instance is there a way to have a function change an argument in return ?

function addadd(static a)
  a=a.."+"
end

cls()
a="hello"
addadd(a)
print(a)

Result would be: hello+

P#116392 2022-08-28 14:22 ( Edited 2022-08-28 14:23)

Lua is not basic, you shouldn't expect things in basic to work in lua.
In lua, you can return multiple values, so the updated value of a can be returned as one of them.

P#116394 2022-08-28 14:29

@thisismypassword, thanks for your interest !

LUA shares many elements of BASIC - or I wouldn't be here. A lot of people wouldn't be here, actually.

Does someone else know how to do this, with example code, please ?

P#116402 2022-08-28 16:43 ( Edited 2022-08-28 16:46)
1

possible methods:

just return the new version

function addadd(a)
  return a.."+"
end

cls()
a="hello"
a=addadd(a)
print(a)

assume not in a table and pass by name as a string

function addadd(a)
  if _ENV[a] then
    _ENV[a]..="+"
  end
end

cls()
a="hello"
addadd("a")
print(a)

allow supplying a containing table in the case that it's not global

function addadd(a,t)
  t=t or _ENV
  if t[a] then 
    t[a]..="+"
  end
end

cls()
a="hello"
addadd("a")
print(a)

parse string name to compensate for being part of a table using the "." lookup method

function addadd(a)
  local names = split(a,".")
  local ref = _ENV
  for i=1,#names-1 do
    ref=ref[names[i]]
  end
  ref[names[#names]]..="+"
end

cls()
a="hello"
addadd("a")
print(a)

In general, if you need to have a function change something in place, a table is needed, because that's the only way to pass things by reference and actually use them as such. Under the hood, all strings are actually references as an optimization, but the operators and functions for strings are designed to use them as values. This is the type of language decision all high-level languages need to make, because handling strings directly in a memory-managed environment is asking for trouble, and handling them in an environment that isn't memory-managed is tedious and requires a lot of caution.

P#116404 2022-08-28 17:29
1

Is there a reason you need to do it without using return and assigning the return value? With Lua using pass by value for non-table arguments, it seems like using return/assign is the path of least resistance, but you may have a use case in mind where it's not desirable that I can't think of. This is one token/7 characters/5 compressed bytes more expensive, so I guess if you're working in cramped quarters every bit helps (but in that case you'd possibly ditch the function entirely since the function adds 8 tokens and saves none per call).

function addadd(a)
  return a.."+"
end

cls()
a="hello"
a=addadd(a)
print(a)
P#116408 2022-08-28 18:07

Hi @2bitchuck:

Well in BlitzMAX for instance, you can modify the argument return through var statement thus:

global a$="hello"
addadd(a$)
print a$
end

function addadd(var t$)
  t$=t$+"+"
endfunction

The var included in the function definition states that if you change this argument inside the code, it will also return that changed value when exiting.

It is convenient for instance suppose I wrote a function that extensively modifies a string. I would rather have:

strip(index)

Rather than:

index=strip(index)

This could also lead to more portable code.

P#116412 2022-08-28 18:13 ( Edited 2022-08-28 18:14)

@kimiyoribaka, I skipped right by you, I do apologize.

Let me try what you have here:

function addadd(a)
  if _ENV[a] then
    _ENV[a]..="+"
  end
end

cls()
a="hello"
addadd("a")
print(a)

Yes ! This works. A shame I have to use quotes between a variable name but maybe those quotes will remind me that I am changing the variable inside the function.

function addadd(a)
  if _𝘦𝘯𝘷[a] then
    _𝘦𝘯𝘷[a]..="+"
  end
end

cls()
apple="hello"
addadd("apple")
print(apple)

Also for those of you following this and cannot get _env to run. Be certain it appears lowercase in Pico-8. To do so type the _ then CTRL+P then env then CTRL+P again to return back to normal typing.

It should work then.

Thank you, kimiyoribaka for solving my question ! It could be done. I just have to send the variable in quotes.

If someone can do this minus quotes that would be better - but this is doable. :)

One other question, kimiyoribaka. Since you can send a variable name inside a string, is it possible to use that string for a number, a possibly calculated one such as:

function calc(a)
  if _env[a] then
    print(_env[a])
  end
end

sum="1+2"
calc("sum")

Or some other way to return the calculated string, no matter how complex it is ?

P#116423 2022-08-28 21:18

@dw817
"no matter how complex it is" is probably a red flag when using pico-8. The answer is yes, but the number of tokens would likely be high. I neglected to put the proper "at" in my post (oops...), but in your previous thread here, I showed parsing for addition and multiplication. The same principle can be continued for any number of operators, but each one would make the algorithm bigger. At some point you'd no longer have enough room for whatever else you're using (parsing user text I'm guessing?).

P#116425 2022-08-28 21:42

Yep I know you wrote some superb code to that effect earlier, @kimiyoribaka.

I'm always just looking for shortcuts - and outside of Bagel - to my knowledge there is =NO= programming language that will let you enter a string and then run it as a true command line, despite how interesting and useful that could be.

a="print"
b="("
c='"'
d="Hello world."
e=")"

_exec(a+b+c+d+c+e)
P#116429 2022-08-28 21:53

what? all or nearly all languages have eval/exec functions!

P#116436 2022-08-28 22:12

@dw817
You might need to experiment with more interpreters and/or dialects, then. Standard Lua lets you do that, and I'm pretty sure Python does too. It's mainly either compiled languages or languages made for sandboxed app development (such as game engines that want to satisfy consoles and mobile OS's by not allowing anything bad) that don't allow that.

To put that concept into the larger context of interpreter languages like Lua, what you're describing is literally how Lua modules in standard Lua work if you don't use the convenience functions. Standard Lua even has three ways to use the Load() function depending on how you want to supply the code (as a string, as a file, or as a generator function). I would guess the reason pico-8 doesn't include that ability is both because pico-8 isn't meant to read files while games are running and because interpreter languages weren't really a thing on consoles or home computers during the era it's mimicking.

P#116435 2022-08-28 22:28 ( Edited 2022-08-28 22:28)

That seems - unlikely, @kimiyoribaka. I really like Pico-8. I've actually been working on and off on a game in it. I will post it when complete.

I'm not sure how something -bad- can happen with command ability as described above with strings.

Zep has locked out rename and delete of files so there isn't too much damage you can do.

Personally I would love to see the ability in Pico-8 to load/ save/ rename/ delete/ and move text files if they are truly *.txt extension - and you cannot access any other file kind this way nor go to a parent directory.

Including loading/saving *.txt online. Yet I can see a problem with this. Flooding the HD or online with files. So perhaps this ?

No more than 16-slots and no more than 32768-bytes per slot.

string = _fileload ( {slot 0-15} , { start char } , {length of chars } )

_filesave ( {slot 0-15}, string, { start char } , { length of chars } )

Where string could also be an array variable.

And array can be varied but still not occupy more than 32768-bytes at a time.

Saved as {cartname_t00}.txt to {cartname_t15}.txt same area as code is run in.

Using a limited 16 file slots since I guess it would be possible to flood the HD with new files if you could just create as many files as you wanted. Keeping the *.txt means you can easily edit them in Notepad.

P#116497 2022-08-29 15:17 ( Edited 2022-08-29 15:36)

It just occurred to me that executing strings as code would also make the token limit obsolete. You'd still likely need a global called _update60 if you wanted 60 fps and and one called _draw if you wanted the regulated rendering cycle, but with the ability to execute strings, you could put nearly your entire code into a string and then only worry about the compression.

P#116501 2022-08-29 15:31

Hi @kimiyoribaka:

Well now I didn't expect it to be used for that. I was thinking of say maybe a limit of 64- 256- characters for the _exec() function. Use it only for simple things like calculations and calling functions with names of arrays instead of actual arrays.

I suppose you could shove a whole real Pico-8 program in there. That might be interesting to see.

P#116502 2022-08-29 15:54

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-19 21:30:18 | 0.038s | Q:27