1use 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 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 if ctx.try_break != None {
101 ctx.try_break = None;
102 break;
103 }
104 if ctx.try_continue != None {
106 ctx.try_continue = None;
107 continue;
108 }
109 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 if ctx.try_break != None {
128 ctx.try_break = None;
129 break;
130 }
131 if ctx.try_continue != None {
133 ctx.try_continue = None;
134 continue;
135 }
136 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 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 let info = NodeVarInfo { level: 1, no: func_no, name: func_name.clone() };
201 let func_value = match ctx.scopes.get_var_value(&info) { Some(v) => v,
205 None => return NodeValue::Empty,
206 };
207 let meta = match ctx.scopes.get_var_meta(&info) { Some(v) => v,
210 None => return NodeValue::Empty,
211 };
212 let func_args: &Vec<SysArg> = match &meta.kind {
215 NodeVarKind::UserFunc(args) => args,
216 _ => return NodeValue::Empty,
217 };
218 let mut scope = NodeScope::new();
221 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 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 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 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 name = &info.name;
275 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 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), '|' => NodeValue::calc_or(&left, &right), '&' => NodeValue::calc_and(&left, &right), '-' => 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 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 let value_node = ¶m_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 let mut index_no = 0;
362 let index_vec: &Vec<Node> = ¶m_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 var = match ctx.scopes.get_var_value_mut(¶m_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 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 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 for index_node in nlist2.iter() {
432 let index_val_opt = run_node(ctx, index_node);
434 match index_val_opt {
435 Some(index_val) => {
436 val = val.get_array_index(index_val.to_int(0) as usize).unwrap_or(NodeValue::Empty);
439 },
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#[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
475pub fn eval(code: &str, options: RunOption) -> Result<NodeValue,String> {
477 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 let tokens = tokenizer::tokenize_test(code);
487 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 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
503pub fn eval_context(ctx: &mut NodeContext, code: &str) -> Result<NodeValue,String> {
505 let tokens = tokenizer::tokenize_test(code);
507 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}