plutolang / pluto Goto Github PK
View Code? Open in Web Editor NEWA superset of Lua 5.4 with a focus on general-purpose programming.
Home Page: https://pluto-lang.org/docs/Introduction
License: MIT License
A superset of Lua 5.4 with a focus on general-purpose programming.
Home Page: https://pluto-lang.org/docs/Introduction
License: MIT License
As opposed to
("str"):contains("s")
I think it would be cool to have the alternative of:
"str":contains("s")
local t = {
f = function(str)
print(str)
end
}
t.f("hi")
This code prints "hi", as expected, but trying to replace this with the following shorthand syntax:
local t = {
function f(str)
print(str)
end
}
t.f("hi")
causes this code to print "nil", because the first argument is seemingly put into self
, instead.
local a = 3
if a == 3 {
print("a is 3!")
}
Mainly I asked for linux because android is basically linux, but apparently it still doesn't work
e.g.
enum begin
RED,
GREEN,
BLUE,
LAST_COLOUR = BLUE
end
I think it would be possible to detect this kind of function call in the paser:
f"Hello, {subject}!"
or, for compatibility:
pluto_f"Hello, {subject}!"
and then generate an expression that's just getting the variables (local or global) and concating it into the final string.
Could just check the function TypeDesc in funcargs and compare to amount of expressions in explist. Just need to handle the case of function being vararg.
Since there's io.makedir for std::filesystem::create_directory
, we could have io.makedirs for std::filesystem::create_directories
, which will not only create the target directory, but also any missing parents.
e.g.
local i = 1
i++ -- i gets set to 2, expression returns 1
++i -- i gets set to 3, expression returns 3
Not sure how we could do this with subtract, tho. Nor how we would properly make these expressions return the expected values while changing the value independently.
Initial expansions could reserve focus on the string
standard library.
Development branch:
https://github.com/well-in-that-case/Pluto/tree/strlib
To-do:
casefold
.strip
.rstrip
.lstrip
.isascii
.islower
.isupper
.isalpha
.isalnum
.iswhitespace
.contains
.rfind
.lfind
.find_first_of
.find_first_not_of
.find_last_of
.find_last_not_of
.Largely intended to mirror an old module of mine: https://well-in-that-case.github.io/LuaString/
The documentation of this module might help explain what these functions would do, in greater detail.
Make this valid syntax:
function func(a = true)
print(a)
end
func()
Such that the code would print "true".
This could be done by implying a ??= true
at the start of the function.
Given the following code:
for t end
We get the following error:
test.lua:1: '=' or 'in' expected, but found reserved keyword 'end'
1 | for t end
| ^^^^^^^^^ here: reserved keyword cannot be used in this context.
+ note: Reserved keywords *can* be used outside of relevant contexts, but this is a relevant context!
Which just seems akward & confused.
Raw String Literals aka. heredoc can be useful for conveniently coding in multi-line string literals or Windows file paths.
Example syntax:
print(R"(Hello \ World!)")
Inspiring from PHP, continue 1
would skip not the current loop, but the first enclosing loop above this one. For example:
for i = 1, 10 do -- Loop 1.
for i = 1, 5 do -- Loop 2.
...
continue 1 -- This would skip 1 iteration of Loop 1.
break 1 -- This would break out of Loop 1.
end
end
This should be fairly simple to implement by accessing the BlockCnt
chain of each FuncState
, and checking the isloop
field appropriately. We can simply continue searching the linked list X many times, where X = the numeric argument after the keyword to find our intended loop. This is exactly how continue
works, but it'll look backwards indefinitely and stop at the first loop.
With the 0.5.0 release, enum
became a reserved keyword, but there were some scripts that used "enum" as a variable name. So, to avoid these sort of upgrading pains going forward, we might want to make compatibility mode more intelligent, by automatically enabling it when the parser notices a reserved token being used as a variable/function/whatever name.
Although this might not be entirely possible due to require
+ global variable declaration that the parser then can't see.
i.e the following code:
enum TestEnum begin
INVALID = -1,
OPT_0,
OPT_1,
end
will generate an error, 2: <integer> expected (got '-')
Ideally, a good auto-formatter can set the universal project style to two-space tabs, brackets on newlines & no space between a function name and its parameters. As of now, it's very inconsistent. This should be done after 0.4.0 is merged, so we can avoid several thousand merge conflicts.
The following code does not work, even tho I would expect it to:
local value = 3
pluto_switch value do
pluto_default:
print("Value is greater than 5.")
break
pluto_case 1:
pluto_case 2:
pluto_case 3:
pluto_case 4:
pluto_case 5:
print("Got 1-5.")
break
end
The fix for this would be rather simple, I could probably do it myself, but I'd rather finish with #59 first to avoid conflicts. Just reporting this bug in case I forget. ๐
Example script:
local test: deez
Trying to run it will show the error, but using plutoc -p
to lint it does not show the error.
Given code like this:
local function get_config(key, default)
-- ...
end
The parser currently emits:
pluto: test.lua:1: <name> or '...' expected near 'default'
I think it would be a lot more clear what the actual issue is if it looked more like this:
pluto: test.lua:1: <name> or '...' expected, but found 'default', which is a reserved keyword
1 | local function get_config(key, default)
^^^^^^^ here: reserved keyword
Is this compatible with linux?
As an alternative to the current "positional parameters" model:
local function greet(greeting, name)
print(greeting .. ", " .. name .. "!")
end
greet(name: "World", greeting: "Hello") -- "Hello, World!"
The syntax might need to be different to stop the parser from dying inside.
Given a table like this:
local t = {
["a"] = true,
}
You can check if it contains a key like this:
print(t["a"] ~= nil)
However, it would be cool to have a shorthand syntax like this:
print("a" in t)
Although I'm not entirely sure if this is even possible.
When building Pluto with LUAI_ASSERT
defined and then running any code using 'in' expressions (inexpr), such as:
if ("hel" in "hello") != true then error() end
if ("abc" in "hello") != false then error() end
There are several asserts that will trigger.
A part of the issue is the call to luaK_storevar
which will assert due to attempting to store a VNONRELOC
, but there are more indirect problems later down the line.
This isn't a huge issue since 'in' expressions seem to work fine, but triggering asserts when everything is fine is ugly.
case & default are narrow tokens now, and I don't think narrow tokens need a compatibility option as they're essentially only reserved in their respective context.
Possible timeline:
The following code,
local function checkThings(value)
return value + 52
end
if checkThings(value := -8) == 44 then
print(value)
end
should theoretically print -8, but it instead prints 44, the return value of the function its being passed to.
This might be the most useless suggestion ever, but I'd much rather type:
foreach v in t do
-- ...
end
than:
for _, v in t do
-- ...
end
or perhaps an alternative syntax that might be possible due to the improved lexer:
for t as v do
-- ...
end
The current configuration system requires uncommenting an undef, but if instead it required something to be defined, it would be much easier to store the Pluto config with existing build configs, e.g. in Visual Studio.
If there's any code in these unreachable parts, the parser could emit a warning:
if true then
break
-- unreachable
end
if true then
goto somewhere
-- unreachable
end
This lovechild of the switch and lambda syntacies could be a nice shorthand:
local function int2eng(i)
return switch i do
case 1 -> "One"
case 2 -> "Two"
default -> "Other"
end
end
This should be unambigious to parse, tho I assume generating (efficient) code for this is gonna be a challenge.
We have a small incongruence in how Pluto deals with character encoding. io.listdir
uses UTF-8 for the return values, which we have decided to do after users were getting errors about some file paths not being encodable in the multibyte encoding of the current C locale. However, the underlying issue persists with other functions such as io.open
, which calls into fopen, and that still uses the multibyte encoding of the current C locale. So, there are two ways out of this mess:
The Lua XOR operator (~
) does not seem to have a compound counterpart in Pluto.
The following code will run forever, even with ILP enabled:
repeat until false
it would be nice if you could iterate through the values of a enum like
enum MyEnum begin
OPTION_1 = 0,
OPTION_2,
OPTION_3 = 5,
OPTION_4
end
for index, value in MyEnum do
print(index, value)
end
which could output something like
1 0
2 1
3 5
4 6
Given a definition such as:
local a <string> = "Hello"
An assignment to "a" such as:
a = 69
Where a violation of the typehint is very apparent, should result in at least a parser warning.
Currently in lua, there is quite a bit of boilerplate code for creating "structs" or "classes" for OOP, and the way it is done is hard to get done "properly" and soundly
---@class Foo
local Foo = {
name = "",
id = 0
}
setmetatable(Foo, Foo)
Foo.__index = Foo
function Foo:new(name, id)
---@type Foo
local o = {}
setmetatable(o, self)
o.name = name
o.id = id
return o
end
function Foo:print()
print("My name is " .. self.name .. " and my id is " .. self.id)
end
return Foo
Having this abstracted away would offer usability and readability improvements.
(Some syntax I thought up):
local struct Foo = {
name;
id;
function create(name, id)
self.name = name
self.id = id
end
function print()
print("My name is " .. self.name .. " and my id is " .. self.id)
end
}
Understandable if you don't want to fix this, but does slightly break backward-compatbility.
This would be extremely useful for integrators looking for a more restrained environment.
Some considerations:
luaL_openlibs
that doesn't expose the filesystemrequire
(except for Pluto's pseudo-modules such as crypto), maybe provide an easy way to make a custom resolveros.sleep
functiont = {}
table.insert(t, "Hello")
table.insert(t, "World")
print(#t)
prints 1
Another case of lack of backward compatibility.
for i = 1, 3 do
if i == 3 then
goto continue
end
print(i)
::continue::
end
test.lua:3: syntax error: expected an identifier.
3 | goto continue
| ^^^^^^^^^^^^^ here: this needs a name.
|
From what I understand, the locals limit exists due to the bytecode format, but Lua does not make any exceptions for compile-time constants that won't be needed at runtime, so it would be good if Pluto would patch this, especially since this causes enums to count towards the locals limit.
In the vein of PHP, I think static typing could be introduced as an opt-in feature:
function greet(name: string, age: ?int = nil): void
if age == nil then
print("Hello, " .. name)
else
-- age is guaranteed to be an int now
print("Hello, " .. age .. " year old " .. name)
end
end
By adding :
after the parameter name, you can then say the type, or the type with a question mark in front to specify its nullable nilable; and the same applies to the end of the function definition, except void is also valid.
If someone attempts to use this function now with e.g. an int for name
, an error is raised.
table.freeze(_G)
_G.string = {}
This code will produce the following error:
[string "table.freeze(_G)..."]:1: attempt to modify frozen table.
Note how it indicates line 1 even tho the attempt to modify is on line 2.
More specifically, it will show whichever non-empty line came before the actual infringing line.
We've decided to use .pluto as the file extension of choice to specify Pluto source files. Now to ratify this decision:
require
package.path
ext
fields on webshell linksJust to name a few points.
I don't think Lua/Pluto is doomed to forever use GC, but removing it would require a few things:
L->top.p--
is used instead of lua_pop
Possible syntax:
local a <constexpr> = 1
It would be a syntax error if the declared value does not result in a compile-time constant
Add compatibility configuration for individual keywords, so e.g. switch
and case
could be used without pluto_
prefix, but it would still be required for default
and continue
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.