Skip to content

Commit d182d03

Browse files
committed
engine: Add Lua scripting support
1 parent 12fb330 commit d182d03

File tree

80 files changed

+12745
-34
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+12745
-34
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto

.luarc.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json",
3+
"workspace.library": ["engine/lua"],
4+
"runtime.version": "Lua 5.4",
5+
"completion.displayContext": 1,
6+
"diagnostics.globals": ["cloe"],
7+
"hint.enable": true
8+
}

NOTICE.md

+25-1
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,36 @@ The following third-party libraries are included in the Cloe repository:
4646
- Website: https://jothepro.github.io/doxygen-awesome-css
4747
- Source: docs/_vendor/doxygen-awesome
4848

49+
- Typecheck
50+
- License: MIT
51+
- License-Source: https://github.com/gvvaughan/typecheck/raw/master/LICENSE.md
52+
- Website: https://github.com/gvvaughan/typecheck
53+
- Source: engine/lua/typecheck.lua
54+
55+
- Tableshape
56+
- License: MIT
57+
- License-Source: https://github.com/leafo/tableshape/blob/v2.6.0/README.md
58+
- Website: https://github.com/leafo/tableshape
59+
- Source: engine/lua/tableshape.lua
60+
4961
- Linenoise
5062
- License: BSD2
5163
- License-Source: https://raw.githubusercontent.com/antirez/linenoise/master/LICENSE
5264
- Website: https://github.com/antirez/linenoise
5365
- Source: engine/vendor/linenoise
5466

67+
- Inspect.lua
68+
- License: MIT
69+
- License-Source: https://raw.githubusercontent.com/kikito/inspect.lua/master/MIT-LICENSE.txt
70+
- Website: https://github.com/kikito/inspect.lua
71+
- Source: engine/lua/inspect.lua
72+
73+
- Lust
74+
- License: MIT
75+
- License-Source: https://raw.githubusercontent.com/bjornbytes/lust/master/LICENSE
76+
- Website: https://github.com/bjornbytes/lust
77+
- Source: engine/lua/lust.lua
78+
5579
The following third-party libraries are used by this project (these are usually
5680
installed with the help of Conan):
5781

@@ -99,7 +123,7 @@ installed with the help of Conan):
99123
- Conan-Package: inja
100124

101125
- Boost
102-
- License: Boost
126+
- License: BSL-1.0
103127
- License-Source: https://www.boost.org/LICENSE_1_0.txt
104128
- Website: https://www.boost.org
105129
- Conan-Package: boost

conanfile.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ class Cloe(ConanFile):
7272

7373
"fable/examples/*",
7474

75+
"engine/lua/*",
7576
"engine/webui/*",
77+
"engine/vendor/*",
7678

7779
"CMakelists.txt"
7880
]
@@ -93,6 +95,7 @@ def requirements(self):
9395
self.requires("incbin/cci.20211107"),
9496
self.requires("inja/3.4.0")
9597
self.requires("nlohmann_json/3.11.3")
98+
self.requires("sol2/3.3.1")
9699
self.requires("spdlog/1.11.0")
97100
if self.options.engine_server:
98101
self.requires("oatpp/1.3.0", private=True)
@@ -105,7 +108,6 @@ def requirements(self):
105108

106109
def build_requirements(self):
107110
self.test_requires("gtest/1.14.0")
108-
self.test_requires("sol2/3.3.0")
109111

110112
def layout(self):
111113
cmake.cmake_layout(self)
@@ -195,14 +197,18 @@ def package_info(self):
195197
self.cpp_info.builddirs.append(os.path.join(self.source_folder, "cmake"))
196198
self.cpp_info.includedirs.append(os.path.join(self.build_folder, "include"))
197199
bindir = os.path.join(self.build_folder, "bin")
200+
luadir = os.path.join(self.source_folder, "engine/lua")
198201
libdir = os.path.join(self.build_folder, "lib");
199202
else:
200203
self.cpp_info.builddirs.append(os.path.join("lib", "cmake", "cloe"))
201204
bindir = os.path.join(self.package_folder, "bin")
205+
luadir = os.path.join(self.package_folder, "lib/cloe/lua")
202206
libdir = None
203207

204208
self.output.info(f"Appending PATH environment variable: {bindir}")
205209
self.runenv_info.prepend_path("PATH", bindir)
210+
self.output.info(f"Appending CLOE_LUA_PATH environment variable: {luadir}")
211+
self.runenv_info.prepend_path("CLOE_LUA_PATH", luadir)
206212
if libdir is not None:
207213
self.output.info(f"Appending LD_LIBRARY_PATH environment variable: {libdir}")
208214
self.runenv_info.append_path("LD_LIBRARY_PATH", libdir)

docs/reference.rst

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ background knowledge for any of the following topics.
4747
:doc:`reference/plugins`
4848
provides an overview of all plugins that are part of the Cloe distribution.
4949

50+
:doc:`reference/lua-initialization`
51+
provides an overview of how the engine processes a Lua file.
52+
5053
.. toctree::
5154
:hidden:
5255

@@ -62,3 +65,4 @@ background knowledge for any of the following topics.
6265
reference/events
6366
reference/actions
6467
reference/plugins
68+
reference/lua-initialization

docs/reference/lua-initialization.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Lua Initialization
2+
------------------
3+
4+
When a Lua file or script is loaded, the Cloe engine provides a preloaded
5+
`cloe` table with a large API. This API is defined in part through a Lua
6+
runtime, and in part from the C++ engine itself.
7+
8+
The following operations occur when the engine runs a simulation defined
9+
by a Lua file: `cloe-engine run simulation.lua`
10+
11+
1. Read options from the command line and environment:
12+
13+
- Lua package path (`--lua-path`, `CLOE_LUA_PATH`)
14+
- Disable system packages (`--no-system-lua`)
15+
- Cloe plugins (`--plugin-path`, `CLOE_PLUGIN_PATH`)
16+
17+
2. Initialize Cloe Stack
18+
19+
- Load plugins found in plugin path
20+
21+
3. Initialize Lua
22+
23+
- Set lua package path
24+
- Load built-in Lua base libraries (e.g. `os`, `string`)
25+
- Expose Cloe API via `cloe` Lua table
26+
- Load Cloe Lua runtime (located in the package `lib/cloe/lua` directory)
27+
28+
4. Source input files
29+
30+
- Files ending with `.lua` are merged as Lua
31+
- Other files are read as JSON
32+
33+
5. Start simulation
34+
35+
- Schedule triggers pending from the Lua script

docs/usage.rst

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ guides will give you a better feel for how Cloe works and how it is built up.
1616
usage/viewing-cloe-registry
1717
usage/running-cloe-webui
1818
usage/creating-a-stackfile
19+
20+
usage/lua-introduction
21+
usage/lua-cloe-shell
22+
usage/lua-editor-integration
23+
1924
usage/configuring-plugins-in-stackfiles
2025
usage/writing-modular-stackfiles
2126
usage/user-cloe-configuration

docs/usage/lua-cloe-shell.md

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
Cloe-Engine Lua Shell
2+
=====================
3+
4+
Cloe Engine provides a small Lua shell that you can use as a REPL or a way to
5+
run Lua scripts with access to the Cloe API without running a simulation.
6+
7+
It currently has the following features:
8+
9+
- Runs Lua files (passed as arguments)
10+
- Runs Lua strings (passed with `-c` option)
11+
- REPL session (by default or with `-i` flag)
12+
- Session history (press Up/Down in interactive session)
13+
- Multi-line editing (experimental)
14+
- Automatic value printing (experimental)
15+
16+
You can start the Lua REPL with `cloe-engine shell`.
17+
18+
Hello World
19+
-----------
20+
21+
Let's demo the various ways we can print "Hello world!" to the console.
22+
23+
### In the REPL
24+
25+
Start the REPL and enter in the statement `print("Hello world!")`:
26+
```console
27+
$ cloe-engine shell
28+
Cloe 0.22.0 Lua interactive shell
29+
Press [Ctrl+D] or [Ctrl+C] to exit.
30+
> print("Hello world!")
31+
Hello world!
32+
>
33+
```
34+
35+
### Running a command
36+
37+
Pass the string from the previous example to the shell with `-c`:
38+
```console
39+
$ cloe-engine shell -c 'print("Hello world!")'
40+
Hello world!
41+
```
42+
You can pass more than one command with `-c` just by repeating it.
43+
44+
45+
### Running a file
46+
47+
Create a file `hello.lua` with the following contents:
48+
```lua
49+
print("Hello world!")
50+
```
51+
Now run it with `cloe-engine shell`:
52+
```console
53+
$ cloe-engine shell hello.lua
54+
Hello world!
55+
```
56+
57+
Multi-Line Editing
58+
------------------
59+
60+
If the statement entered on a line looks complete, the shell will run it.
61+
If there is an error in parsing indicating that the statement looks incomplete,
62+
the shell will prompt you for more input:
63+
```
64+
> print(
65+
>> "Hello world!"
66+
>> )
67+
Hello world!
68+
```
69+
This isn't so important for the above example, but for loops, functions, and
70+
if-statements, it is:
71+
```
72+
> function a()
73+
>> print(
74+
>> "Hello world!"
75+
>> )
76+
>> end
77+
> a()
78+
Hello world!
79+
```
80+
81+
Whitespace
82+
----------
83+
84+
Lua does not care about whitespace very much. This means you can replace
85+
all newlines with spaces and the code works the same.
86+
87+
Consider the following block of code:
88+
```lua
89+
print("...")
90+
io.write("[")
91+
for _, v in ipairs({1, 2, 3}) do
92+
io.write(v .. ",")
93+
end
94+
io.write("]\n")
95+
print("---")
96+
```
97+
This can be minified in the following simple ways:
98+
99+
1. Newlines can be replaced with spaces.
100+
2. Parentheses around plain strings and tables can be removed.
101+
3. Spaces before and after commas, quotes, parentheses, and brackets can be removed.
102+
103+
This leads to the following minified code:
104+
```lua
105+
print"..."io.write"["for _,v in ipairs{1,2,3}do io.write(v..",")end print"]"print"---"
106+
```
107+
This means that sending whole blocks of code from the command line or from
108+
another application or from code generation is a lot easier.
109+
```
110+
$ cloe-engine shell -c 'print"..."io.write"["for _,v in ipairs{1,2,3}do io.write(v..",")end print"]"print"---"'
111+
...
112+
[1,2,3,]
113+
---
114+
```
115+
Of course I don't expect you'd really do this kind of crazy minification, but
116+
it demonstrates just how little Lua cares about whitespace.
117+
118+
:::{note}
119+
This one little quirk can provide significant benefits over the Python
120+
scripting language, because it's very easy to compose generated code without
121+
running into syntax errors because of indentation requirements.
122+
:::

docs/usage/lua-editor-integration.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
Lua Editor Integration
2+
======================
3+
4+
In order to have the best user-experience when working with Lua files, it's
5+
important to have a good language server up and running to provide
6+
hinting, auto-completion, and linting.
7+
8+
The Cloe Engine provides definitions for the
9+
[Sumneko Lua Language Server](https://github.com/LuaLS/vscode-lua),
10+
which can be easily integrated in your favorite editor.
11+
For VS Code, install [this extension](https://marketplace.visualstudio.com/items?itemName=sumneko.lua)
12+
13+
The language server may need a configuration file in order to find the
14+
definitions (though this should not be necessary for the Cloe repository.)
15+
16+
Configuration File
17+
------------------
18+
19+
Let us assume that you have a directory `tests` containing Lua files that you
20+
want to include Cloe definitions for.
21+
22+
Place in the `tests` directory or in any directory containing `tests` (such
23+
as the repository root) a file named `.luarc.json` containing the following
24+
content:
25+
26+
```json
27+
{
28+
"$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json",
29+
"workspace.library": ["PATH_CONTAINING_LUA_MODULES"],
30+
"runtime.version": "Lua 5.3",
31+
"completion.displayContext": 1,
32+
"diagnostics.globals": [],
33+
"hint.enable": true
34+
}
35+
```
36+
37+
Until we develop a plugin for Sumneko containing all the definitions, you need
38+
to tell Sumneko where to find them by hand, where `PATH_CONTAINING_LUA_MODULES`
39+
is above.
40+
41+
One approach is to make a symlink to the source Lua files in your own
42+
repository and set the workspace library to the symlink:
43+
44+
```sh
45+
git clone https://github.com/eclipse/cloe ~/cloe
46+
ln -s ~/cloe/engine/lua meta
47+
sed -e 's/PATH_CONTAINING_LUA_MODULES/meta/' -i .luarc.json
48+
```
49+
50+
If you are not committing the `.luarc.json` file, then you can also just
51+
specify the absolute path.

0 commit comments

Comments
 (0)