This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Midnightas's profile picture

Midnightas' Lua Preprocessor (Adds many new features to Lua)

Started by Midnightas, 18 December 2016 - 02:40 PM
Midnightas #1
Posted 18 December 2016 - 03:40 PM
MLua
A preprocessor that adds support for OOP, lambda, and some more upcoming things.

Syntax
Downloads

Differences between this and the old version:
- No foreach, since Lua has it's own
- None of it's own APIs, that's not something a preprocessor should have
- Classes with no constructors are non-instantiable
- No switch statement (yet)

old deprecated versionLua Preprocessor
This preprocessor adds support for object-oriented programming, and more features.
SyntaxThe syntax is the same as in Lua except for a few exceptions shown in this spoiler.
Ternary OperatorInstead of writing

x == 5 and "yes" or "no"
the syntax has been changed to be identical to the C ternary operator.
OOPA couple of new keywords have been added for object-oriented programming.
To create a class, use the "class" keyword:

class Test contains
end
Between the "contains" and "end" key you may add functions how you would normally do with an optional "static" prefix for static functions.
Same for variables.
Inheritance is simple, too:

class Sub extending Super contains
end
When creating instances, the constructor of each derived class will be called in the order that you specified when declaring the class before your own constructor. When creating instances, the constructor of the derived class will be called first.
Only one constructor for each class is allowed. And only one class in "extending" is allowed.
To create an instance of a class, call it like a function (just like in Python).

class Test contains
static SIMPLE_STR = "5";
constructor(argOne, argTwo)
end
static function addFive(str)
return str .. Test.SIMPLE_STR;
end
end
instance = Test("arg one", "arg two");
IncludesTo include either a Lua file or a file for this preprocessor, use this:
include "simpleFile.lua";
This can either be a relative path (That does NOT start with ./) or an absolute path.
This Lua preprocessor has some builtin includes that will be shown later.
From beta 1.15, if you ever need to use a function called "include", just put brackets and the compiler will parse it like a normal function.
LambdaLambda in this language is the same as in Python:

lambda argOne, argTwo: argOne + argTwo;
First there is a "lambda" keyword, then the list of arguments, the colon and then an expression.
instanceofIf you want to find out whether or not a variable value is an instance of a certain class, use this:
myVariable instanceof SomeClass
Note that this does not work across superclasses.
switchThe switch statement is a little different from C specification.
switch someExpression
  case 1+2 then
	print("it's three");
  case 4 then
	print("four");
  default then
	print("its nor three nor four");
end
Only one case will be called. If none are called then the default case is called.
The above code is compiled into:
function _mlua_switch(t)
  t.case=function(self,x)
	local f=self[x] or self.default;
	if f then
	  if type(f)=="function" then
		f(x,self)
	  else
		error("case "..tostring(x).." not a function")
	  end
	end
  end
  return t
end
(_mlua_switch{
  [3.0]=function()print("it's three"); end,
  [4.0]=function()print("four"); end,
  default=function()print("its nor three nor four"); end,
}):case(someExpression);
Note (shown in the compiled version) that the cases are evaluated first.
foreachFinally, we don't have to do that pairs() and key value nonsense.
foreach varName in someTable do

end
Oh yeah, and this Lua uses semi-colons.
OptimizationThis preprocessor optimizes wherever it can, for an example:

x = 5 + 2;
-- the above code becomes:
x = 7;
However the optimization feature bugs out a bit when using parentheses.
How to CompileDownload the compiler below and open up your terminal of choice.
Use this command:
java -jar preprocessor.jar -f thefile.lua
Replace preprocessor.jar with the name of the compiler, and thefile.lua with your source file path.
The compiler will then spew out the pure Lua version. To redirect the output to a file, simply add
> compiled.lua
to the end of the command above. This will work in both UNIX-based systems and Windows.
Replace compiled.lua with whatever name you choose.
APIs
StringAdded: Beta 1.1

include "string";
local stringBuilder = StringBuilder(); -- You can pass a string to initialize it
stringBuilder:add("Hello, "):add("World"); -- Chained commands are allowed
stringBuilder:addAt(13, "!"); -- Add at a specific location
stringBuilder:charAt(1); -- Get character at index (In this case "H")
stringBuilder:length(); -- Get the length of a string
stringBuilder:slice(2, 5); -- Substring (both indexes inclusive, so "ello")
StreamAdded: Beta 1.15

include "stream";
local stream = Stream({1, 4, 2, 3}); -- Only works on array-tables
stream = stream:map(lambda x: x * 3); -- Triple everything in the stream
stream = stream:filter(lambda x: x % 2 == 0); -- Remove all odd values (leave all even ones)
stream:forEach(lambda x: print(x)); -- Print all values
stream:getCount(); -- Get amount of items in this stream
stream:getArray(); -- Returns the internal array in this stream
DownloadBeta 1.15: https://www.mediafir...r8dp4ykcp55s6u8
Beta 1.14: http://www.mediafire...htaslua1.14.jar
Beta 1.13: https://www.mediafir...2f4j5d8wbk8czpb
Beta 1.12: https://www.mediafir...gy58677g3knf5ga
Beta 1.1: https://www.mediafir...38qdwtorwmngdfm
Beta 1.0: http://www.mediafire...dluaproject.jar
ChangelogBeta 1.1:
- Added instanceof keyword.
- Disallow variable names that start with _ool_.
- Added foreach keyword
- Fixed include issue
Beta 1.12:
- Identifiers can now have numbers
- Function names may now contain dots (someVar.someOtherVar()).
Beta 1.13:
- setVar context now uses funcCallArgs and funcDeclArgs instead of varHeader.
- Relative paths are now allowed in the -f argument.
Beta 1.15:
- Class names can now contain dots and other things
- Added Stream API
- Documented all APIs
Documentation: here
Cons of using this preprocessor
  • Hard to debug. The compiled result is all compressed into one line. Due to this, it is hard to debug.
Help me with names!
I would like to name this project somehow, so please give me some ideas!
Edited on 19 November 2017 - 09:26 AM
Midnightas #2
Posted 19 December 2016 - 07:12 AM
Uploaded beta 1.1. Changes in the changelog.
Also finally documented the lambda feature that was there from the start.
exosceleton #3
Posted 19 December 2016 - 08:32 AM
This is well and truly amazing. Great job.
jv110 #4
Posted 19 December 2016 - 06:55 PM
Does it really force you to use semicolons?

Also, the name of the ?: operator is conditional operator, not ternary operator. "Ternary" just says it has 3 arguments.
Midnightas #5
Posted 19 December 2016 - 08:19 PM
Does it really force you to use semicolons?

Also, the name of the ?: operator is conditional operator, not ternary operator. "Ternary" just says it has 3 arguments.
Yes, it does currently. Although this is beta, so this may change later to be optional.
And the name of the operator has both names, it's just that "ternary operator" is used by the minority.
H4X0RZ #6
Posted 19 December 2016 - 09:23 PM
Does it really force you to use semicolons?

Also, the name of the ?: operator is conditional operator, not ternary operator. "Ternary" just says it has 3 arguments.
Yes, it does currently. Although this is beta, so this may change later to be optional.
And the name of the operator has both names, it's just that "ternary operator" is used by the minority.

How are you "preprocessing" this exactly? Is it actually analyzing the code, building an AST and then "rebuilds" Lua source from that, or does it "just" replace some stuff with something else?

After seeing this I decided to work on something a bit like this too: This compiles from a custom language to Lua, though (and isn't feature complete at all + really needs to be redone)
Edited on 19 December 2016 - 08:30 PM
Midnightas #7
Posted 19 December 2016 - 09:31 PM
Does it really force you to use semicolons?

Also, the name of the ?: operator is conditional operator, not ternary operator. "Ternary" just says it has 3 arguments.
Yes, it does currently. Although this is beta, so this may change later to be optional.
And the name of the operator has both names, it's just that "ternary operator" is used by the minority.

How are you "preprocessing" this exactly? Is it actually analyzing the code, building an AST and then "rebuilds" Lua source from that, or does it "just" replace some stuff with something else?

After seeing this I decided to work on something a bit like this too: This compiles from a custom language to Lua, though (and isn't feature complete at all + really needs to be redone)
This uses ANTLR4. Which yes, It does built an AST and rebuilds a Lua file.
In ANTLR4 you just need to create a grammar file, and then it creates the lexer for you. The parsing is your own work, though.
Edited on 19 December 2016 - 08:32 PM
H4X0RZ #8
Posted 19 December 2016 - 09:41 PM
Oh, that sounds interesting! I once tried to use ANTLR but I always failed, either at writing the grammar, or at compiling the AST.

Well done!
InternetUnexplorer #9
Posted 19 December 2016 - 10:24 PM
Oh, that sounds interesting! I once tried to use ANTLR but I always failed, either at writing the grammar, or at compiling the AST.
Well done!
There are plenty of grammars already written for Antlr4. Such as this one:
https://github.com/antlr/grammars-v4/blob/master/lua/Lua.g4

Excuse the formatting, I'm on mobile.
Midnightas #10
Posted 19 December 2016 - 10:27 PM
Oh, that sounds interesting! I once tried to use ANTLR but I always failed, either at writing the grammar, or at compiling the AST.
Well done!
There are plenty of grammars already written for Antlr4. Such as this one:
https://github.com/a...ster/lua/Lua.g4

Excuse the formatting, I'm on mobile.
Oh wow, how did I forget about that repo? That would've saved me so much time, and this compiler still does not feature many of Lua's syntax features.
Pyuu #11
Posted 19 December 2016 - 11:47 PM
Awesome program! You should use Github or something else to host though. The admins don't like closed-source here.
jv110 #12
Posted 20 December 2016 - 12:59 AM
It's not hard to write a Lua grammar without semicolons. In fact, I find it even harder to write a grammar with semicolons
Midnightas #13
Posted 20 December 2016 - 07:28 AM
Awesome program! You should use Github or something else to host though. The admins don't like closed-source here.
Thank you! And yes, I've added a link to the GitHub repo.
Midnightas #14
Posted 20 December 2016 - 03:53 PM
Uploaded 1.12. Changes in the changelog.
Midnightas #15
Posted 20 December 2016 - 07:41 PM
It's not hard to write a Lua grammar without semicolons. In fact, I find it even harder to write a grammar with semicolons
I did not say It's hard. It's a design choice. As I have said, this is subject to change.
Pyuu #16
Posted 22 December 2016 - 01:30 AM
This project inspired me to write something earlier… would you mind if I post a Pure Lua implementation of this (as in converting the Java program to Lua) if I can get it to work? (I'll follow the terms as stated in the https://creativecomm...nses/by-sa/4.0/ license you provided in your github.) This is a very cool project and I'd love to build on it, but I don't like Java personally.

Also, https://github.com/lvivtotoro/luapreproc/issues/1 having an issue with this. Using the latest build btw.
Edited on 22 December 2016 - 12:49 AM
Midnightas #17
Posted 22 December 2016 - 07:25 AM
Added version 1.13.

This project inspired me to write something earlier… would you mind if I post a Pure Lua implementation of this (as in converting the Java program to Lua) if I can get it to work? (I'll follow the terms as stated in the https://creativecomm...nses/by-sa/4.0/ license you provided in your github.) This is a very cool project and I'd love to build on it, but I don't like Java personally.

Also, https://github.com/l...reproc/issues/1 having an issue with this. Using the latest build btw.
No, I don't mind! Go for it, although converting everything in the parser package will be a pain, since it was machine-generated.
Edited on 22 December 2016 - 06:25 AM
Midnightas #18
Posted 02 January 2017 - 03:40 PM
Had to change the name to something else as requested on GitHub.
Midnightas #19
Posted 10 March 2017 - 06:29 PM
I'm adding in the switch statement but I don't know how to make it look Lua-like.

This is what I've got so far:
switch someNumber if
  case 1 then
   
  end
  case 2 then
   
  end
end
supernicejohn #20
Posted 10 March 2017 - 06:47 PM
Why only numbers? Would be cool to see something really powerful, like all data types mixed together, that would be really useful!
Also I'd say drop the 'if' at the end of the line, but we'll see what others think of it.
Midnightas #21
Posted 10 March 2017 - 06:50 PM
Why only numbers? Would be cool to see something really powerful, like all data types mixed together, that would be really useful!
Also I'd say drop the 'if' at the end of the line, but we'll see what others think of it.
The numbers are just an example. Any expression can be thrown in there.
Yeah, the "if" makes it a lot more verbose.
hbomb79 #22
Posted 10 March 2017 - 08:17 PM
Perhaps?


switch someNumber
  case 1 then
  
  case 2 then
 
  default then
end
Midnightas #23
Posted 10 March 2017 - 09:15 PM
Perhaps?


switch someNumber
  case 1 then
  
  case 2 then

  default then
end
Oh yeah, I completely forgot about the default case :P/>
That actually looks very clean. 'll do that!
Midnightas #24
Posted 11 March 2017 - 08:18 AM
v1.14!
I don't remember much I've added, but looking at the commit changes, I've added a switch statement and some bug fixes.
Download and "switch" tutorial in the main post.
Midnightas #25
Posted 15 May 2017 - 11:22 PM
Beta 1.15! Honestly it should've been 1.2 already.
Added a stream API, documentation in the now-updated main post
Other things have been added
Midnightas #26
Posted 19 November 2017 - 10:28 AM
I completely rewrote MLua from scratch, since the old implementation was way to buggy, and wasn't even a superset of Lua.
Anyways, after a couple of bug fixes and updates, I might discontinue this, since I've lost faith in Minecraft after the Better Together update.