Skip to content

Commit

Permalink
Cairo plugin as a shared library
Browse files Browse the repository at this point in the history
  • Loading branch information
piwonskp committed Sep 23, 2024
1 parent 55e5f21 commit 6b8a6e5
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 489 deletions.
34 changes: 11 additions & 23 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
[package]
name = "hello-cairo-plugin"
version = "0.0.0"
name = "hello_plugin"
version = "1.0.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1.0.75"
cairo-lang-compiler = "2.4.1"
cairo-lang-defs = "2.4.1"
cairo-lang-runner = "2.4.1"
cairo-lang-semantic = "2.4.1"
cairo-lang-sierra = "2.4.1"
cairo-lang-starknet = "2.4.1"
cairo-lang-syntax = "2.4.1"
cairo-lang-utils = "2.4.1"
camino = "1.1.6"
clap = "4.4.8"
indoc = "2.0.4"
scarb = { git = "https://github.com/software-mansion/scarb", tag = "v2.4.1", version = "2.4.1" }
scarb-metadata = "1.8.0"
scarb-ui = "0.1.0"
semver = "1.0.20"
serde = "1.0.193"
serde_json = "1.0.108"
smol_str = "0.2.0"
tracing = "0.1.40"
url = "2.5.0"
cairo-lang-macro = "0.1.0"
cairo-lang-defs = "2.8.2"
cairo-lang-diagnostics = "2.8.2"
cairo-lang-parser = "2.8.2"
cairo-lang-syntax = "2.8.2"
regex = "1.10.6"
4 changes: 2 additions & 2 deletions Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "hello"
version = "0.0.0"
name = "hello_plugin"
version = "1.0.0"

[cairo-plugin]
6 changes: 3 additions & 3 deletions examples/cairo/Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ version = 1
name = "examples"
version = "0.1.0"
dependencies = [
"hello",
"hello_plugin",
]

[[package]]
name = "hello"
version = "0.0.0"
name = "hello_plugin"
version = "1.0.0"
5 changes: 1 addition & 4 deletions examples/cairo/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@ sierra = true

[dependencies]
## Referencing using local package:
hello = { path = "../../" }
hello_plugin = { path = "../../" }

## Referencing using git:
# hello = { git = "https://github.com/piwonskp/hello-cairo-plugin", crate = "hello" }

## Referencing compiled as part of this project:
## As for scarb 2.4.0 this is still an unsupported feature
# hello = ">=0.1.0"


[[target.hello]]
98 changes: 0 additions & 98 deletions src/boilerplate/compiler.rs

This file was deleted.

2 changes: 0 additions & 2 deletions src/boilerplate/mod.rs

This file was deleted.

110 changes: 0 additions & 110 deletions src/boilerplate/plugin_repository.rs

This file was deleted.

77 changes: 77 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use cairo_lang_macro::{
attribute_macro, Diagnostic, Diagnostics, ProcMacroResult, TokenStream,
};
use cairo_lang_diagnostics::FormattedDiagnosticEntry;
use cairo_lang_parser::utils::SimpleParserDatabase;
use cairo_lang_syntax::node::ast::{ModuleItem, SyntaxFile};
use cairo_lang_syntax::node::TypedSyntaxNode;
use core::ops::Deref;
use regex::Regex;


fn parser_to_macro_diagnostic(entry: &FormattedDiagnosticEntry) -> Diagnostic {
let severity = match entry.severity() {
cairo_lang_diagnostics::Severity::Error => cairo_lang_macro::Severity::Error,
cairo_lang_diagnostics::Severity::Warning => cairo_lang_macro::Severity::Warning,
};
Diagnostic {
message: entry.message().to_string(),
severity: severity,
}
}

/// Insert hello at the begining of the function using fully fledged cairo parser
#[attribute_macro]
pub fn hello(_attrs: TokenStream, token_stream: TokenStream) -> ProcMacroResult {
let db = SimpleParserDatabase::default();

let (parsed_node, parser_diagnostics) = db.parse_virtual_with_diagnostics(token_stream);
let formatted_diags = parser_diagnostics.format_with_severity(&db);
let diagnostics = formatted_diags.iter().map(parser_to_macro_diagnostic);

let module_items = SyntaxFile::from_syntax_node(&db, parsed_node)
.items(&db)
.deref()
.elements(&db);
let function = match module_items.as_slice() {
[ModuleItem::FreeFunction(fun)] => fun,
// Currently attribute macros are run only on functions so the code should never reach this place
_ => panic!("hello attribute may be set on functions only"),
};

let instrumented_function = format!(
"
{} {{
core::debug::print_felt252('Hello from ast, {}!');
{}
}}
",
function.declaration(&db).as_syntax_node().get_text(&db),
function
.declaration(&db)
.name(&db)
.as_syntax_node()
.get_text(&db),
function.body(&db).as_syntax_node().get_text(&db)
);

ProcMacroResult::new(TokenStream::new(instrumented_function))
.with_diagnostics(Diagnostics::new(diagnostics.collect()))
}


/// A lightweight version of hello macro using regex
#[attribute_macro]
pub fn hello_regex(_attrs: TokenStream, token_stream: TokenStream) -> ProcMacroResult {
let fn_regex =
Regex::new(r"^(\s*fn\s+(?<function_name>\w+)\s*\(.*?\)\s*(->\s*.*)?\{)").unwrap();
let function = token_stream.to_string();
let instrumented = fn_regex.replace_all(&function, |caps: &regex::Captures| {
format!(
"{}\n\tcore::debug::print_felt252('Hello {}!');",
&caps[0], &caps["function_name"]
)
});

ProcMacroResult::new(TokenStream::new(instrumented.to_string()))
}
Loading

0 comments on commit 6b8a6e5

Please sign in to comment.