nadesiko3/
runner.rs

1//! インタプリタ Node を順に実行する
2// 走者 - Vec<Node>を順に実行
3use crate::{tokenizer, parser};
4use crate::node::*;
5use crate::sys_function_debug;
6use crate::sys_function;
7
8pub fn run_node(ctx: &mut NodeContext, cur: &Node) -> Option<NodeValue> {
9    let mut result = NodeValue::Empty;
10    match cur.kind {
11        NodeKind::Nop => {},
12        NodeKind::Comment => {},
13        NodeKind::LetVarGlobal => result = run_let(ctx, cur),
14        NodeKind::Int => result = cur.value.clone(),
15        NodeKind::Bool => result = cur.value.clone(),
16        NodeKind::Number => result = cur.value.clone(),
17        NodeKind::String => result = cur.value.clone(),
18        NodeKind::GetVarGlobal => result = run_get_var(ctx, cur).unwrap_or(NodeValue::Empty),
19        NodeKind::Operator => result = run_operator(ctx, cur),
20        NodeKind::CallSysFunc => result = run_call_sysfunc(ctx, cur),
21        NodeKind::CallUserFunc => result = run_call_userfunc(ctx, cur),
22        NodeKind::NodeList => {
23            result = match run_nodes(ctx, &cur.value.to_nodes()) {
24                Ok(value) => value,
25                Err(_) => return None,
26            };
27        },
28        NodeKind::If => match run_if(ctx, cur) { Some(v) => result = v, None => {}},
29        NodeKind::Kai => match run_kai(ctx, cur) { Some(v) => result = v, None => {}},
30        NodeKind::For => match run_for(ctx, cur) { Some(v) => result = v, None => {}},
31        NodeKind::Break => { ctx.try_break = Some(ctx.callstack_level) },
32        NodeKind::Continue => { ctx.try_continue = Some(ctx.callstack_level) },
33        NodeKind::Return => result = run_return(ctx, cur),
34        NodeKind::ArrayCreate => result = run_array_create(ctx, cur),
35        NodeKind::ArrayRef => result = run_array_ref(ctx, cur),
36        NodeKind::ArrayLet => result = run_array_let(ctx, cur),
37        _ => { println!("[エラー] runner未実装のノード :{:?}", cur); return None; }
38    }
39    Some(result)
40}
41
42pub fn run_nodes(ctx: &mut NodeContext, nodes: &Vec<Node>) -> Result<NodeValue, String> {
43    ctx.callstack_level += 1;
44    let nodes_len = nodes.len();
45    let mut result = NodeValue::Empty;
46    let mut index = 0;
47    while index < nodes_len {
48        if ctx.has_error() { ctx.callstack_level -= 1; return Err(ctx.get_error_str()); }
49        if ctx.try_continue != None { ctx.callstack_level -= 1; return Ok(NodeValue::Empty); }
50        if ctx.try_break != None { ctx.callstack_level -= 1; return Ok(NodeValue::Empty); }
51        if ctx.try_return != None { ctx.callstack_level -= 1; return Ok(NodeValue::Empty); }
52        let cur:&Node = &nodes[index];
53        if ctx.debug_mode {
54            println!("[RUN:{:2}] {}{}", cur.pos.start, indent_str(ctx.callstack_level-1), cur.to_string());
55        }
56        if let Some(v) = run_node(ctx, cur) { result = v; }
57        index += 1;
58    }
59    ctx.callstack_level -= 1;
60    Ok(result)
61}
62
63
64pub fn run_return(ctx: &mut NodeContext, cur: &Node) -> NodeValue {
65    match &cur.value {
66        NodeValue::NodeList(nodes) => {
67            let node = &nodes[0];
68            let result = run_node(ctx, node).unwrap_or(NodeValue::Empty);
69            ctx.scopes.set_value_local_scope("それ", result.clone());
70            ctx.try_return = Some(ctx.callstack_level);
71            // println!("*** RETUEN *** それ={}", result.clone().to_string());
72            // panic!("!enter");
73            result
74        },
75        _ => NodeValue::Empty,
76    }
77}
78
79pub fn run_for(ctx: &mut NodeContext, cur: &Node) -> Option<NodeValue> {
80    let nodes = cur.value.to_nodes();
81    let loop_node = &nodes[0];
82    let kara_node = &nodes[1];
83    let made_node = &nodes[2];
84    let body_node = &nodes[3];
85    let kara_v = run_node(ctx, &kara_node).unwrap_or(NodeValue::Empty);
86    let made_v = run_node(ctx, &made_node).unwrap_or(NodeValue::Empty);
87    let mut result = None;
88    for i in kara_v.to_int(0)..=made_v.to_int(0) {
89        if loop_node.kind == NodeKind::GetVarGlobal {
90            match &loop_node.value {
91                NodeValue::GetVar(info) => {
92                    let name: String = info.name.clone();
93                    ctx.scopes.set_value_local_scope(&name, NodeValue::I(i));
94                },
95                _ => {},
96            }
97        }
98        result = run_node(ctx, body_node);
99        // 抜けるの処理
100        if ctx.try_break != None {
101            ctx.try_break = None;
102            break;
103        }
104        // 続けるの処理
105        if ctx.try_continue != None {
106            ctx.try_continue = None;
107            continue;
108        }
109        // 戻るの処理
110        if ctx.try_return != None {
111            break;
112        }
113    }
114    result
115}
116
117pub fn run_kai(ctx: &mut NodeContext, cur: &Node) -> Option<NodeValue> {
118    let nodes = cur.value.to_nodes();
119    let kaisu_node = &nodes[0];
120    let body_node = &nodes[1];
121    let kaisu = run_node(ctx, kaisu_node).unwrap_or(NodeValue::I(0));
122    let mut result = None;
123    for i in 0..kaisu.to_int(0) {
124        ctx.scopes.set_value(1, "回数", NodeValue::I(i + 1));
125        result = run_node(ctx, body_node);
126        // 抜けるの処理
127        if ctx.try_break != None {
128            ctx.try_break = None;
129            break;
130        }
131        // 続けるの処理
132        if ctx.try_continue != None {
133            ctx.try_continue = None;
134            continue;
135        }
136        // 戻るの処理
137        if ctx.try_return != None {
138            break;
139        }
140    }
141    result
142}
143
144pub fn run_if(ctx: &mut NodeContext, cur: &Node) -> Option<NodeValue> {
145    let nodes = cur.value.to_nodes();
146    let cond: &Node = &nodes[0];
147    let true_node: &Node = &nodes[1];
148    let false_node: &Node = &nodes[2];
149    match run_node(ctx, cond) {
150        None => None,
151        Some(cond_v) => {
152            if cond_v.to_bool() {
153                run_node(ctx, true_node)
154            } else {
155                run_node(ctx, false_node)
156            }
157        }
158    }
159}
160
161fn run_call_sysfunc(ctx: &mut NodeContext, node: &Node) -> NodeValue {
162    let mut args: Vec<NodeValue> = vec![];
163    let func_no = match &node.value {
164        NodeValue::CallFunc(func_name, no, nodes) => {
165            for n in nodes.iter() {
166                let v = match run_nodes(ctx, &vec![n.clone()]) {
167                    Ok(v) => v,
168                    Err(err) => {
169                        ctx.throw_error(
170                            NodeErrorKind::RuntimeError, NodeErrorLevel::Error, 
171                            format!("『{}』の呼び出しでエラー。{}", func_name, err), 
172                            node.pos);
173                        return NodeValue::Empty;
174                    }
175                };
176                args.push(v);
177            }
178            *no
179        }
180        _ => return NodeValue::Empty,
181    };
182    let info:&SysFuncInfo = &ctx.sysfuncs[func_no];
183    let result = (info.func)(ctx, args);
184    match result {
185        Some(value) => {
186            ctx.scopes.set_value_local_scope("それ", value.clone());
187            value
188        },
189        None => NodeValue::Empty,
190    }
191}
192
193fn run_call_userfunc(ctx: &mut NodeContext, node: &Node) -> NodeValue {
194    // 関数呼び出しの引数を得る
195    let (func_name, func_no, arg_nodes) = match &node.value {
196        NodeValue::CallFunc(func_name, no, nodes) => (func_name, *no, nodes),
197        _ => return NodeValue::Empty,
198    };
199    // 関数を得る
200    let info = NodeVarInfo { level: 1, no: func_no, name: func_name.clone() };
201    // println!("@@context:{:?}", ctx.scopes.scopes[1]);
202    // println!("@@本体:info={:?}", info);
203    let func_value = match ctx.scopes.get_var_value(&info) { // 関数本体
204        Some(v) => v,
205        None => return NodeValue::Empty,
206    };
207    // println!("@@本体:{}", func_value.to_string());
208    let meta = match ctx.scopes.get_var_meta(&info) { // メタ情報
209        Some(v) => v,
210        None => return NodeValue::Empty,
211    };
212    // println!("@@meta:{:?}", meta);
213    // 関数の引数定義を得る
214    let func_args: &Vec<SysArg> = match &meta.kind {
215        NodeVarKind::UserFunc(args) => args,
216        _ => return NodeValue::Empty,
217    };
218    // println!("@@args");
219    // 関数スコープを作り、ローカル変数を登録する
220    let mut scope = NodeScope::new();
221    // 関数の引数を得る
222    for (i, n) in arg_nodes.iter().enumerate() {
223        match run_nodes(ctx, &vec![n.clone()]) {
224            Ok(val) => {
225                let name = &func_args[i].name;
226                scope.set_var(name, val);
227            },
228            Err(err) => {
229                ctx.throw_error(
230                    NodeErrorKind::RuntimeError, NodeErrorLevel::Error, 
231                    format!("『{}』の呼び出しでエラー。{}", func_name, err), 
232                    node.pos);
233                return NodeValue::Empty;
234            }
235        };
236    }
237    // 関数を実行
238    ctx.scopes.push_local(scope);
239    let tmp_return_level = ctx.return_level;
240    ctx.return_level = ctx.callstack_level;
241    match func_value {
242        NodeValue::CallFunc(name, _no, nodes) => {
243            // println!("@@@CALL:{}", nodes_to_string(&nodes, "\n"));
244            match run_nodes(ctx, &nodes) {
245                Ok(v) => v,
246                Err(e) => {
247                    ctx.throw_runtime_error(format!("『{}』の呼び出しでエラー。{}", name, e), node.pos);
248                    NodeValue::Empty
249                }
250            };
251        },
252        _ => {},    
253    };
254    let func_scope = ctx.scopes.pop_local().unwrap_or(NodeScope::new());
255    if let Some(_level) = ctx.try_return {
256        ctx.try_return = None;
257    }
258    ctx.return_level = tmp_return_level;
259    let result = func_scope.get_var("それ");
260    // println!("*** 関数のスコープ={:?}", func_scope);
261    ctx.scopes.set_value_local_scope("それ", result.clone());
262    result
263}
264
265fn run_let(ctx: &mut NodeContext, node: &Node) -> NodeValue {
266    let let_value: &NodeValueParamLet = match &node.value {
267        NodeValue::LetVar(ref let_value) => let_value,
268        _ => return NodeValue::Empty,
269    };
270    let value_node:&Vec<Node> = &let_value.value_node;
271    let value = run_nodes(ctx, value_node).unwrap_or(NodeValue::Empty);
272    let info = let_value.var_info.clone();
273    // let level = info.level;
274    let name = &info.name;
275    // println!("- let {}:L{}={:?}", name, level, value);
276    ctx.scopes.set_value(info.level, name, value.clone());
277    value
278}
279
280fn run_get_var(ctx: &mut NodeContext, node: &Node) -> Option<NodeValue> {
281    let var_info: &NodeVarInfo = match &node.value {
282        NodeValue::GetVar(ref var_info) => var_info,
283        _ => return None,
284    };
285    let v = ctx.get_var_value(var_info);
286    // println!("- get {:?} = {:?}", var_info, v);
287    return v;
288}
289
290fn run_operator(ctx: &mut NodeContext, node: &Node) -> NodeValue {
291    let op = match &node.value {
292        NodeValue::Operator(op) => op,
293        _ => return NodeValue::Empty,
294    };
295    let right = run_nodes(ctx, &vec![op.nodes[1].clone()]).unwrap_or(NodeValue::Empty);
296    let left = run_nodes(ctx, &vec![op.nodes[0].clone()]).unwrap_or(NodeValue::Empty);
297    match op.flag {
298        '(' => left,
299        '!' => NodeValue::B(!left.to_bool()),
300        '+' => NodeValue::calc_plus(&left, &right),
301        '結' => NodeValue::calc_plus_str(&left, &right), // 文字列加算
302        '|' => NodeValue::calc_or(&left, &right), // または
303        '&' => NodeValue::calc_and(&left, &right), // かつ
304        '-' => NodeValue::calc_minus(&left, &right),
305        '*' => NodeValue::calc_mul(&left, &right),
306        '/' => NodeValue::calc_div(&left, &right),
307        '%' => NodeValue::calc_mod(&left, &right),
308        '=' => NodeValue::calc_eq(&left, &right),
309        '≠' => NodeValue::calc_noteq(&left, &right),
310        '>' => NodeValue::calc_gt(&left, &right),
311        '≧' => NodeValue::calc_gteq(&left, &right),
312        '<' => NodeValue::calc_lt(&left, &right),
313        '≦' => NodeValue::calc_lteq(&left, &right),
314        '^' => NodeValue::calc_pow(&left, &right),
315        _ => {
316            println!("[実行時エラー]未実装の演算子記号:『{}』", op.flag);
317            NodeValue::Empty
318        },
319    }
320}
321
322fn run_array_create(ctx: &mut NodeContext, node: &Node) -> NodeValue {
323    let mut val_array: Vec<NodeValue> = vec![];
324    match &node.value {
325        NodeValue::NodeList(nlist) => {
326            for node in nlist.iter() {
327                let opt_val = run_node(ctx, node);
328                match opt_val {
329                    Some(val) => val_array.push(val),
330                    None => {},
331                }
332            }
333        },
334        _ => {}
335    }
336    NodeValue::A(val_array)
337}
338
339fn run_array_let(ctx: &mut NodeContext, node: &Node) -> NodeValue {
340    // 配列要素への代入
341    let param_let = match &node.value {
342        NodeValue::LetVar(param_let) => param_let,
343        _ => { return NodeValue::Empty; }
344    };
345    let name = param_let.var_info.clone().name;
346    let mut index_list: Vec<usize> = vec![];
347    let let_value: NodeValue;
348    let mut var: &mut NodeValue;
349    {
350        // 値を評価
351        let value_node = &param_let.value_node;
352        let_value = match run_node(ctx, &value_node[0]) {
353            Some(v) => v.clone(),
354            None => {
355                let msg = format!("配列変数『{}』に代入で右辺の値が取得できませんでした。", name);
356                ctx.throw_runtime_error(msg, node.pos);
357                return NodeValue::Empty;
358            }
359        };
360        // インデックスを得る
361        let mut index_no = 0;
362        let index_vec: &Vec<Node> = &param_let.index_node;
363        for index_node in index_vec.iter() {
364            let index = match run_node(ctx, index_node) {
365                Some(v) => v.to_int(0),
366                None => {
367                    let msg = format!("配列変数『{}』の{}番目の要素番号が取得できません。", name, index_no + 1);
368                    ctx.throw_runtime_error(msg, node.pos);
369                    return NodeValue::Empty;
370                }
371            };
372            index_list.push(index as usize);
373            index_no += 1;
374        }
375    }
376    {
377        // 変数を得る
378        var = match ctx.scopes.get_var_value_mut(&param_let.var_info) {
379            None => {
380                let msg = format!("初期化されていない配列変数『{}』に代入しようとしました。", name);
381                ctx.throw_runtime_error(msg, node.pos);
382                return NodeValue::Empty;
383            },
384            Some(v) => v,
385        };
386    }
387    {
388        for (i, index_p) in index_list.iter().enumerate() {
389            let index = *index_p;
390            // last?
391            if i == index_list.len() - 1 {
392                if !var.set_array_index(index as usize, let_value) {
393                    let msg = format!("配列変数『{}』の代入に失敗しました。", name);
394                    ctx.throw_runtime_error(msg, node.pos);
395                    return NodeValue::Empty;
396                }
397                return var.clone();
398            } else {
399                var = match var.get_array_index_mut(index) {
400                    Some(v) => v,
401                    None => {
402                        let msg = format!("配列変数『{}』の{}番目の要素が取得できませんでした。", name, i + 1);
403                        ctx.throw_runtime_error(msg, node.pos);
404                        return NodeValue::Empty;
405                    }
406                }
407            }
408        }
409    }
410    NodeValue::Empty
411}
412
413fn run_array_ref(ctx: &mut NodeContext, node: &Node) -> NodeValue {
414    let mut val: NodeValue = NodeValue::Empty;
415    match &node.value {
416        NodeValue::NodeList(nlist) => {
417            let mut nlist2 = nlist.clone();
418            // 変数を得る
419            let val_node = nlist2.remove(0);
420            let val_opt = run_node(ctx, &val_node);
421            match val_opt {
422                Some(v) => val = v,
423                None => {
424                    let msg = format!("配列参照のエラー");
425                    ctx.throw_runtime_error(msg, node.pos);
426                    return NodeValue::Empty
427                }
428            }
429            // println!("@@@array_ref.var={:?}", val);
430            // indexを得る
431            for index_node in nlist2.iter() {
432                // println!("for.nlist={:?}", index_node);
433                let index_val_opt = run_node(ctx, index_node);
434                match index_val_opt {
435                    Some(index_val) => {
436                        // todo: 配列の範囲エラーをチェックする
437                        // println!("@@@array_ref.index={:?}", index_val);
438                        val = val.get_array_index(index_val.to_int(0) as usize).unwrap_or(NodeValue::Empty);
439                        // println!("@@@array_ref.val={:?}", val);
440                    },
441                    None => {
442                        let msg = format!("配列参照のエラー");
443                        ctx.throw_runtime_error(msg, node.pos);
444                        return NodeValue::Empty
445                    }
446                }
447            }
448        },
449        _ => {}
450    }
451    val
452}
453
454// -----------------------------------------------
455// eval
456// -----------------------------------------------
457#[derive(Debug,Clone)]
458pub struct RunOption {
459    pub use_sysfunc: bool,
460    pub debug: bool,
461    pub return_print_log: bool,
462}
463impl RunOption {
464    pub fn normal() -> Self {
465        Self { use_sysfunc: true, debug: false, return_print_log: false }
466    }
467    pub fn simple() -> Self {
468        Self { use_sysfunc: false, debug: true, return_print_log: false }
469    }
470    pub fn print_log() -> Self {
471        Self { use_sysfunc: true, debug: false, return_print_log: true }
472    }
473}
474
475/// eval code
476pub fn eval(code: &str, options: RunOption) -> Result<NodeValue,String> {
477    // 意味解析器を初期化
478    let mut context = NodeContext::new();
479    context.set_filename("eval");
480    if options.use_sysfunc {
481        sys_function::register(&mut context);
482    } else {
483        sys_function_debug::register(&mut context);
484    }
485    // 字句解析
486    let tokens = tokenizer::tokenize_test(code);
487    // 意味解析
488    let mut parser = parser::Parser::new_context(tokens, context.clone());
489    let nodes = match parser.parse() {
490        Ok(nodes) => nodes,
491        Err(e) => { return Err(e); }
492    };
493    // 戻り値として「表示」文のログを返す場合
494    if options.return_print_log {
495        return match run_nodes(&mut context, &nodes) {
496            Ok(_) => Ok(NodeValue::S(String::from(context.print_log.trim_end()))),
497            Err(e) => Err(e)
498        };
499    }
500    run_nodes(&mut context, &nodes)
501}
502
503/// eval code with context (you can add functions, and set filename)
504pub fn eval_context(ctx: &mut NodeContext, code: &str) -> Result<NodeValue,String> {
505    // 字句解析
506    let tokens = tokenizer::tokenize_test(code);
507    // 意味解析
508    let mut parser = parser::Parser::new_context(tokens, ctx.clone());
509    let nodes = match parser.parse() {
510        Ok(nodes) => nodes,
511        Err(e) => { return Err(e); }
512    };
513    match run_nodes(ctx, &nodes) {
514        Ok(_) => Ok(NodeValue::S(String::from(ctx.print_log.trim_end()))),
515        Err(e) => Err(e)
516    }
517}
518
519pub fn eval_str(code: &str) -> String {
520    match eval(code, RunOption::normal()) {
521        Ok(v) => v.to_string(),
522        Err(e) => format!("!!{}", e),
523    }
524}
525pub fn eval_simple_str(code: &str) -> String {
526    match eval(code, RunOption::simple()) {
527        Ok(v) => v.to_string(),
528        Err(e) => format!("!!{}", e),
529    }
530}
531pub fn eval_print_str(code: &str) -> String {
532    match eval(code, RunOption::print_log()) {
533        Ok(v) => v.to_string(),
534        Err(e) => format!("!!{}", e),
535    }
536}
537
538pub fn indent_str(num: usize) -> String {
539    let mut s = String::new();
540    for _ in 0..num {
541        s.push_str("  ");
542    }
543    s
544}
545
546#[cfg(test)]
547mod test_runner {
548    use super::*;
549
550    #[test]
551    fn test_if() {
552        let res = eval_str("N=1;もしN=1ならば\n「OK」と表示;\n違えば\n「NG」と表示\nここまで;");
553        assert_eq!(res, "OK");
554    }
555    #[test]
556    fn test_print() {
557        let res = eval_str("123と表示");
558        assert_eq!(res, String::from("123"));
559        let res = eval_str("「穏やかな心は体に良い」と表示");
560        assert_eq!(res, String::from("穏やかな心は体に良い"));
561    }
562
563    #[test]
564    fn test_debug_print() {
565        let res = eval("123と表示", RunOption::simple());
566        assert_eq!(res.unwrap_or(NodeValue::Empty).to_int(0), 123);
567    }
568    #[test]
569    fn test_calc() {
570        let res = eval_str("1+2と表示");
571        assert_eq!(res, String::from("3"));
572        let res = eval_str("1+2*3と表示");
573        assert_eq!(res, String::from("7"));
574        let res = eval_str("(1+2)*3と表示");
575        assert_eq!(res, String::from("9"));
576    }
577    #[test]
578    fn test_calc_check_operator() {
579        let res = eval_str("1+2と表示");
580        assert_eq!(res, String::from("3"));
581        let res = eval_str("3*2と表示");
582        assert_eq!(res, String::from("6"));
583        let res = eval_str("3×2と表示");
584        assert_eq!(res, String::from("6"));
585        let res = eval_str("1÷2と表示");
586        assert_eq!(res, String::from("0.5"));
587        let res = eval_str("1/2と表示");
588        assert_eq!(res, String::from("0.5"));
589        let res = eval_str("2^3と表示");
590        assert_eq!(res, String::from("8"));
591        let res = eval_str("10%3と表示");
592        assert_eq!(res, String::from("1"));
593        let res = eval_str("10>3と表示");
594        assert_eq!(res, String::from("真"));
595        let res = eval_str("10<3と表示");
596        assert_eq!(res, String::from("偽"));
597        let res = eval_str("5>=5と表示");
598        assert_eq!(res, String::from("真"));
599        let res = eval_str("5<5と表示");
600        assert_eq!(res, String::from("偽"));
601        let res = eval_str("5<=5と表示");
602        assert_eq!(res, String::from("真"));
603        let res = eval_str("真&&真と表示");
604        assert_eq!(res, String::from("真"));
605        let res = eval_str("真 または 真と表示");
606        assert_eq!(res, String::from("真"));
607        let res = eval_str("真 かつ 偽と表示");
608        assert_eq!(res, String::from("偽"));
609        let res = eval_str("真||偽と表示");
610        assert_eq!(res, String::from("真"));
611        let res = eval_str("(1==1)&&(2==2)と表示");
612        assert_eq!(res, String::from("真"));
613        let res = eval_str("1+2*3と表示");
614        assert_eq!(res, String::from("7"));
615        let res = eval_str("1*2+3と表示");
616        assert_eq!(res, String::from("5"));
617        let res = eval_str("5%2+1と表示");
618        assert_eq!(res, String::from("2"));
619        let res = eval_str("5%2=1と表示");
620        assert_eq!(res, String::from("真"));
621    }
622    #[test]
623    fn test_string_ex() {
624        let res = eval_str("A=123;「A={A}」と表示");
625        assert_eq!(res, "A=123");
626    }
627
628    #[test]
629    fn test_let_eval() {
630        let res = eval_str("A=1に2を足す。Aを表示。");
631        assert_eq!(res, "3");
632        let res = eval_str("A=2に3を掛ける。Aを表示。");
633        assert_eq!(res, "6");
634    }
635
636    #[test]
637    fn test_calc_long() {
638        let res = eval_str("(5から3を引く)を表示。");
639        assert_eq!(res, "2");
640        let res = eval_str("5*2+2+3を表示。");
641        assert_eq!(res, "15");
642    }
643
644    #[test]
645    fn test_dainyu() {
646        let res = eval_str("10をAに代入。Aを表示。");
647        assert_eq!(res, "10");
648        let res = eval_str("5*3をAに代入。Aを表示。");
649        assert_eq!(res, "15");
650    }
651
652    #[test]
653    fn test_array() {
654        let res = eval_str("A=[0,1,2,3];A[2]を表示。");
655        assert_eq!(res, "2");
656        let res = eval_str("A=[10,20,30];A[0]=30;A[0]を表示。");
657        assert_eq!(res, "30");
658        let res = eval_str("A=[[0,1],[2,3]];A[0][1]を表示。");
659        assert_eq!(res, "1");
660    }
661
662    #[test]
663    fn test_renbun() {
664        let res = eval_str("1に2を足して3を足して表示。");
665        assert_eq!(res, "6");
666        let res = eval_print_str("2回,1に2を足して表示。");
667        assert_eq!(res, "3\n3");
668    }
669}