From 6f08cee6268d56f3a33f47f33879d0b4e4d729d6 Mon Sep 17 00:00:00 2001 From: chriseth Date: Sat, 25 Feb 2023 19:19:27 +0100 Subject: [PATCH] Support strings and tuples of expressions. --- src/analyzer/mod.rs | 2 ++ src/analyzer/pil_analyzer.rs | 4 ++++ src/asm_compiler/mod.rs | 6 ++++++ src/commit_evaluator/mod.rs | 2 ++ src/constant_evaluator/mod.rs | 2 ++ src/json_exporter/mod.rs | 2 ++ src/parser/ast.rs | 2 ++ src/parser/display.rs | 9 +++++++++ src/parser/powdr.lalrpop | 2 ++ 9 files changed, 31 insertions(+) diff --git a/src/analyzer/mod.rs b/src/analyzer/mod.rs index 2ef55bee9..aae74b024 100644 --- a/src/analyzer/mod.rs +++ b/src/analyzer/mod.rs @@ -150,6 +150,8 @@ pub enum Expression { LocalVariableReference(u64), PublicReference(String), Number(ConstantNumberType), + String(String), + Tuple(Vec), BinaryOperation(Box, BinaryOperator, Box), UnaryOperation(UnaryOperator, Box), /// Call to a non-macro function (like a constant polynomial) diff --git a/src/analyzer/pil_analyzer.rs b/src/analyzer/pil_analyzer.rs index de46e082e..e6e856b39 100644 --- a/src/analyzer/pil_analyzer.rs +++ b/src/analyzer/pil_analyzer.rs @@ -432,6 +432,8 @@ impl PILContext { } ast::Expression::PublicReference(name) => Expression::PublicReference(name.clone()), ast::Expression::Number(n) => Expression::Number(*n), + ast::Expression::String(value) => Expression::String(value.clone()), + ast::Expression::Tuple(items) => Expression::Tuple(self.process_expressions(items)), ast::Expression::BinaryOperation(left, op, right) => { if let Some(value) = self.evaluate_binary_operation(left, op, right) { Expression::Number(value) @@ -516,6 +518,8 @@ impl PILContext { ast::Expression::PolynomialReference(_) => None, ast::Expression::PublicReference(_) => None, ast::Expression::Number(n) => Some(*n), + ast::Expression::String(_) => None, + ast::Expression::Tuple(_) => None, ast::Expression::BinaryOperation(left, op, right) => { self.evaluate_binary_operation(left, op, right) } diff --git a/src/asm_compiler/mod.rs b/src/asm_compiler/mod.rs index 58a18a925..8f00687b9 100644 --- a/src/asm_compiler/mod.rs +++ b/src/asm_compiler/mod.rs @@ -239,6 +239,8 @@ impl ASMPILConverter { )] } Expression::Number(value) => vec![(*value, AffineExpressionComponent::Constant)], + Expression::String(_) => panic!(), + Expression::Tuple(_) => panic!(), Expression::FreeInput(expr) => { vec![(1, AffineExpressionComponent::FreeInput(*expr.clone()))] } @@ -560,9 +562,13 @@ fn substitute(input: &Expression, substitution: &HashMap) -> Exp name.clone(), args.iter().map(|e| substitute(e, substitution)).collect(), ), + Expression::Tuple(items) => { + Expression::Tuple(items.iter().map(|e| substitute(e, substitution)).collect()) + } Expression::Constant(_) | Expression::PublicReference(_) | Expression::Number(_) + | Expression::String(_) | Expression::FreeInput(_) => input.clone(), } } diff --git a/src/commit_evaluator/mod.rs b/src/commit_evaluator/mod.rs index 0fbf6be53..9231cdb2e 100644 --- a/src/commit_evaluator/mod.rs +++ b/src/commit_evaluator/mod.rs @@ -155,6 +155,8 @@ impl<'a> Evaluator<'a> { self.evaluate_binary_operation(left, op, right) } Expression::UnaryOperation(op, expr) => self.evaluate_unary_operation(op, expr), + Expression::Tuple(_) => panic!(), + Expression::String(_) => panic!(), Expression::LocalVariableReference(_) => panic!(), Expression::PublicReference(_) => panic!(), Expression::FunctionCall(_, _) => panic!(), diff --git a/src/constant_evaluator/mod.rs b/src/constant_evaluator/mod.rs index a963b14c4..e2c5b3c5f 100644 --- a/src/constant_evaluator/mod.rs +++ b/src/constant_evaluator/mod.rs @@ -80,6 +80,8 @@ impl<'a> Evaluator<'a> { Expression::LocalVariableReference(i) => self.variables[*i as usize], Expression::PublicReference(_) => todo!(), Expression::Number(n) => *n, + Expression::String(_) => panic!(), + Expression::Tuple(_) => panic!(), Expression::BinaryOperation(left, op, right) => { self.evaluate_binary_operation(left, op, right) } diff --git a/src/json_exporter/mod.rs b/src/json_exporter/mod.rs index 718568eaa..09fd15218 100644 --- a/src/json_exporter/mod.rs +++ b/src/json_exporter/mod.rs @@ -303,6 +303,8 @@ impl<'a> Exporter<'a> { Expression::FunctionCall(_, _) => { panic!("No function calls allowed here.") } + Expression::String(_) => panic!("Strings not allowed here."), + Expression::Tuple(_) => panic!("Tuples not allowed here"), } } diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 2e6b3360a..f7319328c 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -43,6 +43,8 @@ pub enum Expression { PolynomialReference(PolynomialReference), PublicReference(String), Number(ConstantNumberType), + String(String), + Tuple(Vec), BinaryOperation(Box, BinaryOperator, Box), UnaryOperation(UnaryOperator, Box), FunctionCall(String, Vec), diff --git a/src/parser/display.rs b/src/parser/display.rs index 2e566c556..5df6e0f3b 100644 --- a/src/parser/display.rs +++ b/src/parser/display.rs @@ -122,6 +122,8 @@ impl Display for Expression { Expression::PolynomialReference(reference) => write!(f, "{reference}"), Expression::PublicReference(name) => write!(f, "{name}"), Expression::Number(value) => write!(f, "{value}"), + Expression::String(value) => write!(f, "\"{value}\""), // TODO quote? + Expression::Tuple(items) => write!(f, "({})", format_expressions(items)), Expression::BinaryOperation(left, op, right) => write!(f, "({left} {op} {right})"), Expression::UnaryOperation(op, exp) => write!(f, "{op}{exp}"), Expression::FunctionCall(fun, args) => write!(f, "{fun}({})", format_expressions(args)), @@ -227,4 +229,11 @@ public out = y(%last_row);"#; let printed = format!("{}", parser::parse(Some("input"), input).unwrap()); assert_eq!(input.trim(), printed.trim()); } + + #[test] + fn reparse_strings_and_tuples() { + let input = r#"constant %N = ("abc", 3);"#; + let printed = format!("{}", parser::parse(Some("input"), input).unwrap()); + assert_eq!(input.trim(), printed.trim()); + } } diff --git a/src/parser/powdr.lalrpop b/src/parser/powdr.lalrpop index 8fcd88ab7..0608a375a 100644 --- a/src/parser/powdr.lalrpop +++ b/src/parser/powdr.lalrpop @@ -290,6 +290,8 @@ Term: Box = { PolynomialReference => Box::new(Expression::PolynomialReference(<>)), PublicReference => Box::new(Expression::PublicReference(<>)), Number => Box::new(Expression::Number(<>)), + StringLiteral => Box::new(Expression::String(<>)), + "(" "," ")" => { let mut list = vec![head]; list.extend(tail); Box::new(Expression::Tuple(list)) }, "(" ")", "${" "}" => Box::new(Expression::FreeInput(<>)) }