├── .gitignore
├── .travis.yml
├── README.md
├── benchmarks
├── fibonacci.lua
└── mandelbrot.lua
├── bin
└── luatruffle
├── pom.xml
└── src
├── main
└── java
│ └── org
│ └── luatruffle
│ └── main
│ ├── Main.java
│ ├── builtins
│ ├── LuaOSClockBuiltin.java
│ └── LuaPrintBuiltin.java
│ ├── nodes
│ ├── LuaBinaryNode.java
│ ├── LuaBooleanConstantNode.java
│ ├── LuaExpressionNode.java
│ ├── LuaFunctionBodyNode.java
│ ├── LuaLongConstantNode.java
│ ├── LuaNode.java
│ ├── LuaObjectConstantNode.java
│ ├── LuaRootNode.java
│ ├── LuaStatementNode.java
│ ├── LuaTypes.java
│ ├── LuaUnaryNode.java
│ ├── call
│ │ ├── LuaAbstractDispatchNode.java
│ │ ├── LuaDirectDispatchNode.java
│ │ ├── LuaFunctionCall.java
│ │ ├── LuaGenericDispatchNode.java
│ │ └── LuaUninitializedDispatchNode.java
│ ├── expressions
│ │ ├── LuaFunctionBody.java
│ │ └── LuaFunctionNode.java
│ ├── local
│ │ ├── LuaReadArgumentNode.java
│ │ ├── LuaReadLocalVariableNode.java
│ │ └── LuaWriteLocalVariableNode.java
│ ├── operations
│ │ ├── arithmetic
│ │ │ ├── LuaAddNode.java
│ │ │ ├── LuaDivisionOperation.java
│ │ │ ├── LuaExponentiationNode.java
│ │ │ ├── LuaMultiplicationNode.java
│ │ │ ├── LuaNegateNode.java
│ │ │ └── LuaSubtractionNode.java
│ │ └── relational
│ │ │ ├── LuaEqualsNode.java
│ │ │ ├── LuaGreaterOrEqualsNode.java
│ │ │ ├── LuaGreaterThanNode.java
│ │ │ ├── LuaLessOrEqualsNode.java
│ │ │ └── LuaLessThanNode.java
│ └── statements
│ │ ├── LuaBlockNode.java
│ │ ├── LuaBreakNode.java
│ │ ├── LuaIfNode.java
│ │ ├── LuaNopNode.java
│ │ ├── LuaReturnNode.java
│ │ ├── LuaWhileDoNode.java
│ │ └── controlflow
│ │ ├── LuaBreakException.java
│ │ └── LuaReturnException.java
│ ├── runtime
│ ├── LuaContext.java
│ ├── LuaFunction.java
│ ├── LuaFunctionRegistry.java
│ └── LuaNull.java
│ └── translator
│ └── Translator.java
└── test
├── java
└── org
│ └── luatruffle
│ └── main
│ └── translator
│ ├── ArithmeticOperatorsTest.java
│ ├── BaseTranslatorTest.java
│ ├── MethodDefinitionTest.java
│ ├── RelationalOperators.java
│ ├── TranslatorTest.java
│ ├── ValueTypesTest.java
│ └── VariablesTest.java
└── resources
├── fibonacci.lua
├── functions.lua
├── ifthenelse.lua
├── numeric_for.lua
├── numeric_for2.lua
├── numeric_for3.lua
└── numeric_for_dynamic.lua
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/*
2 | *.iml
3 | target/*
4 | *.class
5 | .classpath
6 | .project
7 | .settings
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 | - oraclejdk7
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LuaTruffle - A Java implementation of the Lua language using Truffle
2 |
3 | Master: [](https://travis-ci.org/lucasallan/LuaTruffle)
4 |
5 | ## Compiling
6 |
7 | mvn package
8 |
9 | ## Running
10 |
11 | bin/luatruffle my.lua
12 |
13 | ## Running With Graal
14 |
15 | Download one of:
16 |
17 | * http://lafo.ssw.uni-linz.ac.at/graalvm/openjdk-8-graalvm-b132-linux-x86_64-0.5.tar.gz
18 | * http://lafo.ssw.uni-linz.ac.at/graalvm/openjdk-8-graalvm-b132-macosx-x86_64-0.5.tar.gz
19 |
20 | Then run:
21 |
22 | JAVACMD=../graalvm-jdk1.8.0/bin/java bin/luatruffle my.lua
23 |
24 | ## Options
25 |
26 | To pass options to the JVM, prefix with `-J`. For example, `-J-Xmx1G`.
27 |
28 | ## Performance
29 |
30 | Fibonacci is of course a terrible benchmark, but it's all we can run at the
31 | moment. We also probably don't implement Lua correctly yet.
32 |
33 | Compare:
34 |
35 | lua src/test/resources/fibonacci.lua
36 | luajit src/test/resources/fibonacci.lua
37 | JAVACMD=../graalvm-jdk1.8.0/bin/java bin/luatruffle src/test/resources/fibonacci.lua
38 |
39 | We're around 6x compared to `lua`, and a third as fast as `luajit`.
40 |
--------------------------------------------------------------------------------
/benchmarks/fibonacci.lua:
--------------------------------------------------------------------------------
1 | function fibonacci(n)
2 | if n < 2 then
3 | return n
4 | end
5 | return fibonacci(n-1) + fibonacci(n-2)
6 | end
7 |
8 | while true do
9 | local start = os.clock()
10 | print(fibonacci(40))
11 | print(os.clock() - start)
12 | end
13 |
--------------------------------------------------------------------------------
/benchmarks/mandelbrot.lua:
--------------------------------------------------------------------------------
1 | -- The Computer Language Shootout
2 | -- http://shootout.alioth.debian.org/
3 | -- contributed by Mike Pall
4 |
5 | function mandelbro(width)
6 | local height, wscale = width, 2/width
7 | local m, limit2 = 50, 4.0
8 | local iter = 0
9 |
10 | for y=0,height-1 do
11 | local Ci = 2*y / height - 1
12 | for xb=0,width-1,8 do
13 | local bits = 0
14 | local xbb = xb+7
15 | local loopend
16 | if xbb < width then loopend = xbb else loopend = width - 1 end
17 | for x=xb,loopend do
18 | bits = bits + bits
19 | local Zr, Zi, Zrq, Ziq = 0.0, 0.0, 0.0, 0.0
20 | local Cr = x * wscale - 1.5
21 | for i=1,m do
22 | local Zri = Zr*Zi
23 | Zr = Zrq - Ziq + Cr
24 | Zi = Zri + Zri + Ci
25 | Zrq = Zr*Zr
26 | Ziq = Zi*Zi
27 | iter = iter + 1
28 | if Zrq + Ziq > limit2 then
29 | bits = bits + 1
30 | break
31 | end
32 | end
33 | end
34 | if xbb >= width then
35 | for x=width,xbb do bits = bits + bits + 1 end
36 | end
37 | end
38 | end
39 | return iter
40 | end
41 |
42 | while true do
43 | local t1 = os.clock()
44 | mandelbro(1000)
45 | print(os.clock()-t1)
46 | end
47 |
--------------------------------------------------------------------------------
/bin/luatruffle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | JAVACMD=${JAVACMD:=java}
4 | LUATRUFFLE_JAR=${LUATRUFFLE_JAR:=target/luatruffle-complete-0.1-SNAPSHOT.jar}
5 |
6 | PROGRAM_ARGS=""
7 | JAVA_ARGS=""
8 |
9 | for opt in "$@"
10 | do
11 | case $opt in
12 | -J*)
13 | opt=${1:2}
14 | JAVA_ARGS="$JAVA_ARGS $opt" ;;
15 | *)
16 | PROGRAM_ARGS="$PROGRAM_ARGS $opt" ;;
17 | esac
18 | done
19 |
20 | $JAVACMD $JAVA_ARGS -jar $LUATRUFFLE_JAR $PROGRAM_ARGS
21 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.luatruffle
7 | luatruffle
8 | 0.1-SNAPSHOT
9 |
10 |
11 |
12 |
13 | true
14 |
15 |
16 | false
17 |
18 | truffle
19 | http://lafo.ssw.uni-linz.ac.at/nexus/content/repositories/releases/
20 |
21 |
22 |
23 |
24 |
25 | org.luaj
26 | luaj-jse
27 | 3.0
28 |
29 |
30 | com.oracle
31 | truffle
32 | 0.6
33 |
34 |
35 | com.oracle
36 | truffle-dsl-processor
37 | 0.6
38 | provided
39 |
40 |
41 | junit
42 | junit
43 | 4.11
44 | test
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.apache.maven.plugins
52 | maven-shade-plugin
53 | 2.3
54 |
55 |
56 | package
57 |
58 | shade
59 |
60 |
61 | ${project.artifactId}-complete-${project.version}
62 |
63 |
64 | org.luatruffle.main.Main
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | maven-compiler-plugin
76 | 3.1
77 |
78 | 1.7
79 | 1.7
80 |
81 |
82 |
83 | anno
84 | process-resources
85 |
86 | compile
87 |
88 |
89 |
90 | com.oracle.truffle.dsl.processor.TruffleProcessor
91 |
92 | target/generated-sources
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/Main.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main;
2 |
3 | import org.luatruffle.main.runtime.LuaContext;
4 | import org.luaj.vm2.ast.Chunk;
5 | import org.luaj.vm2.parser.LuaParser;
6 |
7 | import java.io.FileInputStream;
8 |
9 | /**
10 | * Created by Lucas Allan Amorim on 2014-09-08.
11 | */
12 | public class Main {
13 |
14 | public static void main(String args[]) {
15 | try {
16 | if (args.length != 1) {
17 | System.err.println("usage: luatruffle file");
18 | System.exit(1);
19 | }
20 |
21 | final String file = args[0];
22 |
23 | LuaParser parser = new LuaParser(new FileInputStream(file));
24 | Chunk chunk = parser.Chunk();
25 |
26 | new LuaContext().executeMain(chunk);
27 |
28 | } catch (Exception e) {
29 | e.printStackTrace();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/builtins/LuaOSClockBuiltin.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.builtins;
2 |
3 | import com.oracle.truffle.api.dsl.Specialization;
4 | import com.oracle.truffle.api.nodes.NodeInfo;
5 | import org.luatruffle.main.nodes.LuaNode;
6 |
7 | /**
8 | * Created by Lucas Allan Amorim on 2014-09-14.
9 | */
10 | @NodeInfo(shortName = "osclock")
11 | public abstract class LuaOSClockBuiltin extends LuaNode {
12 |
13 | @Specialization
14 | public double osclock() {
15 | return System.nanoTime() / 1e9;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/builtins/LuaPrintBuiltin.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.builtins;
2 |
3 | import com.oracle.truffle.api.CompilerDirectives;
4 | import com.oracle.truffle.api.dsl.NodeChild;
5 | import com.oracle.truffle.api.dsl.Specialization;
6 | import com.oracle.truffle.api.nodes.NodeInfo;
7 | import org.luatruffle.main.nodes.LuaNode;
8 |
9 | /**
10 | * Created by Lucas Allan Amorim on 2014-09-14.
11 | */
12 | @NodeInfo(shortName = "print")
13 | @NodeChild(value = "value", type = LuaNode.class)
14 | public abstract class LuaPrintBuiltin extends LuaNode {
15 |
16 | @CompilerDirectives.TruffleBoundary
17 | @Specialization
18 | public long print(long value) {
19 | System.out.println(value);
20 | return value;
21 | }
22 |
23 | @CompilerDirectives.TruffleBoundary
24 | @Specialization
25 | public boolean print(boolean value) {
26 | System.out.println(value);
27 | return value;
28 | }
29 |
30 | @CompilerDirectives.TruffleBoundary
31 | @Specialization
32 | public String print(String value) {
33 | System.out.println(value);
34 | return value;
35 | }
36 |
37 | @CompilerDirectives.TruffleBoundary
38 | @Specialization
39 | public Object print(Object value) {
40 | System.out.println(value);
41 | return value;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaBinaryNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import com.oracle.truffle.api.dsl.NodeChild;
4 | import com.oracle.truffle.api.dsl.NodeChildren;
5 |
6 | /**
7 | * Created by lucas on 2014-09-14.
8 | */
9 | @NodeChildren({@NodeChild("leftNode"), @NodeChild("rightNode")})
10 | public abstract class LuaBinaryNode extends LuaExpressionNode {
11 |
12 | protected boolean isEitherString(Object a, Object b) {
13 | return a instanceof String || b instanceof String;
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaBooleanConstantNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 |
5 | /**
6 | * Created by Lucas Allan Amorim on 2014-09-11.
7 | */
8 | public class LuaBooleanConstantNode extends LuaExpressionNode {
9 |
10 | private final boolean value;
11 |
12 | public LuaBooleanConstantNode(boolean value) {
13 | this.value = value;
14 | }
15 |
16 | @Override
17 | public Object execute(VirtualFrame frame) {
18 | return executeBoolean(frame);
19 | }
20 |
21 | @Override
22 | public boolean executeBoolean(VirtualFrame frame) {
23 | return value;
24 | }
25 |
26 | public String toString(){
27 | return "Constant: " + value;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaExpressionNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | /**
4 | * Created by Lucas Allan Amorim on 2014-09-08.
5 | */
6 | public abstract class LuaExpressionNode extends LuaNode {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaFunctionBodyNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 | import org.luatruffle.main.nodes.statements.controlflow.LuaReturnException;
5 | import org.luatruffle.main.runtime.LuaNull;
6 |
7 | /**
8 | * Created by Lucas Allan Amorim on 2014-09-10.
9 | */
10 | public class LuaFunctionBodyNode extends LuaExpressionNode {
11 |
12 | @Child private LuaStatementNode statementNode;
13 |
14 | public LuaFunctionBodyNode(LuaStatementNode statementNode) {
15 | super();
16 | this.statementNode = statementNode;
17 | }
18 |
19 | @Override
20 | public Object execute(VirtualFrame frame) {
21 | try {
22 | statementNode.executeVoid(frame);
23 | } catch (LuaReturnException ex) {
24 | return ex.result;
25 | }
26 | return LuaNull.SINGLETON;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaLongConstantNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 |
5 | /**
6 | * Created by Lucas Allan Amorim on 2014-09-11.
7 | */
8 | public class LuaLongConstantNode extends LuaExpressionNode {
9 |
10 | private final long value;
11 |
12 | public LuaLongConstantNode(long value) {
13 | this.value = value;
14 | }
15 |
16 | @Override
17 | public Object execute(VirtualFrame frame) {
18 | return executeLong(frame);
19 | }
20 |
21 | @Override
22 | public long executeLong(VirtualFrame frame) {
23 | return value;
24 | }
25 |
26 | public String toString(){
27 | return "Constant: " + value;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import com.oracle.truffle.api.dsl.TypeSystemReference;
4 | import com.oracle.truffle.api.frame.VirtualFrame;
5 | import com.oracle.truffle.api.nodes.Node;
6 | import com.oracle.truffle.api.nodes.UnexpectedResultException;
7 | import org.luatruffle.main.runtime.LuaFunction;
8 | import org.luatruffle.main.runtime.LuaNull;
9 |
10 | import java.math.BigInteger;
11 |
12 | /**
13 | * Created by Lucas Allan Amorim on 2014-09-10.
14 | */
15 | @TypeSystemReference(LuaTypes.class)
16 | public abstract class LuaNode extends Node {
17 |
18 | public abstract Object execute(VirtualFrame frame);
19 |
20 | public void executeVoid(VirtualFrame frame) {
21 | execute(frame);
22 | }
23 |
24 | public double executeDouble(VirtualFrame frame) throws UnexpectedResultException {
25 | return LuaTypesGen.LUATYPES.expectDouble(execute(frame));
26 | }
27 |
28 | public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
29 | return LuaTypesGen.LUATYPES.expectBoolean(execute(frame));
30 | }
31 |
32 | public long executeLong(VirtualFrame frame) throws UnexpectedResultException {
33 | return LuaTypesGen.LUATYPES.expectLong(execute(frame));
34 | }
35 |
36 | public BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException {
37 | return LuaTypesGen.LUATYPES.expectBigInteger(execute(frame));
38 | }
39 |
40 | public String executeString(VirtualFrame frame) throws UnexpectedResultException {
41 | return LuaTypesGen.LUATYPES.expectString(execute(frame));
42 | }
43 |
44 | public LuaNull executeLuaNull(VirtualFrame frame) throws UnexpectedResultException {
45 | return LuaTypesGen.LUATYPES.expectLuaNull(execute(frame));
46 | }
47 |
48 | public LuaFunction executeLuaMethod(VirtualFrame frame) throws UnexpectedResultException {
49 | return LuaTypesGen.LUATYPES.expectLuaFunction(execute(frame));
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaObjectConstantNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 |
5 | /**
6 | * Created by Lucas Allan Amorim on 2014-09-11.
7 | */
8 | public class LuaObjectConstantNode extends LuaExpressionNode {
9 |
10 | private final Object value;
11 |
12 | public LuaObjectConstantNode(Object value) {
13 | this.value = value;
14 | }
15 |
16 | @Override
17 | public Object execute(VirtualFrame frame) {
18 | return value;
19 | }
20 |
21 | public String toString(){
22 | return "Constant: " + value;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaRootNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import com.oracle.truffle.api.frame.FrameDescriptor;
4 | import com.oracle.truffle.api.frame.VirtualFrame;
5 | import com.oracle.truffle.api.nodes.RootNode;
6 |
7 | /**
8 | * Created by Lucas Allan Amorim on 2014-09-08.
9 | */
10 | public class LuaRootNode extends RootNode {
11 |
12 | @Child protected LuaNode body;
13 |
14 | public LuaRootNode(LuaNode body, FrameDescriptor frameDescriptor) {
15 | super(null, frameDescriptor);
16 | this.body = body;
17 | }
18 |
19 | @Override
20 | public Object execute(VirtualFrame frame) {
21 | return body.execute(frame);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaStatementNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import com.oracle.truffle.api.CompilerAsserts;
4 | import com.oracle.truffle.api.frame.VirtualFrame;
5 |
6 | /**
7 | * Created by Lucas Allan Amorim on 2014-09-08.
8 | */
9 | public abstract class LuaStatementNode extends LuaNode {
10 |
11 | @Override
12 | public Object execute(VirtualFrame frame) {
13 | final String message = "Statements never return results";
14 | CompilerAsserts.neverPartOfCompilation(message);
15 | throw new UnsupportedOperationException(message);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaTypes.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import java.math.BigInteger;
4 |
5 | import com.oracle.truffle.api.dsl.*;
6 | import org.luatruffle.main.runtime.LuaFunction;
7 | import org.luatruffle.main.runtime.LuaNull;
8 |
9 | /**
10 | * Created by Lucas Allan Amorim on 2014-09-08.
11 | */
12 | @TypeSystem({ long.class, BigInteger.class, double.class, boolean.class, String.class, LuaNull.class, LuaFunction.class})
13 | public abstract class LuaTypes {
14 |
15 | @TypeCheck
16 | public boolean isLuaNull(Object value) {
17 | return value == LuaNull.SINGLETON;
18 | }
19 |
20 | @TypeCast
21 | public LuaNull asLuaNull(Object value) {
22 | assert isLuaNull(value);
23 | return LuaNull.SINGLETON;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/LuaUnaryNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes;
2 |
3 | import com.oracle.truffle.api.dsl.NodeChild;
4 | import com.oracle.truffle.api.dsl.NodeChildren;
5 |
6 | /**
7 | * Created by lucas on 2014-09-14.
8 | */
9 | @NodeChildren({@NodeChild("childNode")})
10 | public abstract class LuaUnaryNode extends LuaExpressionNode {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/call/LuaAbstractDispatchNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.call;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 | import com.oracle.truffle.api.nodes.Node;
5 | import org.luatruffle.main.runtime.LuaFunction;
6 |
7 | /**
8 | * Created by Lucas Allan Amorim on 2014-09-21.
9 | */
10 | public abstract class LuaAbstractDispatchNode extends Node {
11 |
12 | protected static final int INLINE_CACHE_SIZE = 4;
13 |
14 | protected abstract Object executeDispatch(VirtualFrame frame, LuaFunction function, Object[] arguments);
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/call/LuaDirectDispatchNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.call;
2 |
3 | import com.oracle.truffle.api.Assumption;
4 | import com.oracle.truffle.api.Truffle;
5 | import com.oracle.truffle.api.frame.VirtualFrame;
6 | import com.oracle.truffle.api.nodes.DirectCallNode;
7 | import com.oracle.truffle.api.nodes.InvalidAssumptionException;
8 | import org.luatruffle.main.runtime.LuaFunction;
9 |
10 | /**
11 | * Created by Lucas Allan Amorim on 2014-09-24.
12 | */
13 | public final class LuaDirectDispatchNode extends LuaAbstractDispatchNode {
14 |
15 | private final LuaFunction cachedMethod;
16 | @Child private DirectCallNode callCachedTargetNode;
17 | private final Assumption cachedTargetStable;
18 | @Child private LuaAbstractDispatchNode nextNode;
19 |
20 | public LuaDirectDispatchNode(LuaAbstractDispatchNode next, LuaFunction cachedFunction) {
21 | this.cachedMethod = cachedFunction;
22 | this.callCachedTargetNode = Truffle.getRuntime().createDirectCallNode(cachedFunction.getCallTarget());
23 | this.cachedTargetStable = cachedFunction.getCallTargetStable();
24 | this.nextNode = next;
25 | }
26 |
27 | @Override
28 | protected Object executeDispatch(VirtualFrame frame, LuaFunction function, Object[] arguments) {
29 | if (this.cachedMethod == function) {
30 | try {
31 | cachedTargetStable.check();
32 | return callCachedTargetNode.call(frame, arguments);
33 | } catch (InvalidAssumptionException ex) {
34 | replace(nextNode);
35 | }
36 | }
37 | return nextNode.executeDispatch(frame, function, arguments);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/call/LuaFunctionCall.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.call;
2 |
3 | import com.oracle.truffle.api.CompilerAsserts;
4 | import com.oracle.truffle.api.dsl.UnsupportedSpecializationException;
5 | import com.oracle.truffle.api.frame.VirtualFrame;
6 | import com.oracle.truffle.api.nodes.ExplodeLoop;
7 | import com.oracle.truffle.api.nodes.Node;
8 | import com.oracle.truffle.api.nodes.UnexpectedResultException;
9 | import org.luatruffle.main.nodes.LuaExpressionNode;
10 | import org.luatruffle.main.runtime.LuaFunction;
11 |
12 | /**
13 | * Created by Lucas Allan Amorim on 2014-09-18.
14 | */
15 | public final class LuaFunctionCall extends LuaExpressionNode {
16 |
17 | @Child protected LuaExpressionNode functionNode;
18 | @Children protected final LuaExpressionNode[] argumentNodes;
19 | @Child protected LuaAbstractDispatchNode dispatchNode;
20 |
21 | public LuaFunctionCall(LuaExpressionNode[] argumentNodes, LuaExpressionNode functionNode, LuaAbstractDispatchNode abstractDispatchNode) {
22 | this.argumentNodes = argumentNodes;
23 | this.functionNode = functionNode;
24 | this.dispatchNode = abstractDispatchNode;
25 | }
26 |
27 | @Override
28 | @ExplodeLoop
29 | public Object execute(VirtualFrame frame) {
30 | try {
31 | LuaFunction method = functionNode.executeLuaMethod(frame);
32 | CompilerAsserts.compilationConstant(argumentNodes.length);
33 |
34 | Object[] argumentValues = new Object[argumentNodes.length];
35 | for (int i = 0; i < argumentNodes.length; i++) {
36 | argumentValues[i] = argumentNodes[i].execute(frame);
37 | }
38 | return dispatchNode.executeDispatch(frame, method, argumentValues);
39 | } catch (UnexpectedResultException ex) {
40 | throw new UnsupportedSpecializationException(this, new Node[]{functionNode}, ex.getResult());
41 | }
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/call/LuaGenericDispatchNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.call;
2 |
3 | import com.oracle.truffle.api.Truffle;
4 | import com.oracle.truffle.api.frame.VirtualFrame;
5 | import com.oracle.truffle.api.nodes.IndirectCallNode;
6 | import org.luatruffle.main.runtime.LuaFunction;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-24.
10 | */
11 | public class LuaGenericDispatchNode extends LuaAbstractDispatchNode {
12 |
13 | @Child private IndirectCallNode callNode = Truffle.getRuntime().createIndirectCallNode();
14 |
15 | @Override
16 | protected Object executeDispatch(VirtualFrame frame, LuaFunction function, Object[] arguments) {
17 | return callNode.call(frame, function.getCallTarget(), arguments);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/call/LuaUninitializedDispatchNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.call;
2 |
3 | import com.oracle.truffle.api.CompilerDirectives;
4 | import com.oracle.truffle.api.frame.VirtualFrame;
5 | import com.oracle.truffle.api.nodes.Node;
6 | import org.luatruffle.main.runtime.LuaFunction;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-24.
10 | */
11 | public final class LuaUninitializedDispatchNode extends LuaAbstractDispatchNode {
12 | @Override
13 | protected Object executeDispatch(VirtualFrame frame, LuaFunction function, Object[] arguments) {
14 | CompilerDirectives.transferToInterpreterAndInvalidate();
15 |
16 | Node cur = this;
17 | int depth = 0;
18 | while (cur.getParent() instanceof LuaAbstractDispatchNode) {
19 | cur = cur.getParent();
20 | depth++;
21 | }
22 | LuaFunctionCall methodNode = (LuaFunctionCall) cur.getParent();
23 |
24 | LuaAbstractDispatchNode replacement;
25 | if (function.getCallTarget() == null) {
26 | throw new UnsupportedOperationException("Call of undefined method: " + function.getName());
27 |
28 | } else if (depth < INLINE_CACHE_SIZE) {
29 | LuaAbstractDispatchNode next = new LuaUninitializedDispatchNode();
30 | replacement = new LuaDirectDispatchNode(next, function);
31 | replace(replacement);
32 |
33 | } else {
34 | replacement = new LuaGenericDispatchNode();
35 | methodNode.dispatchNode.replace(replacement);
36 | }
37 |
38 | return replacement.executeDispatch(frame, function, arguments);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/expressions/LuaFunctionBody.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.expressions;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 | import org.luatruffle.main.nodes.LuaExpressionNode;
5 | import org.luatruffle.main.nodes.LuaStatementNode;
6 | import org.luatruffle.main.nodes.statements.controlflow.LuaReturnException;
7 | import org.luatruffle.main.runtime.LuaNull;
8 |
9 | /**
10 | * Created by Lucas Allan Amorim on 2014-09-12.
11 | */
12 | public class LuaFunctionBody extends LuaExpressionNode{
13 |
14 | @Child private LuaStatementNode bodyNode;
15 |
16 | public LuaFunctionBody(LuaStatementNode bodyNode) {
17 | this.bodyNode = bodyNode;
18 | }
19 |
20 | @Override
21 | public Object execute(VirtualFrame frame) {
22 | try {
23 | bodyNode.executeVoid(frame);
24 | } catch (LuaReturnException ex) {
25 | return ex.result;
26 | }
27 |
28 | return LuaNull.SINGLETON;
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/expressions/LuaFunctionNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.expressions;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 | import org.luatruffle.main.nodes.LuaExpressionNode;
5 | import org.luatruffle.main.runtime.LuaFunction;
6 |
7 | /**
8 | * Created by Lucas Allan Amorim on 2014-09-24.
9 | */
10 | public final class LuaFunctionNode extends LuaExpressionNode {
11 |
12 | private final LuaFunction value;
13 |
14 | public LuaFunctionNode(LuaFunction value) {
15 | this.value = value;
16 | }
17 |
18 | public LuaFunction executeFunction(VirtualFrame frame) {
19 | return (LuaFunction) execute(frame);
20 | }
21 |
22 | public Object executeGeneric(VirtualFrame frame) {
23 | return execute(frame);
24 | }
25 |
26 | @Override
27 | public Object execute(VirtualFrame frame) {
28 | return value;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/local/LuaReadArgumentNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.local;
2 |
3 | import com.oracle.truffle.api.dsl.NodeField;
4 | import com.oracle.truffle.api.frame.FrameSlot;
5 | import com.oracle.truffle.api.frame.VirtualFrame;
6 | import org.luatruffle.main.nodes.LuaExpressionNode;
7 | import org.luatruffle.main.runtime.LuaNull;
8 |
9 | /**
10 | * Created by Lucas Allan Amorim on 2014-09-14.
11 | */
12 | @NodeField(name = "slot", type = FrameSlot.class)
13 | public class LuaReadArgumentNode extends LuaExpressionNode {
14 |
15 | private final int index;
16 |
17 | public LuaReadArgumentNode(int index) {
18 | this.index = index;
19 | }
20 |
21 | @Override
22 | public Object execute(VirtualFrame frame) {
23 | Object[] args = frame.getArguments();
24 | if (index < args.length) {
25 | return args[index];
26 | } else {
27 | return LuaNull.SINGLETON;
28 | }
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/local/LuaReadLocalVariableNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.local;
2 |
3 | import com.oracle.truffle.api.dsl.NodeField;
4 | import com.oracle.truffle.api.dsl.Specialization;
5 | import com.oracle.truffle.api.frame.FrameSlot;
6 | import com.oracle.truffle.api.frame.FrameSlotTypeException;
7 | import com.oracle.truffle.api.frame.VirtualFrame;
8 | import org.luatruffle.main.nodes.LuaExpressionNode;
9 |
10 | /**
11 | * Created by Lucas Allan Amorim on 2014-09-15.
12 | */
13 | @NodeField(name = "slot", type = FrameSlot.class)
14 | public abstract class LuaReadLocalVariableNode extends LuaExpressionNode {
15 |
16 | protected abstract FrameSlot getSlot();
17 |
18 | @Specialization(rewriteOn = FrameSlotTypeException.class)
19 | protected long readLong(VirtualFrame frame) throws FrameSlotTypeException {
20 | return frame.getLong(getSlot());
21 | }
22 |
23 | @Specialization(rewriteOn = FrameSlotTypeException.class)
24 | protected boolean readBoolean(VirtualFrame frame) throws FrameSlotTypeException {
25 | return frame.getBoolean(getSlot());
26 | }
27 |
28 | @Specialization(rewriteOn = FrameSlotTypeException.class)
29 | protected Object readObject(VirtualFrame frame) throws FrameSlotTypeException {
30 | return frame.getObject(getSlot());
31 | }
32 |
33 | @Specialization(contains = {"readLong", "readBoolean", "readObject"})
34 | protected Object read(VirtualFrame frame) {
35 | return frame.getValue(getSlot());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/local/LuaWriteLocalVariableNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.local;
2 |
3 | import com.oracle.truffle.api.CompilerDirectives;
4 | import com.oracle.truffle.api.dsl.NodeChild;
5 | import com.oracle.truffle.api.dsl.NodeField;
6 | import com.oracle.truffle.api.dsl.Specialization;
7 | import com.oracle.truffle.api.frame.FrameSlot;
8 | import com.oracle.truffle.api.frame.FrameSlotKind;
9 | import com.oracle.truffle.api.frame.VirtualFrame;
10 | import org.luatruffle.main.nodes.LuaExpressionNode;
11 |
12 | /**
13 | * Created by Lucas Allan Amorim on 2014-09-15.
14 | */
15 | @NodeChild("valueNode")
16 | @NodeField(name = "slot", type = FrameSlot.class)
17 | public abstract class LuaWriteLocalVariableNode extends LuaExpressionNode {
18 |
19 | protected abstract FrameSlot getSlot();
20 |
21 | @Specialization(guards = "isLongKind")
22 | protected long writeLong(VirtualFrame frame, long value) {
23 | frame.setLong(getSlot(), value);
24 | return value;
25 | }
26 |
27 | @Specialization(guards = "isBooleanKind")
28 | protected boolean writeBoolean(VirtualFrame frame, boolean value) {
29 | frame.setBoolean(getSlot(), value);
30 | return value;
31 | }
32 |
33 | @Specialization
34 | protected Object writeObject(VirtualFrame frame, Object value) {
35 | frame.setObject(getSlot(), value);
36 | return value;
37 | }
38 |
39 | protected boolean isLongKind() {
40 | return isKind(FrameSlotKind.Long);
41 | }
42 |
43 | protected boolean isBooleanKind() {
44 | return isKind(FrameSlotKind.Boolean);
45 | }
46 |
47 | private boolean isKind(FrameSlotKind kind) {
48 | if (getSlot().getKind() == kind) {
49 | return true;
50 | } else if (getSlot().getKind() == FrameSlotKind.Illegal) {
51 | CompilerDirectives.transferToInterpreterAndInvalidate();
52 | getSlot().setKind(kind);
53 | return true;
54 | } else {
55 | return false;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/arithmetic/LuaAddNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.arithmetic;
2 |
3 | import com.oracle.truffle.api.ExactMath;
4 | import com.oracle.truffle.api.dsl.Specialization;
5 | import org.luatruffle.main.nodes.LuaBinaryNode;
6 |
7 | import java.math.BigInteger;
8 |
9 | /**
10 | * Created by Lucas Allan Amorim on 2014-09-14.
11 | */
12 | public abstract class LuaAddNode extends LuaBinaryNode {
13 |
14 | @Specialization
15 | protected long add(long left, long right) {
16 | return ExactMath.addExact(left, right);
17 | }
18 |
19 | @Specialization
20 | protected BigInteger add(BigInteger left, BigInteger right) {
21 | return left.add(right);
22 | }
23 |
24 | @Specialization(guards = "isString")
25 | protected String add(Object left, Object right) {
26 | return left.toString() + right.toString();
27 | }
28 |
29 | protected boolean isString(Object a, Object b) {
30 | return a instanceof String || b instanceof String;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/arithmetic/LuaDivisionOperation.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.arithmetic;
2 |
3 | import com.oracle.truffle.api.dsl.Specialization;
4 | import org.luatruffle.main.nodes.LuaBinaryNode;
5 |
6 | import java.math.BigInteger;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-15.
10 | */
11 | public abstract class LuaDivisionOperation extends LuaBinaryNode {
12 |
13 | @Specialization
14 | protected long divide(long left, long right) {
15 | return left / right;
16 | }
17 |
18 | @Specialization
19 | protected BigInteger divide(BigInteger left, BigInteger right) {
20 | return left.divide(right);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/arithmetic/LuaExponentiationNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.arithmetic;
2 |
3 | import com.oracle.truffle.api.dsl.Specialization;
4 | import org.luatruffle.main.nodes.LuaBinaryNode;
5 |
6 | import java.math.BigInteger;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-15.
10 | */
11 | public abstract class LuaExponentiationNode extends LuaBinaryNode {
12 |
13 | @Specialization
14 | protected long pow(long left, long right) {
15 | return (long) Math.pow(left, right);
16 | }
17 |
18 | @Specialization
19 | protected BigInteger pow(BigInteger left, BigInteger right) {
20 | return left.pow(right.intValue());
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/arithmetic/LuaMultiplicationNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.arithmetic;
2 |
3 | import com.oracle.truffle.api.ExactMath;
4 | import com.oracle.truffle.api.dsl.Specialization;
5 | import org.luatruffle.main.nodes.LuaBinaryNode;
6 |
7 | import java.math.BigInteger;
8 |
9 | /**
10 | * Created by Lucas Allan Amorim on 2014-09-15.
11 | */
12 | public abstract class LuaMultiplicationNode extends LuaBinaryNode {
13 |
14 | @Specialization
15 | protected long multiply(long left, long right) {
16 | return ExactMath.multiplyExact(left, right);
17 | }
18 |
19 | @Specialization
20 | protected BigInteger multiply(BigInteger left, BigInteger right) {
21 | return left.multiply(right);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/arithmetic/LuaNegateNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.arithmetic;
2 |
3 | import com.oracle.truffle.api.ExactMath;
4 | import com.oracle.truffle.api.dsl.Specialization;
5 | import org.luatruffle.main.nodes.LuaBinaryNode;
6 | import org.luatruffle.main.nodes.LuaUnaryNode;
7 |
8 | import java.math.BigInteger;
9 |
10 | /**
11 | * Created by Lucas Allan Amorim on 2014-09-14.
12 | */
13 | public abstract class LuaNegateNode extends LuaUnaryNode {
14 |
15 | @Specialization
16 | protected long negate(long value) {
17 | return -value;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/arithmetic/LuaSubtractionNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.arithmetic;
2 |
3 | import com.oracle.truffle.api.ExactMath;
4 | import com.oracle.truffle.api.dsl.Specialization;
5 | import org.luatruffle.main.nodes.LuaBinaryNode;
6 |
7 | import java.math.BigInteger;
8 |
9 | /**
10 | * Created by Lucas Allan Amorim on 2014-09-15.
11 | */
12 | public abstract class LuaSubtractionNode extends LuaBinaryNode {
13 |
14 | @Specialization
15 | protected long subtract(long left, long right) {
16 | return ExactMath.subtractExact(left, right);
17 | }
18 |
19 | @Specialization
20 | protected double subtract(double left, double right) {
21 | return left - right;
22 | }
23 |
24 | @Specialization
25 | protected BigInteger subtract(BigInteger left, BigInteger right) {
26 | return left.subtract(right);
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/relational/LuaEqualsNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.relational;
2 |
3 | import com.oracle.truffle.api.dsl.Specialization;
4 | import org.luatruffle.main.nodes.LuaBinaryNode;
5 |
6 | import java.math.BigInteger;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-14.
10 | */
11 | public abstract class LuaEqualsNode extends LuaBinaryNode {
12 |
13 | @Specialization
14 | protected boolean isEquals(long left, long right) {
15 | return left == right;
16 | }
17 |
18 | @Specialization
19 | protected boolean isEquals(BigInteger left, BigInteger right) {
20 | return left.equals(right);
21 | }
22 |
23 | @Specialization(guards = "isEitherString")
24 | protected boolean isEquals(Object left, Object right) {
25 | return left.toString().equals(right.toString());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/relational/LuaGreaterOrEqualsNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.relational;
2 |
3 | import com.oracle.truffle.api.dsl.Specialization;
4 | import org.luatruffle.main.nodes.LuaBinaryNode;
5 |
6 | import java.math.BigInteger;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-14.
10 | */
11 | public abstract class LuaGreaterOrEqualsNode extends LuaBinaryNode {
12 |
13 | @Specialization
14 | protected boolean isGreaterOrEquals(long left, long right) {
15 | return left >= right;
16 | }
17 |
18 | @Specialization
19 | protected boolean isGreaterOrEquals(BigInteger left, BigInteger right) {
20 | return left.compareTo(right) >= 0;
21 | }
22 |
23 | @Specialization(guards = "isEitherString")
24 | protected boolean isGreaterOrEquals(Object left, Object right) {
25 | return left.toString().length() >= right.toString().length();
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/relational/LuaGreaterThanNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.relational;
2 |
3 | import com.oracle.truffle.api.dsl.Specialization;
4 | import org.luatruffle.main.nodes.LuaBinaryNode;
5 |
6 | import java.math.BigInteger;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-14.
10 | */
11 | public abstract class LuaGreaterThanNode extends LuaBinaryNode {
12 |
13 | @Specialization
14 | protected boolean isGreaterThan(long left, long right) {
15 | return left > right;
16 | }
17 |
18 | @Specialization
19 | protected boolean isGreaterThan(BigInteger left, BigInteger right) {
20 | return left.compareTo(right) == 1;
21 | }
22 |
23 | @Specialization(guards = "isEitherString")
24 | protected boolean isGreaterThan(Object left, Object right) {
25 | return left.toString().length() > right.toString().length();
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/relational/LuaLessOrEqualsNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.relational;
2 |
3 | import com.oracle.truffle.api.dsl.Specialization;
4 | import org.luatruffle.main.nodes.LuaBinaryNode;
5 |
6 | import java.math.BigInteger;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-14.
10 | */
11 | public abstract class LuaLessOrEqualsNode extends LuaBinaryNode {
12 |
13 | @Specialization
14 | protected boolean isLessOrEquals(long left, long right) {
15 | return left <= right;
16 | }
17 |
18 | @Specialization
19 | protected boolean isLessOrEquals(BigInteger left, BigInteger right) {
20 | return left.compareTo(right) <= 0;
21 | }
22 |
23 | @Specialization(guards = "isEitherString")
24 | protected boolean isLessOrEquals(Object left, Object right) {
25 | return left.toString().length() <= right.toString().length();
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/operations/relational/LuaLessThanNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.operations.relational;
2 |
3 | import com.oracle.truffle.api.dsl.Specialization;
4 | import org.luatruffle.main.nodes.LuaBinaryNode;
5 |
6 | import java.math.BigInteger;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-14.
10 | */
11 | public abstract class LuaLessThanNode extends LuaBinaryNode {
12 |
13 | @Specialization
14 | protected boolean isLessThan(long left, long right) {
15 | return left < right;
16 | }
17 |
18 | @Specialization
19 | protected boolean isLessThan(BigInteger left, BigInteger right) {
20 | return left.compareTo(right) == -1;
21 | }
22 |
23 | @Specialization(guards = "isEitherString")
24 | protected boolean isLessThan(Object left, Object right) {
25 | return left.toString().length() < right.toString().length();
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/statements/LuaBlockNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.statements;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 | import com.oracle.truffle.api.nodes.ExplodeLoop;
5 | import org.luatruffle.main.nodes.LuaNode;
6 | import org.luatruffle.main.nodes.LuaStatementNode;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-10.
10 | */
11 | public class LuaBlockNode extends LuaStatementNode {
12 |
13 | @Children private final LuaNode[] bodyNodes;
14 |
15 | public LuaBlockNode(LuaNode[] nodes) {
16 | this.bodyNodes = nodes;
17 | }
18 |
19 | @ExplodeLoop
20 | @Override
21 | public void executeVoid(VirtualFrame frame) {
22 | for (LuaNode node : bodyNodes) {
23 | if (node != null){
24 | node.executeVoid(frame);
25 | }
26 | }
27 | }
28 |
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/statements/LuaBreakNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.statements;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 | import org.luatruffle.main.nodes.LuaStatementNode;
5 | import org.luatruffle.main.nodes.statements.controlflow.LuaBreakException;
6 |
7 | /**
8 | * Created by Lucas Allan Amorim on 15-01-10.
9 | */
10 | public class LuaBreakNode extends LuaStatementNode {
11 |
12 | @Override
13 | public void executeVoid(VirtualFrame frame) {
14 | throw LuaBreakException.SINGLETON;
15 | }
16 | }
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/statements/LuaIfNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.statements;
2 |
3 | import com.oracle.truffle.api.nodes.UnexpectedResultException;
4 | import org.luatruffle.main.nodes.LuaExpressionNode;
5 | import org.luatruffle.main.nodes.LuaNode;
6 | import org.luatruffle.main.nodes.LuaStatementNode;
7 |
8 | import com.oracle.truffle.api.CompilerDirectives;
9 | import com.oracle.truffle.api.frame.VirtualFrame;
10 | import com.oracle.truffle.api.nodes.NodeInfo;
11 | import com.oracle.truffle.api.utilities.BranchProfile;
12 |
13 | /**
14 | * Created by Lucas Allan Amorim on 2014-09-08.
15 | */
16 | @NodeInfo(shortName = "if", description = "The node implementing a condional statement")
17 | public class LuaIfNode extends LuaStatementNode {
18 |
19 | @Child
20 | private LuaExpressionNode conditionNode;
21 | @Child
22 | private LuaNode thenPartNode;
23 | @Child
24 | private LuaNode elsePartNode;
25 |
26 | private final BranchProfile thenProfile = BranchProfile.create();
27 | private final BranchProfile elseProfile = BranchProfile.create();
28 |
29 | @CompilerDirectives.CompilationFinal
30 | private int thenCount;
31 | @CompilerDirectives.CompilationFinal
32 | private int elseCount;
33 |
34 | public LuaIfNode(LuaExpressionNode conditionNode,
35 | LuaNode thenPartNode, LuaNode elsePartNode) {
36 | this.conditionNode = conditionNode;
37 | this.thenPartNode = thenPartNode;
38 | this.elsePartNode = elsePartNode;
39 | }
40 |
41 | @Override
42 | public void executeVoid(VirtualFrame frame) {
43 | final boolean condition;
44 |
45 | try {
46 | condition = conditionNode.executeBoolean(frame);
47 | } catch (UnexpectedResultException e) {
48 | // TODO
49 | throw new UnsupportedOperationException(e);
50 | }
51 |
52 | if (CompilerDirectives.injectBranchProbability(getBranchProbability(), condition)) {
53 | if (CompilerDirectives.inInterpreter()) {
54 | thenCount++;
55 | }
56 | thenProfile.enter();
57 | thenPartNode.executeVoid(frame);
58 | } else {
59 | if (CompilerDirectives.inInterpreter()) {
60 | elseCount++;
61 | }
62 | elseProfile.enter();
63 | elsePartNode.executeVoid(frame);
64 | }
65 |
66 | }
67 |
68 | private double getBranchProbability() {
69 | final int totalCount = thenCount + elseCount;
70 |
71 | if (totalCount == 0) {
72 | return 0;
73 | } else {
74 | return (double) thenCount / (double) (thenCount + elseCount);
75 | }
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/statements/LuaNopNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.statements;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 | import org.luatruffle.main.nodes.LuaStatementNode;
5 |
6 | /**
7 | * Created by chrisseaton on 18/09/2014.
8 | */
9 | public class LuaNopNode extends LuaStatementNode {
10 |
11 | @Override
12 | public void executeVoid(VirtualFrame frame) {
13 |
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/statements/LuaReturnNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.statements;
2 |
3 | import com.oracle.truffle.api.frame.VirtualFrame;
4 | import org.luatruffle.main.nodes.LuaNode;
5 | import org.luatruffle.main.nodes.LuaStatementNode;
6 | import org.luatruffle.main.nodes.statements.controlflow.LuaReturnException;
7 |
8 | /**
9 | * Created by Lucas Allan Amorim on 2014-09-10.
10 | */
11 | public class LuaReturnNode extends LuaStatementNode {
12 |
13 | @Child
14 | private LuaNode valueNode;
15 |
16 | public LuaReturnNode(LuaNode valueNode) {
17 | this.valueNode = valueNode;
18 | }
19 |
20 | @Override
21 | public void executeVoid(VirtualFrame frame) {
22 | Object value = valueNode.execute(frame);
23 | throw new LuaReturnException(value);
24 | }
25 |
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/statements/LuaWhileDoNode.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.statements;
2 |
3 | import com.oracle.truffle.api.Truffle;
4 | import com.oracle.truffle.api.frame.VirtualFrame;
5 | import com.oracle.truffle.api.nodes.*;
6 | import org.luatruffle.main.nodes.LuaExpressionNode;
7 | import org.luatruffle.main.nodes.LuaNode;
8 | import org.luatruffle.main.nodes.LuaStatementNode;
9 | import org.luatruffle.main.nodes.statements.controlflow.LuaBreakException;
10 |
11 | /**
12 | * Created by Lucas Allan Amorim on 2014-09-15.
13 | */
14 | @NodeInfo(shortName = "while")
15 | public class LuaWhileDoNode extends LuaStatementNode {
16 |
17 | @Child protected LoopNode loopNode;
18 |
19 | public LuaWhileDoNode(LuaExpressionNode conditionNode, LuaNode blockNode) {
20 | loopNode = Truffle.getRuntime().createLoopNode(new RepeatingWhileNode(conditionNode, blockNode));
21 | }
22 |
23 | @Override
24 | public void executeVoid(VirtualFrame frame) {
25 | try {
26 | loopNode.executeLoop(frame);
27 | } catch (LuaBreakException e) {
28 | }
29 | }
30 |
31 | private static class RepeatingWhileNode extends Node implements RepeatingNode {
32 |
33 | @Child private LuaExpressionNode conditionNode;
34 | @Child private LuaNode blockNode;
35 |
36 | public RepeatingWhileNode(LuaExpressionNode conditionNode, LuaNode blockNode) {
37 | this.conditionNode = conditionNode;
38 | this.blockNode = blockNode;
39 | }
40 |
41 | @Override
42 | public boolean executeRepeating(VirtualFrame frame) {
43 | try {
44 | if (!conditionNode.executeBoolean(frame)) {
45 | return false;
46 | }
47 | } catch (UnexpectedResultException e) {
48 | throw new UnsupportedOperationException(e);
49 | }
50 |
51 | blockNode.executeVoid(frame);
52 |
53 | return true;
54 | }
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/statements/controlflow/LuaBreakException.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.statements.controlflow;
2 |
3 | import com.oracle.truffle.api.nodes.ControlFlowException;
4 |
5 | /**
6 | * Created by Lucas Allan Amorim on 2014-09-15.
7 | */
8 | public class LuaBreakException extends ControlFlowException {
9 |
10 | public static final LuaBreakException SINGLETON = new LuaBreakException();
11 |
12 | private LuaBreakException() {}
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/nodes/statements/controlflow/LuaReturnException.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.nodes.statements.controlflow;
2 |
3 | import com.oracle.truffle.api.nodes.ControlFlowException;
4 |
5 | /**
6 | * Created by Lucas Allan Amorim on 2014-09-10.
7 | */
8 | public class LuaReturnException extends ControlFlowException{
9 | public final Object result;
10 |
11 | public LuaReturnException(Object result) {
12 | super();
13 | this.result = result;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/runtime/LuaContext.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.runtime;
2 |
3 | import com.oracle.truffle.api.CallTarget;
4 | import com.oracle.truffle.api.ExecutionContext;
5 | import com.oracle.truffle.api.Truffle;
6 | import com.oracle.truffle.api.dsl.NodeFactory;
7 | import com.oracle.truffle.api.nodes.NodeInfo;
8 | import org.luatruffle.main.builtins.LuaPrintBuiltinFactory;
9 | import org.luatruffle.main.builtins.LuaOSClockBuiltinFactory;
10 | import org.luatruffle.main.nodes.LuaNode;
11 | import org.luatruffle.main.nodes.LuaRootNode;
12 | import org.luatruffle.main.nodes.LuaStatementNode;
13 | import org.luatruffle.main.nodes.expressions.LuaFunctionBody;
14 | import org.luatruffle.main.nodes.local.LuaReadArgumentNode;
15 | import org.luatruffle.main.translator.Translator;
16 | import org.luaj.vm2.ast.Chunk;
17 |
18 | import java.io.PrintStream;
19 |
20 | /**
21 | * Created by Lucas Allan Amorim on 2014-09-14.
22 | */
23 | public class LuaContext extends ExecutionContext {
24 |
25 | private final LuaFunctionRegistry luaFunctionRegistry;
26 | private final LuaFunctionRegistry luaGlobalVariableRegistry;
27 |
28 | public LuaContext() {
29 | this.luaFunctionRegistry = new LuaFunctionRegistry();
30 | this.luaGlobalVariableRegistry = new LuaFunctionRegistry();
31 | installBuiltins();
32 | }
33 |
34 | public LuaFunction findLuaMethod(String name){
35 | return luaFunctionRegistry.lookup(name);
36 | }
37 | public LuaFunction findVariable(String name){
38 | return luaGlobalVariableRegistry.lookup(name);
39 | }
40 |
41 | public void addLuaFunction(String name, LuaRootNode node) {
42 | luaFunctionRegistry.register(name, node);
43 | }
44 |
45 | public void addGlobalVariable(String name, LuaRootNode node) {
46 | luaGlobalVariableRegistry.register(name, node);
47 | }
48 |
49 | public PrintStream getOutput() {
50 | return System.out;
51 | }
52 |
53 | private void installBuiltins() {
54 | installBuiltin(LuaPrintBuiltinFactory.getInstance());
55 | installBuiltin(LuaOSClockBuiltinFactory.getInstance());
56 | }
57 |
58 | public void installBuiltin(NodeFactory extends LuaNode> factory) {
59 | int argumentCount = factory.getExecutionSignature().size();
60 | Object[] argumentNodes = new Object[argumentCount];
61 | for (int i = 0; i < argumentCount; i++) {
62 | argumentNodes[i] = new LuaReadArgumentNode(i);
63 | }
64 | for (int i = 0; i < argumentCount; i++) {
65 | argumentNodes[i] = new LuaReadArgumentNode(i);
66 | }
67 |
68 | LuaNode builtinBodyNode = factory.createNode(argumentNodes);
69 | String name = builtinBodyNode.getClass().getAnnotation(NodeInfo.class).shortName();
70 |
71 | LuaRootNode rootNode = new LuaRootNode(builtinBodyNode, null);
72 |
73 | luaFunctionRegistry.register(name, rootNode);
74 | }
75 |
76 | @Override
77 | public String getLanguageShortName() {
78 | return "Lua";
79 | }
80 |
81 | public void executeMain(Chunk chunk) {
82 | final Translator translator = new Translator(this);
83 | LuaStatementNode statement = (LuaStatementNode) translator.translate(chunk.block);
84 | LuaFunctionBody body = new LuaFunctionBody(statement);
85 | LuaRootNode root = new LuaRootNode(body, translator.getFrameDescriptor());
86 | CallTarget callTarget = Truffle.getRuntime().createCallTarget(root);
87 |
88 | callTarget.call();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/runtime/LuaFunction.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.runtime;
2 |
3 | import com.oracle.truffle.api.Assumption;
4 | import com.oracle.truffle.api.RootCallTarget;
5 | import com.oracle.truffle.api.utilities.CyclicAssumption;
6 |
7 | /**
8 | * Created by Lucas Allan Amorim on 2014-09-10.
9 | */
10 | public final class LuaFunction {
11 |
12 | private final String name;
13 |
14 |
15 | private RootCallTarget callTarget;
16 |
17 | private final CyclicAssumption callTargetStable;
18 |
19 | protected LuaFunction(String name) {
20 | this.name = name;
21 | this.callTargetStable = new CyclicAssumption(name);
22 | }
23 |
24 | public String getName() {
25 | return name;
26 | }
27 |
28 | protected void setCallTarget(RootCallTarget callTarget) {
29 | this.callTarget = callTarget;
30 | callTargetStable.invalidate();
31 | }
32 |
33 | public RootCallTarget getCallTarget() {
34 | return callTarget;
35 | }
36 |
37 | public Assumption getCallTargetStable() {
38 | return callTargetStable.getAssumption();
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return name;
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/runtime/LuaFunctionRegistry.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.runtime;
2 |
3 | import com.oracle.truffle.api.CompilerAsserts;
4 | import com.oracle.truffle.api.RootCallTarget;
5 | import com.oracle.truffle.api.Truffle;
6 | import org.luatruffle.main.nodes.LuaRootNode;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | /**
12 | * Created by Lucas Allan Amorim on 2014-09-14.
13 | */
14 | public final class LuaFunctionRegistry {
15 |
16 | private final Map methods = new HashMap<>();
17 |
18 | public LuaFunction lookup(String name) {
19 | CompilerAsserts.neverPartOfCompilation();
20 |
21 | LuaFunction result = methods.get(name);
22 | if (result == null) {
23 | result = new LuaFunction(name);
24 | methods.put(name, result);
25 | }
26 | return result;
27 | }
28 |
29 | public void register(String name, LuaRootNode rootNode, String[] params) {
30 | CompilerAsserts.neverPartOfCompilation();
31 |
32 | LuaFunction method = lookup(name);
33 | RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
34 | method.setCallTarget(callTarget);
35 | }
36 |
37 | public void register(String name, LuaRootNode rootNode) {
38 | CompilerAsserts.neverPartOfCompilation();
39 |
40 | LuaFunction method = lookup(name);
41 | RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
42 | method.setCallTarget(callTarget);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/runtime/LuaNull.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.runtime;
2 |
3 | /**
4 | * Created by Lucas Allan Amorim on 2014-09-10.
5 | */
6 | public final class LuaNull {
7 | public static final LuaNull SINGLETON = new LuaNull();
8 |
9 | private LuaNull() {}
10 |
11 | @Override
12 | public String toString() {
13 | return "nil";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/luatruffle/main/translator/Translator.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.translator;
2 |
3 | import com.oracle.truffle.api.frame.FrameDescriptor;
4 | import com.oracle.truffle.api.frame.FrameSlot;
5 | import org.luatruffle.main.nodes.*;
6 | import org.luatruffle.main.nodes.call.LuaFunctionCall;
7 | import org.luatruffle.main.nodes.call.LuaUninitializedDispatchNode;
8 | import org.luatruffle.main.nodes.expressions.LuaFunctionBody;
9 | import org.luatruffle.main.nodes.expressions.LuaFunctionNode;
10 | import org.luatruffle.main.nodes.local.LuaReadArgumentNode;
11 | import org.luatruffle.main.nodes.local.LuaReadLocalVariableNodeFactory;
12 | import org.luatruffle.main.nodes.local.LuaWriteLocalVariableNode;
13 | import org.luatruffle.main.nodes.local.LuaWriteLocalVariableNodeFactory;
14 | import org.luatruffle.main.nodes.operations.arithmetic.*;
15 | import org.luatruffle.main.nodes.operations.relational.*;
16 | import org.luatruffle.main.nodes.statements.*;
17 | import org.luatruffle.main.runtime.LuaContext;
18 | import org.luatruffle.main.runtime.LuaFunction;
19 | import org.luatruffle.main.runtime.LuaNull;
20 | import org.luaj.vm2.ast.*;
21 | import org.luaj.vm2.ast.Stat.LocalAssign;
22 |
23 | import java.util.ArrayList;
24 | import java.util.List;
25 |
26 | /**
27 | * Created by Lucas Allan Amorim on 2014-09-08.
28 | */
29 |
30 | public class Translator extends Visitor {
31 |
32 | private FrameDescriptor frameDescriptor;
33 | private LuaContext context;
34 | private Object rootNode;
35 |
36 | public Translator(LuaContext context) {
37 | frameDescriptor = new FrameDescriptor();
38 | this.context = context;
39 | }
40 |
41 | // TODO needs a good cleaup
42 | public Object translate(Object object) {
43 | try {
44 | if (object instanceof Chunk) {
45 | return visitChunk((Chunk) object);
46 | } else if (object instanceof Block) {
47 | return visitBlock((Block) object);
48 | } else if (object instanceof Stat.IfThenElse) {
49 | return visitIfThenElse((Stat.IfThenElse) object);
50 | } else if (object instanceof Exp.BinopExp) {
51 | return visitBinoExp((Exp.BinopExp) object);
52 | } else if (object instanceof Stat.Return) {
53 | return visitReturn((Stat.Return) object);
54 | } else if (object instanceof Exp.Constant) {
55 | return visitConstant((Exp.Constant) object);
56 | } else if (object instanceof Stat.FuncDef) {
57 | return visitFuncDef((Stat.FuncDef) object);
58 | } else if (object instanceof Stat.FuncCallStat) {
59 | return visitFuncCallStat((Stat.FuncCallStat) object);
60 | } else if (object instanceof Exp.ParensExp) {
61 | return visitParensExp((Exp.ParensExp) object);
62 | } else if (object instanceof Stat.WhileDo) {
63 | return visitWhileDo((Stat.WhileDo) object);
64 | } else if (object instanceof Stat.LocalAssign) {
65 | return visitLocalAssign((Stat.LocalAssign) object);
66 | } else if (object instanceof Exp.NameExp) {
67 | return visitLocalNameExp((Exp.NameExp) object);
68 | } else if (object instanceof Exp.FuncCall) {
69 | return visitFuncCall((Exp.FuncCall) object);
70 | } else if (object instanceof Stat.LocalFuncDef) {
71 | return visitLocalFuncDef((Stat.LocalFuncDef) object);
72 | } else if (object instanceof Stat.NumericFor) {
73 | return visitNumericFor((Stat.NumericFor) object);
74 | } else if (object instanceof Exp.UnopExp) {
75 | return visitUnopExp((Exp.UnopExp) object);
76 | } else if (object instanceof Stat.Assign) {
77 | return visitAssign((Stat.Assign) object);
78 | } else if (object instanceof Long) {
79 | return new LuaLongConstantNode((Long) object);
80 | } else if (object instanceof Stat.Break) {
81 | return new LuaBreakNode();
82 | } else if (object instanceof Stat.GenericFor) {
83 | return visitGenericFor((Stat.GenericFor) object);
84 | }
85 | else {
86 | if (object != null) {
87 | System.err.println("Needs be handled: " + object.getClass().getName());
88 | }
89 | return rootNode;
90 | }
91 | } catch (Exception e) {
92 | if (object instanceof Exp) {
93 | System.out.println("Error line: " + ((Exp) object).beginLine + " Column: " + ((Exp) object).beginColumn );
94 | } else if (object instanceof Stat) {
95 | System.out.println("Error line: " + ((Stat) object).beginLine + " Column: " + ((Stat) object).beginColumn );
96 | }
97 |
98 | e.printStackTrace();
99 | return null;
100 | }
101 | }
102 |
103 | private Object visitGenericFor(Stat.GenericFor genericFor) {
104 | System.out.printf("No support for GenericFor yet. Line: " + genericFor.beginLine);
105 | return new LuaBlockNode(new LuaNode[0]);
106 | }
107 |
108 | private Object visitAssign(Stat.Assign assign) {
109 | final List assignments = new ArrayList<>();
110 |
111 | for(int i = 0; i< assign.vars.size(); i++) {
112 | LuaExpressionNode luaExpressionNode = (LuaExpressionNode) translate(assign.exps.get(i));
113 | Exp.NameExp name = (Exp.NameExp) assign.vars.get(i);
114 | assignments.add(declareGlobalVariable(name.name.name, luaExpressionNode));
115 | //System.out.printf("No support to global variables yet - '%s' declared as a local variable.\n", name.name.name);
116 | }
117 |
118 | if (assignments.size() == 1) {
119 | return assignments.get(0);
120 | } else {
121 | return new LuaBlockNode(assignments.toArray(new LuaNode[assignments.size()]));
122 | }
123 | }
124 |
125 | private Object visitUnopExp(Exp.UnopExp unoExp) {
126 | LuaExpressionNode child = (LuaExpressionNode) translate( unoExp.rhs);
127 |
128 | switch (unoExp.op) {
129 | case 19:
130 | return LuaNegateNodeFactory.create(child);
131 | }
132 | throw new UnsupportedOperationException(String.valueOf(unoExp.op));
133 | }
134 |
135 | private Object visitNumericFor(Stat.NumericFor numericFor) {
136 | /*
137 | * Desugar from this:
138 | *
139 | * for loopVariable = initial, step, limit
140 | * block
141 | * end
142 | *
143 | * to this:
144 | *
145 | * loopVariable = initial
146 | * while loopVariable <= limit
147 | * block
148 | * loopVariable += step
149 | * end
150 | */
151 |
152 | final FrameSlot loopVariableFrameSlot = frameDescriptor.findOrAddFrameSlot(numericFor.name.name);
153 |
154 | final LuaExpressionNode translatedStep;
155 |
156 | if (numericFor.step == null) {
157 | translatedStep = new LuaLongConstantNode(1);
158 | } else {
159 | translatedStep = (LuaExpressionNode) translate(numericFor.step);
160 | }
161 |
162 | return new LuaBlockNode(new LuaNode[]{
163 | LuaWriteLocalVariableNodeFactory.create((LuaExpressionNode) translate(numericFor.initial), loopVariableFrameSlot),
164 | new LuaWhileDoNode(
165 | LuaLessOrEqualsNodeFactory.create(
166 | LuaReadLocalVariableNodeFactory.create(loopVariableFrameSlot),
167 | (LuaExpressionNode) translate(numericFor.limit)),
168 | new LuaBlockNode(new LuaNode[]{
169 | (LuaNode) translate(numericFor.block),
170 | LuaWriteLocalVariableNodeFactory.create(
171 | LuaAddNodeFactory.create(
172 | LuaReadLocalVariableNodeFactory.create(loopVariableFrameSlot),
173 | translatedStep),
174 | loopVariableFrameSlot)
175 | })
176 | )
177 | });
178 | }
179 |
180 | private Object visitLocalFuncDef(Stat.LocalFuncDef localFuncDef) {
181 | final LuaWriteLocalVariableNode[] paramsIntoLocals = new LuaWriteLocalVariableNode[localFuncDef.body.parlist.names.size()];
182 | for(int i = 0; i < localFuncDef.body.parlist.names.size(); i++) {
183 | Name paramName = (Name) localFuncDef.body.parlist.names.get(i);
184 | paramsIntoLocals[i] = addFormalParameter(paramName.name, i);
185 | }
186 | LuaBlockNode prelude = new LuaBlockNode(paramsIntoLocals);
187 | LuaStatementNode body = (LuaStatementNode) translate(localFuncDef.body.block);
188 | LuaBlockNode preludeAndBody = new LuaBlockNode(new LuaNode[]{prelude, body});
189 | LuaFunctionBody methodBody = new LuaFunctionBody(preludeAndBody);
190 | String name = localFuncDef.name.name;
191 | LuaRootNode root = new LuaRootNode(methodBody, getFrameDescriptor());
192 | context.addLuaFunction(name, root);
193 | System.out.printf("No support to local methods yet - using global methods.\n");
194 | return root;
195 | }
196 |
197 | private Object visitLocalNameExp(Exp.NameExp nameExp) {
198 | Object name = visitName(nameExp.name);
199 | if (name == null) {
200 | throw new RuntimeException(String.format("Name '%s' not found in translator - Line %s column %s", nameExp.name.name, nameExp.beginLine, nameExp.beginColumn));
201 | }
202 | return name;
203 | }
204 |
205 | private Object visitName(Name name) {
206 | final FrameSlot frameSlot = frameDescriptor.findFrameSlot(name.name);
207 | if (frameSlot == null) {
208 | return visitGlobalName(name);
209 | }
210 | return LuaReadLocalVariableNodeFactory.create(frameSlot);
211 | }
212 |
213 | private Object visitGlobalName(Name name) {
214 | LuaFunction method = context.findVariable(name.name);
215 | if (method == null) {
216 | return null;
217 | }
218 | return new LuaFunctionCall(new LuaExpressionNode[0], new LuaFunctionNode(method), new LuaUninitializedDispatchNode());
219 | }
220 |
221 | private Object visitWhileDo(Stat.WhileDo whileDo) {
222 | LuaExpressionNode expression = (LuaExpressionNode) translate(whileDo.exp);
223 | LuaBlockNode whileBlock = (LuaBlockNode) translate(whileDo.block);
224 | return new LuaWhileDoNode(expression, whileBlock);
225 | }
226 |
227 | public Object visitIfThenElse(Stat.IfThenElse ifThenElse) {
228 |
229 | LuaExpressionNode expression = (LuaExpressionNode) translate(ifThenElse.ifexp);
230 | LuaNode ifBlock;
231 | LuaNode elseBlock;
232 |
233 | if (ifThenElse.ifblock != null) {
234 | LuaNode[] ifBlocks = new LuaNode[ifThenElse.ifblock.stats.size()];
235 | for (int i = 0; i < ifThenElse.ifblock.stats.size(); i++) {
236 | ifBlocks[i] = (LuaNode) translate(ifThenElse.ifblock.stats.get(i));
237 | }
238 | ifBlock = new LuaBlockNode(ifBlocks);
239 | } else {
240 | ifBlock = new LuaNopNode();
241 | }
242 |
243 | if (ifThenElse.elseblock != null) {
244 | LuaNode[] elseBlocks = new LuaNode[ifThenElse.elseblock.stats.size()];
245 | for (int i = 0; i < ifThenElse.elseblock.stats.size(); i++) {
246 | elseBlocks[i] = (LuaNode) translate(ifThenElse.elseblock.stats.get(i));
247 | }
248 | elseBlock = new LuaBlockNode(elseBlocks);
249 | } else {
250 | elseBlock = new LuaNopNode();
251 | }
252 |
253 | // TODO Handle elseIfs
254 | return new LuaIfNode(expression, ifBlock, elseBlock);
255 | }
256 |
257 | public LuaNode visitChunk(Chunk chunk) {
258 | return visitBlock(chunk.block);
259 | }
260 |
261 | public LuaNode visitBlock(Block block){
262 | //visit(block.scope);
263 | LuaNode blockNode;
264 |
265 | if ( block.stats != null ) {
266 | LuaNode blocks[] = new LuaNode[block.stats.size()];
267 |
268 | for (int i = 0, n = block.stats.size(); i < n; i++) {
269 | Object returnedBlock = translate(block.stats.get(i));
270 | if (returnedBlock instanceof LuaNode) {
271 | blocks[i] = (LuaNode) returnedBlock;
272 | }
273 | }
274 |
275 | blockNode = new LuaBlockNode(blocks);
276 | } else {
277 | blockNode = new LuaNopNode();
278 | }
279 |
280 | setRootBlock(blockNode);
281 | return blockNode;
282 | }
283 |
284 | public Object visitFuncDef(Stat.FuncDef funcDef) {
285 | final LuaWriteLocalVariableNode[] paramsIntoLocals = new LuaWriteLocalVariableNode[funcDef.body.parlist.names.size()];
286 | for(int i = 0; i < funcDef.body.parlist.names.size(); i++) {
287 | Name paramName = (Name) funcDef.body.parlist.names.get(i);
288 | paramsIntoLocals[i] = addFormalParameter(paramName.name, i);
289 | }
290 | LuaBlockNode prelude = new LuaBlockNode(paramsIntoLocals);
291 | LuaStatementNode body = (LuaStatementNode) translate(funcDef.body.block);
292 | LuaBlockNode preludeAndBody = new LuaBlockNode(new LuaNode[]{prelude, body});
293 | LuaFunctionBody methodBody = new LuaFunctionBody(preludeAndBody);
294 | LuaRootNode root = new LuaRootNode(methodBody, getFrameDescriptor());
295 | String name = funcDef.name.name.name;
296 | context.addLuaFunction(name, root);
297 | return root;
298 | }
299 |
300 | public LuaWriteLocalVariableNode addFormalParameter(String nameToken, int parameterCount) {
301 | final LuaReadArgumentNode readArg = new LuaReadArgumentNode(parameterCount);
302 | return LuaWriteLocalVariableNodeFactory.create(readArg, getFrameDescriptor().findOrAddFrameSlot(nameToken));
303 | }
304 |
305 | public Object visitFuncCallStat(Stat.FuncCallStat funcCallStat) {
306 | return visitFuncCall(funcCallStat.funccall);
307 | }
308 |
309 | public Object visitFuncCall(Exp.FuncCall funcCall) {
310 | if (funcCall.isfunccall()) {
311 | // Calling a function
312 |
313 | LuaFunction method;
314 |
315 | if (funcCall.lhs instanceof Exp.NameExp) {
316 | Exp.NameExp nameExp = (Exp.NameExp) funcCall.lhs;
317 | method = context.findLuaMethod(nameExp.name.name);
318 | } else if (funcCall.lhs instanceof Exp.FieldExp) {
319 | Exp.FieldExp fieldExp = (Exp.FieldExp) funcCall.lhs;
320 |
321 | // Hack: statically look for os.clock and use osclock
322 |
323 | if (fieldExp.lhs instanceof Exp.NameExp && ((Exp.NameExp) fieldExp.lhs).name.name.equals("os") && fieldExp.name.name.equals("clock")) {
324 | method = context.findLuaMethod("osclock");
325 | } else {
326 | throw new UnsupportedOperationException();
327 | }
328 | } else {
329 | throw new UnsupportedOperationException();
330 | }
331 |
332 | List arguments = visitFuncArgs(funcCall.args);
333 | return new LuaFunctionCall(arguments.toArray(new LuaExpressionNode[arguments.size()]), new LuaFunctionNode(method), new LuaUninitializedDispatchNode());
334 | }
335 | throw new UnsupportedOperationException(String.valueOf("FuncCallStat"));
336 | }
337 |
338 | public List visitFuncArgs(FuncArgs funcArgs) {
339 | List params = new ArrayList();
340 | if (funcArgs.exps != null) {
341 | for (Object object : funcArgs.exps) {
342 | //LuaReadArgumentNode
343 | LuaExpressionNode node = (LuaExpressionNode) translate(object);
344 | params.add(node);
345 | }
346 | }
347 | return params;
348 | }
349 |
350 | public Object visitLocalAssign(LocalAssign localAssign) {
351 | final List assignments = new ArrayList<>();
352 |
353 | for(int i = 0; i< localAssign.names.size(); i++) {
354 | LuaExpressionNode luaExpressionNode;
355 | if (localAssign.values == null || localAssign.values.get(i) == null) {
356 | luaExpressionNode = new LuaObjectConstantNode(LuaNull.SINGLETON);
357 | } else {
358 | luaExpressionNode = (LuaExpressionNode) translate(localAssign.values.get(i));
359 | }
360 | String name = ((Name) localAssign.names.get(i)).name;
361 | assignments.add(declareLocalVariable(name, luaExpressionNode));
362 | }
363 |
364 | if (assignments.size() == 1) {
365 | return assignments.get(0);
366 | } else {
367 | return new LuaBlockNode(assignments.toArray(new LuaNode[assignments.size()]));
368 | }
369 | }
370 |
371 | public LuaReturnNode visitReturn(Stat.Return aReturn) {
372 | //System.out.println(aReturn.nreturns()); //might have more than one return
373 | Object objectReturned = translate(aReturn.values.get(0));
374 | return new LuaReturnNode((LuaNode) objectReturned);
375 | }
376 |
377 | @Override
378 | public void visit(FuncBody funcBody) {
379 | funcBody.block.accept(this);
380 | funcBody.parlist.accept(this);
381 | }
382 |
383 | public Object visitBinoExp(Exp.BinopExp binopExp) {
384 | LuaExpressionNode left = (LuaExpressionNode) translate( binopExp.lhs);
385 | LuaExpressionNode right = (LuaExpressionNode) translate(binopExp.rhs);
386 |
387 | switch (binopExp.op) {
388 | case 13:
389 | return LuaAddNodeFactory.create(left, right);
390 | case 24:
391 | return LuaEqualsNodeFactory.create(left, right);
392 | case 61:
393 | return LuaEqualsNodeFactory.create(left, right);
394 | case 63:
395 | return LuaGreaterThanNodeFactory.create(left, right);
396 | case 62:
397 | return LuaGreaterOrEqualsNodeFactory.create(left, right);
398 | case 26:
399 | return LuaLessOrEqualsNodeFactory.create(left, right);
400 | case 25:
401 | return LuaLessThanNodeFactory.create(left, right);
402 | case 15:
403 | return LuaMultiplicationNodeFactory.create(left, right);
404 | case 16:
405 | return LuaDivisionOperationFactory.create(left, right);
406 | case 14:
407 | return LuaSubtractionNodeFactory.create(left, right);
408 | case 18:
409 | return LuaExponentiationNodeFactory.create(left, right);
410 | }
411 | throw new UnsupportedOperationException(String.valueOf(binopExp.op));
412 | }
413 |
414 | public LuaNode visitConstant(Exp.Constant constant){
415 | if (constant.value.typename().equals("number")){
416 | return new LuaLongConstantNode(constant.value.checklong());
417 | } else if (constant.value.typename().equals("nil")) {
418 | return new LuaObjectConstantNode(LuaNull.SINGLETON);
419 | } else if (constant.value.typename().equals("string")){
420 | return new LuaObjectConstantNode(constant.value.toString());
421 | } else if (constant.value.typename().equals("boolean")){
422 | return new LuaBooleanConstantNode(constant.value.checkboolean());
423 | }
424 | // needs to handle others lua types
425 | throw new UnsupportedOperationException(constant.value.typename());
426 | }
427 |
428 | public Object visitParensExp(Exp.ParensExp parensExp) {
429 | return translate(parensExp.exp);
430 | }
431 |
432 | public void setRootBlock(Object object) {
433 | if (rootNode == null) {
434 | this.rootNode = object;
435 | }
436 | }
437 |
438 | public FrameDescriptor getFrameDescriptor() {
439 | return frameDescriptor;
440 | }
441 |
442 | private LuaNode declareLocalVariable(String name, LuaExpressionNode value) {
443 | return LuaWriteLocalVariableNodeFactory.create(value, frameDescriptor.findOrAddFrameSlot(name));
444 | }
445 |
446 | private LuaRootNode declareGlobalVariable(String name, LuaExpressionNode value) {
447 | LuaRootNode root = new LuaRootNode(value, getFrameDescriptor());
448 | context.addGlobalVariable(name, root);
449 | return root;
450 | }
451 | }
452 |
--------------------------------------------------------------------------------
/src/test/java/org/luatruffle/main/translator/ArithmeticOperatorsTest.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.translator;
2 |
3 | import org.junit.Test;
4 | import org.luatruffle.main.translator.BaseTranslatorTest;
5 |
6 | /**
7 | * Created by Lucas Allan Amorim on 2014-09-15.
8 | */
9 | public class ArithmeticOperatorsTest extends BaseTranslatorTest {
10 |
11 | @Test
12 | public void testAddOperatorsWithNumbers(){
13 | long expectedResult = 4;
14 | assertEquals(createCallTarget(createTempFile("return 2 + 2")).call(), expectedResult);
15 | }
16 |
17 | @Test
18 | public void testAddOperatorsWithString(){
19 | assertEquals(createCallTarget(createTempFile("return 'Hello' + ' world'")).call(), "Hello world");
20 | }
21 |
22 | @Test
23 | public void testMultiplicationOperators(){
24 | long expectedValue = 8;
25 | assertEquals(createCallTarget(createTempFile("return 2 * 4")).call(), expectedValue);
26 | }
27 |
28 | @Test
29 | public void testDivisionOperators(){
30 | long expectedValue = 2;
31 | assertEquals(createCallTarget(createTempFile("return 4 / 2")).call(), expectedValue);
32 | }
33 |
34 | @Test
35 | public void testSubtractionOperators(){
36 | long expectedValue = 2;
37 | assertEquals(createCallTarget(createTempFile("return 4 - 2")).call(), expectedValue);
38 | }
39 |
40 | @Test
41 | public void testExponentiationOperators(){
42 | long expectedValue = 16;
43 | assertEquals(createCallTarget(createTempFile("return 4 ^ 2")).call(), expectedValue);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/org/luatruffle/main/translator/BaseTranslatorTest.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.translator;
2 |
3 | import com.oracle.truffle.api.CallTarget;
4 | import com.oracle.truffle.api.Truffle;
5 | import junit.framework.TestCase;
6 | import org.luatruffle.main.nodes.LuaRootNode;
7 | import org.luatruffle.main.nodes.LuaStatementNode;
8 | import org.luatruffle.main.nodes.expressions.LuaFunctionBody;
9 | import org.luatruffle.main.runtime.LuaContext;
10 | import org.luaj.vm2.ast.Chunk;
11 | import org.luaj.vm2.parser.LuaParser;
12 | import org.luatruffle.main.translator.Translator;
13 |
14 | import java.io.*;
15 |
16 | /**
17 | * Created by Lucas Allan Amorim on 2014-09-15.
18 | */
19 | public abstract class BaseTranslatorTest extends TestCase {
20 |
21 | protected CallTarget createCallTarget(String file) {
22 | try {
23 | Translator translator = new Translator(new LuaContext());
24 | LuaParser parser = new LuaParser(new FileInputStream(file));
25 | Chunk chunk = parser.Chunk();
26 |
27 | LuaStatementNode statement = (LuaStatementNode) translator.translate(chunk.block);
28 | LuaFunctionBody body = new LuaFunctionBody(statement);
29 | LuaRootNode root = new LuaRootNode(body, translator.getFrameDescriptor());
30 | CallTarget callTarget = Truffle.getRuntime().createCallTarget(root);
31 |
32 | return callTarget;
33 | } catch (Exception ex) {
34 | ex.printStackTrace();
35 | return null;
36 | }
37 | }
38 |
39 | protected String getLuaFile(String file) {
40 | return getClass().getResource("/" + file).getFile();
41 | }
42 |
43 | protected String createTempFile(String content) {
44 | try {
45 | File temp = File.createTempFile("tmp_file", ".tmp");
46 | FileWriter fw = new FileWriter(temp.getAbsoluteFile());
47 | BufferedWriter bw = new BufferedWriter(fw);
48 | bw.write(content);
49 | bw.close();
50 | return temp.getAbsolutePath();
51 | } catch (IOException e) {
52 | e.printStackTrace();
53 | }
54 | return null;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/test/java/org/luatruffle/main/translator/MethodDefinitionTest.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.translator;
2 |
3 | import org.junit.Test;
4 | import org.luatruffle.main.runtime.LuaNull;
5 |
6 | /**
7 | * Created by Lucas Allan Amorim on 2014-09-25.
8 | */
9 | public class MethodDefinitionTest extends BaseTranslatorTest {
10 | @Test
11 | public void testFunctionDefinitionAndCallTest(){
12 | assertEquals(createCallTarget(createTempFile(
13 | "function newFunction()\n" +
14 | "return 10\n" +
15 | "end\n" +
16 | "return newFunction()")
17 | ).call(), (long) 10);
18 | }
19 | @Test
20 | public void testFunctionsWithParamTest(){
21 | assertEquals(createCallTarget(createTempFile(
22 | "function return_value(a)\n" +
23 | "return a\n" +
24 | "end\n" +
25 | "return return_value(10)")
26 | ).call(), (long) 10);
27 | }
28 |
29 | public void testDefiningLocalFunctions() {
30 | assertEquals(createCallTarget(createTempFile(
31 | "local function newFunction()\n" +
32 | "return 10\n" +
33 | "end")
34 | ).call(), LuaNull.SINGLETON);
35 | }
36 |
37 | public void testCallingLocalFunctions() {
38 | assertEquals(createCallTarget(createTempFile(
39 | "local function return_value()\n" +
40 | "return 10\n" +
41 | "end\n" +
42 | "return return_value()")
43 | ).call(), (long) 10);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/org/luatruffle/main/translator/RelationalOperators.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.translator;
2 |
3 | import org.junit.Test;
4 |
5 | /**
6 | * Created by Lucas Allan Amorim on 2014-09-15.
7 | */
8 | public class RelationalOperators extends TranslatorTest {
9 |
10 | @Test
11 | public void testEqualsNode() {
12 | assertEquals(createCallTarget(createTempFile("return 1 == 1")).call(), true);
13 | assertEquals(createCallTarget(createTempFile("return 1 ~= 1")).call(), true);
14 | }
15 |
16 | @Test
17 | public void testGreaterOrEqualsNode(){
18 | assertEquals(createCallTarget(createTempFile("return 1 >= 1")).call(), true);
19 | assertEquals(createCallTarget(createTempFile("return 2 >= 1")).call(), true);
20 | assertEquals(createCallTarget(createTempFile("return 1 >= 2")).call(), false);
21 | }
22 |
23 | @Test
24 | public void testGreaterThanNode(){
25 | assertEquals(createCallTarget(createTempFile("return 1 > 1")).call(), false);
26 | assertEquals(createCallTarget(createTempFile("return 2 > 1")).call(), true);
27 | assertEquals(createCallTarget(createTempFile("return 1 > 2")).call(), false);
28 | }
29 |
30 | @Test
31 | public void testLessThanNode(){
32 | assertEquals(createCallTarget(createTempFile("return 1 < 1")).call(), false);
33 | assertEquals(createCallTarget(createTempFile("return 2 < 1")).call(), false);
34 | assertEquals(createCallTarget(createTempFile("return 1 < 2")).call(), true);
35 | }
36 |
37 | @Test
38 | public void testLessOrEqualsNode(){
39 | assertEquals(createCallTarget(createTempFile("return 1 <= 1")).call(), true);
40 | assertEquals(createCallTarget(createTempFile("return 2 <= 1")).call(), false);
41 | assertEquals(createCallTarget(createTempFile("return 1 <= 2")).call(), true);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/test/java/org/luatruffle/main/translator/TranslatorTest.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.translator;
2 |
3 | import com.oracle.truffle.api.CallTarget;
4 | import org.junit.Test;
5 | /**
6 | * Created by Lucas Allan Amorim on 2014-09-12.
7 | */
8 | public class TranslatorTest extends BaseTranslatorTest {
9 |
10 | @Test
11 | public void testIfThenElse() {
12 | CallTarget callTarget = createCallTarget(getLuaFile("ifthenelse.lua"));
13 | long expectResult = 10;
14 | assertEquals(callTarget.call(), expectResult);
15 | }
16 |
17 | @Test
18 | public void testNumericFor() {
19 | CallTarget callTarget = createCallTarget(getLuaFile("numeric_for.lua"));
20 | long expectResult = 10;
21 | assertEquals(callTarget.call(), expectResult);
22 | }
23 |
24 | @Test
25 | public void testNumericForWithParam() {
26 | CallTarget callTarget = createCallTarget(getLuaFile("numeric_for2.lua"));
27 | long expectResult = 0;
28 | assertEquals(callTarget.call(), expectResult);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/java/org/luatruffle/main/translator/ValueTypesTest.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.translator;
2 |
3 | import org.luatruffle.main.runtime.LuaNull;
4 | import org.junit.Test;
5 |
6 | /**
7 | * Created by Lucas Allan Amorim on 2014-09-16.
8 | */
9 | public class ValueTypesTest extends BaseTranslatorTest {
10 |
11 | @Test
12 | public void testNilValue() {
13 | assertEquals(createCallTarget(createTempFile("return nil")).call(), LuaNull.SINGLETON);
14 | }
15 |
16 | @Test
17 | public void testStringValue() {
18 | assertEquals(createCallTarget(createTempFile("return 'hello'")).call(), "hello");
19 | }
20 |
21 | @Test
22 | public void testNumericValue() {
23 | assertEquals(createCallTarget(createTempFile("return 12")).call(), (long) 12);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/java/org/luatruffle/main/translator/VariablesTest.java:
--------------------------------------------------------------------------------
1 | package org.luatruffle.main.translator;
2 |
3 | import org.junit.Test;
4 |
5 | /**
6 | * Created by Lucas Allan Amorim on 2014-09-18.
7 | */
8 | public class VariablesTest extends BaseTranslatorTest {
9 |
10 | @Test
11 | public void testLocalVariables(){
12 | assertEquals(createCallTarget(createTempFile("local num = 20\nreturn num")).call(), (long) 20);
13 | }
14 |
15 | @Test
16 | public void testGlobalVariables(){
17 | assertEquals(createCallTarget(createTempFile("num = 20\nreturn num")).call(), (long) 20);
18 | }
19 |
20 | @Test
21 | public void testMultipleAssignment(){
22 | assertEquals(createCallTarget(createTempFile("local a, b = 14, 2\nreturn a + b")).call(), (long) 14 + 2);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/resources/fibonacci.lua:
--------------------------------------------------------------------------------
1 | function fibonacci(n)
2 | if n < 2 then
3 | return n
4 | end
5 | return fibonacci(n-1) + fibonacci(n-2)
6 | end
7 |
8 | while true do
9 | start = os.clock()
10 | print(fibonacci(40))
11 | print(os.clock() - start)
12 | end
13 |
--------------------------------------------------------------------------------
/src/test/resources/functions.lua:
--------------------------------------------------------------------------------
1 | function newFunction(name)
2 | print(name)
3 | end
4 | return newFunction("hello")
--------------------------------------------------------------------------------
/src/test/resources/ifthenelse.lua:
--------------------------------------------------------------------------------
1 | if 1 ~= 0 then
2 | return 0
3 | else
4 | return 10
5 | end
6 |
--------------------------------------------------------------------------------
/src/test/resources/numeric_for.lua:
--------------------------------------------------------------------------------
1 | local count = 0
2 | for i=0,9,10 do
3 | local count = count + 10
4 | end
5 | return count
--------------------------------------------------------------------------------
/src/test/resources/numeric_for2.lua:
--------------------------------------------------------------------------------
1 | local count = 0
2 | for i=10,1,-1 do
3 | local count = count + 10
4 | end
5 | return count
--------------------------------------------------------------------------------
/src/test/resources/numeric_for3.lua:
--------------------------------------------------------------------------------
1 | local count = 1
2 |
3 | for i=0,10 do
4 | count = count + i
5 | end
6 | print(count) -- 56
7 | return count
--------------------------------------------------------------------------------
/src/test/resources/numeric_for_dynamic.lua:
--------------------------------------------------------------------------------
1 | local loop_start = 0
2 | local loop_end = 100
3 | local count = 0
4 | for i=loop_start,loop_end do
5 | count = count + 1
6 | end
7 | return count
8 |
--------------------------------------------------------------------------------