GithubHelp home page GithubHelp logo

plutolang / pluto Goto Github PK

View Code? Open in Web Editor NEW
308.0 8.0 19.0 3.92 MB

A superset of Lua 5.4 with a focus on general-purpose programming.

Home Page: https://pluto-lang.org/docs/Introduction

License: MIT License

Makefile 0.69% C 6.25% C++ 65.41% Lua 27.20% PHP 0.46%
lua programming-language plutolang language dialect pluto superset

pluto's People

Contributors

data-man avatar komothecat avatar sainan avatar shawsumma avatar well-in-that-case avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

pluto's Issues

Short string method call

As opposed to

("str"):contains("s")

I think it would be cool to have the alternative of:

"str":contains("s")

Method shorthand discrepancy

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.

f-strings

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.

Too many arguments warning

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.

io.makedirs

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.

Add 1 Shorthand

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.

[Enhancement] Expansions to Standard Library.

Initial expansions could reserve focus on the string standard library.
Development branch:
https://github.com/well-in-that-case/Pluto/tree/strlib

To-do:

  • Optimize existing functions.
  • Implement casefold.
  • Implement strip.
  • Implement rstrip.
  • Implement lstrip.
  • Implement isascii.
  • Implement islower.
  • Implement isupper.
  • Implement isalpha.
  • Implement isalnum.
  • Implement iswhitespace.
  • Implement contains.
  • Implement rfind.
  • Implement lfind.
  • Implement find_first_of.
  • Implement find_first_not_of.
  • Implement find_last_of.
  • Implement find_last_not_of.
  • Write tests for all this mumbo jumbo.
  • Add them to "Standard Library Additions" in README.md
  • Create documentation website for all new functions.

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.

Default parameters

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.

Confused error message

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

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!)")

"Continue X" & "Break X" syntax for manipulating enclosed loops.

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.

Smart Compatibility Mode

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.

Reformat code styling.

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.

Switch's default case can't be the first case

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. ๐Ÿ’€

Better expected name error message

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

Named Parameters

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.

Shorthand table contains key syntax

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.

Asserts with 'in' expressions

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.

Deprecate pluto_case & pluto_default

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:

  • Remove PLUTO_COMPATIBLE_CASE & PLUTO_COMPATIBLE_DEFAULT in 0.5.0
  • Add deprecation warning for "pluto_case" & "pluto_default" in 0.5.0
  • Remove "pluto_case" & "pluto_default" in 0.6.0

"foreach" keyword

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

Better configuration system

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.

Unreachable code warning

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

Switch Expression

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.

Character encoding is coming to haunt us

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:

  • We say UTF-8 is the way paths should be encoded and update the other iolib functions accordingly
  • We stay with the C locale system, say that io.listdir errors for unencodable paths are as expected, and point out os.setlocale as a possible solution

Enum Iteration

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

Typehint warnings

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.

[Request] OOP Structures, Syntactic Sugar

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
}

Sandbox Mode

This would be extremely useful for integrators looking for a more restrained environment.

Some considerations:

  • A limited luaL_openlibs that doesn't expose the filesystem
  • Disallow require (except for Pluto's pseudo-modules such as crypto), maybe provide an easy way to make a custom resolver
  • Hard execution time limit (alternatively, ILP but no way to get around it)
    • Considerations for os.sleep function

Goto label can't be named "continue"

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.
|

Exclude compile-time constants from locals limit

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.

Optional static typing

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.

Attempt to modify a frozen table error shows wrong line

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.

Ratify file extension

We've decided to use .pluto as the file extension of choice to specify Pluto source files. Now to ratify this decision:

  • Rename tests (better to do around 0.5.0 release to reduce conflicts)
  • Update require default package.path
  • Update ext fields on webshell links

Just to name a few points.

Considerations about RAII over GC

I don't think Lua/Pluto is doomed to forever use GC, but removing it would require a few things:

  • A hook when variables go out of scope
  • A way to GC a variable outside of a GC cycle (so the GC also wont try to clean up this variable anymore)
  • Replacing all instances where L->top.p-- is used instead of lua_pop

Granual compatibility mode

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.