From 30ab0cf7daa0267821f0e1a2d08099e3e7c58f6c Mon Sep 17 00:00:00 2001 From: Erin Date: Sat, 22 Jan 2022 20:37:44 +0100 Subject: [PATCH 1/4] Implemented Len in parser --- ablescript/src/ast.rs | 1 + ablescript/src/interpret.rs | 1 + ablescript/src/parser.rs | 26 ++++++++++++++++++++++---- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ablescript/src/ast.rs b/ablescript/src/ast.rs index a5f1905..3a7941e 100644 --- a/ablescript/src/ast.rs +++ b/ablescript/src/ast.rs @@ -190,6 +190,7 @@ pub enum ExprKind { expr: Box, index: Box, }, + Len(Box), Variable(String), } diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 183eb9f..044e9e3 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -175,6 +175,7 @@ impl ExecEnv { .map(|x| x.borrow().clone()) .unwrap_or(Value::Nul) } + Len(_) => todo!("length"), // TODO: not too happy with constructing an artificial // Ident here. diff --git a/ablescript/src/parser.rs b/ablescript/src/parser.rs index 6f7ebb6..9fd351e 100644 --- a/ablescript/src/parser.rs +++ b/ablescript/src/parser.rs @@ -195,10 +195,7 @@ impl<'source> Parser<'source> { Token::LeftBracket => match buf.take() { Some(buf) => Ok(Expr::new( - ExprKind::Index { - expr: Box::new(buf), - index: Box::new(self.expr_flow(Token::RightBracket)?), - }, + self.index_flow(buf)?, start..self.lexer.span().end, )), None => Ok(Expr::new(self.cart_flow()?, start..self.lexer.span().end)), @@ -279,6 +276,27 @@ impl<'source> Parser<'source> { Ok(ExprKind::Cart(cart)) } + /// Flow for indexing operations + /// + /// Indexing with empty index resolves to length of expression, else it indexes + fn index_flow(&mut self, expr: Expr) -> Result { + let mut buf = None; + Ok(loop { + match self.checked_next()? { + Token::RightBracket => match buf { + Some(index) => { + break ExprKind::Index { + expr: Box::new(expr), + index: Box::new(index), + } + } + None => break ExprKind::Len(Box::new(expr)), + }, + token => buf = Some(self.parse_expr(token, &mut buf)?), + } + }) + } + /// Flow for operators /// /// Generates operation from LHS buffer and next expression as RHS From 3f29fb09cdc4649774a4f6cc24a9e6b65ae45be4 Mon Sep 17 00:00:00 2001 From: Erin Date: Sat, 22 Jan 2022 20:48:21 +0100 Subject: [PATCH 2/4] Implemented [] as length operator --- ablescript/src/interpret.rs | 2 +- ablescript/src/variables.rs | 77 ++++++++++++++++++++++++------------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 044e9e3..bb79d33 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -175,7 +175,7 @@ impl ExecEnv { .map(|x| x.borrow().clone()) .unwrap_or(Value::Nul) } - Len(_) => todo!("length"), + Len(expr) => Value::Int(self.eval_expr(expr)?.len()), // TODO: not too happy with constructing an artificial // Ident here. diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 5d42a19..9b85c18 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -122,36 +122,10 @@ impl Value { match self { Value::Abool(a) => a as _, Value::Bool(b) => b as _, - Value::Functio(func) => match func { - // Compares lengths of functions: - // BfFunctio - Sum of lengths of instructions and length of tape - // AbleFunctio - Sum of argument count and body length - // Eval - Length of input code - Functio::Bf { - instructions, - tape_len, - } => (instructions.len() + tape_len) as _, - Functio::Able { params, body } => (params.len() + format!("{:?}", body).len()) as _, - Functio::Chain { functios, kind } => { - let (lhs, rhs) = *functios; - match kind { - FunctioChainKind::Equal => { - Value::Int(Value::Functio(lhs).into_i32()) - + Value::Int(Value::Functio(rhs).into_i32()) - } - FunctioChainKind::ByArity => { - Value::Int(Value::Functio(lhs).into_i32()) - * Value::Int(Value::Functio(rhs).into_i32()) - } - } - .into_i32() - } - Functio::Eval(s) => s.len() as _, - }, Value::Int(i) => i, Value::Nul => consts::ANSWER, Value::Str(text) => text.parse().unwrap_or(consts::ANSWER), - Value::Cart(c) => c.len() as _, + _ => self.len() as _, } } @@ -410,6 +384,55 @@ impl Value { Value::Cart(c) => c, } } + + /// Get a lenght of a value + pub fn len(&self) -> i32 { + match self { + Value::Nul => 0, + Value::Str(s) => s.len() as _, + Value::Int(i) => i.count_zeros() as _, + Value::Bool(b) if *b => -2, + Value::Bool(_) => 2, + Value::Abool(a) => match a { + Abool::Never => -3, + Abool::Sometimes => { + if rand::thread_rng().gen() { + 3 + } else { + -3 + } + } + Abool::Always => 3, + }, + Value::Functio(f) => match f { + // Compares lengths of functions: + // BfFunctio - Sum of lengths of instructions and length of tape + // AbleFunctio - Sum of argument count and body length + // Eval - Length of input code + Functio::Bf { + instructions, + tape_len, + } => (instructions.len() + tape_len) as _, + Functio::Able { params, body } => (params.len() + format!("{:?}", body).len()) as _, + Functio::Chain { functios, kind } => { + let (lhs, rhs) = *functios.clone(); + match kind { + FunctioChainKind::Equal => { + Value::Int(Value::Functio(lhs).into_i32()) + + Value::Int(Value::Functio(rhs).into_i32()) + } + FunctioChainKind::ByArity => { + Value::Int(Value::Functio(lhs).into_i32()) + * Value::Int(Value::Functio(rhs).into_i32()) + } + } + .into_i32() + } + Functio::Eval(s) => s.len() as _, + }, + Value::Cart(c) => c.len() as _, + } + } } impl ops::Add for Value { From a3a9b777adbc53df00cef4be5468282bfac099a3 Mon Sep 17 00:00:00 2001 From: Erin Date: Sat, 22 Jan 2022 20:52:09 +0100 Subject: [PATCH 3/4] Cart -> Int more cursed --- ablescript/src/variables.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 9b85c18..96d89d2 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -122,10 +122,14 @@ impl Value { match self { Value::Abool(a) => a as _, Value::Bool(b) => b as _, + Value::Functio(_) => self.len(), Value::Int(i) => i, Value::Nul => consts::ANSWER, Value::Str(text) => text.parse().unwrap_or(consts::ANSWER), - _ => self.len() as _, + Value::Cart(c) => c + .into_iter() + .map(|(i, v)| i.into_i32() * v.borrow().clone().into_i32()) + .sum(), } } From 6f5b96b26b97e80e083ab8ce36444549b67e8ec1 Mon Sep 17 00:00:00 2001 From: Erin Date: Sat, 22 Jan 2022 21:02:10 +0100 Subject: [PATCH 4/4] Functio -> Int more cursed --- ablescript/src/variables.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 96d89d2..545f2d4 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -122,7 +122,29 @@ impl Value { match self { Value::Abool(a) => a as _, Value::Bool(b) => b as _, - Value::Functio(_) => self.len(), + Value::Functio(f) => match f { + Functio::Bf { + instructions, + tape_len, + } => instructions.into_iter().map(|x| x as i32).sum::() * tape_len as i32, + Functio::Able { params, body } => { + params + .into_iter() + .map(|x| x.bytes().map(|x| x as i32).sum::()) + .sum::() + + body.len() as i32 + } + Functio::Chain { functios, kind } => { + let (lf, rf) = *functios; + Value::Functio(lf).into_i32() + + Value::Functio(rf).into_i32() + * match kind { + FunctioChainKind::Equal => -1, + FunctioChainKind::ByArity => 1, + } + } + Functio::Eval(code) => code.bytes().map(|x| x as i32).sum(), + }, Value::Int(i) => i, Value::Nul => consts::ANSWER, Value::Str(text) => text.parse().unwrap_or(consts::ANSWER),