Jump to content




[Language] Luva v1.12 - Compiles to Lua


  • You cannot reply to this topic
62 replies to this topic

#1 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 26 December 2015 - 06:10 PM

So, I've always been fascinated by programming languages, virtual machines, and all the like.
As such, I've periodically searched the forum for any alternative programming languages.

Now, there were many interesting programming languages, but many of them weren't a real plausible alternative to Lua.
From the ones I've seen, they often had limited capabilities, or were an extension of Lua itself.

So, I took it upon myself to create an alternative to Lua, which, naturally, would compile to Lua.
I've looked at several other prominent programming languages, and drew inspiration from them, as well from Lua itself to create what I call Luva (pronounced "Luu-va").

You can find the compiler here (pastebin get Kus6yZwV). It probably isn't the most efficient compiler design, but it gets the job done.
The compiler itself is under the Creative Commons Attribution-NonCommercial 4.0 International Public License (a summary of the license can be found here).
Similarly, you can also find it's Github here if you plan to contribute or report bugs. Be sure to give the full error, as well as the code you attempted to use if you are reporting an error.

Here are the arguments you can give the compiler:
Luva <filename/foldername> <output>

If you run Luva without any arguments, you're put into a console that's similar to the Lua program.
Though, it's still buggy.

Giving it just a filename will have the compiler attempt to compile the file.
By default, it will save to 'compiled,' but this can be changed by using the <output> argument.

Lastly, you can supply the compiler with a folder.
What this will do is go through the folder and attempt to compile every file there.
The files will be saved to an identical folder, with the content placing saved.

The default folder name is also 'compiled' unless the <output> argument is given to specify a different location.

Here's what sets Luva and Lua apart:
  • Overloaded functions.
  • Different combinations of repeat/while/until for a more customized loop.
  • 20+ extra operators, such as >>, +=, --, etc.
  • Syntax of tables ({1, 2, 3} becomes [1, 2, 3], and {A = "test", [2] = 30, B3 = 10} becomes [A: "test", 2: 30, B3: 10]
  • then/end keywords replaced with { } (If <condition> { <statement> })
  • Ability to make objects have their own types.
  • Type specification in function declaration.
  • Assigning default values when one isn't given.
  • Switch statements.
  • Preallocation of arrays.
  • Native support for binary numbers.
  • You don't need to end long comments, making it quicker to block off large sections of code.
  • Three-way-comparison operator (<=>). A < B = false, A == B = nil, A > B = true. (Why is it here? Just because.)
  • Identical operator (===), and it's counterpart (~==) to compare tables ([1,2,3] == [1,2,3] is false, [1,2,3] === [1,2,3] is true. Beware that the operator uses lazy index checking).
  • Unless statements.
  • Guard statements.
  • Try, With, and Catch statements.
  • OOP /w inheritance and sub classes.
  • And some other stuff I've probably forgot to list.
And here's the feature(s) that are planned for the future, which I'm still working in:
  • Require function to import APIs.
  • Make code indented.
Here's what the current update, Version 1.12 changes:
Spoiler

You can find the tutorials on the language at its Github Wiki. Though, at this moment, it's still incomplete, so do bare with me.

I'd like feedback, more criticism than not, if possible; I'd like to know what you guys think, what you like, and what you dislike (maybe even why? :P)

Edited by Detective_Smith, 14 February 2016 - 03:06 PM.


#2 InDieTasten

  • Members
  • 357 posts
  • LocationGermany

Posted 26 December 2015 - 06:24 PM

+1 looking forward to see more features

#3 Blue

  • Members
  • 309 posts
  • LocationGlass/UX/main.lua

Posted 26 December 2015 - 06:35 PM

Looks amazing!

#4 SquidDev

    Frickin' laser beams | Resident Necromancer

  • Members
  • 1,427 posts
  • LocationDoes anyone put something serious here?

Posted 26 December 2015 - 06:40 PM

Every time someone releases a new language I think ' I need to get back to work on mine' and then get distracted by something else fun.
  • The overloading looks nice: though it would be nice to expand it to full pattern matching - Metalua has a decent (though suboptimal) implementation of it.
  • With operators like += does it evaluate the left side multiple times (so foo().x += 1 is shouldn't be expanded to foo().x = foo().x + 1 but local temp = foo() temp.x = temp.x + 1)
  • I like the binary operators!
  • Not sure about new table and boolean operator syntax - Lua's and and or are more complex than && and || (though I guess Javascript uses them so no harm). The table syntax doesn't allow something like: { [foo] = bar } which is sometimes useful.


#5 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 26 December 2015 - 06:59 PM

View PostSquidDev, on 26 December 2015 - 06:40 PM, said:

Every time someone releases a new language I think ' I need to get back to work on mine' and then get distracted by something else fun.
Heh, I know what you mean.

View PostSquidDev, on 26 December 2015 - 06:40 PM, said:

  • The overloading looks nice: though it would be nice to expand it to full pattern matching - Metalua has a decent (though suboptimal) implementation of it.
Yeah, I would like such a feature as well. I just haven't thought of a good way to do it yet.

View PostSquidDev, on 26 December 2015 - 06:40 PM, said:

  • With operators like += does it evaluate the left side multiple times (so foo().x += 1 is shouldn't be expanded to foo().x = foo().x + 1 but local temp = foo() temp.x = temp.x + 1)
Unfortunately, as of now, it does. I have yet to make the compiler create efficient code like that. However, I would like to add in the ability to do that in the future.

View PostSquidDev, on 26 December 2015 - 06:40 PM, said:

  • I like the binary operators!
Thanks, thought they'd be useful :).

View PostSquidDev, on 26 December 2015 - 06:40 PM, said:

  • Not sure about new table and boolean operator syntax - Lua's and and or are more complex than && and || (though I guess Javascript uses them so no harm). The table syntax doesn't allow something like: { [foo] = bar } which is sometimes useful.
Tables use '[]' instead of '{}' because of how they would often interfere with statements.
Consider the following below:

if x == 1 { print("yay!") }

The compiler would often try to make the line '{ print("yay!") }' into a table, which of course would error.

With your example of { [foo] = bar }, I agree I will need to find a work around for doing such in my language.
Any thoughts on doing this to overcome the problem?

local foo, bar = 10, 20
local a = ["foo": bar, foo: bar]

As for the boolean operators, they behave exactly like lua's and, or, and nots.
I'm using && and the other symbols because I wanted to try out how it would feel to program in my language using them.
In my opinion, they are a bit weird, so I've thought about just switching back to using and/or/not.

Edited by Detective_Smith, 26 December 2015 - 07:01 PM.


#6 SquidDev

    Frickin' laser beams | Resident Necromancer

  • Members
  • 1,427 posts
  • LocationDoes anyone put something serious here?

Posted 26 December 2015 - 07:27 PM

View PostDetective_Smith, on 26 December 2015 - 06:59 PM, said:

With your example of { [foo] = bar }, I agree I will need to find a work around for doing such in my language.
Any thoughts on doing this to overcome the problem?

local foo, bar = 10, 20
local a = ["foo": bar, foo: bar]

I'd forgotten you'd used braces for statements. However raw strings for properties in tables is useful (like { x = 23, y = 23, radius = 10 }). One solution would be to parse the key as an expression and if it is an identifier, then convert it to a string:

x = [
  foo: "string key",
  "bar": "string key",
  (foo): "key from variable",
]

Though I'm not 100% convinced by that either.

Edited by SquidDev, 26 December 2015 - 07:27 PM.


#7 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 26 December 2015 - 07:41 PM

Perhaps a colon can be used instead?

local table = [
     foo: "string key",
     :bar: "variable key",
]

Or perhaps a period instead of a colon.

#8 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 26 December 2015 - 09:26 PM

Just added switch statements. For now, they're just if-elseif-else statements in a different syntax. I have an idea of how to make them faster in the future, however.

#9 Creator

    Mad Dash Victor

  • Members
  • 2,168 posts
  • LocationYou will never find me, muhahahahahaha

Posted 26 December 2015 - 10:12 PM

Is Luva on GitHub? Can we help?

#10 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 26 December 2015 - 10:16 PM

At the moment, it isn't. I may put it on Github once it's more fully developed, however.
For now, the help I would appreciate is any criticism you may have while I develop it :).

Edited by Detective_Smith, 26 December 2015 - 10:17 PM.


#11 Creator

    Mad Dash Victor

  • Members
  • 2,168 posts
  • LocationYou will never find me, muhahahahahaha

Posted 26 December 2015 - 10:42 PM

The things I don't like:
  • { } instead of then end
  • tables being declared with [ ] and not with { } because it does not allow for smth = { [foo] = bar }
The things I like:
  • += and company.


#12 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 26 December 2015 - 10:53 PM

So you can't use both "2" and 2 as keys?

#13 Creator

    Mad Dash Victor

  • Members
  • 2,168 posts
  • LocationYou will never find me, muhahahahahaha

Posted 26 December 2015 - 10:55 PM

View PostLyqyd, on 26 December 2015 - 10:53 PM, said:

So you can't use both "2" and 2 as keys?

A good point too. I add it to my I don't like it list.

#14 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 26 December 2015 - 11:14 PM

View PostCreator, on 26 December 2015 - 10:42 PM, said:

The things I don't like:
  • { } instead of then end
  • tables being declared with [ ] and not with { } because it does not allow for smth = { [foo] = bar }

I chose to use { } in order to help speed up the programming of statements (It feels less tedious to me to use { } rather than then-end).
As far as as tables using [ ] instead of { } go, that's a result of having statements use { }.

Also, it's possible to solve the problem of smth = { [foo] = bar }. I just haven't decided on how it should be done in terms of syntax.

Here's what I'm considering currently:
local smth = [2: "Numerical Index", "2": "String Index", foo: "Variable Index"]
local smth = [[2]: "Numerical Index", 2: "String Index", :foo: "Variable Index"]
local smth = [(2): "Numerical Index", 2: "String Index", (foo): "Variable Index"]

Edited by Detective_Smith, 27 December 2015 - 12:19 AM.


#15 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 27 December 2015 - 04:13 PM

Alright, just made some final tweaks to tables. Here's the syntax for them:

local x, y = 10, 20
local z = x + y
print(z)

local w = [10, 20, 30, 40, 50, 9:90]
print(w[1] + w[2]); w[6] = 60

local v = [A: 20, B: 40, C: 60, "D": 80, "2": 2, 10: 5, :z: w[3], :10 + (30 / 2): "yay!"]
print(v.A, v.B, v.C, v.D, v["2"], v[10], v[z], v[25]) // Prints '204060802530yay!'

// Basically, anything that isn't a string or a number, such as an expression, will need to be in :<expression>:
// You can also do other stuff like this:
local a = [:[1, 2, 3]: 10, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]]
// Just tables in tables as well as indexing by a table.


#16 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 27 December 2015 - 07:15 PM

Made preallocating arrays different in syntax and more useful. Also added ability to more easily define binary numbers. Check the bottom of the main post for more info.

#17 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 29 December 2015 - 03:24 PM

Made more changes:

-- Better expression parsing
-- Numerical for loops, just like how it's done in lua.
-- Semi colons can be used, but are optional.
-- Added 'guard' statements

I plan to start working on classes once all the other features I want to get out of the way are done.
They're mostly little things, such as optimizations. But, as it is now, you can pretty much port any Lua code
to Luva fully, and it should work just fine.

EDIT: Just so I can get an idea of things, anyone plan to use Luva?

Edited by Detective_Smith, 29 December 2015 - 03:25 PM.


#18 Creator

    Mad Dash Victor

  • Members
  • 2,168 posts
  • LocationYou will never find me, muhahahahahaha

Posted 29 December 2015 - 08:57 PM

If it has some proper class implementation, maybe. I could help you out with it.

#19 SquidDev

    Frickin' laser beams | Resident Necromancer

  • Members
  • 1,427 posts
  • LocationDoes anyone put something serious here?

Posted 29 December 2015 - 10:26 PM

View PostDetective_Smith, on 29 December 2015 - 03:24 PM, said:

-- Added 'guard' statements

Those look fancy! Would you consider something like try with resources/using blocks:
with x = fs.open("foobar", "r") do
  x.write("foo bar baz")
end
compiles to
local x = fs.open("foobar", "r")
local s, m = pcall(function() x.write("foo bar baz") end)
x.close()
if not s then error(m, 0) end

In fact: the whole try/catch thing would be pretty awesome. The hard bit is capturing returns from these blocks, but Metalua has an implementation of it.

View PostDetective_Smith, on 29 December 2015 - 03:24 PM, said:

EDIT: Just so I can get an idea of things, anyone plan to use Luva?

We in the forums do suffer from "Not invented here", but I might give it a go.

Edited by SquidDev, 29 December 2015 - 10:26 PM.


#20 Antelux

  • Members
  • 295 posts
  • LocationSomewhere in the middle of nowhere.

Posted 29 December 2015 - 11:22 PM

View PostCreator, on 29 December 2015 - 08:57 PM, said:

If it has some proper class implementation, maybe. I could help you out with it.

Anything in mind you'd like to see?

View PostSquidDev, on 29 December 2015 - 10:26 PM, said:

Would you consider something like try with resources/using blocks:
with x = fs.open("foobar", "r") do
  x.write("foo bar baz")
end
compiles to
local x = fs.open("foobar", "r")
local s, m = pcall(function() x.write("foo bar baz") end)
x.close()
if not s then error(m, 0) end

In fact: the whole try/catch thing would be pretty awesome. The hard bit is capturing returns from these blocks, but Metalua has an implementation of it.

Oh, I like the look of that. I think I'll try to give it a go. Guess I'll also have a more in-depth look at Metalua as well.

View PostSquidDev, on 29 December 2015 - 10:26 PM, said:

View PostDetective_Smith, on 29 December 2015 - 03:24 PM, said:

EDIT: Just so I can get an idea of things, anyone plan to use Luva?

We in the forums do suffer from "Not invented here", but I might give it a go.

Didn't know there was a term for it. Learn something new every day.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users