aboutsummaryrefslogtreecommitdiff
path: root/spec/cpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2026-07-24 17:12:21 +0800
committerLi Jin <dragon-fly@qq.com>2026-07-24 17:12:21 +0800
commit676da10a45af912d9226dce4cb447bf7bd923da0 (patch)
tree1d973ebb1dd157c6db9f99c50259d5248a2d8240 /spec/cpp
parentc9f3a486cfdad6e134ec88b1e43717508e066796 (diff)
downloadyuescript-676da10a45af912d9226dce4cb447bf7bd923da0.tar.gz
yuescript-676da10a45af912d9226dce4cb447bf7bd923da0.tar.bz2
yuescript-676da10a45af912d9226dce4cb447bf7bd923da0.zip
Optimize compiler parsing and module state
Diffstat (limited to 'spec/cpp')
-rw-r--r--spec/cpp/same_module_state_test.cpp107
1 files changed, 107 insertions, 0 deletions
diff --git a/spec/cpp/same_module_state_test.cpp b/spec/cpp/same_module_state_test.cpp
new file mode 100644
index 0000000..35235d7
--- /dev/null
+++ b/spec/cpp/same_module_state_test.cpp
@@ -0,0 +1,107 @@
1#include <iostream>
2#include <string>
3#include <string_view>
4
5#include "yuescript/yue_compiler.h"
6
7extern "C" {
8#include "lauxlib.h"
9#include "lua.h"
10#include "lualib.h"
11int luaopen_yue(lua_State* L);
12}
13
14namespace {
15
16size_t moduleCount(lua_State* L) {
17 lua_pushliteral(L, "__yue_modules__");
18 lua_rawget(L, LUA_REGISTRYINDEX);
19#if LUA_VERSION_NUM > 501
20 const size_t count = lua_isnil(L, -1) ? 0 : lua_rawlen(L, -1);
21#else
22 const size_t count = lua_isnil(L, -1) ? 0 : lua_objlen(L, -1);
23#endif
24 lua_pop(L, 1);
25 return count;
26}
27
28bool expect(bool condition, std::string_view message) {
29 if (!condition) {
30 std::cerr << "same_module state test failed: " << message << '\n';
31 }
32 return condition;
33}
34
35} // namespace
36
37int main() {
38 constexpr std::string_view defineAndUse =
39 "macro double = (x) -> \"#{x} * 2\"\n"
40 "result = $double 5\n";
41 constexpr std::string_view failAfterMacro =
42 "macro double = (x) -> \"#{x} * 2\"\n"
43 "result = $missing 5\n";
44 constexpr std::string_view useOnly = "result = $double 7\n";
45
46 lua_State* L = luaL_newstate();
47 if (!expect(L != nullptr, "failed to create Lua state")) return 1;
48 luaL_openlibs(L);
49#if LUA_VERSION_NUM > 501
50 luaL_requiref(L, "yue", luaopen_yue, 0);
51#else
52 lua_pushcfunction(L, luaopen_yue);
53 lua_call(L, 0, 1);
54#endif
55 lua_pop(L, 1);
56
57 yue::YueConfig config;
58 bool passed = true;
59 {
60 yue::YueCompiler compiler(L, nullptr, true);
61 std::string expectedCodes;
62 for (int i = 0; i < 500; i++) {
63 auto result = compiler.compile(defineAndUse, config);
64 passed &= expect(!result.error, "repeated compilation returned an error");
65 if (i == 0) {
66 expectedCodes = result.codes;
67 } else {
68 passed &= expect(result.codes == expectedCodes, "repeated compilation changed its output");
69 }
70 }
71 passed &= expect(moduleCount(L) == 1, "repeated compilation grew the module registry");
72 }
73
74 yue::YueCompiler::clear(L);
75 {
76 yue::YueCompiler compiler(L, nullptr, true);
77 auto failed = compiler.compile(failAfterMacro, config);
78 passed &= expect(failed.error.has_value(), "expected macro expansion failure");
79 auto next = compiler.compile(useOnly, config);
80 passed &= expect(next.error.has_value(), "failed compilation leaked a macro into the next compilation");
81 passed &= expect(moduleCount(L) == 1, "failed compilation grew the module registry");
82 }
83
84 yue::YueCompiler::clear(L);
85 {
86 yue::YueCompiler compiler(L, nullptr, true);
87 passed &= expect(!compiler.compile(defineAndUse, config).error, "initial live-clear compilation failed");
88 yue::YueCompiler::clear(L);
89 passed &= expect(!compiler.compile(defineAndUse, config).error, "compiler did not rebuild a cleared registry");
90 passed &= expect(moduleCount(L) == 1, "rebuilt registry has an unexpected module count");
91 }
92
93 yue::YueCompiler::clear(L);
94 {
95 yue::YueCompiler compiler(L, nullptr, false);
96 passed &= expect(!compiler.compile(defineAndUse, config).error, "isolated compilation failed");
97 passed &= expect(moduleCount(L) == 0, "sameModule=false retained a module");
98 }
99
100 yue::YueCompiler::clear(L);
101 lua_close(L);
102 if (passed) {
103 std::cout << "same_module state test passed\n";
104 return 0;
105 }
106 return 1;
107}