From c5ce9722e3e1b115ba87c807190be9a704d88041 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Mon, 29 Mar 2021 10:43:10 +0900 Subject: [PATCH 01/26] added an alternative SAT example. --- examples/sat2.kx | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 examples/sat2.kx diff --git a/examples/sat2.kx b/examples/sat2.kx new file mode 100644 index 000000000..1b1ec5f93 --- /dev/null +++ b/examples/sat2.kx @@ -0,0 +1,55 @@ +using SatisfiablitySolver; + +var vs = new VersionSatisfiablity(); + +var X = vs.addProduct("X") + .addVersion("0.0.1", true); +var A = vs.addProduct("A") + .addVersion("0.0.1") + .addVersion("0.0.2"); +var B = vs.addProduct("B") + .addVersion("0.0.1") + .addVersion("0.0.2"); +var Z = vs.addProduct("Z") + .addVersion("0.0.1") + .addVersion("0.0.2"); + +function msg(a) { + if (a.not) { + return ("%1% is NOT v%2%" % a.value.name % a.value.version).format(); + } else { + return ("%1% is v%2%" % a.value.name % a.value.version).format(); + } +} +function error(item) { + switch (item.length()) { + when 1: + System.println("- ", msg(item[0])); + when 2: + item[0].not = !item[0].not; // (!A || B) means (A => B) + System.println("- ", msg(item[0]), " => ", msg(item[1])); + else: + System.println("- ", item.map { => msg(_1) }.join(', or\n ')); + } +} + +function tryit() { + var count = 0; + for (var e in vs) { + System.println("%d: " % ++count, e.toJsonString(true)); + } + if (count == 0) { + System.println("Unsatisfiable - Conflict here"); + vs.getConflict().each { => error(_1) }; + } +} + +A("0.0.1").dependsOn(Z("0.0.1")); +A("0.0.2").dependsOn(Z("0.0.2")); + +B("0.0.1").dependsOn(Z("0.0.1")); +B("0.0.2").dependsOn(Z("0.0.2")); + +X("0.0.1").dependsOn(A("0.0.2")); +X("0.0.1").dependsOn(B("0.0.1")); +tryit(); From b10fdb10adeffa8797445284ce05c37458d9cd10 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Mon, 29 Mar 2021 11:50:02 +0900 Subject: [PATCH 02/26] refs #255: a range/int index for infinite Range. --- docs/spec/lib/basic/range.md | 70 +++++++++++++++++++++++++++++++++--- lib/std/kxenumerable.kx | 58 +++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 6 deletions(-) diff --git a/docs/spec/lib/basic/range.md b/docs/spec/lib/basic/range.md index d92cbf3db..be4713a81 100644 --- a/docs/spec/lib/basic/range.md +++ b/docs/spec/lib/basic/range.md @@ -181,7 +181,7 @@ out of range (9) out of range (10) ``` -### Example 5. Range for Switch-Case (2) +### Example 6. Range for Switch-Case (2) #### Code @@ -224,7 +224,7 @@ okay 1 (ae) out of range (af) ``` -### Example 6. Range for String +### Example 7. Range for String Range for String means to return a part of string between the start and the end of `Range`. It is like `String#subString()` but note that `String#subString()` requires a length. @@ -246,7 +246,7 @@ cdefghijklmnopqrstuvwxy cdefghijklmnopqrstuvwxy ``` -### Example 7. Range for Array +### Example 8. Range for Array Range for Array means to return a part of array between the start and the end of `Range`. It is like `Array#subArray()` but note that `Array#subArray()` requires a length. @@ -268,7 +268,7 @@ System.println(ary.subArray(2, 10)); // [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] ``` -### Example 8. Range for Binary +### Example 9. Range for Binary Range for Binary means to return a part of binary between the start and the end of `Range`. It is like `Binary#subBinary()` but note that `Binary#subBinary()` requires a length. @@ -290,7 +290,7 @@ System.println(bin.subBinary(2, 10)); // <0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x <0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b> ``` -### Example 9. Range for Range +### Example 10. Range for Range Range for Range means to return parts between the start and the end by `Range` at the index. @@ -308,3 +308,63 @@ System.println(range[2...12]); // [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] ``` + +### Example 11. Infinite Range (Range Index) + +Range for Range means to return parts between the start and the end by `Range` at the index. + +#### Code + +```javascript +var range = 0..; +System.println(range[2..12]); // [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +System.println(range[2...12]); // [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] +``` + +#### Result + +``` +[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +[2, 3, 4, 5, 6, 7, 8, 9, 10, 11] +``` + +### Example 12. Infinite Range (Integer Index) + +Range for Range means to return parts between the start and the end by `Range` at the index. + +#### Code + +```javascript +var range = 1..; +System.println(range[2]); // 3 +System.println(range[22]); // 23 +System.println(range[1050]); // 1051 +``` + +#### Result + +``` +3 +23 +1051 +``` + +### Example 13. Range for Range (Infinite Range Index) + +Range for Range means to return parts between the start and the end by `Range` at the index. + +#### Code + +```javascript +System.println((1..10)[2..]); // 3..10 +System.println((1...10)[2..]); // 3...10 +System.println((100..)[2..]); // 102.. +``` + +#### Result + +``` +Range(3, 10, false) +Range(3, 10, true) +Range(102, null, false) +``` diff --git a/lib/std/kxenumerable.kx b/lib/std/kxenumerable.kx index 7bdb598f1..4701c34a1 100644 --- a/lib/std/kxenumerable.kx +++ b/lib/std/kxenumerable.kx @@ -820,6 +820,8 @@ _class _Range(start_, end_, excludeEnd_) { mixin _Enumerable; @Enumerable.sum = @sum; @isRange = true; + var arrayCache_ = []; + var arrayCacheLastIndex_ = 0; var cur_; private initialize() { cur_ = start_; @@ -853,6 +855,9 @@ _class _Range(start_, end_, excludeEnd_) { return a <=> b; } private eachByFunction(func) { + if (!@array && arrayCacheLastIndex_ > 0) { + @array = @toArray(); + } if (@array) { var i = 0; var sz = @array.length(); @@ -897,6 +902,9 @@ _class _Range(start_, end_, excludeEnd_) { if (func.isFunction) { return eachByFunction(func); } + if (!@array && arrayCacheLastIndex_ > 0) { + @array = @toArray(); + } if (@array) { @array.each(&(e) => { yield e; @@ -945,9 +953,57 @@ _class _Range(start_, end_, excludeEnd_) { } return true; } + public toString() { + return "Range(%{start_}, %{end_.isDefined ? end_ : 'null'}, %{excludeEnd_ ? 'true' : 'false'})"; + } + public toArray() { + if (end_.isUndefined) { + throw FiberException("Cannot complete the iteration"); + } + while (true) { + if (end_.isDefined && excludeEnd_ && comp(cur_, end_) >= 0) { + break; + } + arrayCache_.push(cur_); + if (end_.isDefined && !excludeEnd_ && comp(cur_, end_) >= 0) { + break; + } + cur_ = cur_.next(); + } + return arrayCache_; + } public [](rhs) { + if (rhs.isInteger) { + var n = rhs - arrayCacheLastIndex_ + 1; + if (n > 0) { + arrayCache_ += @take(n); + arrayCacheLastIndex_ += n; + } + return arrayCache_[rhs]; + } + if (rhs.isRange) { + var s = rhs.begin(); + var e = rhs.end(); + var ex = rhs.isEndExcluded(); + if (e.isUndefined) { + if (end_.isUndefined) { + return new Range(start_ + s, null, ex); + } else { + return new Range(start_ + s, end_, excludeEnd_); + } + } + if (end_.isUndefined) { + var n = e + (ex ? 0 : 1) - arrayCacheLastIndex_; + if (n > 0) { + arrayCache_ += @take(n); + arrayCacheLastIndex_ += n; + } + return arrayCache_[rhs]; + } + /* will do toArray. */ + } if (!@array) { - @array = @toArray(); + @array = toArray(); } return @array[rhs]; } From acc9622fa50af8f5bcff88d02ea60c92983b23c0 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Mon, 29 Mar 2021 11:56:14 +0900 Subject: [PATCH 03/26] fixed #255: added a test code. --- docs/spec/lib/basic/range.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/spec/lib/basic/range.md b/docs/spec/lib/basic/range.md index be4713a81..6edc8cc71 100644 --- a/docs/spec/lib/basic/range.md +++ b/docs/spec/lib/basic/range.md @@ -349,7 +349,7 @@ System.println(range[1050]); // 1051 1051 ``` -### Example 13. Range for Range (Infinite Range Index) +### Example 13. Range for Range (Infinite Range Index 1) Range for Range means to return parts between the start and the end by `Range` at the index. @@ -368,3 +368,28 @@ Range(3, 10, false) Range(3, 10, true) Range(102, null, false) ``` + +### Example 14. Range for Range (Infinite Range Index 2) + +Range for Range means to return parts between the start and the end by `Range` at the index. + +#### Code + +```javascript +var range = (1...10)[2..]; +for (e in range) { + System.println(e); +} +``` + +#### Result + +``` +3 +4 +5 +6 +7 +8 +9 +``` From b2ccb9f9418262fe296ce71f3a1ac89a224d6921 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Mon, 29 Mar 2021 12:55:21 +0900 Subject: [PATCH 04/26] refs #255: updated Range. --- lib/std/kxenumerable.kx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/std/kxenumerable.kx b/lib/std/kxenumerable.kx index 4701c34a1..67ab81891 100644 --- a/lib/std/kxenumerable.kx +++ b/lib/std/kxenumerable.kx @@ -986,11 +986,7 @@ _class _Range(start_, end_, excludeEnd_) { var e = rhs.end(); var ex = rhs.isEndExcluded(); if (e.isUndefined) { - if (end_.isUndefined) { - return new Range(start_ + s, null, ex); - } else { - return new Range(start_ + s, end_, excludeEnd_); - } + return new Range(start_ + s, end_, excludeEnd_); } if (end_.isUndefined) { var n = e + (ex ? 0 : 1) - arrayCacheLastIndex_; From b794ed79734727590dcbac5cfa1706c2aa4c46cf Mon Sep 17 00:00:00 2001 From: Kray-G Date: Mon, 29 Mar 2021 13:57:45 +0900 Subject: [PATCH 05/26] updated ChangeLog.md --- ChangeLog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 02452399e..3fe213551 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -16,13 +16,14 @@ * New Features * Supported SAT solver by picosat. * Supported SemanticVersion class. -* Improvements +* Improvements/Enhancements * Supported putting a comma at the end of an argument's list for both declaration and calling. * Supported the operator of `==` and `!=` in Boolean class. * Supported `String#isIntegerString`. * Shared an implementation of conversion for a string, an integer, and a double. * Improved type analysis for the language server. * SpecTest: Made a space wider of Test case number. + * #255: Improved the `operator[]` in `Range`. * Bug Fixed * #235: Crash when using `_` outside a function. * #236: Can't specify the class as a return type of function. From 10ade65ddfc2fb17b9994c524e515dbac7fbcbe5 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 08:46:55 +0900 Subject: [PATCH 06/26] removed an unnecessary folder. --- lib/exec/3rdparty/.gitignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 lib/exec/3rdparty/.gitignore diff --git a/lib/exec/3rdparty/.gitignore b/lib/exec/3rdparty/.gitignore deleted file mode 100644 index d6b7ef32c..000000000 --- a/lib/exec/3rdparty/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore From d2b978f7cd8c3a8611903d09dcdca277d4d80516 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 08:47:28 +0900 Subject: [PATCH 07/26] added a package folder to .gitignor file. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 28ce6b820..c22ce1cfb 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ TEMP* /*.so* /TEST.md /*.deb +/lib/package From d1f8f212550a4fd3ec044b8b11285888ed35a356 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 08:48:05 +0900 Subject: [PATCH 08/26] setup a package path. --- lib/std/kxstartup.kx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/kxstartup.kx b/lib/std/kxstartup.kx index 43881cdaa..79450d88a 100644 --- a/lib/std/kxstartup.kx +++ b/lib/std/kxstartup.kx @@ -82,7 +82,7 @@ var Xml, Net; } } $libpath = libpath; - $pkgpath = (libpath / "../kinxpkg").replace(/\/[^\/]+\/\.\./, ""); + $pkgpath = (libpath / "package").replace(/\/[^\/]+\/\.\./, ""); })(); const KX_KEY_ESC = 0x1b; From b3d36d16c577181c0620c61b1164314d2839cba1 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 08:45:13 +0900 Subject: [PATCH 09/26] refs #256: added a test code. --- docs/spec/others/bugfixes.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/spec/others/bugfixes.md b/docs/spec/others/bugfixes.md index b9cd539fd..d1493e620 100644 --- a/docs/spec/others/bugfixes.md +++ b/docs/spec/others/bugfixes.md @@ -95,7 +95,7 @@ for (ypix in 0...24) { : ......------------------------::::::::::;;;;+==x& &x=+;;;::::::-------. ``` -### Example 3. Comparing between variables of a string. +### Example 3. Comparing between variables of a string This bug's was caused by missing implementation. @@ -155,3 +155,32 @@ f().xxx(); ``` Successful ``` + +### Example 5. Comparison Failure & Crash + +This bug's was caused by lack of the code which moves to the next opcode. + +* Issue: [#256](https://github.com/Kray-G/kinx/issues/256) +* Fixed: [bf1b5ba926db08a69a5c6786d7557f9f6d7e420f](https://github.com/Kray-G/kinx/commit/bf1b5ba926db08a69a5c6786d7557f9f6d7e420f) + +#### Code + +```javascript +function test1(a) { return 10 >= a; } +function test2(a) { return -1 <= a; } +function test3(a) { return 100 < a; } + +System.println(test1(10.5)); +System.println(test2(10.5)); +System.println(test3(10.5)); +``` + +#### Result + +``` +0 +1 +0 +``` + + From 6ea4e8c8605ff4db2967f12fe538054161d06a7e Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 08:39:49 +0900 Subject: [PATCH 10/26] fixed #256: comparison should work. --- src/exec/code/ge.inc | 1 + src/exec/code/le.inc | 1 + src/exec/code/lt.inc | 1 + 3 files changed, 3 insertions(+) diff --git a/src/exec/code/ge.inc b/src/exec/code/ge.inc index 854fd56ba..6ead4bed9 100644 --- a/src/exec/code/ge.inc +++ b/src/exec/code/ge.inc @@ -118,6 +118,7 @@ int exc = 0; \ (void)kx_try_le_i(ctx, cur, v1, &exc); /* comparing by opposite operation */ \ KX_EXCEPTION_CHECK("SystemException", exc); \ + cur = cur->next; \ } \ } \ /**/ diff --git a/src/exec/code/le.inc b/src/exec/code/le.inc index b9bdbf575..f9dfd0aa2 100644 --- a/src/exec/code/le.inc +++ b/src/exec/code/le.inc @@ -118,6 +118,7 @@ int exc = 0; \ (void)kx_try_ge_i(ctx, cur, v1, &exc); /* comparing by opposite operation */ \ KX_EXCEPTION_CHECK("SystemException", exc); \ + cur = cur->next; \ } \ } \ /**/ diff --git a/src/exec/code/lt.inc b/src/exec/code/lt.inc index 62346e988..e7f950913 100644 --- a/src/exec/code/lt.inc +++ b/src/exec/code/lt.inc @@ -118,6 +118,7 @@ int exc = 0; \ (void)kx_try_gt_i(ctx, cur, v1, &exc); /* comparing by opposite operation */ \ KX_EXCEPTION_CHECK("SystemException", exc); \ + cur = cur->next; \ } \ } \ /**/ From da97cf8b04fe29e269908ff408f51924e260d39a Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 11:46:17 +0900 Subject: [PATCH 11/26] refs #232: added the code for packages. --- include/kinx.h | 3 +- include/kxastobject.h | 1 + include/parser.h | 9 +++ src/ast_analyzer.c | 3 +- src/ast_defdisp.c | 3 +- src/ast_display.c | 3 +- src/ast_gencode.c | 6 +- src/ast_object.c | 19 ++++- src/global.c | 4 ++ src/kinx.y | 6 +- src/lexer.c | 164 ++++++++++++++++++++++++++++++++++++------ src/loadlib.c | 15 ++++ src/mainlib.c | 83 ++++++++++++++++++++- src/parser.c | 6 +- 14 files changed, 285 insertions(+), 40 deletions(-) diff --git a/include/kinx.h b/include/kinx.h index 3021d6010..827370b72 100644 --- a/include/kinx.h +++ b/include/kinx.h @@ -31,8 +31,9 @@ typedef struct kx_lexinfo_ { int is_trim; kx_lexinner_t inner; kx_yyin_t in; - int tempbuf[16]; + const char *pkgkey; const int *restart; + int tempbuf[16]; } kx_lexinfo_t; kvec_init_t(kx_lexinfo_t); diff --git a/include/kxastobject.h b/include/kxastobject.h index 9588932a2..06effb634 100644 --- a/include/kxastobject.h +++ b/include/kxastobject.h @@ -34,6 +34,7 @@ extern kx_object_t *kx_gen_str_object_pos(name_t name); extern const char *kx_gen_constant_string(const char *name); extern const char *kx_check_the_name(kx_object_t *obj); extern kx_object_t *kx_gen_stmtlist(kx_object_t *lhs, kx_object_t *rhs); +extern kx_object_t *kx_gen_exprlist(kx_object_t *lhs, kx_object_t *rhs); extern kx_object_t *kx_gen_range_object(kx_object_t *start, kx_object_t *end, int include_end); extern kx_object_t *kx_gen_case_when_object(kx_object_t *decl, kx_object_t *expr, kx_object_t *modifier); extern kx_object_t *kx_gen_forin_object(kx_object_t *var, kx_object_t *range, kx_object_t *stmt, int is_decl); diff --git a/include/parser.h b/include/parser.h index cef129b9d..1a888a53b 100644 --- a/include/parser.h +++ b/include/parser.h @@ -4,6 +4,13 @@ #include #include +#include + +typedef struct package_t_ { + const char *vers; + struct package_t_ *next; +} package_t; +KHASH_MAP_INIT_STR(package, package_t *) typedef struct name_t_ { const char *name; @@ -11,11 +18,13 @@ typedef struct name_t_ { int pos1; int pos2; } name_t; + typedef struct arytype_t_ { int type; int depth; const char *name; /* class name */ } arytype_t; + typedef struct named_stmt_ { const char *name; /* class name */ kx_object_t *stmt; diff --git a/src/ast_analyzer.c b/src/ast_analyzer.c index 86725cec8..c106c3bdb 100644 --- a/src/ast_analyzer.c +++ b/src/ast_analyzer.c @@ -1468,7 +1468,8 @@ LOOP_HEAD:; case KXST_EXPRSEQ: /* lhs: expr1: rhs: expr2 */ case KXST_EXPRLIST: /* lhs: expr1: rhs: expr2 */ analyze_ast(ctx, node->lhs, actx); - analyze_ast(ctx, node->rhs, actx); + node = node->rhs; + if (node) goto LOOP_HEAD; break; case KXST_STMTLIST: /* lhs: stmt2: rhs: stmt1 */ analyze_ast(ctx, node->lhs, actx); diff --git a/src/ast_defdisp.c b/src/ast_defdisp.c index 2b3c99781..7acde0bd4 100644 --- a/src/ast_defdisp.c +++ b/src/ast_defdisp.c @@ -555,7 +555,8 @@ LOOP_HEAD:; break; case KXST_EXPRLIST: /* lhs: expr1: rhs: expr2 */ display_def_ast(dctx, node->lhs, lvalue); - display_def_ast(dctx, node->rhs, lvalue); + node = node->rhs; + if (node) goto LOOP_HEAD; break; case KXST_STMTLIST: /* lhs: stmt1: rhs: stmt2 */ display_def_ast(dctx, node->lhs, lvalue); diff --git a/src/ast_display.c b/src/ast_display.c index e97eecfe6..0c53ed89d 100644 --- a/src/ast_display.c +++ b/src/ast_display.c @@ -399,7 +399,8 @@ LOOP_HEAD:; break; case KXST_EXPRLIST: /* lhs: expr1: rhs: expr2 */ display_ast(node->lhs, indent, lvalue); - display_ast(node->rhs, indent, lvalue); + node = node->rhs; + if (node) goto LOOP_HEAD; break; case KXST_STMTLIST: /* lhs: stmt1: rhs: stmt2 */ display_ast(node->lhs, indent, 0); diff --git a/src/ast_gencode.c b/src/ast_gencode.c index 87482de67..7a3763023 100644 --- a/src/ast_gencode.c +++ b/src/ast_gencode.c @@ -1099,6 +1099,7 @@ static void gencode_ast(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, } LOOP_HEAD:; +// printf("%s:%d, node->type = %d (%s:%d)\n", __FILE__, __LINE__, node->type, node->file, node->line); kx_module_t *module = ana->module; switch (node->type) { case KXVL_UNKNOWN: @@ -1994,9 +1995,8 @@ LOOP_HEAD:; } case KXST_EXPRLIST: { /* lhs: expr1: rhs: expr2 */ gencode_ast_hook(ctx, node->lhs, ana, 0); - if (node->rhs) { - gencode_ast_hook(ctx, node->rhs, ana, 0); - } + node = node->rhs; + if (node) goto LOOP_HEAD; break; } case KXST_STMTLIST: { /* lhs: stmt1: rhs: stmt2 */ diff --git a/src/ast_object.c b/src/ast_object.c index ceaaabba0..8415c1aee 100644 --- a/src/ast_object.c +++ b/src/ast_object.c @@ -257,6 +257,22 @@ kx_object_t *kx_gen_stmtlist(kx_object_t *lhs, kx_object_t *rhs) return lhs; } +kx_object_t *kx_gen_exprlist(kx_object_t *lhs, kx_object_t *rhs) +{ + if (!lhs) { + return rhs; + } + if (lhs->type != KXST_EXPRLIST) { + return kx_gen_bexpr_object(KXST_EXPRLIST, lhs, rhs); + } + kx_object_t *node = lhs->ex ? lhs->ex : lhs; + while (node->rhs && node->rhs->type == KXST_EXPRLIST) { + node = node->rhs; + } + lhs->ex = node->rhs = kx_gen_bexpr_object(KXST_EXPRLIST, node->rhs, rhs); + return lhs; +} + kx_object_t *kx_gen_range_object(kx_object_t *lhs, kx_object_t *end, int exclude_end) { return kx_gen_obj(KXOP_MKRANGE, exclude_end, lhs, end, NULL); @@ -690,9 +706,6 @@ static kx_object_t *kx_gen_func_object_impl(int type, int optional, arytype_t *r } } kx_object_t *obj = kx_gen_obj(type, (type != KXST_NATIVE) ? optional : KXFT_ANONYMOUS, lhs, rhs, ex); - if (inherit) { - obj->typename = inherit; - } obj->line2 = obj->line; if (line > 0) { obj->line = line; diff --git a/src/global.c b/src/global.c index 7a0072dae..99c14be62 100644 --- a/src/global.c +++ b/src/global.c @@ -1,6 +1,9 @@ #include #include +#include #include +#define KX_NO_INCLUDE_PARSER_TAB_H +#include /* used in parsing, parsing phase is not reentrant. */ kx_lexinfo_t kx_lexinfo = {0}; @@ -10,6 +13,7 @@ kx_object_t *kx_ast_root = NULL; int g_yyerror = 0; int g_yywarning = 0; kx_context_t *g_parse_ctx = NULL; +khash_t(package) *g_packages; /* used in runtime. */ volatile int g_terminated = 0; diff --git a/src/kinx.y b/src/kinx.y index 72af82c8b..f87cd2f73 100644 --- a/src/kinx.y +++ b/src/kinx.y @@ -821,7 +821,7 @@ AssignExpressionObjList KeyValueList : KeyValue - | KeyValueList ',' KeyValue { $$ = kx_gen_bexpr_object(KXST_EXPRLIST, $1, $3); } + | KeyValueList ',' KeyValue { $$ = kx_gen_exprlist($1, $3); } ; KeyValue @@ -1034,9 +1034,9 @@ Inherit_Opt .name = kx_check_the_name($3), .stmt = kx_gen_bexpr_object(KXST_STMTLIST, - kx_gen_bexpr_object(KXOP_DECL, kx_gen_var_object_line("this", KX_UNKNOWN_T, $2), + kx_gen_bexpr_object(KXOP_DECL, kx_gen_var_object_line("this", KX_OBJ_T, $2), kx_gen_bexpr_object(KXOP_CALL, kx_gen_bexpr_object(KXOP_IDX, $3, kx_gen_str_object("create")), $4)), - kx_gen_bexpr_object(KXOP_DECL, kx_gen_var_object_line("super", KX_UNKNOWN_T, $2), + kx_gen_bexpr_object(KXOP_DECL, kx_gen_var_object_line("super", KX_OBJ_T, $2), kx_gen_bexpr_object(KXOP_CALL, kx_gen_bexpr_object(KXOP_IDX, kx_gen_var_object("System", KX_UNKNOWN_T), kx_gen_str_object("makeSuper")), kx_gen_var_object("this", KX_UNKNOWN_T))) ), }; diff --git a/src/lexer.c b/src/lexer.c index cbe0d48d6..24863e0f3 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -15,6 +15,7 @@ static int g_binmode = 0; static int g_regexmode = 0; static const char *varname = NULL; static const char *modulename = NULL; +extern khash_t(package) *g_packages; static const char *parent_path(const char *str) { @@ -45,6 +46,7 @@ void setup_lexinfo(kx_context_t *ctx, const char *file, kx_yyin_t *yyin) kx_lexinfo.inner.brcount = 0; kx_lexinfo.inner.quote = 0; kx_lexinfo.in = *yyin; + kx_lexinfo.pkgkey = NULL; } void init_lexer(kx_context_t *ctx) @@ -69,7 +71,22 @@ void kx_make_regex_mode(int br) g_regexmode = br; } -static void load_using_module_asta(const char *name, int len) +static const char *search_using_path(const char *name) +{ + char libname[LIBNAME_BUFSIZE*2] = {0}; + const char *file = NULL; + /* Trying to search the file in the same directory first. */ + snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s%c%s.kx", parent_path(kx_lexinfo.file), PATH_DELCH, name); + if (file_exists(libname)) { + file = libname; + } else { + snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s.kx", name); + file = kxlib_file_exists(libname); + } + return file; +} + +static void load_using_module_asta(const char *name, int len, const char *pkgkey) { char *path = kx_calloc(len+2, sizeof(char)); memcpy(path, name, len); @@ -87,6 +104,10 @@ static void load_using_module_asta(const char *name, int len) .str = NULL, .file = const_str(g_parse_ctx, file) }); + if (pkgkey) { + kx_lexinfo.pkgkey = pkgkey; + pkgkey = NULL; + } kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); } } @@ -95,7 +116,7 @@ static void load_using_module_asta(const char *name, int len) kx_free(path); } -static int load_using_module(const char *name, int no_error) +static int load_using_module(const char *name, const char *pkgkey, int no_error) { char libname[LIBNAME_BUFSIZE*2] = {0}; const char *file = NULL; @@ -104,27 +125,21 @@ static int load_using_module(const char *name, int no_error) if (name[len-2] != PATH_DELCH) { kx_yywarning("Can not use '*' with a current directoy in 'using' directive"); } else { - load_using_module_asta(name, len); + load_using_module_asta(name, len, pkgkey); return kx_yylex(); } } else { - /* Trying to search the file in the same directory first. */ - snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s%c%s.kx", parent_path(kx_lexinfo.file), PATH_DELCH, name); - if (file_exists(libname)) { - file = libname; - } else { - snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s.kx", name); - if (!(file = kxlib_file_exists(libname))) { - if (!no_error) { - char buf[LIBNAME_BUFSIZE*3] = {0}; - snprintf(buf, LIBNAME_BUFSIZE*3-1, "File not found(%s)", libname); - kx_yywarning(buf); - } - while (kx_lexinfo.ch && kx_lexinfo.ch != ';') { - kx_lex_next(kx_lexinfo); - } - return no_error ? ';' : ERROR; + file = search_using_path(name); + if (!file) { + if (!no_error) { + char buf[LIBNAME_BUFSIZE*3] = {0}; + snprintf(buf, LIBNAME_BUFSIZE*3-1, "Library file not found(%s)", name); + kx_yywarning(buf); + } + while (kx_lexinfo.ch && kx_lexinfo.ch != ';') { + kx_lex_next(kx_lexinfo); } + return no_error ? ';' : ERROR; } kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); @@ -134,12 +149,63 @@ static int load_using_module(const char *name, int no_error) .str = NULL, .file = const_str(g_parse_ctx, file) }); + if (pkgkey) { + kx_lexinfo.pkgkey = pkgkey; + } } kx_lex_next(kx_lexinfo); return kx_yylex(); /* recursive call for the new file. */ } +static void push_package_version(const char *key, const char *ver) +{ + khint_t k = kh_get(package, g_packages, key); + if (k != kh_end(g_packages)) { + key = kx_const_str(g_parse_ctx, key); + ver = kx_const_str(g_parse_ctx, ver); + package_t *pkg = kh_value(g_packages, k); + package_t *newp = kx_calloc(1, sizeof(package_t)); + newp->vers = ver; + newp->next = pkg; + kh_value(g_packages, k) = newp; + } +} + +static void pop_package_version(const char *key) +{ + khint_t k = kh_get(package, g_packages, key); + if (k != kh_end(g_packages)) { + package_t *pkg = kh_value(g_packages, k); + if (pkg->next) { + package_t *next = pkg->next; + kx_free(pkg); + kh_value(g_packages, k) = next; + } + } +} + +static int set_package_version(const char *pkgname, int pos) +{ + khint_t k = kh_get(package, g_packages, pkgname); + if (k != kh_end(g_packages)) { + package_t *pkg = kh_value(g_packages, k); + const char *p = pkg->vers; + if (p) { + kx_strbuf[pos++] = PATH_DELCH; + while (*p) { + kx_strbuf[pos++] = *p++; + } + kx_strbuf[pos++] = PATH_DELCH; + kx_strbuf[pos++] = 'l'; + kx_strbuf[pos++] = 'i'; + kx_strbuf[pos++] = 'b'; + kx_strbuf[pos++] = PATH_DELCH; + } + } + return pos; +} + static int process_using(void) { int no_error = 0; @@ -151,16 +217,65 @@ static int process_using(void) while (kx_is_whitespace(kx_lexinfo)) { kx_lex_next(kx_lexinfo); } + const char *pkgname = NULL; + int pushed_version = 0; + int is_package = kx_lexinfo.ch == '@'; + int is_package_version = 0; + int is_package_verspos = 0; + int is_package_namepos = 0; int pos = 0; - kx_strbuf[pos++] = kx_lexinfo.ch; + if (is_package) { + kx_strbuf[pos++] = 'p'; + kx_strbuf[pos++] = 'a'; + kx_strbuf[pos++] = 'c'; + kx_strbuf[pos++] = 'k'; + kx_strbuf[pos++] = 'a'; + kx_strbuf[pos++] = 'g'; + kx_strbuf[pos++] = 'e'; + kx_strbuf[pos++] = PATH_DELCH; + is_package_namepos = pos; + } else { + kx_strbuf[pos++] = kx_lexinfo.ch; + } kx_lex_next(kx_lexinfo); while (pos < POSMAX && (kx_is_filechar(kx_lexinfo) || kx_lexinfo.ch == '*')) { - kx_strbuf[pos++] = kx_lexinfo.ch == '.' ? PATH_DELCH : kx_lexinfo.ch; + if (is_package) { + if (is_package_version == 0 && kx_lexinfo.ch == '.') { + kx_strbuf[pos] = 0; + pkgname = kx_const_str(g_parse_ctx, kx_strbuf + is_package_namepos); + pos = set_package_version(pkgname, pos); + is_package_version = 2; + } else if (is_package_version == 0 && kx_lexinfo.ch == '(') { + kx_strbuf[pos] = 0; + pkgname = kx_const_str(g_parse_ctx, kx_strbuf + is_package_namepos); + is_package_version = 1; + kx_strbuf[pos++] = PATH_DELCH; + is_package_verspos = pos; + } else if (is_package_version == 1 && kx_lexinfo.ch == ')') { + kx_strbuf[pos] = 0; + const char *ver = kx_const_str(g_parse_ctx, kx_strbuf + is_package_verspos); + pushed_version = 1; + push_package_version(pkgname, ver); + is_package_version = 2; + kx_strbuf[pos++] = PATH_DELCH; + kx_strbuf[pos++] = 'l'; + kx_strbuf[pos++] = 'i'; + kx_strbuf[pos++] = 'b'; + } else { + if (is_package_version == 1) { + kx_strbuf[pos++] = kx_lexinfo.ch; + } else { + kx_strbuf[pos++] = kx_lexinfo.ch == '.' ? PATH_DELCH : kx_lexinfo.ch; + } + } + } else { + kx_strbuf[pos++] = kx_lexinfo.ch == '.' ? PATH_DELCH : kx_lexinfo.ch; + } kx_lex_next(kx_lexinfo); } kx_strbuf[pos] = 0; - return load_using_module(kx_strbuf, no_error); + return load_using_module(kx_strbuf, pushed_version ? pkgname : NULL, no_error); } static int get_keyword_token(const char *val) @@ -646,7 +761,7 @@ static int process_import(void) return ';'; case 6: g_import = 0; - return load_using_module(modulename, 1); + return load_using_module(modulename, NULL, 1); } return ERROR; } @@ -683,6 +798,9 @@ int kx_yylex() if (kx_lexinfo.in.fp && kx_lexinfo.in.fp != stdin) { fclose(kx_lexinfo.in.fp); } + if (kx_lexinfo.pkgkey) { + pop_package_version(kx_lexinfo.pkgkey); + } kx_lexinfo = kv_pop(kx_lex_stack); if (!kx_lexinfo.in.fp && !kx_lexinfo.in.str) { kx_lexinfo.in.fp = fopen(kx_lexinfo.in.file, "r"); diff --git a/src/loadlib.c b/src/loadlib.c index ecbdb62b6..024cd44d0 100644 --- a/src/loadlib.c +++ b/src/loadlib.c @@ -107,6 +107,21 @@ void unload_library(void *h) } #endif +const char *kxlib_package_file(void) +{ + const char *checkfile = make_path_with(get_kinx_path(), "lib"PATH_DELIM"package", "kxpackage.ini"); + if (file_exists(checkfile)) { + return checkfile; + } + #if !defined(KCC_WINDOWS) + checkfile = make_path_with("/usr/bin", "kinxlib/package", "kxpackage.ini"); + if (file_exists(checkfile)) { + return checkfile; + } + #endif + return NULL; +} + const char *kxlib_file_exists_no_current(const char *file) { const char *checkfile = make_path(get_kinx_path(), file); diff --git a/src/mainlib.c b/src/mainlib.c index 380b47d3b..78897db04 100644 --- a/src/mainlib.c +++ b/src/mainlib.c @@ -38,6 +38,8 @@ extern void alloc_initialize(void); extern void alloc_finalize(void); extern void init_allocator(void); extern volatile int g_terminated; +extern khash_t(package) *g_packages; +extern const char *kxlib_package_file(void); #ifdef YYDEBUG extern int kx_yydebug; @@ -122,7 +124,18 @@ static void version(int detail) if (detail) { printf("- platform: %s\n", sljit_get_platform_name()); printf("- path: %s\n", get_kinx_path()); - printf("\n"); + + /* Package List */ + if (kh_end(g_packages) > 0) { + printf("\nPackages:\n"); + for (khint_t k = 0; k < kh_end(g_packages); ++k) { + if (kh_exist(g_packages, k)) { + const char *key = kh_key(g_packages, k); + package_t *p = kh_value(g_packages, k); + printf(" * %s v%s\n", key, p->vers); + } + } + } } } @@ -166,6 +179,72 @@ static void setup_run_environment(const char *filename) #endif } +static void setup_package_info(kx_context_t *ctx) +{ + g_packages = kh_init(package); + const char *pkgfile = kxlib_package_file(); + if (!pkgfile) { + return; + } + FILE *fp = fopen(pkgfile, "r"); + if (fp) { + char buf[1024] = {0}; + while (fgets(buf, 1020, fp)) { + char *p = strrchr(buf, '='); + if (!p || p == buf) continue; + char *s = p; + while (buf < s) { + --s; + if (*s != ' ' && *s != '\t') { + break; + } + *s = 0; + } + if (buf == s) continue; + ++p; + while (*p) { + if (*p != ' ' && *p != '\t') { + break; + } + ++p; + } + char *e = p + strlen(p) - 1; + while (*e == '\n' || *e == '\r') { + *e = 0; + --e; + } + if (*p) { + int absent; + const char *key = kx_const_str(ctx, buf); + const char *ver = kx_const_str(ctx, p); + package_t *pkg = kx_calloc(1, sizeof(package_t)); + pkg->vers = ver; + khint_t k = kh_put(package, g_packages, key, &absent); + kh_value(g_packages, k) = pkg; + if (absent) { + kh_key(g_packages, k) = key; + } + } + } + fclose(fp); + } +} + +static void free_package_info(void) +{ + for (khint_t k = 0; k < kh_end(g_packages); ++k) { + if (kh_exist(g_packages, k)) { + package_t *p = kh_value(g_packages, k); + while (p) { + package_t *n = p->next; + kx_free(p); + p = n; + } + } + } + kh_destroy(package, g_packages); +} + DllExport int do_main(int ac, char **av) { int r = 1; @@ -196,6 +275,7 @@ DllExport int do_main(int ac, char **av) const char *workdir = NULL; kx_context_t *ctx = make_context(); g_main_thread = ctx; + setup_package_info(ctx); char lname[LONGNAME_MAX] = {0}; char param[LONGNAME_MAX] = {0}; char *execname = NULL; @@ -395,6 +475,7 @@ DllExport int do_main(int ac, char **av) } g_terminated = 1; + free_package_info(); context_cleanup(ctx); free_nodes(); pthread_mutex_destroy(&g_mutex); diff --git a/src/parser.c b/src/parser.c index e5508ae51..921813db1 100644 --- a/src/parser.c +++ b/src/parser.c @@ -2841,7 +2841,7 @@ int yyparse(YYPARSE_ARG) { yyval.obj = kx_gen_bexpr_object(KXST_EXPRSEQ, YYASP(1-4).obj, kx_gen_uexpr_object_line(KXOP_MKOBJ, NULL, YYASP(3-4).intval)); } break; case 363: #line 824 "src/kinx.y" -{ yyval.obj = kx_gen_bexpr_object(KXST_EXPRLIST, YYASP(1-3).obj, YYASP(3-3).obj); } break; +{ yyval.obj = kx_gen_exprlist(YYASP(1-3).obj, YYASP(3-3).obj); } break; case 364: #line 828 "src/kinx.y" { yyval.obj = kx_gen_keyvalue_object(YYASP(2-5).strval, YYASP(5-5).obj); } break; @@ -3254,9 +3254,9 @@ int yyparse(YYPARSE_ARG) .name = kx_check_the_name(YYASP(3-4).obj), .stmt = kx_gen_bexpr_object(KXST_STMTLIST, - kx_gen_bexpr_object(KXOP_DECL, kx_gen_var_object_line("this", KX_UNKNOWN_T, YYASP(2-4).intval), + kx_gen_bexpr_object(KXOP_DECL, kx_gen_var_object_line("this", KX_OBJ_T, YYASP(2-4).intval), kx_gen_bexpr_object(KXOP_CALL, kx_gen_bexpr_object(KXOP_IDX, YYASP(3-4).obj, kx_gen_str_object("create")), YYASP(4-4).obj)), - kx_gen_bexpr_object(KXOP_DECL, kx_gen_var_object_line("super", KX_UNKNOWN_T, YYASP(2-4).intval), + kx_gen_bexpr_object(KXOP_DECL, kx_gen_var_object_line("super", KX_OBJ_T, YYASP(2-4).intval), kx_gen_bexpr_object(KXOP_CALL, kx_gen_bexpr_object(KXOP_IDX, kx_gen_var_object("System", KX_UNKNOWN_T), kx_gen_str_object("makeSuper")), kx_gen_var_object("this", KX_UNKNOWN_T))) ), }; From af11eb99e4a9b3745ee29390502305ca1fa102c4 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 11:52:51 +0900 Subject: [PATCH 12/26] updated a spec changed. --- lib/std/MarkdownParser.kx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/std/MarkdownParser.kx b/lib/std/MarkdownParser.kx index a16f11876..a608dae9c 100644 --- a/lib/std/MarkdownParser.kx +++ b/lib/std/MarkdownParser.kx @@ -51,7 +51,7 @@ namespace Markdown { } public toObject() { var obj = {}; - @keySet().each { &(key): + @keySet().each { &(key) if (key[0] != '_'[0] && !this[key].isFunction) { if (this[key].isNode) { obj[key] = this[key].toObject(); @@ -213,9 +213,9 @@ namespace Markdown { } } - _class Table(_rows) : Node('table', 'block') { + class Table(_rows) : Node('table', 'block') { private initialize() { - const [heading, separator, ...rows] = _rows.map(&(line) => line.replace(/^\||\|$/, '').split('|')); + var [heading, separator, ...rows] = _rows.map({ &(line) => line.replace(/^\||\|$/, '').split('|') }); @headings = heading.map(&(cell) => inlineParser(cell.trim())); @aligns = separator.map(&(cell) => { cell = cell.trim(); From a22d34bd2e1b377ecc9ace7e9c33b60ac241d89d Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 17:08:17 +0900 Subject: [PATCH 13/26] added a simple trace code. --- include/ir.h | 2 +- include/parser.h | 8 ++++++ src/lexer.c | 37 ++++++++++++++++++++++++- src/mainlib.c | 72 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 108 insertions(+), 11 deletions(-) diff --git a/include/ir.h b/include/ir.h index 11374a1ea..1baac7db3 100644 --- a/include/ir.h +++ b/include/ir.h @@ -883,7 +883,7 @@ typedef struct kx_options_ { int output_location:1; int src_stdin:1; int utf8inout:1; - int native_verbose:1; + int verbose:1; int with_native:1; /* dump with native */ int exception_detail_info:1; int debug_mode:1; diff --git a/include/parser.h b/include/parser.h index 1a888a53b..95285b382 100644 --- a/include/parser.h +++ b/include/parser.h @@ -34,4 +34,12 @@ typedef struct named_stmt_ { #include #endif /* KX_PARSER */ +extern int kx_trace_fmt(kx_context_t *ctx, int nested, const char *fmt, ...); +#define kx_trace(ctx, nested, fmt, ...) do {\ + if (ctx->options.verbose) { \ + kx_trace_fmt(ctx, nested, fmt, __VA_ARGS__);\ + } \ +} while (0); \ +/**/ + #endif /* KX_PARSER_H */ diff --git a/src/lexer.c b/src/lexer.c index 24863e0f3..84b79156c 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -17,6 +17,18 @@ static const char *varname = NULL; static const char *modulename = NULL; extern khash_t(package) *g_packages; +static int get_nested_level(void) +{ + int l, r = kv_size(kx_lex_stack); + for (l = r - 1; 0 <= l; --l) { + kx_lexinfo_t *lexinfo = &(kv_A(kx_lex_stack, l)); + if (lexinfo->in.fp || lexinfo->in.str) { + break; + } + } + return l + 1; +} + static const char *parent_path(const char *str) { static char buf[LIBNAME_BUFSIZE] = {0}; @@ -37,6 +49,9 @@ static inline const char* make_path(const char* base, const char* name) void setup_lexinfo(kx_context_t *ctx, const char *file, kx_yyin_t *yyin) { + if (yyin->fp || yyin->str) { + kx_trace(g_parse_ctx, get_nested_level(), "[>>] %s\n", file); + } kx_lexinfo.ch = 0; kx_lexinfo.restart = NULL; kx_lexinfo.file = const_str(ctx, file); @@ -88,10 +103,12 @@ static const char *search_using_path(const char *name) static void load_using_module_asta(const char *name, int len, const char *pkgkey) { + int nested = get_nested_level(); char *path = kx_calloc(len+2, sizeof(char)); memcpy(path, name, len); path[len-2] = 0; const char *search = kxlib_file_exists(path); + kx_trace(g_parse_ctx, nested, "[using:dir] %s\n", search); kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); kx_dirent_t *entry = NULL; @@ -99,6 +116,7 @@ static void load_using_module_asta(const char *name, int len, const char *pkgkey while ((entry = kx_read_dir(dir)) != NULL) { if (entry->d_name[0] != '.') { const char *file = make_path(search, entry->d_name); + kx_trace(g_parse_ctx, nested, "[using:*] %s\n", file); setup_lexinfo(g_parse_ctx, file, &(kx_yyin_t){ .fp = NULL, .str = NULL, @@ -141,7 +159,6 @@ static int load_using_module(const char *name, const char *pkgkey, int no_error) } return no_error ? ';' : ERROR; } - kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); FILE *fp = fopen(file, "r"); setup_lexinfo(g_parse_ctx, file, &(kx_yyin_t){ @@ -158,6 +175,19 @@ static int load_using_module(const char *name, const char *pkgkey, int no_error) return kx_yylex(); /* recursive call for the new file. */ } +static void kx_trace_versions(const char *key, const char *op, package_t *pkg) +{ + if (g_parse_ctx->options.verbose) { + kx_trace(g_parse_ctx, get_nested_level(), "[package:version/%s] %s (%s", op, key, pkg->vers); + pkg = pkg->next; + while (pkg) { + kx_trace(g_parse_ctx, 0, " -> %s", pkg->vers); + pkg = pkg->next; + } + kx_trace(g_parse_ctx, 0, ")\n"); + } +} + static void push_package_version(const char *key, const char *ver) { khint_t k = kh_get(package, g_packages, key); @@ -169,6 +199,7 @@ static void push_package_version(const char *key, const char *ver) newp->vers = ver; newp->next = pkg; kh_value(g_packages, k) = newp; + kx_trace_versions(key, "add", newp); } } @@ -181,6 +212,7 @@ static void pop_package_version(const char *key) package_t *next = pkg->next; kx_free(pkg); kh_value(g_packages, k) = next; + kx_trace_versions(key, "del", next); } } } @@ -802,6 +834,9 @@ int kx_yylex() pop_package_version(kx_lexinfo.pkgkey); } kx_lexinfo = kv_pop(kx_lex_stack); + if (kx_lexinfo.in.file) { + kx_trace(g_parse_ctx, get_nested_level(), "[<<] %s:%d\n", kx_lexinfo.in.file, kx_lexinfo.line); + } if (!kx_lexinfo.in.fp && !kx_lexinfo.in.str) { kx_lexinfo.in.fp = fopen(kx_lexinfo.in.file, "r"); } diff --git a/src/mainlib.c b/src/mainlib.c index 78897db04..a9d0cfd85 100644 --- a/src/mainlib.c +++ b/src/mainlib.c @@ -1,6 +1,7 @@ #define KX_LIB_DLL #include #include +#include #include #include #include @@ -41,6 +42,18 @@ extern volatile int g_terminated; extern khash_t(package) *g_packages; extern const char *kxlib_package_file(void); +int kx_trace_fmt(kx_context_t *ctx, int nested, const char *fmt, ...) +{ + for (int i = 0; i < nested; ++i) { + printf(" "); + } + va_list list; + va_start(list, fmt); + int r = vprintf(fmt, list); + va_end(list); + return r; +} + #ifdef YYDEBUG extern int kx_yydebug; #endif @@ -186,6 +199,7 @@ static void setup_package_info(kx_context_t *ctx) if (!pkgfile) { return; } + kx_trace(ctx, 0, "[package:ini] %s\n", pkgfile); FILE *fp = fopen(pkgfile, "r"); if (fp) { char buf[1024] = {0}; @@ -217,6 +231,7 @@ static void setup_package_info(kx_context_t *ctx) int absent; const char *key = kx_const_str(ctx, buf); const char *ver = kx_const_str(ctx, p); + kx_trace(ctx, 0, "[add:package/version] %s (%s)\n", key, ver); package_t *pkg = kx_calloc(1, sizeof(package_t)); pkg->vers = ver; khint_t k = kh_put(package, g_packages, key, &absent); @@ -245,6 +260,36 @@ static void free_package_info(void) kh_destroy(package, g_packages); } +const char *search_exec_file(kx_context_t *ctx, const char *execname) +{ + const char *execfile = kxlib_exec_file_exists(execname); + if (execfile) { + kx_trace(ctx, 0, "[exec:found] %s\n", execfile); + return execfile; + } + + kstr_t *ksv = ks_new(); + for (khint_t k = 0; k < kh_end(g_packages); ++k) { + if (kh_exist(g_packages, k)) { + const char *pkgname = kh_key(g_packages, k); + package_t *p = kh_value(g_packages, k); + ks_clear(ksv); + ks_appendf(ksv, "lib%cpackage%c%s%c%s%cbin%c%s.kx", PATH_DELCH, PATH_DELCH, pkgname, PATH_DELCH, p->vers, PATH_DELCH, PATH_DELCH, execname); + kx_trace(ctx, 0, "[exec:check] %s", ks_string(ksv)); + if (file_exists(ks_string(ksv))) { + execfile = kx_const_str(ctx, ks_string(ksv)); + kx_trace(ctx, 0, " ... found\n"); + break; + } else { + kx_trace(ctx, 0, " ... not found\n"); + } + } + } + ks_free(ksv); + + return execfile; +} + DllExport int do_main(int ac, char **av) { int r = 1; @@ -271,11 +316,11 @@ DllExport int do_main(int ac, char **av) #endif int error_code = -1; + int disp_version = -1; const char *filename = NULL; const char *workdir = NULL; kx_context_t *ctx = make_context(); g_main_thread = ctx; - setup_package_info(ctx); char lname[LONGNAME_MAX] = {0}; char param[LONGNAME_MAX] = {0}; char *execname = NULL; @@ -285,8 +330,8 @@ DllExport int do_main(int ac, char **av) case '-': get_long_option(optarg, lname, param); if (!strcmp(lname, "version")) { - version(1); - goto CLEANUP; + disp_version = 1; + goto END_OF_OPT; } else if (!strcmp(lname, "dot")) { ctx->options.dot = 1; } else if (!strcmp(lname, "native-call-max-depth")) { @@ -295,8 +340,8 @@ DllExport int do_main(int ac, char **av) ctx->options.with_native = param[0] ? strtol(param, NULL, 0) : 1; } else if (!strcmp(lname, "exception-detail-info")) { ctx->options.exception_detail_info = param[0] ? strtol(param, NULL, 0) : 1; - } else if (!strcmp(lname, "native-verbose")) { - ctx->options.native_verbose = param[0] ? strtol(param, NULL, 0) : 1; + } else if (!strcmp(lname, "verbose")) { + ctx->options.verbose = param[0] ? strtol(param, NULL, 0) : 1; } else if (!strcmp(lname, "case-threshold")) { ctx->options.case_threshold = param[0] ? strtol(param, NULL, 0) : 16; } else if (!strcmp(lname, "error-code")) { @@ -340,8 +385,8 @@ DllExport int do_main(int ac, char **av) usage(); goto CLEANUP; case 'v': - version(0); - goto CLEANUP; + disp_version = 0; + goto END_OF_OPT; default: usage(); goto CLEANUP; @@ -349,6 +394,12 @@ DllExport int do_main(int ac, char **av) } END_OF_OPT: + setup_package_info(ctx); + if (disp_version >= 0) { + version(disp_version); + goto CLEANUP; + } + #if defined(_WIN32) || defined(_WIN64) if (GetConsoleCP() == CP_UTF8) { ctx->options.utf8inout = 1; @@ -361,7 +412,7 @@ DllExport int do_main(int ac, char **av) } kx_lexinfo.quiet = ctx->options.quiet; if (execname) { - const char *execfile = kxlib_exec_file_exists(execname); + const char *execfile = search_exec_file(ctx, execname); if (!execfile) { fprintf(stderr, "No internal execution code(%s).\n", execname); r = 1; @@ -474,6 +525,7 @@ DllExport int do_main(int ac, char **av) start_display_def_ast(kx_ast_root); } + kx_trace(ctx, 0, "[cleanup] terminating the program...\n"); g_terminated = 1; free_package_info(); context_cleanup(ctx); @@ -488,7 +540,9 @@ DllExport int do_main(int ac, char **av) #if defined(_WIN32) || defined(_WIN64) WSACleanup(); #endif - return error_code >= 0 ? error_code : r; + r = error_code >= 0 ? error_code : r; + kx_trace(ctx, 0, "[done:status] %d\n", r); + return r; } /* Interfaces As a Library */ From d26dfea1453186336c1aafcfa102d4c968402268 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 17:12:01 +0900 Subject: [PATCH 14/26] updated a package default version file. --- src/loadlib.c | 4 ++-- src/mainlib.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/loadlib.c b/src/loadlib.c index 024cd44d0..2daab0bf9 100644 --- a/src/loadlib.c +++ b/src/loadlib.c @@ -109,12 +109,12 @@ void unload_library(void *h) const char *kxlib_package_file(void) { - const char *checkfile = make_path_with(get_kinx_path(), "lib"PATH_DELIM"package", "kxpackage.ini"); + const char *checkfile = make_path_with(get_kinx_path(), "lib"PATH_DELIM"package", "kxpackage.def"); if (file_exists(checkfile)) { return checkfile; } #if !defined(KCC_WINDOWS) - checkfile = make_path_with("/usr/bin", "kinxlib/package", "kxpackage.ini"); + checkfile = make_path_with("/usr/bin", "kinxlib/package", "kxpackage.def"); if (file_exists(checkfile)) { return checkfile; } diff --git a/src/mainlib.c b/src/mainlib.c index a9d0cfd85..668f90bf8 100644 --- a/src/mainlib.c +++ b/src/mainlib.c @@ -145,7 +145,7 @@ static void version(int detail) if (kh_exist(g_packages, k)) { const char *key = kh_key(g_packages, k); package_t *p = kh_value(g_packages, k); - printf(" * %s v%s\n", key, p->vers); + printf(" * %s %s\n", key, p->vers); } } } From 065953e1af06d891ed7f8247bf4d63dcc83ce7b8 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 17:22:32 +0900 Subject: [PATCH 15/26] updated for packages. --- build/Makefile | 2 +- build/template/install.nsi | 3 ++- install.nsi | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/build/Makefile b/build/Makefile index 9d1a95953..a29c6fabf 100644 --- a/build/Makefile +++ b/build/Makefile @@ -160,7 +160,7 @@ all: timex kinx $(SOFILES) main_kxcmd install: mkdir -p /usr/bin/kinxlib/include mkdir -p /usr/bin/kinxlib/docs/licenses - mkdir -p /usr/bin/kinxlib/exec/3rdparty + mkdir -p /usr/bin/kinxlib/package cp -f ./kinx /usr/bin/kinx cp -f ./kxrepl /usr/bin/kxrepl cp -f ./kxtest /usr/bin/kxtest diff --git a/build/template/install.nsi b/build/template/install.nsi index d841d4d69..1f9a8079d 100644 --- a/build/template/install.nsi +++ b/build/template/install.nsi @@ -76,10 +76,11 @@ Section File /r /x ".gitignore" "lib\webview" SetOutPath "$INSTDIR\docs" - File /r /x "typesetting" "docs\licenses" + File /r "docs\licenses" # Uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe" + CreateDirectory "$INSTDIR\bin\lib\package" # Shortcut to start menu CreateDirectory "$SMPROGRAMS\Kinx" diff --git a/install.nsi b/install.nsi index c712cb994..995134126 100644 --- a/install.nsi +++ b/install.nsi @@ -76,10 +76,11 @@ Section File /r /x ".gitignore" "lib\webview" SetOutPath "$INSTDIR\docs" - File /r /x "typesetting" "docs\licenses" + File /r "docs\licenses" # Uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe" + CreateDirectory "$INSTDIR\bin\lib\package" # Shortcut to start menu CreateDirectory "$SMPROGRAMS\Kinx" From 547e4577a0efcc1cb30e54eac193358a578d1599 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 13:51:15 +0900 Subject: [PATCH 16/26] fixed #257: fix a decl in const. --- src/ast_gencode.c | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/ast_gencode.c b/src/ast_gencode.c index 7a3763023..476266bf4 100644 --- a/src/ast_gencode.c +++ b/src/ast_gencode.c @@ -124,7 +124,7 @@ static const kx_block_t kx_empty_block = {0}; static const kx_function_t kx_empty_func = {0}; -static void apply_getvals(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, int jmp, int nested); +static void apply_getvals(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, int decl, int jmp, int nested); static void gencode_ast(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, int lvalue); static int new_function(kx_analyze_t *ana, kx_object_t *node) @@ -376,19 +376,19 @@ if (code_size(module, ana) > 0) { \ } \ /**/ -static int apply_getval(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, int jmp, int index, int nested) +static int apply_getval(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, int decl, int jmp, int index, int nested) { kx_module_t *module = ana->module; if (!node) { return index; } if (node->type == KXST_EXPRLIST) { - index = apply_getval(ctx, node->lhs, ana, jmp, index, nested); - index = apply_getval(ctx, node->rhs, ana, jmp, index, nested); + index = apply_getval(ctx, node->lhs, ana, decl, jmp, index, nested); + index = apply_getval(ctx, node->rhs, ana, decl, jmp, index, nested); return index; } if (node->type == KXOP_CAST) { - return apply_getval(ctx, node->lhs, ana, jmp, index, nested); + return apply_getval(ctx, node->lhs, ana, decl, jmp, index, nested); } if (node->type == KXOP_KEYVALUE) { kx_yyerror_line("Cannot use a key-value pair in array item", node->file, node->line); @@ -440,8 +440,8 @@ static int apply_getval(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_DUP })); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_TYPEOF, .value1 = { .i = KX_ARY_T } })); KX_CHECK_PATTERN_JMP(jmpblk, nested+1); - int idx = apply_getval(ctx, node->lhs, ana, jmp, 0, nested + 1); - (void)apply_getval(ctx, node->rhs, ana, jmp, idx, nested + 1); + int idx = apply_getval(ctx, node->lhs, ana, decl, jmp, 0, nested + 1); + (void)apply_getval(ctx, node->rhs, ana, decl, jmp, idx, nested + 1); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_POP })); break; case KXOP_MKOBJ: @@ -450,7 +450,7 @@ static int apply_getval(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_DUP })); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_TYPEOF, .value1 = { .i = KX_OBJ_T } })); KX_CHECK_PATTERN_JMP(jmpblk, nested+1); - apply_getvals(ctx, node->lhs, ana, jmp, nested + 1); + apply_getvals(ctx, node->lhs, ana, decl, jmp, nested + 1); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_POP })); break; case KXOP_MKRANGE: @@ -463,7 +463,7 @@ static int apply_getval(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, default: if (!(node->type == KXOP_VAR && node->var_type == KX_UND_T)) { // KXDC_CONST means with a pin operator. - if (node->optional == KXDC_CONST) { + if (!decl && node->optional == KXDC_CONST) { kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_DUP })); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_APPLYVI, .value1.i = index })); gencode_ast_hook(ctx, node, ana, 0); @@ -483,15 +483,15 @@ static int apply_getval(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, return index + 1; } -static void apply_getvals(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, int jmp, int nested) +static void apply_getvals(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *ana, int decl, int jmp, int nested) { kx_module_t *module = ana->module; if (!node) { return; } if (node->type == KXST_EXPRLIST) { - apply_getvals(ctx, node->lhs, ana, jmp, nested); - apply_getvals(ctx, node->rhs, ana, jmp, nested); + apply_getvals(ctx, node->lhs, ana, decl, jmp, nested); + apply_getvals(ctx, node->rhs, ana, decl, jmp, nested); return; } @@ -544,8 +544,8 @@ static void apply_getvals(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *an kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_DUP })); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_TYPEOF, .value1 = { .i = KX_ARY_T } })); KX_CHECK_PATTERN_JMP(jmpblk, nested+1); - int idx = apply_getval(ctx, value->lhs, ana, jmp, 0, nested + 1); - (void)apply_getval(ctx, value->rhs, ana, jmp, idx, nested + 1); + int idx = apply_getval(ctx, value->lhs, ana, decl, jmp, 0, nested + 1); + (void)apply_getval(ctx, value->rhs, ana, decl, jmp, idx, nested + 1); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_POP })); break; } @@ -555,7 +555,7 @@ static void apply_getvals(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *an kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_DUP })); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_TYPEOF, .value1 = { .i = KX_OBJ_T } })); KX_CHECK_PATTERN_JMP(jmpblk, nested+1); - apply_getvals(ctx, value->lhs, ana, jmp, nested + 1); + apply_getvals(ctx, value->lhs, ana, decl, jmp, nested + 1); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_POP })); break; case KXOP_MKRANGE: @@ -567,7 +567,7 @@ static void apply_getvals(kx_context_t *ctx, kx_object_t *node, kx_analyze_t *an break; default: // KXDC_CONST means with a pin operator. - if (value->optional == KXDC_CONST) { + if (!decl && value->optional == KXDC_CONST) { kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_DUP })); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE(ana), .op = KX_APPLYVS, .value1.s = key })); gencode_ast_hook(ctx, value, ana, 0); @@ -1336,9 +1336,9 @@ LOOP_HEAD:; } } if (node->lhs->type == KXOP_MKARY) { - apply_getval(ctx, node->lhs->lhs, ana, -1, 0, 0); + apply_getval(ctx, node->lhs->lhs, ana, 1, -1, 0, 0); } else if (node->lhs->type == KXOP_MKOBJ) { - apply_getvals(ctx, node->lhs->lhs, ana, -1, 0); + apply_getvals(ctx, node->lhs->lhs, ana, 1, -1, 0); } else { gencode_ast_hook(ctx, node->lhs, ana, 1); if ((code_size(module, ana) > 0) && last_op(ana) == KX_PUSHLV) { @@ -1414,9 +1414,9 @@ LOOP_HEAD:; } } if (node->lhs->type == KXOP_MKARY) { - apply_getval(ctx, node->lhs->lhs, ana, -1, 0, 0); + apply_getval(ctx, node->lhs->lhs, ana, 0, -1, 0, 0); } else if (node->lhs->type == KXOP_MKOBJ) { - apply_getvals(ctx, node->lhs->lhs, ana, -1, 0); + apply_getvals(ctx, node->lhs->lhs, ana, 0, -1, 0); } else { gencode_ast_hook(ctx, node->lhs, ana, 1); if ((code_size(module, ana) > 0) && last_op(ana) == KX_PUSHLV) { @@ -1757,7 +1757,7 @@ LOOP_HEAD:; get_block(module, chklen_block)->tf[0] = ana->block; } if (last || exblk < 0) { - apply_getval(ctx, cond->lhs, ana, next, 0, 1); + apply_getval(ctx, cond->lhs, ana, 0, next, 0, 1); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE_OF(cond, ana), .op = KX_POP })); get_block(module, curblk)->tf[1] = next; if (chklen_block > 0) { @@ -1765,7 +1765,7 @@ LOOP_HEAD:; } } else { int nc = new_block_hook(ana); - apply_getval(ctx, cond->lhs, ana, nc, 0, 1); + apply_getval(ctx, cond->lhs, ana, 0, nc, 0, 1); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE_OF(cond, ana), .op = KX_POP })); get_block(module, ana->block)->tf[0] = exblk; get_block(module, curblk)->tf[1] = nc; @@ -1784,12 +1784,12 @@ LOOP_HEAD:; get_block(module, curblk)->tf[0] = ana->block; if (last || exblk < 0) { - apply_getvals(ctx, cond->lhs, ana, next, 1); + apply_getvals(ctx, cond->lhs, ana, 0, next, 1); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE_OF(cond, ana), .op = KX_POP })); get_block(module, curblk)->tf[1] = next; } else { int nc = new_block_hook(ana); - apply_getvals(ctx, cond->lhs, ana, nc, 1); + apply_getvals(ctx, cond->lhs, ana, 0, nc, 1); kv_push(kx_code_t, get_block(module, ana->block)->code, ((kx_code_t){ FILELINE_OF(cond, ana), .op = KX_POP })); get_block(module, ana->block)->tf[0] = exblk; get_block(module, curblk)->tf[1] = nc; From af895a8c91ec7c089942bf375c5c0f863f095c7e Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 13:52:33 +0900 Subject: [PATCH 17/26] refs #257: added a test code. --- docs/spec/others/bugfixes.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/spec/others/bugfixes.md b/docs/spec/others/bugfixes.md index d1493e620..cb21b947c 100644 --- a/docs/spec/others/bugfixes.md +++ b/docs/spec/others/bugfixes.md @@ -127,7 +127,7 @@ Successful Successful ``` -### Example 4. Can't specify a return type of function. +### Example 4. Can't specify a return type of function This bug's was caused by lack of consideration of a part of type propagation. @@ -183,4 +183,34 @@ System.println(test3(10.5)); 0 ``` +### Example 6. Fails a Destructuring Assignment in Const +This bug's was caused by an incorrect bytecode. + +* Issue: [#257](https://github.com/Kray-G/kinx/issues/257) +* Fixed: [43d82765b577221c820575b7f5e7323cc0171be1](https://github.com/Kray-G/kinx/commit/43d82765b577221c820575b7f5e7323cc0171be1) + +#### Code + +```javascript +function test1(data) { + var [a, b, ...c] = data.split(','); +} +function test2(data) { + [a, b, ...c] = data.split(','); +} +function test3(data) { + const [a, b, ...c] = data.split(','); +} +test1("1,2,3,4,5,6,7,8,9"); +test2("1,2,3,4,5,6,7,8,9"); +test3("1,2,3,4,5,6,7,8,9"); + +System.println("Successful"); +``` + +#### Result + +``` +Successful +``` From 0baf97a72eb78dc66d715880f5ed9dabb703c58b Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 17:34:38 +0900 Subject: [PATCH 18/26] updated macro. --- include/parser.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/parser.h b/include/parser.h index 95285b382..7011137ea 100644 --- a/include/parser.h +++ b/include/parser.h @@ -34,10 +34,10 @@ typedef struct named_stmt_ { #include #endif /* KX_PARSER */ -extern int kx_trace_fmt(kx_context_t *ctx, int nested, const char *fmt, ...); -#define kx_trace(ctx, nested, fmt, ...) do {\ +extern int kx_trace_fmt(kx_context_t *ctx, int nested, ...); +#define kx_trace(ctx, nested, ...) do {\ if (ctx->options.verbose) { \ - kx_trace_fmt(ctx, nested, fmt, __VA_ARGS__);\ + kx_trace_fmt(ctx, nested, __VA_ARGS__);\ } \ } while (0); \ /**/ From 0cba58b8fb48e9a0e4cf33fe8ab9feca57527545 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 17:36:05 +0900 Subject: [PATCH 19/26] updated macro. --- include/parser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/parser.h b/include/parser.h index 7011137ea..bf0eed2e6 100644 --- a/include/parser.h +++ b/include/parser.h @@ -34,7 +34,7 @@ typedef struct named_stmt_ { #include #endif /* KX_PARSER */ -extern int kx_trace_fmt(kx_context_t *ctx, int nested, ...); +extern int kx_trace_fmt(kx_context_t *ctx, int nested, const char *fmt, ...); #define kx_trace(ctx, nested, ...) do {\ if (ctx->options.verbose) { \ kx_trace_fmt(ctx, nested, __VA_ARGS__);\ From f069e4e277dcdf156f9df863e308987184c33c17 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 17:40:29 +0900 Subject: [PATCH 20/26] updated ChangeLog.md --- ChangeLog_v1.0.x.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog_v1.0.x.md b/ChangeLog_v1.0.x.md index 1d2266225..1defd64cb 100644 --- a/ChangeLog_v1.0.x.md +++ b/ChangeLog_v1.0.x.md @@ -6,6 +6,8 @@ * #235: Crash when using `_` outside a function. * #236: Can't specify the class as a return type of function. * #237: Comparing between variables having a string is failed. + * #256: Comparison operator will be failed with an integer on LHS and a variable(double) on RHS. + * #257: Fails a destructuring assignment when declaration with const. ## V1.0.0 (Official Release) - 2021/03/16 From 6bab74962e8ce63411495e5dd7017a4a97c594e2 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 17:42:24 +0900 Subject: [PATCH 21/26] updated ChangeLog.md --- ChangeLog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 3fe213551..ea20205e5 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -28,6 +28,8 @@ * #235: Crash when using `_` outside a function. * #236: Can't specify the class as a return type of function. * #237: Comparing between variables having a string is failed. + * #256: Comparison operator will be failed with an integer on LHS and a variable(double) on RHS. + * #257: Fails a destructuring assignment when declaration with const. ## V1.0.0 (Official Release) - 2021/03/16 This is a 1st official release version. From 7f77e981f9b0f7017d21dd9a34244081b3ba8aa5 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 17:48:52 +0900 Subject: [PATCH 22/26] updated initialization of g_packages. --- src/global.c | 2 +- src/mainlib.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/global.c b/src/global.c index 99c14be62..7b56ab8d8 100644 --- a/src/global.c +++ b/src/global.c @@ -13,7 +13,7 @@ kx_object_t *kx_ast_root = NULL; int g_yyerror = 0; int g_yywarning = 0; kx_context_t *g_parse_ctx = NULL; -khash_t(package) *g_packages; +khash_t(package) *g_packages = NULL; /* used in runtime. */ volatile int g_terminated = 0; diff --git a/src/mainlib.c b/src/mainlib.c index 668f90bf8..7781ff3ea 100644 --- a/src/mainlib.c +++ b/src/mainlib.c @@ -194,7 +194,6 @@ static void setup_run_environment(const char *filename) static void setup_package_info(kx_context_t *ctx) { - g_packages = kh_init(package); const char *pkgfile = kxlib_package_file(); if (!pkgfile) { return; @@ -315,6 +314,7 @@ DllExport int do_main(int ac, char **av) } #endif + g_packages = kh_init(package); int error_code = -1; int disp_version = -1; const char *filename = NULL; From 4a07a02d68b03861a7352293840296137c55bc6b Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 18:45:35 +0900 Subject: [PATCH 23/26] improved error messages. --- src/lexer.c | 198 ++++++++++++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 91 deletions(-) diff --git a/src/lexer.c b/src/lexer.c index 84b79156c..127e1f11e 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -86,95 +86,6 @@ void kx_make_regex_mode(int br) g_regexmode = br; } -static const char *search_using_path(const char *name) -{ - char libname[LIBNAME_BUFSIZE*2] = {0}; - const char *file = NULL; - /* Trying to search the file in the same directory first. */ - snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s%c%s.kx", parent_path(kx_lexinfo.file), PATH_DELCH, name); - if (file_exists(libname)) { - file = libname; - } else { - snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s.kx", name); - file = kxlib_file_exists(libname); - } - return file; -} - -static void load_using_module_asta(const char *name, int len, const char *pkgkey) -{ - int nested = get_nested_level(); - char *path = kx_calloc(len+2, sizeof(char)); - memcpy(path, name, len); - path[len-2] = 0; - const char *search = kxlib_file_exists(path); - kx_trace(g_parse_ctx, nested, "[using:dir] %s\n", search); - - kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); - kx_dirent_t *entry = NULL; - kx_dir_t *dir = kx_open_dir(search); - while ((entry = kx_read_dir(dir)) != NULL) { - if (entry->d_name[0] != '.') { - const char *file = make_path(search, entry->d_name); - kx_trace(g_parse_ctx, nested, "[using:*] %s\n", file); - setup_lexinfo(g_parse_ctx, file, &(kx_yyin_t){ - .fp = NULL, - .str = NULL, - .file = const_str(g_parse_ctx, file) - }); - if (pkgkey) { - kx_lexinfo.pkgkey = pkgkey; - pkgkey = NULL; - } - kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); - } - } - - kx_close_dir(dir); - kx_free(path); -} - -static int load_using_module(const char *name, const char *pkgkey, int no_error) -{ - char libname[LIBNAME_BUFSIZE*2] = {0}; - const char *file = NULL; - int len = strlen(name); - if (name[len-1] == '*') { - if (name[len-2] != PATH_DELCH) { - kx_yywarning("Can not use '*' with a current directoy in 'using' directive"); - } else { - load_using_module_asta(name, len, pkgkey); - return kx_yylex(); - } - } else { - file = search_using_path(name); - if (!file) { - if (!no_error) { - char buf[LIBNAME_BUFSIZE*3] = {0}; - snprintf(buf, LIBNAME_BUFSIZE*3-1, "Library file not found(%s)", name); - kx_yywarning(buf); - } - while (kx_lexinfo.ch && kx_lexinfo.ch != ';') { - kx_lex_next(kx_lexinfo); - } - return no_error ? ';' : ERROR; - } - kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); - FILE *fp = fopen(file, "r"); - setup_lexinfo(g_parse_ctx, file, &(kx_yyin_t){ - .fp = fp, - .str = NULL, - .file = const_str(g_parse_ctx, file) - }); - if (pkgkey) { - kx_lexinfo.pkgkey = pkgkey; - } - } - - kx_lex_next(kx_lexinfo); - return kx_yylex(); /* recursive call for the new file. */ -} - static void kx_trace_versions(const char *key, const char *op, package_t *pkg) { if (g_parse_ctx->options.verbose) { @@ -188,6 +99,12 @@ static void kx_trace_versions(const char *key, const char *op, package_t *pkg) } } +static int is_package_installed(const char *key) +{ + khint_t k = kh_get(package, g_packages, key); + return k != kh_end(g_packages); +} + static void push_package_version(const char *key, const char *ver) { khint_t k = kh_get(package, g_packages, key); @@ -238,6 +155,105 @@ static int set_package_version(const char *pkgname, int pos) return pos; } +static const char *search_using_path(const char *name) +{ + char libname[LIBNAME_BUFSIZE*2] = {0}; + const char *file = NULL; + /* Trying to search the file in the same directory first. */ + snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s%c%s.kx", parent_path(kx_lexinfo.file), PATH_DELCH, name); + if (file_exists(libname)) { + file = libname; + } else { + snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s.kx", name); + file = kxlib_file_exists(libname); + } + return file; +} + +static void load_using_module_asta(const char *name, int len, const char *pkgname, const char *pkgkey) +{ + int nested = get_nested_level(); + char *path = kx_calloc(len+2, sizeof(char)); + memcpy(path, name, len); + path[len-2] = 0; + const char *search = kxlib_file_exists(path); + if (!search) { + const char *msg = pkgname && !is_package_installed(pkgname) + ? static_format("Package(%s) not installed", pkgname, path) + : static_format("Library file not found(%s)", path); + kx_yyerror(msg); +printf("1 ch = %c(%d)\n", kx_lexinfo.ch, kx_lexinfo.ch); + } else { + kx_trace(g_parse_ctx, nested, "[using:dir] %s\n", search); + + kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); + kx_dirent_t *entry = NULL; + kx_dir_t *dir = kx_open_dir(search); + while ((entry = kx_read_dir(dir)) != NULL) { + if (entry->d_name[0] != '.') { + const char *file = make_path(search, entry->d_name); + kx_trace(g_parse_ctx, nested, "[using:*] %s\n", file); + setup_lexinfo(g_parse_ctx, file, &(kx_yyin_t){ + .fp = NULL, + .str = NULL, + .file = const_str(g_parse_ctx, file) + }); + if (pkgkey) { + kx_lexinfo.pkgkey = pkgkey; + pkgkey = NULL; + } + kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); + } + } + + kx_close_dir(dir); + } + + kx_free(path); +} + +static int load_using_module(const char *name, const char *pkgname, const char *pkgkey, int no_error) +{ + char libname[LIBNAME_BUFSIZE*2] = {0}; + const char *file = NULL; + int len = strlen(name); + if (name[len-1] == '*') { + if (name[len-2] != PATH_DELCH) { + kx_yyerror("Can not use '*' with a current directoy in 'using' directive"); + } else { + load_using_module_asta(name, len, pkgname, pkgkey); + return kx_yylex(); + } + } else { + file = search_using_path(name); + if (!file) { + if (!no_error) { + const char *msg = pkgname && !is_package_installed(pkgname) + ? static_format("Package(%s) not installed", pkgname, name) + : static_format("Library file not found(%s)", name); + kx_yyerror(msg); + } + while (kx_lexinfo.ch && kx_lexinfo.ch != ';') { + kx_lex_next(kx_lexinfo); + } + return ';'; + } + kv_push(kx_lexinfo_t, kx_lex_stack, kx_lexinfo); + FILE *fp = fopen(file, "r"); + setup_lexinfo(g_parse_ctx, file, &(kx_yyin_t){ + .fp = fp, + .str = NULL, + .file = const_str(g_parse_ctx, file) + }); + if (pkgkey) { + kx_lexinfo.pkgkey = pkgkey; + } + } + + kx_lex_next(kx_lexinfo); + return kx_yylex(); /* recursive call for the new file. */ +} + static int process_using(void) { int no_error = 0; @@ -307,7 +323,7 @@ static int process_using(void) } kx_strbuf[pos] = 0; - return load_using_module(kx_strbuf, pushed_version ? pkgname : NULL, no_error); + return load_using_module(kx_strbuf, pkgname, pushed_version ? pkgname : NULL, no_error); } static int get_keyword_token(const char *val) @@ -793,7 +809,7 @@ static int process_import(void) return ';'; case 6: g_import = 0; - return load_using_module(modulename, NULL, 1); + return load_using_module(modulename, NULL, NULL, 1); } return ERROR; } From 29d60fa7925e309059a40b8c7ef2a7dc965073ae Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 20:19:53 +0900 Subject: [PATCH 24/26] updated a lexer. --- src/lexer.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/lexer.c b/src/lexer.c index 127e1f11e..9cec817bd 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -64,18 +64,21 @@ void setup_lexinfo(kx_context_t *ctx, const char *file, kx_yyin_t *yyin) kx_lexinfo.pkgkey = NULL; } -void init_lexer(kx_context_t *ctx) -{ - kv_init(kx_lex_stack); - g_parse_ctx = ctx; -} - void free_lexer(void) { g_parse_ctx = NULL; kv_destroy(kx_lex_stack); } +void init_lexer(kx_context_t *ctx) +{ + if (g_parse_ctx) { + free_lexer(); + } + kv_init(kx_lex_stack); + g_parse_ctx = ctx; +} + void kx_make_bin_mode(void) { g_binmode = 1; @@ -170,8 +173,9 @@ static const char *search_using_path(const char *name) return file; } -static void load_using_module_asta(const char *name, int len, const char *pkgname, const char *pkgkey) +static int load_using_module_asta(const char *name, int len, const char *pkgname, const char *pkgkey) { + int r = ';'; int nested = get_nested_level(); char *path = kx_calloc(len+2, sizeof(char)); memcpy(path, name, len); @@ -182,7 +186,9 @@ static void load_using_module_asta(const char *name, int len, const char *pkgnam ? static_format("Package(%s) not installed", pkgname, path) : static_format("Library file not found(%s)", path); kx_yyerror(msg); -printf("1 ch = %c(%d)\n", kx_lexinfo.ch, kx_lexinfo.ch); + while (kx_lexinfo.ch && kx_lexinfo.ch != ';') { + kx_lex_next(kx_lexinfo); + } } else { kx_trace(g_parse_ctx, nested, "[using:dir] %s\n", search); @@ -207,9 +213,11 @@ printf("1 ch = %c(%d)\n", kx_lexinfo.ch, kx_lexinfo.ch); } kx_close_dir(dir); + r = kx_yylex(); } kx_free(path); + return r; } static int load_using_module(const char *name, const char *pkgname, const char *pkgkey, int no_error) @@ -221,8 +229,7 @@ static int load_using_module(const char *name, const char *pkgname, const char * if (name[len-2] != PATH_DELCH) { kx_yyerror("Can not use '*' with a current directoy in 'using' directive"); } else { - load_using_module_asta(name, len, pkgname, pkgkey); - return kx_yylex(); + return load_using_module_asta(name, len, pkgname, pkgkey); } } else { file = search_using_path(name); From e22282adb480906d733102f9e071572fa033a2bf Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 20:53:20 +0900 Subject: [PATCH 25/26] updated mainlib. --- src/mainlib.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mainlib.c b/src/mainlib.c index 7781ff3ea..e42c2ea20 100644 --- a/src/mainlib.c +++ b/src/mainlib.c @@ -291,11 +291,6 @@ const char *search_exec_file(kx_context_t *ctx, const char *execname) DllExport int do_main(int ac, char **av) { - int r = 1; - init_allocator(); - alloc_initialize(); - pthread_mutex_init(&g_mutex, NULL); - #ifdef YYDEBUG kx_yydebug = 1; #endif @@ -314,7 +309,14 @@ DllExport int do_main(int ac, char **av) } #endif + /* initializations */ + init_allocator(); + alloc_initialize(); + pthread_mutex_init(&g_mutex, NULL); g_packages = kh_init(package); + + /* option check */ + int r = 1; int error_code = -1; int disp_version = -1; const char *filename = NULL; From 642a9f4b47837ecc2f9e64160e71e54bd9cc7ef8 Mon Sep 17 00:00:00 2001 From: Kray-G Date: Tue, 30 Mar 2021 22:42:57 +0900 Subject: [PATCH 26/26] updated a lexer. --- src/lexer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lexer.c b/src/lexer.c index 9cec817bd..e2467a7a5 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -158,16 +158,15 @@ static int set_package_version(const char *pkgname, int pos) return pos; } -static const char *search_using_path(const char *name) +static const char *search_using_path(const char *name, char *libname, int size) { - char libname[LIBNAME_BUFSIZE*2] = {0}; const char *file = NULL; /* Trying to search the file in the same directory first. */ - snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s%c%s.kx", parent_path(kx_lexinfo.file), PATH_DELCH, name); + snprintf(libname, size-1, "%s%c%s.kx", parent_path(kx_lexinfo.file), PATH_DELCH, name); if (file_exists(libname)) { file = libname; } else { - snprintf(libname, LIBNAME_BUFSIZE*2-1, "%s.kx", name); + snprintf(libname, size-1, "%s.kx", name); file = kxlib_file_exists(libname); } return file; @@ -232,7 +231,7 @@ static int load_using_module(const char *name, const char *pkgname, const char * return load_using_module_asta(name, len, pkgname, pkgkey); } } else { - file = search_using_path(name); + file = search_using_path(name, libname, LIBNAME_BUFSIZE*2-1); if (!file) { if (!no_error) { const char *msg = pkgname && !is_package_installed(pkgname)