-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
816 lines (627 loc) · 27.5 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
var input_code = ""
var tokens = []
var ast = []
//parser()の時に使う
//文法規則:演算子などの優先順位
//下に行くほど優先度が高くなる
const rules = [
{ops:[]},
{ops:["(equal)"]},
{ops:["(dot)"]},
{ops:["(greater)","(smaller)"]},
{ops:["(plus)","(minus)"]},
{ops:["(times)","(division)","(percent)"]},
];
var pare_runfunc = false
//変数の値と名前を関連付けるリスト
var var_list_val = [] //値
var var_list_name = [] //名前
var var_local_val = [] //ローカル変数
var var_local_name = []
//関数の名前と位置を関連付けるリスト
var func_list_num = [] //何番目か
var func_list_name = [] //関数の名前
var if_mode = false //if文の時に(equal)を変数宣言ではなく、比較として使用する時がtrue
var func_mode = false //関数実行モード
var func_return = null //プログラム内のreturnの値を収納する
var else_jud = false //ifの前にelseがついていたか
var else_false_jud = false //ifの前にelseがついていた場合で判定がfalseだった場合
function run(){
//init
input_code = ""
tokens = []
ast = []
pare_runfunc = false
var_list_val = []
var_list_name = []
func_list_num = []
func_list_name = []
func_args_run = []
if_mode = false
func_mode = false
input_code = String(read_code())
document.getElementById("output").innerHTML = ""
//input_code = document.getElementById("editor").textContent
lexer() //字句解析
tokens = add_funcrun() //関数を実行する関数のようなものを追加する
console.log("debug tokens :")
console.log(tokens) //debug
ast = parser_generator()
console.log("debug ast :")
console.log(ast) //debug
mkfunc_list()
console.log(func_list_name)
console.log(func_list_num)
cmd_run(ast)
console.log(var_list_name)
console.log(var_list_val)
}
/*read******************************/
//コードを読み込む
function read_code(){
var code_element = document.getElementById("editor").getElementsByTagName("div")
var ret_code = ""
for(var i = 0;i < code_element.length;i++){
if(code_element[i].getElementsByTagName("img").length != 0){ //この中にimg(命令、cmd)があったら altも追加
var tmp = String(code_element[i].innerHTML)
var ret_list = []
var cmd_tmp = ""
for(var j = 0;j < tmp.length;j++){ //altも含めて返す
if(tmp[j] == "<"){
if(cmd_tmp != ""){
ret_list.push(cmd_tmp)
}
cmd_tmp = tmp[j]
}else if(tmp[j] == ">"){
if(cmd_tmp != ""){
ret_list.push(cmd_tmp+tmp[j])
cmd_tmp = ""
}
}else{
cmd_tmp += tmp[j]
}
}
//最後は追加されないため追加する
ret_list.push(cmd_tmp)
cmd_tmp = ""
console.log("debug")
console.log(ret_list)
//imgのaltを無理やりとってくる
for(var j = 0;j < ret_list.length;j++){
var div = document.createElement('div');
div.innerHTML = ret_list[j]; //html要素に変換
document.body.appendChild(div); //bodyに追加
if(div.getElementsByTagName("img").length != 0){ //img (命令)なら
var ret_alt = div.getElementsByTagName("img")[0].getAttribute('alt') //altを取得
}else if(div.getElementsByTagName("br").length != 0){ //brなら改行
var ret_alt = "\n"
}else{
var ret_alt = div.textContent //img(命令)以外はテキストを読む
}
document.body.removeChild(div); //bodyから削除
console.log(ret_alt) //alt
ret_code += ret_alt
}
ret_code += "\n" //divの終わりに改行 (つまり、divとbrで改行)
//ヒュー終わった
}else{ //なかったらそのまま読んで追加
ret_code += code_element[i].textContent+"\n"
}
}
ret_code = ret_code.replace(/ /g," ") // を空白に変換
console.log("ret code")
console.log(ret_code)
return ret_code
}
/****************************************/
function lexer(){
tokens = []
var command_tmp = "" //とりあえず途中のコードはここに保存
var command_rec = false //これが命令かを示す
var string_token = false //「"」で囲まれた文字列(つまりプログラムの中でのstring)は命令とみなさない true・・・string
for(var i = 0;i < input_code.length;i++){
//ここから先がstringだった場合 / stringの終わりだった場合
if(string_token == false && input_code[i] == '"'){
string_token = true //ここから先はstring型ですよ
if(command_tmp != ""){
tokens.push(command_tmp) //区切る
}
command_tmp = ""+input_code[i]
}else if(string_token == true && input_code[i] == '"'){
string_token = false //普通のモードに直す
if(command_tmp != ""){
tokens.push(command_tmp+input_code[i]) //stringとして保存する
}
command_tmp = ""
}
//ここから先がコマンドだった場合
if(input_code[i] == "(" && command_rec == false && string_token == false){
command_rec = true
//後ろを区切る
if(command_tmp != ""){
tokens.push(command_tmp)
command_tmp = ""
}
}
//一時的に保存しておく
if(input_code[i] != '"' && input_code[i] != "\n"){
//空白がstringだったら保存、空白がstringじゃなかったら保存しない
if(input_code[i].replace(/\s+/g, "").length != 0){ //editorから入力された文字が空白かどうかを判定できないバグを修正
if(string_token == false){
command_tmp += input_code[i]
}
}
if(string_token == true){
command_tmp += input_code[i]
}
}
//命令の終わりだった場合コマンドをtokensに保存する
if(input_code[i] == ")" && command_rec == true){
tokens.push(command_tmp)
command_rec = false
command_tmp = ""
}
//改行だったら区切る
if(input_code[i] == "\n"){
if(command_tmp != ""){
tokens.push(command_tmp)
}
command_tmp = ""
}
}
//コマンドが余っていたらtokensに追加する
if(command_tmp != ""){
tokens.push(command_tmp)
}
}
//関数の先頭に関数実行を意味する "(funcrun)" をつける & 関数を実行できるようにする (pare)~(pare_end)のバグ修正
function add_funcrun(){
var def_function = ["(none)","(equal)","(plus)","(minus)","(times)","(division)","(percent)",
"(pare)","(pare_end)","(dot)",
"(function)",
"(command_end)","(else)",
"(if)","(loop)",
"(greater)","(smaller)",
"(comment)"] //デフォルトの関数,予約語
var tokens_ret = []
var token_before = "" //ひとつ前の命令
for(var i = 0;i < tokens.length;i++){
if(def_function.indexOf(tokens[i]) == -1 && token_before != "(function)"){ //登録されていない関数なら
if(tokens[i][0] == "(" && tokens[i][tokens[i].length-1] == ")"){
tokens_ret.push("(funcrun)")
}
}
tokens_ret.push(tokens[i])
//(pare)~(pare_end)の中に何の値も入っていなかったら(none)を追加
if(tokens[i] == "(pare)" && tokens[i+1] == "(pare_end)"){
tokens_ret.push("(none)")
}
token_before = tokens[i]
}
return tokens_ret
}
//パーサージェネレーター
function parser_generator(){
ast = []
while(true){
if(tokens.length != 0){
console.log(tokens)
ast.push(parser(tokens,p=0))
}else{
break;
}
}
return ast
}
//参考 > ttps://3iz.jp/
//パーサーを作る
function parser(t,p=0){
//ifやfunctionなどの例外の処理
//(memo)とりあえず(pare)と(pare_end)の中の優先順位を上げたい
if(t[0] == "(pare)"){ //関数の括弧 "("
var left_pare = t.shift();
var op_pare = parser(t,0)
console.log(op_pare)
}
if(t[0] == "(pare_end)"){ //関数の括弧 ")"
var right_pare = t.shift()
var cmd_contents = []
if(!pare_runfunc){ //if文やfunction定義の時は "{"のように内容の始まりとみなす
//opに[{命令},{命令},{..}]のような感じに追加していく
while(true){ //複数の命令があったときに対応している
if(t[0] == "(command_end)" || t[0] == "(else)"){
break;
}else{
cmd_contents.push(parser(t,0))
}
}
}else{
return {left:left_pare,op:op_pare,right:right_pare}
}
}
if(t[0] == "(command_end)" || t[0] == "(else)"){ // "}" のような役割を持ってるif文の終わりやfunction宣言の終りなどに使われる || elseの役割
var cmd_right = t.shift()
return {left:{left:left_pare,op:op_pare,right:right_pare},op:cmd_contents,right:cmd_right}
}
//[(function)] [関数名] [(pare)(pare_end)...(command_end)] と言う形式にしたいので普通の命令と違う形式をとる
if(t[0] == "(function)"){
pare_runfunc = false //関数呼び出しではないので(command_end)までをしまう
var left_func = t.shift()
var op_func = t.shift()
var right_func = parser(t,0)
var left_tmp = {left:left_func,op:op_func,right:right_func}
}else
if(t[0] == "(funcrun)"){ //関数実行
pare_runfunc = true
var left_func = t.shift()
var op_func = t.shift()
var right_func = parser(t,0)
var left_tmp = {left:left_func,op:op_func,right:right_func}
}else
if(t[0] == "(comment)"){ //コメント
pare_runfunc = true
var left_func = t.shift()
var op_func = t.shift()
var left_tmp = {left:left_func,op:op_func,right:"(none)"}
}
//loop/if のast (基本的に文法が似てる or 同じなので一つにした)
//
//[(loop)] [(pare) loop number (pare_end)...(command_end)] [(none)] loop文です
//[if] [(pare)(pare_end)...(command_end)] [(none)] if文はこんな感じ
//(none)は何も意味を持たない
if(t[0] == "(if)" || t[0] == "(loop)"){
pare_runfunc = false
var left_if = t.shift()
var op_if = parser(t,0)
left_tmp = {left:left_if,op:op_if,right:"(none)"}
}
if(p==rules.length) {//この文字列が文法規則になかったら
return t.shift();
}
var ops = rules[p].ops //今の優先順位の文字列を取り出す
if(left_tmp){
var left = left_tmp
}else{
var left = parser(t,p+1);
}
//パーサーのコアと言っても過言ではないところ
while(ops.includes(t[0])){ //この文字列の優先順位がpだったら
var op = t.shift();
var right = parser(t,p+1)
left = {left:left,op:op,right:right}
}
tokens = t
return left
}
function mkfunc_list(){
for(var i = 0;i < ast.length;i++){
if(ast[i].left == "(function)"){ //これが関数なら
func_list_num.push(i) //この位置と関数を関連付ける
func_list_name.push(ast[i].op)
}
}
}
//@param cmd json (parsed code)
//命令実行のメインの部分
//予約語の機能、関数の機能を定義している
//コマンドを実行できる
function cmd_run(cmd){
if(Array.isArray(cmd)){ //入力されたastはArrayか、そうじゃないか判断する
for(var i = 0;i < cmd.length;i++){ //Arrayの場合は命令がたくさん詰まっているのでその命令をすべて実行する
console.log(cmd[i])
if(cmd[i].op == "(return)"){ //return なら速攻返す
console.log("debug return")
func_return = cmd_run(cmd[i])
return 0;
}else{ //普通は順番に実行する
cmd_run(cmd[i])
}
}
}else if(typeof(cmd) == "object"){ //jsonだった場合、普通にleft,op,rightを読み込んで実行
var op_cmd_list = ["(equal)","(dot)","(greater)","(smaller)","(plus)","(minus)","(times)","(division)","(percent)"] //何かの値の真ん中に来るコマンド集
if(op_cmd_list.indexOf(cmd.op) != -1){ //真ん中に来るコマンドなら
if(cmd.right == undefined){ //右側の値がなかったら
echo_error('There wasn\'t a value to right of the command "'+cmd.op+'".') //op error msg
}
if(cmd.left == undefined){ //右側の値がなかったら
echo_error('There wasn\'t a value to left of the command "'+cmd.op+'".') //op error msg
}
}
switch(cmd.op){ //真ん中に命令があるか確かめる 四則演算など
case "(equal)": //変数宣言
if(typeof(cmd.left) != "string"){
echo_error('Unknown syntax error by "'+cmd.op+'" .')
}
if(if_mode){ //if_mode=trueなら(equal)を比較とみなす
if(cmd_run(cmd.left) == cmd_run(cmd.right)){ // left = right
return true //trueを返す
}else{
return false
}
}else if(cmd.left != "(none)"){ //変数の名前がnoneじゃない and if_mode=falseなら 変数宣言
//console.log(cmd_run(cmd.right)) //debug ※関数の返り値を変数にしまうときに 2回実行してしまうのでコメントアウトしておく
if(var_list_name.includes(cmd.left)){ //今の変数があったら(宣言されていたら)
var_list_val[var_list_name.indexOf(cmd.left)] = str_to_val(cmd_run(cmd.right)) //その変数に対応する場所に変数の値をしまう
}else{
var_list_name.push(cmd.left) //変数を宣言する
var_list_val.push(str_to_val(cmd_run(cmd.right)))
}
}
break;
case "(plus)":
if(!isNaN(cmd_run(cmd.left)) && !isNaN(cmd_run(cmd.right))){
return Number(cmd_run(cmd.left)) + Number(cmd_run(cmd.right)) //もし数字ならそのまま計算して返す
}else{ //文字同士なら、文字をつなぐ
return cmd_run(cmd.left) + cmd_run(cmd.right)
}
case "(minus)":
return Number(cmd_run(cmd.left)) - Number(cmd_run(cmd.right))
case "(times)":
return Number(cmd_run(cmd.left)) * Number(cmd_run(cmd.right))
case "(division)":
return Number(cmd_run(cmd.left)) / Number(cmd_run(cmd.right))
case "(percent)":
return Number(cmd_run(cmd.left)) % Number(cmd_run(cmd.right))
case "(dot)": //引数やリストの値を区切るときに使う "," の役割をする
var dot_left = str_to_val(cmd_run(cmd.left))
var dot_right = str_to_val(cmd_run(cmd.right))
if(Array.isArray(dot_left)){ //Arrayなら
dot_left.push(dot_right) //値をぶち込む
return dot_left
}else{
return [dot_left,dot_right]
}
case "(greater)": // ">" if文比較
if(cmd_run(cmd.left) > cmd_run(cmd.right)){
return true
}else{
return false
}
break;
case "(smaller)": // "<" if文比較
if(cmd_run(cmd.left) < cmd_run(cmd.right)){
return true
}else{
return false
}
break;
default:
break;
}
switch(cmd.left){
case "(funcrun)": //関数実行
if(cmd.right == undefined){
echo_error('There wasn\'t a argument by function "'+cmd.op+'".') //funcrun error msg
}
var func_args = cmd_run(cmd.right["op"])
if(!Array.isArray(func_args)){ //Arrayじゃないなら無理やりArrayにする
func_args = [str_to_val(func_args)]
}
console.log(func_args)
return funcrun(cmd.op,func_args)
break;
case "(if)":
if(cmd.op["op"] == undefined || cmd.op["left"]["op"] == "(none)"){ //条件式がない
echo_error('There wasn\'t a conditional expression by "if command".')
}
if_mode = true //(equal)を比較記号とみなす
var if_jud = cmd_run(cmd.op["left"]["op"])
if_mode = false
console.log(if_jud)
if(if_jud){ //trueなら実行
//elseが宣言されていて、前のif文の結果がfalseだった場合
if(else_jud && else_false_jud){
cmd_run(cmd.op["op"])
}else if(!else_jud){ //elseが宣言されていない
cmd_run(cmd.op["op"])
}
if(cmd.op["right"] == "(else)"){ //else(falseだった場合のコマンド)が宣言されていたら
else_jud = true //判定 true
}else{
else_jud = false
}
else_false_jud = false
}else{ //結果がfalseだった場合
if(else_jud == true){ //else(falseだった場合のコマンド)が宣言されていたら
else_false_jud = true
}
}
break;
case "(loop)":
if(isNaN(cmd.op["left"]["op"])){ //数字じゃなかったら
echo_error('There wasn\'t number by loop.')
}
var nam = cmd_run(cmd.op["left"]["op"])
if(!isNaN(nam)){
for(var i = 0;i < nam;i++){
cmd_run(cmd.op["op"])
}
}
break;
case "(function)":
if(func_mode){ //関数実行モード
var input_list = cmd_run(cmd.right["left"]["op"]) //引数を代入する変数の名前
if(cmd.right == undefined){
echo_error('There wasn\'t a command for run by "function command".')
}
if(!Array.isArray(input_list)){ //Arrayじゃないなら無理やりArrayにする
input_list = [input_list]
}
for(var i = 0;i < input_list.length;i++){ // '"' をつける
input_list[i] = var_to_val(input_list[i])
}
console.log(input_list)
console.log(var_local_val)
for(var i = 0;i < var_local_val.length;i++){//ローカル変数を引数の数に合わせる
var_local_name.push(input_list[i])
}
console.log("debug : local var")
console.log(var_local_name)
console.log(var_local_val)
cmd_run(cmd.right["op"])
//関数を実行し終わったらローカル変数を消す
var_local_name = []
var_local_val = []
}
break;
default:
break;
}
}else{
return var_to_val(cmd)
}
}
//strだったらクオーテーションを取って返す
//変数だったらその値を返す
function var_to_val(str){
if(isNaN(str) && str != undefined && str != null){
if(str[0] == '"' && str[str.length-1] == '"'){ //str型なら
return str.replace(/"/g,"") //外して返す
}
}
//グローバル変数
for(var i = 0;i < var_list_name.length;i++){ //これが変数かそうではないかを確かめる
if(str == var_list_name[i]){ //変数だったらその変数の値を返す
return var_list_val[i]
}
}
//local var.(ローカル変数)
for(var i = 0;i < var_local_name.length;i++){ //これが変数かそうではないかを確かめる
if(str == var_local_name[i]){ //変数だったらその変数の値を返す
return var_local_val[i]
}
}
//何でもなかったらそのまま
return str
}
//strにダブルクオーテーションをつける
//文字列をstring型にする
//数字はnumberにする
function str_to_val(str){
console.log("debug str")
console.log(str)
if(str == ""){
return ""
}
if(!isNaN(str)){ //数字だったら
return Number(str)
}
if(typeof(str) == "string"){ //stringだったら
return '"'+str+'"'
}
return str
}
//@param str string
//echo to string
//@param mode number
//1:echo the string in console
//@param data string
//mode>1:string's color
function console_api(str,mode,data){
output_area = document.getElementById("output")
switch(mode){
case 1: //mode 1
if(data != ""){ //カラーコードが渡された場合色を塗る
output_area.innerHTML+= "<span style='color:"+data+";'>"+str+"</span><br>"
}else{ //渡されていない場合はそのまんま
output_area.innerHTML+= str+"<br>"
}
default:
break;
}
}
//echo error
function echo_error(str){
console_api("ERROR: "+str,1,"#ff0000")
}
function funcrun(func,args){ //関数を実行する
//args[n] 引数
switch(func){
//デフォルトの関数の場合
//basic command
//args:print value
case "(print)":
var print_text = String(var_to_val(args[0]))
console.log("debug : "+args[0])
console.log("output_print_function : "+print_text) //ダブルクオーテーションを外すとかして、表示する
console_api(print_text,1)
break;
//args:echo value
case "(input)":
var print_text = String(var_to_val(args[0]))
console.log("debug : "+args[0])
console.log("output_print_function : "+print_text) //ダブルクオーテーションを外すとかして、表示する
output_area.textContent += print_text+">"
var input_text = prompt(print_text)
console_api(input_text,1)
return str_to_val(input_text)
break;
//args : return value
case "(return)":
return var_to_val(args[0]) //リターンするだけの関数
break;
/*They functions are not added in editor yet*****************************************************************/
//gui support command
//open the window
//args : width,height
case "(start_win)":
if(args[0] == undefined || args[1] == undefined){ //引数が入力されていなかったら
canvas.width = 400
canvas.height = 400
}else{ //引数が入力されている
canvas.width = str_to_val(args[0])
canvas.height = str_to_val(args[1])
}
location.href = "#gui"
break;
//draw rect
//args : x,y,width,height,color code
case "(draw_rect)":
//x,y,width,height
ctx.beginPath()
ctx.rect(args[0],args[1],args[2],args[3])
ctx.fillStyle = var_to_val(args[4]) //color code(RGB)
ctx.fill()
ctx.closePath()
break;
//clean the canvas
//args : x,y,width,height
case "(clean_can)":
//x,y,width,height
ctx.clearRect(args[0],args[1],args[2],args[3])
return 0;
break;
//プログラム内で作られた関数の場合
default:
var is_function = false; //これは関数かそうじゃないか エラーを出力するときに使う
var_local_val = args //ローカル変数を引数にする
func_mode = true //関数実行中
for(var i = 0;i < func_list_name.length;i++){ //関数をひとつずつ探す
if(func_list_name[i] == func){ //この名前の関数が見つかったら
is_function = true //これは関数と判明
cmd_run(ast[func_list_num[i]]) //関数を実行
console.log(func_return) //debug : func_return
func_mode = false
if(func_return != undefined){ //undefinedでなければreturnの値を返す
return func_return
}else{ //でなければnull
return "(null)"
}
break;
}
}
if(!is_function){
echo_error('Not found this function "'+func+'".') //function error_msg
}
break;
}
}
/*
#functions
cmd_run(json[program]) :run anything commands
var_to_val(str) :"variable to value" or "remove double quotations"
str_to_val(str) :string to value (number,etc...)
##console
console_api(str,mode,data) :echo the strings on console
echo_error(str) :echo the error on console
*/