From d29110cd66e9b6535f990b60b44cbbb1d4ae77b6 Mon Sep 17 00:00:00 2001 From: Gil Ben-Shachar Date: Sun, 25 Jun 2023 16:39:11 +0300 Subject: [PATCH] Add array! macro. --- .../src/plugins/inline_macro_plugin.rs | 2 + .../src/plugins/inline_macros/array.rs | 41 ++++++++++++++++ .../src/plugins/inline_macros/mod.rs | 1 + .../src/test_data/inline_macros | 47 +++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 crates/cairo-lang-plugins/src/plugins/inline_macros/array.rs diff --git a/crates/cairo-lang-plugins/src/plugins/inline_macro_plugin.rs b/crates/cairo-lang-plugins/src/plugins/inline_macro_plugin.rs index cd7f124ba3f..ff5c75c6b52 100644 --- a/crates/cairo-lang-plugins/src/plugins/inline_macro_plugin.rs +++ b/crates/cairo-lang-plugins/src/plugins/inline_macro_plugin.rs @@ -9,6 +9,7 @@ use cairo_lang_syntax::node::db::SyntaxGroup; use cairo_lang_syntax::node::kind::SyntaxKind; use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode}; +use super::inline_macros::array::ArrayMacro; use super::inline_macros::consteval_int::ConstevalIntMacro; /// The result of expanding an inline macro. @@ -39,6 +40,7 @@ pub trait InlineMacro { /// Returns the inline macro plugin for the given macro name, or None if no such plugin exists. fn get_inline_macro_plugin(macro_name: &str) -> Option> { match macro_name { + "array" => Some(Box::new(ArrayMacro)), "consteval_int" => Some(Box::new(ConstevalIntMacro)), _ => None, } diff --git a/crates/cairo-lang-plugins/src/plugins/inline_macros/array.rs b/crates/cairo-lang-plugins/src/plugins/inline_macros/array.rs new file mode 100644 index 00000000000..07bf962c6ae --- /dev/null +++ b/crates/cairo-lang-plugins/src/plugins/inline_macros/array.rs @@ -0,0 +1,41 @@ +use cairo_lang_syntax::node::TypedSyntaxNode; + +use crate::plugins::InlineMacro; + +pub struct ArrayMacro; +impl InlineMacro for ArrayMacro { + fn append_macro_code( + &self, + macro_expander_data: &mut crate::plugins::InlineMacroExpanderData, + db: &dyn cairo_lang_syntax::node::db::SyntaxGroup, + macro_arguments: &cairo_lang_syntax::node::ast::ExprList, + ) { + let args = macro_arguments.elements(db); + let mut expanded_code = "{ + let mut __array_builder_macro_result__ = ArrayTrait::new();" + .to_string(); + for arg in args { + expanded_code.push_str(&format!( + "\n __array_builder_macro_result__.append({});", + arg.as_syntax_node().get_text(db) + )); + } + expanded_code.push_str( + "\n __array_builder_macro_result__ + }", + ); + macro_expander_data.result_code.push_str(&expanded_code); + macro_expander_data.code_changed = true; + } + + fn is_bracket_type_allowed( + &self, + db: &dyn cairo_lang_syntax::node::db::SyntaxGroup, + macro_ast: &cairo_lang_syntax::node::ast::ExprInlineMacro, + ) -> bool { + matches!( + macro_ast.arguments(db), + cairo_lang_syntax::node::ast::WrappedExprList::BracketedExprList(_) + ) + } +} diff --git a/crates/cairo-lang-plugins/src/plugins/inline_macros/mod.rs b/crates/cairo-lang-plugins/src/plugins/inline_macros/mod.rs index 1ee3a38b44d..852db443cc0 100644 --- a/crates/cairo-lang-plugins/src/plugins/inline_macros/mod.rs +++ b/crates/cairo-lang-plugins/src/plugins/inline_macros/mod.rs @@ -1 +1,2 @@ +pub mod array; pub mod consteval_int; diff --git a/crates/cairo-lang-plugins/src/test_data/inline_macros b/crates/cairo-lang-plugins/src/test_data/inline_macros index 3f6ba1241f2..c9668001459 100644 --- a/crates/cairo-lang-plugins/src/test_data/inline_macros +++ b/crates/cairo-lang-plugins/src/test_data/inline_macros @@ -178,3 +178,50 @@ error: Unknown inline macro: foo --> dummy_file.cairo:2:13 let x = foo!(0); ^*****^ + +//! > ========================================================================== + +//! > Test array macro + +//! > test_runner_name +test_expand_plugin + +//! > cairo_code +fn foo() { + let arr = array![1,2,3]; +} + +//! > generated_cairo_code +fn foo() { + let arr = { + let mut __array_builder_macro_result__ = ArrayTrait::new(); + __array_builder_macro_result__.append(1); + __array_builder_macro_result__.append(2); + __array_builder_macro_result__.append(3); + __array_builder_macro_result__ + }; +} + +//! > expected_diagnostics + +//! > ========================================================================== + +//! > Test array macro empty + +//! > test_runner_name +test_expand_plugin + +//! > cairo_code +fn foo() { + let arr = array![]; +} + +//! > generated_cairo_code +fn foo() { + let arr = { + let mut __array_builder_macro_result__ = ArrayTrait::new(); + __array_builder_macro_result__ + }; +} + +//! > expected_diagnostics