nadesiko3 3.2.48 → 3.2.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/release/_hash.txt +24 -24
- package/release/_script-tags.txt +13 -13
- package/release/command.json +1 -1
- package/release/command.json.js +1 -1
- package/release/command_cnako3.json +1 -1
- package/release/command_list.json +1 -1
- package/release/editor.js +1 -1
- package/release/nako_gen_async.js +1 -1
- package/release/stats.json +1 -1
- package/release/version.js +1 -1
- package/release/wnako3.js +1 -1
- package/release/wnako3webworker.js +1 -1
- package/release/wnako3webworker.js.LICENSE.txt +4 -0
- package/src/nako3.js +9 -8
- package/src/nako_from_dncl.js +1 -1
- package/src/nako_gen.js +105 -36
- package/src/nako_indent.js +2 -1
- package/src/nako_lex_rules.js +1 -1
- package/src/nako_lexer.js +5 -4
- package/src/nako_version.js +2 -2
- package/src/plugin_node.js +0 -12
- package/test/common/basic_test.js +13 -0
- package/test/common/dncl_test.js +4 -0
|
@@ -538,6 +538,10 @@
|
|
|
538
538
|
!*** ./node_modules/core-js/modules/es.function.name.js ***!
|
|
539
539
|
\**********************************************************/
|
|
540
540
|
|
|
541
|
+
/*!**********************************************************!*\
|
|
542
|
+
!*** ./node_modules/core-js/modules/es.number.is-nan.js ***!
|
|
543
|
+
\**********************************************************/
|
|
544
|
+
|
|
541
545
|
/*!**********************************************************!*\
|
|
542
546
|
!*** ./node_modules/core-js/modules/es.object.assign.js ***!
|
|
543
547
|
\**********************************************************/
|
package/src/nako3.js
CHANGED
|
@@ -87,10 +87,10 @@ function NakoGen (mode) {
|
|
|
87
87
|
* checkInit?: boolean
|
|
88
88
|
* }} Ast
|
|
89
89
|
*
|
|
90
|
-
* @typedef {
|
|
91
|
-
* | { type: 'func', josi: string[][], pure?: boolean, fn?: Function, return_none: boolean }
|
|
90
|
+
* @typedef {
|
|
91
|
+
* | { type: 'func', josi: string[][], pure?: boolean, fn?: Function, return_none: boolean, asyncFn: boolean }
|
|
92
92
|
* | { type: 'var' | 'const', value: any}
|
|
93
|
-
*
|
|
93
|
+
* } NakoFunction
|
|
94
94
|
*/
|
|
95
95
|
|
|
96
96
|
class NakoCompiler {
|
|
@@ -123,7 +123,7 @@ class NakoCompiler {
|
|
|
123
123
|
this.pluginfiles = {} // 取り込んだファイル一覧
|
|
124
124
|
this.isSetter = false // 代入的関数呼び出しを管理(#290)
|
|
125
125
|
this.commandlist = new Set() // プラグインで定義された定数・変数・関数の名前
|
|
126
|
-
/** @type {Record<string, { josi: string[][], fn: string, type: 'func' }>} */
|
|
126
|
+
/** @type {Record<string, { josi: string[][], fn: string, type: 'func', asyncFn: boolean }>} */
|
|
127
127
|
this.nako_func = {} // __v1に配置するJavaScriptのコードで定義された関数
|
|
128
128
|
|
|
129
129
|
this.logger = new NakoLogger()
|
|
@@ -758,7 +758,7 @@ class NakoCompiler {
|
|
|
758
758
|
throw new Error('プラグインの追加でエラー。')
|
|
759
759
|
}
|
|
760
760
|
// コマンドを登録するか?
|
|
761
|
-
if (key === '初期化' || key.
|
|
761
|
+
if (key === '初期化' || key.substring(0, 1) === '!') { // 登録しない関数名
|
|
762
762
|
continue
|
|
763
763
|
}
|
|
764
764
|
this.commandlist.add(key)
|
|
@@ -811,10 +811,11 @@ class NakoCompiler {
|
|
|
811
811
|
* @param {string} key 関数名
|
|
812
812
|
* @param {string[][]} josi 助詞
|
|
813
813
|
* @param {Function} fn 関数
|
|
814
|
-
* @param {boolean} returnNone 値を返す関数の場合はfalse
|
|
814
|
+
* @param {boolean} returnNone 値を返す関数の場合はfalseを指定
|
|
815
|
+
* @param {boolean} asyncFn Promiseを返す関数かを指定
|
|
815
816
|
*/
|
|
816
|
-
addFunc (key, josi, fn, returnNone = true) {
|
|
817
|
-
this.funclist[key] = { josi, fn, type: 'func', return_none: returnNone }
|
|
817
|
+
addFunc (key, josi, fn, returnNone = true, asyncFn = false) {
|
|
818
|
+
this.funclist[key] = { josi, fn, type: 'func', return_none: returnNone, asyncFn }
|
|
818
819
|
this.pluginFunclist[key] = cloneAsJSON(this.funclist[key])
|
|
819
820
|
this.__varslist[0][key] = fn
|
|
820
821
|
}
|
package/src/nako_from_dncl.js
CHANGED
|
@@ -27,7 +27,7 @@ function isIndentSyntaxEnabled(src) {
|
|
|
27
27
|
const keywords = DNCL_KEYWORDS
|
|
28
28
|
const lines = src.split('\n', 30)
|
|
29
29
|
for (const line of lines) {
|
|
30
|
-
const line2 = line.replace(
|
|
30
|
+
const line2 = line.replace(/(!|💡)/, '!')
|
|
31
31
|
if (keywords.indexOf(line2) >= 0) {
|
|
32
32
|
return true
|
|
33
33
|
}
|
package/src/nako_gen.js
CHANGED
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
|
|
9
9
|
const { NakoSyntaxError, NakoError, NakoRuntimeError } = require('./nako_errors')
|
|
10
10
|
const nakoVersion = require('./nako_version')
|
|
11
|
+
const isIE11 = () => {
|
|
12
|
+
if (typeof(window) == 'object' && window.navigator && window.navigator.userAgent) {
|
|
13
|
+
return (window.navigator.userAgent.indexOf('MSIE') >= 0)
|
|
14
|
+
}
|
|
15
|
+
return false
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// なでしこで定義した関数の開始コードと終了コード
|
|
19
|
+
const topOfFunction = '(function(){\n'
|
|
20
|
+
const endOfFunction = '})'
|
|
21
|
+
const topOfFunctionAsync = '(async function(){\n'
|
|
11
22
|
|
|
12
23
|
/**
|
|
13
24
|
* @typedef {import("./nako3").Ast} Ast
|
|
@@ -24,13 +35,18 @@ class NakoGen {
|
|
|
24
35
|
static generate (com, ast, isTest) {
|
|
25
36
|
const gen = new NakoGen(com)
|
|
26
37
|
|
|
27
|
-
//
|
|
38
|
+
// ※ [関数定義に関するコード生成のヒント]
|
|
39
|
+
// ※ 関数の名前だけを(1)で登録して、(2)で実際に関数のコードを生成する。
|
|
40
|
+
// ※ ただし(2)では生成するだけなので、(3)でプログラム冒頭に関数定義のコードを記述する。
|
|
41
|
+
// この順番を変えることはできない (グローバル変数が認識できなくなったり、関数定義のタイミングがずれる)
|
|
42
|
+
|
|
43
|
+
// (1) ユーザー定義関数をシステムに登録する
|
|
28
44
|
gen.registerFunction(ast)
|
|
29
45
|
|
|
30
|
-
// JSコードを生成する
|
|
46
|
+
// (2) JSコードを生成する
|
|
31
47
|
let js = gen.convGen(ast, !!isTest)
|
|
32
|
-
|
|
33
|
-
// JSコードを実行するための事前ヘッダ部分の生成
|
|
48
|
+
|
|
49
|
+
// (3) JSコードを実行するための事前ヘッダ部分の生成
|
|
34
50
|
js = gen.getDefFuncCode(isTest) + js
|
|
35
51
|
|
|
36
52
|
// テストの実行
|
|
@@ -39,11 +55,7 @@ class NakoGen {
|
|
|
39
55
|
}
|
|
40
56
|
// async method
|
|
41
57
|
if (gen.numAsyncFn > 0) {
|
|
42
|
-
let canAsync =
|
|
43
|
-
if (typeof(window) == 'object' && window.navigator && window.navigator.userAgent) {
|
|
44
|
-
const ua = window.navigator.userAgent
|
|
45
|
-
canAsync = (ua.indexOf('MSIE') === -1)
|
|
46
|
-
}
|
|
58
|
+
let canAsync = !isIE11()
|
|
47
59
|
if (canAsync) {
|
|
48
60
|
js = `
|
|
49
61
|
// <nadesiko3::gen::async>
|
|
@@ -130,6 +142,12 @@ try {
|
|
|
130
142
|
* @type {number}
|
|
131
143
|
*/
|
|
132
144
|
this.numAsyncFn = 0
|
|
145
|
+
/**
|
|
146
|
+
* 関数定義の際、関数の中でasyncFn=trueの関数を呼び出したかどうかを調べる
|
|
147
|
+
* @type {boolean}
|
|
148
|
+
* @see convDefFuncCommon
|
|
149
|
+
*/
|
|
150
|
+
this.usedAsyncFn = false
|
|
133
151
|
|
|
134
152
|
/**
|
|
135
153
|
* 変換中の処理が、ループの中かどうかを判定する
|
|
@@ -181,10 +199,20 @@ try {
|
|
|
181
199
|
systemFunctionBody: 0 // システム関数(呼び出しコードを除く)
|
|
182
200
|
}
|
|
183
201
|
|
|
202
|
+
/**
|
|
203
|
+
* 未定義の変数の警告を行う
|
|
204
|
+
* @type { boolean }
|
|
205
|
+
*/
|
|
206
|
+
this.warnUndefinedVar = true
|
|
207
|
+
|
|
184
208
|
// 暫定変数
|
|
209
|
+
/** @type { number } */
|
|
185
210
|
this.warnUndefinedReturnUserFunc = 1
|
|
186
|
-
|
|
187
|
-
this.
|
|
211
|
+
/** @type { number } */
|
|
212
|
+
this.warnUndefinedCallingUserFunc = 1
|
|
213
|
+
/** @type { number } */
|
|
214
|
+
this.warnUndefinedCallingSystemFunc = 1
|
|
215
|
+
/** @type { number } */
|
|
188
216
|
this.warnUndefinedCalledUserFuncArgs = 1
|
|
189
217
|
}
|
|
190
218
|
|
|
@@ -297,8 +325,9 @@ try {
|
|
|
297
325
|
let nakoFuncCode = ''
|
|
298
326
|
for (const key in this.nako_func) {
|
|
299
327
|
const f = this.nako_func[key].fn
|
|
328
|
+
const isAsync = this.nako_func[key].asyncFn ? 'true' : 'false'
|
|
300
329
|
nakoFuncCode += '' +
|
|
301
|
-
`//[DEF_FUNC name='${key}']\n` +
|
|
330
|
+
`//[DEF_FUNC name='${key}' asyncFn=${isAsync}]\n` +
|
|
302
331
|
`__v1["${key}"]=${f};\n;` +
|
|
303
332
|
`//[/DEF_FUNC name='${key}']\n`
|
|
304
333
|
}
|
|
@@ -396,6 +425,11 @@ try {
|
|
|
396
425
|
registerFunction (ast) {
|
|
397
426
|
if (ast.type !== 'block') { throw NakoSyntaxError.fromNode('構文解析に失敗しています。構文は必ずblockが先頭になります', ast) }
|
|
398
427
|
|
|
428
|
+
/** 関数一覧
|
|
429
|
+
* @type {Array<{name: string, node: Object}>}
|
|
430
|
+
*/
|
|
431
|
+
const funcList = []
|
|
432
|
+
// なでしこ関数を定義して this.nako_func[name] に定義する
|
|
399
433
|
const registFunc = (node) => {
|
|
400
434
|
for (let i = 0; i < node.block.length; i++) {
|
|
401
435
|
const t = node.block[i]
|
|
@@ -403,20 +437,24 @@ try {
|
|
|
403
437
|
const name = t.name.value
|
|
404
438
|
this.used_func.add(name)
|
|
405
439
|
this.__self.__varslist[1][name] = function () { } // 事前に適当な値を設定
|
|
440
|
+
this.varslistSet[1].names.add(name) // global
|
|
406
441
|
this.nako_func[name] = {
|
|
407
442
|
josi: t.name.meta.josi,
|
|
408
443
|
fn: '',
|
|
409
|
-
type: 'func'
|
|
444
|
+
type: 'func',
|
|
445
|
+
asyncFn: false
|
|
410
446
|
}
|
|
411
|
-
|
|
412
|
-
|
|
447
|
+
funcList.push({name: name, node: t})
|
|
448
|
+
}
|
|
449
|
+
// 実行速度優先 などのオプションが付いている場合の処理
|
|
450
|
+
else if (t.type === 'speed_mode') {
|
|
413
451
|
if (t.block.type === 'block') {
|
|
414
452
|
registFunc(t.block)
|
|
415
453
|
} else {
|
|
416
454
|
registFunc(t)
|
|
417
455
|
}
|
|
418
|
-
}
|
|
419
|
-
if (t.type === 'performance_monitor') {
|
|
456
|
+
}
|
|
457
|
+
else if (t.type === 'performance_monitor') {
|
|
420
458
|
if (t.block.type === 'block') {
|
|
421
459
|
registFunc(t.block)
|
|
422
460
|
} else {
|
|
@@ -425,6 +463,7 @@ try {
|
|
|
425
463
|
}
|
|
426
464
|
}
|
|
427
465
|
}
|
|
466
|
+
// 関数の登録
|
|
428
467
|
registFunc(ast)
|
|
429
468
|
|
|
430
469
|
// __self.__varslistの変更を反映
|
|
@@ -435,6 +474,15 @@ try {
|
|
|
435
474
|
this.varsSet = { isFunction: false, names: initialNames, readonly: new Set() }
|
|
436
475
|
this.varslistSet = this.__self.__varslist.map((v) => ({ isFunction: false, names: new Set(Object.keys(v)), readonly: new Set() }))
|
|
437
476
|
this.varslistSet[2] = this.varsSet
|
|
477
|
+
|
|
478
|
+
// 非同期関数(asyncFn)があるかどうかテストする
|
|
479
|
+
// 後ほど改めて再度同じ関数を呼ぶため、警告などは抑止する
|
|
480
|
+
const tmpWarn = this.warnUndefinedVar
|
|
481
|
+
this.warnUndefinedVar = false // 未定義の変数の警告を抑止 #1192
|
|
482
|
+
for (let ff of funcList) {
|
|
483
|
+
this.convDefFuncCommon(ff.node, ff.name)
|
|
484
|
+
}
|
|
485
|
+
this.warnUndefinedVar = tmpWarn
|
|
438
486
|
}
|
|
439
487
|
|
|
440
488
|
/**
|
|
@@ -524,7 +572,7 @@ try {
|
|
|
524
572
|
case 'func':
|
|
525
573
|
case 'func_pointer':
|
|
526
574
|
case 'calc_func':
|
|
527
|
-
code += this.
|
|
575
|
+
code += this.convCallFunc(node, isExpression)
|
|
528
576
|
break
|
|
529
577
|
case 'if':
|
|
530
578
|
code += this.convIf(node)
|
|
@@ -635,7 +683,9 @@ try {
|
|
|
635
683
|
if (name === '引数' || name === 'それ' || name === '対象' || name === '対象キー') {
|
|
636
684
|
// デフォルト定義されている変数名
|
|
637
685
|
} else {
|
|
638
|
-
this.
|
|
686
|
+
if (this.warnUndefinedVar) {
|
|
687
|
+
this.__self.logger.warn(`変数『${name}』は定義されていません。`, position)
|
|
688
|
+
}
|
|
639
689
|
}
|
|
640
690
|
this.varsSet.names.add(name)
|
|
641
691
|
return this.varname(name)
|
|
@@ -734,8 +784,6 @@ try {
|
|
|
734
784
|
'try {\n'
|
|
735
785
|
performanceMonitorInjectAtEnd = '} finally { performanceMonitorEnd(); }\n'
|
|
736
786
|
}
|
|
737
|
-
const topOfFunction = '(function(){\n'
|
|
738
|
-
const endOfFunction = '})'
|
|
739
787
|
let variableDeclarations = ''
|
|
740
788
|
let popStack = ''
|
|
741
789
|
const initialNames = new Set()
|
|
@@ -756,7 +804,7 @@ try {
|
|
|
756
804
|
const meta = (!name) ? node.meta : node.name.meta
|
|
757
805
|
for (let i = 0; i < meta.varnames.length; i++) {
|
|
758
806
|
const word = meta.varnames[i]
|
|
759
|
-
if (this.
|
|
807
|
+
if (this.warnUndefinedCalledUserFuncArgs === 0) {
|
|
760
808
|
code += ` ${this.varname(word)} = arguments[${i}];\n`
|
|
761
809
|
} else
|
|
762
810
|
if (name) {
|
|
@@ -770,13 +818,19 @@ try {
|
|
|
770
818
|
if (name) {
|
|
771
819
|
this.used_func.add(name)
|
|
772
820
|
this.varslistSet[1].names.add(name)
|
|
773
|
-
this.nako_func[name]
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
821
|
+
if (this.nako_func[name] === undefined) {
|
|
822
|
+
// 既に generate で作成済みのはず(念のため)
|
|
823
|
+
this.nako_func[name] = {
|
|
824
|
+
josi: node.name.meta.josi,
|
|
825
|
+
fn: '',
|
|
826
|
+
type: 'func',
|
|
827
|
+
asyncFn: false
|
|
828
|
+
}
|
|
777
829
|
}
|
|
778
830
|
}
|
|
779
831
|
// ブロックを解析
|
|
832
|
+
const oldUsedAsyncFn = this.usedAsyncFn
|
|
833
|
+
this.usedAsyncFn = false
|
|
780
834
|
const block = this._convGen(node.block, false)
|
|
781
835
|
code += block.split('\n').map((line) => ' ' + line).join('\n') + '\n'
|
|
782
836
|
// 関数の最後に、変数「それ」をreturnするようにする
|
|
@@ -785,6 +839,10 @@ try {
|
|
|
785
839
|
}
|
|
786
840
|
// パフォーマンスモニタ:ユーザ関数のinject
|
|
787
841
|
code += performanceMonitorInjectAtEnd
|
|
842
|
+
// ブロックでasyncFnを使ったか
|
|
843
|
+
if (name && this.usedAsyncFn) {
|
|
844
|
+
this.nako_func[name].asyncFn = true
|
|
845
|
+
}
|
|
788
846
|
// 関数の末尾に、ローカル変数をPOP
|
|
789
847
|
|
|
790
848
|
// 関数内で定義されたローカル変数の宣言
|
|
@@ -808,15 +866,23 @@ try {
|
|
|
808
866
|
variableDeclarations += ` ${this.varname('それ')} = '';`
|
|
809
867
|
}
|
|
810
868
|
}
|
|
811
|
-
|
|
869
|
+
// usedAsyncFnの値に応じて関数定義の方法を変更
|
|
870
|
+
const tof = (this.usedAsyncFn) ? topOfFunctionAsync : topOfFunction
|
|
871
|
+
// 関数コード全体を構築
|
|
872
|
+
code = tof + performanceMonitorInjectAtStart + variableDeclarations + code + popStack
|
|
812
873
|
code += endOfFunction
|
|
813
874
|
|
|
814
|
-
|
|
875
|
+
// 名前があれば、関数を登録する
|
|
876
|
+
if (name) {
|
|
877
|
+
this.nako_func[name].fn = code
|
|
878
|
+
this.nako_func[name].asyncFn = this.usedAsyncFn
|
|
879
|
+
meta.asyncFn = this.usedAsyncFn
|
|
880
|
+
}
|
|
881
|
+
this.usedAsyncFn = oldUsedAsyncFn // 以前の値を戻す
|
|
815
882
|
|
|
816
883
|
this.varslistSet.pop()
|
|
817
884
|
this.varsSet = this.varslistSet[this.varslistSet.length - 1]
|
|
818
|
-
if (name) {
|
|
819
|
-
|
|
885
|
+
if (name) {this.__self.__varslist[1][name] = code }
|
|
820
886
|
return code
|
|
821
887
|
}
|
|
822
888
|
|
|
@@ -842,10 +908,12 @@ try {
|
|
|
842
908
|
}
|
|
843
909
|
|
|
844
910
|
convDefFunc (node) {
|
|
911
|
+
// ※ [関数定義のメモ]
|
|
912
|
+
// ※ 関数の定義はプログラムの冒頭に移される。
|
|
913
|
+
// ※ そのため、生成されたコードはここでは返さない
|
|
914
|
+
// ※ registerFunction を参照
|
|
845
915
|
const name = NakoGen.getFuncName(node.name.value)
|
|
846
916
|
this.convDefFuncCommon(node, name)
|
|
847
|
-
// ★この時点では関数のコードを生成しない★
|
|
848
|
-
// プログラム冒頭でコード生成時に関数定義を行う
|
|
849
917
|
return ''
|
|
850
918
|
}
|
|
851
919
|
|
|
@@ -1192,12 +1260,14 @@ try {
|
|
|
1192
1260
|
* @param {boolean} isExpression
|
|
1193
1261
|
* @returns string コード
|
|
1194
1262
|
*/
|
|
1195
|
-
|
|
1263
|
+
convCallFunc (node, isExpression) {
|
|
1196
1264
|
const funcName = NakoGen.getFuncName(node.name)
|
|
1197
1265
|
const res = this.findVar(funcName)
|
|
1198
1266
|
if (res === null) {
|
|
1199
1267
|
throw NakoSyntaxError.fromNode(`関数『${funcName}』が見当たりません。有効プラグイン=[` + this.getPluginList().join(', ') + ']', node)
|
|
1200
1268
|
}
|
|
1269
|
+
// どの関数を呼び出すのか関数を特定する
|
|
1270
|
+
/** @type {import('./nako3').NakoFunction} */
|
|
1201
1271
|
let func
|
|
1202
1272
|
if (res.i === 0) { // plugin function
|
|
1203
1273
|
func = this.__self.funclist[funcName]
|
|
@@ -1213,9 +1283,6 @@ try {
|
|
|
1213
1283
|
if (node.type === 'func_pointer') {
|
|
1214
1284
|
return res.js
|
|
1215
1285
|
}
|
|
1216
|
-
// なでしこで定義した関数?
|
|
1217
|
-
// const isUserFunc = (typeof(func.fn) === 'string')
|
|
1218
|
-
// console.log('@@@', funcName, typeof(func.fn))
|
|
1219
1286
|
|
|
1220
1287
|
// 関数の参照渡しでない場合
|
|
1221
1288
|
// 関数定義より助詞を一つずつ調べる
|
|
@@ -1280,6 +1347,7 @@ try {
|
|
|
1280
1347
|
}
|
|
1281
1348
|
|
|
1282
1349
|
// 関数呼び出しコードの構築
|
|
1350
|
+
/** @type {string} */
|
|
1283
1351
|
let argsCode
|
|
1284
1352
|
if ((this.warnUndefinedCallingUserFunc === 0 && res.i !== 0) || (this.warnUndefinedCallingSystemFunc === 0 && res.i === 0)) {
|
|
1285
1353
|
argsCode = args.join(',')
|
|
@@ -1304,6 +1372,7 @@ try {
|
|
|
1304
1372
|
funcDef = `async ${funcDef}`
|
|
1305
1373
|
funcCall = `await ${funcCall}`
|
|
1306
1374
|
this.numAsyncFn++
|
|
1375
|
+
this.usedAsyncFn = true
|
|
1307
1376
|
}
|
|
1308
1377
|
if (res.i === 0 && this.performanceMonitor.systemFunctionBody !== 0) {
|
|
1309
1378
|
let key = funcName
|
package/src/nako_indent.js
CHANGED
|
@@ -27,7 +27,8 @@ function isIndentSyntaxEnabled (code) {
|
|
|
27
27
|
const keywords = ['!インデント構文', '!ここまでだるい']
|
|
28
28
|
const lines = code.split('\n', 30)
|
|
29
29
|
for (const line of lines) {
|
|
30
|
-
const
|
|
30
|
+
const sline = line.replace(/^(!|💡)/, '!')
|
|
31
|
+
const s9 = sline.substring(0, 8)
|
|
31
32
|
if (keywords.indexOf(s9) >= 0) {
|
|
32
33
|
return true
|
|
33
34
|
}
|
package/src/nako_lex_rules.js
CHANGED
|
@@ -54,7 +54,7 @@ module.exports = {
|
|
|
54
54
|
{ name: 'noteq', pattern: /^(≠|<>|!=)/ },
|
|
55
55
|
{ name: '←', pattern: /^(←|<--)/ }, // 関数呼び出し演算子 #891 #899
|
|
56
56
|
{ name: 'eq', pattern: /^(=|🟰)/ },
|
|
57
|
-
{ name: 'line_comment', pattern:
|
|
57
|
+
{ name: 'line_comment', pattern: /^(!|💡)(インデント構文|ここまでだるい)[^\n]*/ }, // #1184
|
|
58
58
|
{ name: 'not', pattern: /^(!|💡)/ }, // #1184
|
|
59
59
|
{ name: 'gt', pattern: /^>/ },
|
|
60
60
|
{ name: 'lt', pattern: /^</ },
|
package/src/nako_lexer.js
CHANGED
|
@@ -236,6 +236,7 @@ class NakoLexer {
|
|
|
236
236
|
type: 'func',
|
|
237
237
|
josi,
|
|
238
238
|
fn: null,
|
|
239
|
+
asyncFn: false,
|
|
239
240
|
varnames,
|
|
240
241
|
funcPointers
|
|
241
242
|
}
|
|
@@ -498,7 +499,7 @@ class NakoLexer {
|
|
|
498
499
|
columnCurrent = column
|
|
499
500
|
lineCurrent = line
|
|
500
501
|
column += m[0].length
|
|
501
|
-
src = src.
|
|
502
|
+
src = src.substring(m[0].length)
|
|
502
503
|
if ((rule.name === 'eol' && value === '\n') || rule.name === '_eol') {
|
|
503
504
|
value = line++
|
|
504
505
|
column = 1
|
|
@@ -509,7 +510,7 @@ class NakoLexer {
|
|
|
509
510
|
// 単位があれば読み飛ばす
|
|
510
511
|
const um = lexRules.unitRE.exec(src)
|
|
511
512
|
if (um) {
|
|
512
|
-
src = src.
|
|
513
|
+
src = src.substring(um[0].length)
|
|
513
514
|
column += m[0].length
|
|
514
515
|
}
|
|
515
516
|
}
|
|
@@ -520,10 +521,10 @@ class NakoLexer {
|
|
|
520
521
|
if (j) {
|
|
521
522
|
josi = j[0].replace(/^\s+/, '')
|
|
522
523
|
column += j[0].length
|
|
523
|
-
src = src.
|
|
524
|
+
src = src.substring(j[0].length)
|
|
524
525
|
// 助詞の直後にあるカンマを無視 #877
|
|
525
526
|
if (src.charAt(0) === ',') {
|
|
526
|
-
src = src.
|
|
527
|
+
src = src.substring(1)
|
|
527
528
|
}
|
|
528
529
|
// 「**である」なら削除 #939 #974
|
|
529
530
|
if (removeJosiMap[josi]) { josi = '' }
|
package/src/nako_version.js
CHANGED
package/src/plugin_node.js
CHANGED
|
@@ -553,18 +553,6 @@ const PluginNode = {
|
|
|
553
553
|
},
|
|
554
554
|
return_none: true
|
|
555
555
|
},
|
|
556
|
-
'秒待': { // @NodeでN秒待つ // @びょうまつ
|
|
557
|
-
type: 'func',
|
|
558
|
-
josi: [['']],
|
|
559
|
-
pure: true,
|
|
560
|
-
fn: function (sec, sys) {
|
|
561
|
-
const msleep = (n) => {
|
|
562
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, n) // eslint-disable-line no-undef
|
|
563
|
-
}
|
|
564
|
-
msleep(sec * 1000)
|
|
565
|
-
},
|
|
566
|
-
return_none: true
|
|
567
|
-
},
|
|
568
556
|
'OS取得': { // @OSプラットフォームを返す(darwin/win32/linux) // @OSしゅとく
|
|
569
557
|
type: 'func',
|
|
570
558
|
josi: [],
|
|
@@ -129,6 +129,19 @@ describe('basic', () => {
|
|
|
129
129
|
'2'
|
|
130
130
|
)
|
|
131
131
|
})
|
|
132
|
+
it('💡のインデント構文 #1184', () => {
|
|
133
|
+
cmp(
|
|
134
|
+
'💡インデント構文\n' +
|
|
135
|
+
'3で条件分岐\n' +
|
|
136
|
+
' 2ならば\n' +
|
|
137
|
+
' 2を表示\n' +
|
|
138
|
+
' 3ならば\n' +
|
|
139
|
+
' 3を表示\n' +
|
|
140
|
+
' 違えば\n' +
|
|
141
|
+
' 5を表示\n',
|
|
142
|
+
'3'
|
|
143
|
+
)
|
|
144
|
+
})
|
|
132
145
|
it('独立した助詞『ならば』の位置の取得', () => {
|
|
133
146
|
const out = nako.lex('もし存在するならば\nここまで', '')
|
|
134
147
|
const sonzai = out.tokens.find((t) => t.value === '存在')
|
package/test/common/dncl_test.js
CHANGED