From 007fdc2ed598fdbdc615fd7cd73caeccb0cba2d2 Mon Sep 17 00:00:00 2001 From: linsy king Date: Thu, 6 Apr 2023 13:50:11 +0800 Subject: [PATCH] feat: - add hd and tl - add if for better efficency --- examples/syn.meow | 30 +++++++++++++++++++--- src/cat.rs | 63 +++++++++++++++++++++++++++++++++++++++++++---- src/expr.lalrpop | 2 +- src/parse.lalrpop | 2 +- 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/examples/syn.meow b/examples/syn.meow index a644e63..392c6a3 100644 --- a/examples/syn.meow +++ b/examples/syn.meow @@ -1,6 +1,6 @@ -true() {"T"} +T() {"T"} -false() {"F"} +F() {"F"} 0() {"0"} @@ -116,7 +116,15 @@ in(x,y) { } not(x) { - if(x, false(), true()) + if(x, F(), T()) +} + +or(x,y) { + if(x,T(), y) +} + +and(x,y) { + if(x,y,F()) } eq0(x) { @@ -261,3 +269,19 @@ fib(x) { ) ) } + +tl(x) { + var en = { + "#$" + enraw(hd(x)) = "#$"; + encode(x) + }; + decode(en) +} + +wd(x) { + if( + or(eq(x, ""), eq(hd(x)," ")), + "", + hd(x) + wd(tl(x)) + ) +} diff --git a/src/cat.rs b/src/cat.rs index b2bb271..b5480da 100644 --- a/src/cat.rs +++ b/src/cat.rs @@ -42,6 +42,27 @@ impl Context { body: Vec::new(), }), ), + ( + "hd".to_string(), + Symbol::Macro(Macro { + args: vec!["x".to_string()], + body: Vec::new(), + }), + ), + ( + "tl".to_string(), + Symbol::Macro(Macro { + args: vec!["x".to_string()], + body: Vec::new(), + }), + ), + ( + "if".to_string(), + Symbol::Macro(Macro { + args: vec!["x".to_string(), "x".to_string(), "x".to_string()], + body: Vec::new(), + }), + ), ]), rules: Vec::new(), } @@ -61,8 +82,8 @@ fn eval_macap(mac: &Macro, args: &Vec>, context: &Box) -> Stri fn clear_context(context: &Context) -> Context { // clear the context - let mut newcontext = Context::new(); - newcontext.symbols = context + let mut newcontext = context.clone(); + newcontext.symbols = newcontext .symbols .iter() .filter(|(_, v)| match v { @@ -71,13 +92,14 @@ fn clear_context(context: &Context) -> Context { }) .map(|(k, v)| (k.clone(), v.clone())) .collect(); + newcontext.rules.clear(); newcontext } fn clear_rules(context: &Context) -> Context { // clear the context - let mut newcontext = Context::new(); - newcontext.symbols = context.symbols.clone(); + let mut newcontext = context.clone(); + newcontext.rules.clear(); newcontext } @@ -98,7 +120,7 @@ fn apply_rule(x: &String, rules: &Vec, context: &mut Box) -> Stri fn eval_strict(expr: &mut Vec, context: &mut Box) -> String { // Take one argument from the expression - // println!("eval strict: {:?}", expr); + // println!("[strict] {:?}", expr); let first = eat_one_para(expr); match &first { Tok::Literal(lit) => lit.clone(), @@ -124,6 +146,37 @@ fn eval_strict(expr: &mut Vec, context: &mut Box) -> String { let y = eval_strict(expr, cleancontext); x + y.as_str() } + "hd" => { + // Head of a string + let cleancontext = &mut Box::new(clear_rules(context)); + let x = eval_strict(expr, cleancontext); + if x.is_empty() { + String::new() + } else { + x.chars().next().unwrap().to_string() + } + } + "tl" => { + // Tail of a string + let cleancontext = &mut Box::new(clear_rules(context)); + let x = eval_strict(expr, cleancontext); + if x.is_empty() { + String::new() + } else { + x.chars().skip(1).collect() + } + } + "if" => { + let cleancontext = &mut Box::new(clear_rules(context)); + let x = eval_strict(expr, cleancontext); + let y = &mut eval_lazy(expr, cleancontext); + let z = &mut eval_lazy(expr, cleancontext); + if &x == "T" { + eval_strict(y, cleancontext) + } else { + eval_strict(z, cleancontext) + } + } _ => { let sym = context .symbols diff --git a/src/expr.lalrpop b/src/expr.lalrpop index 3e8842a..c94b092 100644 --- a/src/expr.lalrpop +++ b/src/expr.lalrpop @@ -12,7 +12,7 @@ Tokz: Tok = { } VarName: String = { - r"[a-z0-9_]*" => String::from_str(<>).unwrap(), + r"[a-zA-Z0-9_]*" => String::from_str(<>).unwrap(), } Literal: String = { diff --git a/src/parse.lalrpop b/src/parse.lalrpop index 124ec72..df6aa98 100644 --- a/src/parse.lalrpop +++ b/src/parse.lalrpop @@ -61,7 +61,7 @@ VarDef: (String, String) = { } VarName: String = { - r"[a-z0-9_]*" => String::from_str(<>).unwrap() + r"[a-zA-Z0-9_]*" => String::from_str(<>).unwrap() } Literal: String = {