philiproman / optic-lua-dev Goto Github PK
View Code? Open in Web Editor NEWLicense: BSD 2-Clause "Simplified" License
License: BSD 2-Clause "Simplified" License
The current design is flawed and does not permit correct indentation in some cases, such as function bodies.
The current model is nearly unmaintainable, does not support colon call syntax and has several known bugs. Example:
local a = {
b = function()
return {
c = 5
}
end
}
print(a.b().c) -- expected "5" got "table 0x3754a4bf"
Implement "and", "or" and "not" operators with lazy evaluation where required.
The compiler currently doesn't support "~=" and "//" operators.
Local declaration without initialization throws an error during parsing. Standard Lua and LuaJit accept such statements.
Operator functions from runtime library should invoke metamethods when necessary.
For-range loops where start index is greater than end index should behave as if step was -1
For-range loops where step is negative should use ">=" limit comparison instead of "<="
An ideal solution would avoid duplicating the loop body.
For floating-point comparisons (x < y) is not the same as not (x >= y) in the presence of NaNs.
Proof:
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> z = 0/0
> =z
-nan
> return z>z
false
> return z<z
false
> return z>=z
false
> return not (z>=z)
true
This will allow using Java keywords as Lua local variable names. Ideally the names should still be human readable.
Add the option to launch the compiler as an interactive shell which reads statements line-by-line and compiles each statement before executing.
This would greatly improve the efficiency of debugging the compiler.
f2 = function() return "one", "two" end
print(f2())
-- one two
print(f2(), "three")
-- [one, two] three
Refactoring table implementation caused this bug.
The current representation is missing several features:
While test coverage reports are now being generated upon build, there is still no integration with GitHub.
"\n"
in Lua source code causes a newline character to be written in the Java source during compilation, which then causes a compiler error since Java string literals may not contain newlines. This happens because the parser converts the "\n"
within string literals to actual newlines.
The options baseName
and classifier
for Jar tasks have been deprecated in favor of archiveBaseName
and archiveClassifier
.
The removal of variable-length registers has caused a bug to appear (found on ir_refactor
branch):
function f() print "Hit!"; return 1, 2, 3 end
local a, b, c, d = 0, f()
Expected output:
Hit!
Actual output:
Hit!
Hit!
Hit!
There is a class for compiling Lua sources to JVM bytecode but no way to access it from the command line.
Since we have fine-grained control over the array allocation and going out of scope, these arrays can be pooled and reused.
Lua strings are simply arrays of bytes (and often are used to store binary data). Seems like byte buffers would be a better fit for this (and would also allow better low-level manipulations, if necessary).
We have to manually intern the string literals, by storing them as constants.
Stack traces from generated code should contain line numbers.
Ideally, the stack trace could even show the respective Lua source file and line.
While we can't assume the type of expressions like f() + g()
due to the presence of metatables, we can speculate that variables which use standard operators are primitive and generate a fast path.
Add missing functions from standard library.
Kotlin is used in just a few places in this project. Removing it will simplify and speed up the build process as well as reduce the size of the shadow jar.
The original goal of Message API was to implement an error list, but now it has turned into a full-blown (and horrible in terms of maintainability) logging framework. This should be fixed.
Users should be able to manipulate arbitrary Java objects, classes and methods from Lua code as if they were Lua tables and functions. There should also be special functions for operations provided by the language itself which aren't available through standard libraries, like array creation, etc. Example Lua code:
local list = ArrayList.new()
list:addAll {"a", "b", "c"}
print(list:toString())
local sort = Arrays.sort
local array = "Hello, world!".toByteArray()
sort(array)
System.out.write(array)
There should be sensible operators available on the types, for example instances of java.util.Map
or java.util.List
should support the index access and length operators.
Java allows method overloading and there is no way to correctly choose a single overload in the general case. For example:
local write = OutputStream.write -- write(int) or write(byte[])?
As such, the obtained function is not a direct handle to a specific method, but rather a dynamic dispatch proxy, which will decide which method to call depending on argument types.
Still, there are several cases where it is not possible to determine the function that should be called, such as, for example, Math.round(double)
versus Math.round(float)
. In these cases, the proxy should prefer primitives with larger capacity.
When the argument is null or for any other reason there exists a conflict between overloads, the proxy would be allowed to pick any arbitrary overload.
If creating a full FFI interface turns out too difficult, the project should at least support converting a Java method to Lua function by wrapping the method with type adapter code.
Evaluating
(function() return function() return 1 end end)()()
in Lua 5.3 yields 1
but in optic-lua it returns function 2dc54ad4
Interestingly, evaluating
f = function()
return function()
return 1
end
end
a = f()
print(a())
prints 1
which is the correct output. That suggests that the issue is caused by the flattening process.
Essentially, the problem is that the statement:
print(((function() return 1, 2, 3 end)()))
in standard Lua 5.3 prints:
1
whereas in optic-lua it prints:
1 2 3
This doesn't usually cause issues, but it is still non-standard behaviour.
Lua parser currently does not understand expression "a ^ -b". Standard Lua 5.3 interpreter accepts this as valid code.
An expression in form of f(x, y, ...)
where f is a final local (or final upvalue) variable should call the body of f
directly. In the ideal case, argument checks could be lifted out of the function.
Integration tests take quite a long time to run, they should not be a part of the gradle test
build cycle.
Useful link: https://www.michael-bull.com/blog/2016/06/04/separating-integration-and-unit-tests-with-gradle
Previous link died, here is another one: https://blog.inspeerity.com/gradle/integration-and-unit-separate-gradle-tasks/
Create a contributing guide, including code formatting style.
The build process should produce a Jar that contains only the runtime API classes.
Requirements:
optic.lua.runtime
packageTest case:
local function fact(n)
if(n <= 1) then
return 1
else
return n * fact(n-1)
end
end
Will currently throw an error because inside the function body, "fact" is considered global.
Note that the next example must NOT work the same way, due to Lua language rules:
local fact = function(n)
if(n <= 1) then
return 1
else
return n * fact(n-1)
end
end
The local x = function() ... end
and local function x() ... end
are NOT semantically equal - the second notation declares "x" BEFORE evaluating function body!
There should be an option to bypass hash-table lookup for the standard library. Sample code:
local x = tonumber(io.read()) + 1
Currently would generate this:
Object x = add(call(getglobal("tonumber"), call(index(getglobal("io"), "read"))), 1);
If the user is willing to sacrifice the ability to dynamically replace these functions, we could instead generate code like this:
int x = __tonumber(_ioread()) + 1
A similar mechanism could be used in implementing FFI (#18)
local function f()
return true
end
print(f() or g())
Running the above script causes an error due to trying to call a nil value ("g"). In standard Lua, the script prints "true" because of lazy evaluation. Looking at the generated Java code, it's clear that arguments to logical operators are evaluated eagerly (look below the comment "// line 5")
import optic.lua.runtime.*;
import static optic.lua.runtime.DynamicOps.*;
import static optic.lua.runtime.ListOps.*;
import optic.lua.runtime.invoke.*;
import java.util.Iterator;
public class logic_dlua {
public static Object[] run(final LuaContext context_v4, Object[] args) { if(1 == 1) {
final CallSite call_site_vA = context_v4.callSite(4);
final CallSite call_site_v9 = context_v4.callSite(3);
final CallSite call_site_v8 = context_v4.callSite(2);
final FunctionFactory function_factory_v6 = context_v4.functionFactory(1);
// line 1
final Object L_f;
L_f =
new LuaFunction(function_factory_v6){ Object[] call(LuaContext context_v7, Object[] argsv5) { if(1==1) {
// line 2
return list(true);
} return EMPTY; }}
;
// line 5
Object v1 = get(call_site_v8.invoke(context_v4, L_f,list()), 0);
Object v2 = get(call_site_v9.invoke(context_v4, context_v4.getGlobal("g"),list()), 0);
call_site_vA.invoke(context_v4, context_v4.getGlobal("print"),list(((Object)(v1) == null || (Object)(v1) == Boolean.FALSE ? (Object)(v2) : (Object)(v1))));
} return EMPTY; }
public static void main(String... args) {
run(LuaContext.create(), args);
}
}
The current implementation is a naive java.util.HashMap
with additional overhead for keeping track of length and max index. A better implementation is needed, preferably with special treatment for numeric keys and values.
Information in README should include:
Currently the jar of this project weighs 205 KB, while the full jar with dependencies (which is the one you'd use to run the actual compiler) is 19 MB!
Typing the following code in interactive shell:
function f() end
results in the following exception:
[main] ERROR optic.lua.io.InteractiveShell - Uncaught error
java.lang.IllegalArgumentException: Line number must be greater than 0
at optic.lua.asm.Step$LineNumber.<init>(Step.java:216)
at optic.lua.asm.StepFactory.lineNumber(StepFactory.java:82)
at optic.lua.asm.MutableFlattener.flatten(MutableFlattener.java:60)
at optic.lua.asm.MutableFlattener.flatten(MutableFlattener.java:48)
at optic.lua.io.LuaToJavaCompiler.compile(LuaToJavaCompiler.java:15)
at optic.lua.io.InteractiveShell.evaluate(InteractiveShell.java:93)
at optic.lua.io.InteractiveShell.run(InteractiveShell.java:73)
at optic.lua.Main.main(Main.java:74)
The current parser contains several bugs and is quite difficult to use. Apparently, ANTLR provides a grammar for Lua here: https://github.com/antlr/grammars-v4/tree/master/lua .
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.