aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/inputs/test/ast_spec.yue91
-rw-r--r--spec/inputs/test/format_spec.yue4
-rw-r--r--spec/outputs/test/ast_spec.lua85
-rw-r--r--spec/outputs/test/format_spec.lua4
-rw-r--r--src/yuescript/yuescript.cpp20
5 files changed, 198 insertions, 6 deletions
diff --git a/spec/inputs/test/ast_spec.yue b/spec/inputs/test/ast_spec.yue
new file mode 100644
index 0000000..11efc94
--- /dev/null
+++ b/spec/inputs/test/ast_spec.yue
@@ -0,0 +1,91 @@
1yue = require "yue"
2
3describe "yue.to_ast", ->
4 it "should return AST with end position for simple expression", ->
5 ast = yue.to_ast "x = 1"
6 assert.is_not_nil ast
7 -- ast format: [name, begin_line, begin_col, end_line, end_col, ...children]
8 assert.same ast[1], "File"
9 assert.same ast[2], 1 -- begin line
10 assert.same ast[3], 1 -- begin col
11 assert.is_number ast[4] -- end line
12 assert.is_number ast[5] -- end col
13
14 it "should have correct end position for leaf nodes", ->
15 ast = yue.to_ast "1"
16 assert.is_not_nil ast
17 -- Leaf node with no children should have format: [name, begin_line, begin_col, end_line, end_col, value]
18 assert.same ast[1], "File"
19 assert.same ast[2], 1
20 assert.same ast[3], 1
21 assert.is_number ast[4]
22 assert.is_number ast[5]
23
24 it "should have end position for multi-line code", ->
25 code = [[
26x = 1
27y = 2]]
28 ast = yue.to_ast code
29 assert.is_not_nil ast
30 assert.same ast[1], "File"
31 assert.same ast[2], 1
32 assert.same ast[3], 1
33 -- End position should be on line 2
34 assert.is_true ast[4] >= 2
35
36 it "should have end position for function definition", ->
37 code = [[
38add = (a, b) ->
39 a + b]]
40 ast = yue.to_ast code
41 assert.is_not_nil ast
42 assert.same ast[1], "File"
43 assert.same ast[2], 1
44 assert.same ast[3], 1
45 assert.is_number ast[4]
46 assert.is_number ast[5]
47
48 it "should have end position for table literal", ->
49 ast = yue.to_ast "{a: 1, b: 2}"
50 assert.is_not_nil ast
51 assert.same ast[1], "File"
52 assert.same ast[2], 1
53 assert.same ast[3], 1
54 assert.is_number ast[4]
55 assert.is_number ast[5]
56
57 it "should have end position for class definition", ->
58 code = [[
59class Person
60 new: (@name) =>
61 getName: => @name]]
62 ast = yue.to_ast code
63 assert.is_not_nil ast
64 assert.same ast[1], "File"
65 assert.same ast[2], 1
66 assert.same ast[3], 1
67 assert.is_true ast[4] >= 3
68
69 it "should return nil and error message for invalid syntax", ->
70 ast, err = yue.to_ast "if then else"
71 assert.is_nil ast
72 assert.is_string err
73
74 it "should support flatten level parameter", ->
75 ast = yue.to_ast "x = 1", 0
76 assert.is_not_nil ast
77 assert.same ast[1], "File"
78 assert.is_number ast[4]
79 assert.is_number ast[5]
80
81 it "should have end position in nested structures", ->
82 code = "x = [i for i = 1, 10]"
83 ast = yue.to_ast code
84 assert.is_not_nil ast
85 assert.same ast[1], "File"
86 assert.same ast[2], 1
87 assert.same ast[3], 1
88 assert.is_number ast[4]
89 assert.is_number ast[5]
90 -- End column should reflect the end of the expression
91 assert.is_true ast[5] > 1
diff --git a/spec/inputs/test/format_spec.yue b/spec/inputs/test/format_spec.yue
index 8c6096a..310b610 100644
--- a/spec/inputs/test/format_spec.yue
+++ b/spec/inputs/test/format_spec.yue
@@ -165,7 +165,9 @@ import "yue"
165rewriteLineCol = (item)-> 165rewriteLineCol = (item)->
166 item[2] = 0 166 item[2] = 0
167 item[3] = 0 167 item[3] = 0
168 for i = 4, #item 168 item[4] = 0
169 item[5] = 0
170 for i = 6, #item
169 switch type item[i] when "table" 171 switch type item[i] when "table"
170 if item[i][1] == "comment" 172 if item[i][1] == "comment"
171 table.remove item, i 173 table.remove item, i
diff --git a/spec/outputs/test/ast_spec.lua b/spec/outputs/test/ast_spec.lua
new file mode 100644
index 0000000..bab5b9e
--- /dev/null
+++ b/spec/outputs/test/ast_spec.lua
@@ -0,0 +1,85 @@
1local yue = require("yue")
2return describe("yue.to_ast", function()
3 it("should return AST with end position for simple expression", function()
4 local ast = yue.to_ast("x = 1")
5 assert.is_not_nil(ast)
6 assert.same(ast[1], "File")
7 assert.same(ast[2], 1)
8 assert.same(ast[3], 1)
9 assert.is_number(ast[4])
10 return assert.is_number(ast[5])
11 end)
12 it("should have correct end position for leaf nodes", function()
13 local ast = yue.to_ast("1")
14 assert.is_not_nil(ast)
15 assert.same(ast[1], "File")
16 assert.same(ast[2], 1)
17 assert.same(ast[3], 1)
18 assert.is_number(ast[4])
19 return assert.is_number(ast[5])
20 end)
21 it("should have end position for multi-line code", function()
22 local code = [[x = 1
23y = 2]]
24 local ast = yue.to_ast(code)
25 assert.is_not_nil(ast)
26 assert.same(ast[1], "File")
27 assert.same(ast[2], 1)
28 assert.same(ast[3], 1)
29 return assert.is_true(ast[4] >= 2)
30 end)
31 it("should have end position for function definition", function()
32 local code = [[add = (a, b) ->
33 a + b]]
34 local ast = yue.to_ast(code)
35 assert.is_not_nil(ast)
36 assert.same(ast[1], "File")
37 assert.same(ast[2], 1)
38 assert.same(ast[3], 1)
39 assert.is_number(ast[4])
40 return assert.is_number(ast[5])
41 end)
42 it("should have end position for table literal", function()
43 local ast = yue.to_ast("{a: 1, b: 2}")
44 assert.is_not_nil(ast)
45 assert.same(ast[1], "File")
46 assert.same(ast[2], 1)
47 assert.same(ast[3], 1)
48 assert.is_number(ast[4])
49 return assert.is_number(ast[5])
50 end)
51 it("should have end position for class definition", function()
52 local code = [[class Person
53 new: (@name) =>
54 getName: => @name]]
55 local ast = yue.to_ast(code)
56 assert.is_not_nil(ast)
57 assert.same(ast[1], "File")
58 assert.same(ast[2], 1)
59 assert.same(ast[3], 1)
60 return assert.is_true(ast[4] >= 3)
61 end)
62 it("should return nil and error message for invalid syntax", function()
63 local ast, err = yue.to_ast("if then else")
64 assert.is_nil(ast)
65 return assert.is_string(err)
66 end)
67 it("should support flatten level parameter", function()
68 local ast = yue.to_ast("x = 1", 0)
69 assert.is_not_nil(ast)
70 assert.same(ast[1], "File")
71 assert.is_number(ast[4])
72 return assert.is_number(ast[5])
73 end)
74 return it("should have end position in nested structures", function()
75 local code = "x = [i for i = 1, 10]"
76 local ast = yue.to_ast(code)
77 assert.is_not_nil(ast)
78 assert.same(ast[1], "File")
79 assert.same(ast[2], 1)
80 assert.same(ast[3], 1)
81 assert.is_number(ast[4])
82 assert.is_number(ast[5])
83 return assert.is_true(ast[5] > 1)
84 end)
85end)
diff --git a/spec/outputs/test/format_spec.lua b/spec/outputs/test/format_spec.lua
index c9ea3c2..d38a0ad 100644
--- a/spec/outputs/test/format_spec.lua
+++ b/spec/outputs/test/format_spec.lua
@@ -164,7 +164,9 @@ local rewriteLineCol
164rewriteLineCol = function(item) 164rewriteLineCol = function(item)
165 item[2] = 0 165 item[2] = 0
166 item[3] = 0 166 item[3] = 0
167 for i = 4, #item do 167 item[4] = 0
168 item[5] = 0
169 for i = 6, #item do
168 local _exp_0 = type(item[i]) 170 local _exp_0 = type(item[i])
169 if "table" == _exp_0 then 171 if "table" == _exp_0 then
170 if item[i][1] == "comment" then 172 if item[i][1] == "comment" then
diff --git a/src/yuescript/yuescript.cpp b/src/yuescript/yuescript.cpp
index 0dbfe2f..7645ef4 100644
--- a/src/yuescript/yuescript.cpp
+++ b/src/yuescript/yuescript.cpp
@@ -380,18 +380,22 @@ static int yuetoast(lua_State* L) {
380 int count = current.children ? static_cast<int>(current.children->size()) : 0; 380 int count = current.children ? static_cast<int>(current.children->size()) : 0;
381 switch (count) { 381 switch (count) {
382 case 0: { 382 case 0: {
383 lua_createtable(L, 4, 0); 383 lua_createtable(L, 6, 0);
384 getName(node); 384 getName(node);
385 lua_rawseti(L, -2, 1); 385 lua_rawseti(L, -2, 1);
386 lua_pushinteger(L, node->m_begin.m_line); 386 lua_pushinteger(L, node->m_begin.m_line);
387 lua_rawseti(L, -2, 2); 387 lua_rawseti(L, -2, 2);
388 lua_pushinteger(L, node->m_begin.m_col); 388 lua_pushinteger(L, node->m_begin.m_col);
389 lua_rawseti(L, -2, 3); 389 lua_rawseti(L, -2, 3);
390 lua_pushinteger(L, node->m_end.m_line);
391 lua_rawseti(L, -2, 4);
392 lua_pushinteger(L, node->m_end.m_col);
393 lua_rawseti(L, -2, 5);
390 formatter.indent = 0; 394 formatter.indent = 0;
391 auto str = node->to_string(&formatter); 395 auto str = node->to_string(&formatter);
392 yue::Utils::trim(str); 396 yue::Utils::trim(str);
393 lua_pushlstring(L, str.c_str(), str.length()); 397 lua_pushlstring(L, str.c_str(), str.length());
394 lua_rawseti(L, -2, 4); 398 lua_rawseti(L, -2, 6);
395 lua_rawseti(L, tableIndex, static_cast<int>(lua_objlen(L, tableIndex)) + 1); 399 lua_rawseti(L, tableIndex, static_cast<int>(lua_objlen(L, tableIndex)) + 1);
396 break; 400 break;
397 } 401 }
@@ -404,6 +408,10 @@ static int yuetoast(lua_State* L) {
404 lua_rawseti(L, -2, 2); 408 lua_rawseti(L, -2, 2);
405 lua_pushinteger(L, node->m_begin.m_col); 409 lua_pushinteger(L, node->m_begin.m_col);
406 lua_rawseti(L, -2, 3); 410 lua_rawseti(L, -2, 3);
411 lua_pushinteger(L, node->m_end.m_line);
412 lua_rawseti(L, -2, 4);
413 lua_pushinteger(L, node->m_end.m_col);
414 lua_rawseti(L, -2, 5);
407 lua_pop(L, 1); 415 lua_pop(L, 1);
408 break; 416 break;
409 } 417 }
@@ -411,14 +419,18 @@ static int yuetoast(lua_State* L) {
411 } 419 }
412 default: { 420 default: {
413 auto len = static_cast<int>(lua_objlen(L, tableIndex)); 421 auto len = static_cast<int>(lua_objlen(L, tableIndex));
414 lua_createtable(L, count + 3, 0); 422 lua_createtable(L, count + 5, 0);
415 getName(node); 423 getName(node);
416 lua_rawseti(L, -2, 1); 424 lua_rawseti(L, -2, 1);
417 lua_pushinteger(L, node->m_begin.m_line); 425 lua_pushinteger(L, node->m_begin.m_line);
418 lua_rawseti(L, -2, 2); 426 lua_rawseti(L, -2, 2);
419 lua_pushinteger(L, node->m_begin.m_col); 427 lua_pushinteger(L, node->m_begin.m_col);
420 lua_rawseti(L, -2, 3); 428 lua_rawseti(L, -2, 3);
421 for (int i = count, j = 4; i >= 1; i--, j++) { 429 lua_pushinteger(L, node->m_end.m_line);
430 lua_rawseti(L, -2, 4);
431 lua_pushinteger(L, node->m_end.m_col);
432 lua_rawseti(L, -2, 5);
433 for (int i = count, j = 6; i >= 1; i--, j++) {
422 lua_rawgeti(L, tableIndex, len - i + 1); 434 lua_rawgeti(L, tableIndex, len - i + 1);
423 lua_rawseti(L, -2, j); 435 lua_rawseti(L, -2, j);
424 } 436 }