From 47bfd2e09687588c51cc437f705de09af5cb3c99 Mon Sep 17 00:00:00 2001 From: howardwu Date: Tue, 28 Jul 2020 21:18:43 -0700 Subject: [PATCH 1/5] Adds serialization of Leo AST for unit testing and rformal verification --- .cargo/config | 3 ++ Cargo.lock | 2 ++ ast/Cargo.toml | 2 ++ ast/src/access/access.rs | 3 +- ast/src/access/array_access.rs | 6 ++-- ast/src/access/assignee_access.rs | 3 +- ast/src/access/call_access.rs | 6 ++-- ast/src/access/member_access.rs | 6 ++-- ast/src/access/static_member_access.rs | 6 ++-- ast/src/circuits/circuit.rs | 6 ++-- ast/src/circuits/circuit_field.rs | 6 ++-- ast/src/circuits/circuit_field_definition.rs | 6 ++-- ast/src/circuits/circuit_function.rs | 6 ++-- ast/src/circuits/circuit_member.rs | 3 +- ast/src/common/assignee.rs | 6 ++-- ast/src/common/declare.rs | 7 ++-- ast/src/common/eoi.rs | 3 +- ast/src/common/identifier.rs | 9 +++-- ast/src/common/line_end.rs | 3 +- ast/src/common/mutable.rs | 3 +- ast/src/common/range.rs | 6 ++-- ast/src/common/range_or_expression.rs | 3 +- ast/src/common/return_.rs | 3 +- ast/src/common/return_tuple.rs | 6 ++-- ast/src/common/spread.rs | 6 ++-- ast/src/common/spread_or_expression.rs | 3 +- ast/src/common/static_.rs | 3 +- ast/src/common/variable.rs | 5 ++- ast/src/errors/parser.rs | 9 +++++ .../array_initializer_expression.rs | 6 ++-- .../expressions/array_inline_expression.rs | 6 ++-- ast/src/expressions/binary_expression.rs | 6 ++-- .../expressions/circuit_inline_expression.rs | 6 ++-- ast/src/expressions/expression.rs | 3 +- ast/src/expressions/not_expression.rs | 6 ++-- ast/src/expressions/postfix_expression.rs | 6 ++-- ast/src/expressions/ternary_expression.rs | 6 ++-- ast/src/files/file.rs | 5 ++- ast/src/functions/function.rs | 6 ++-- ast/src/functions/function_input.rs | 5 ++- ast/src/functions/test_function.rs | 6 ++-- ast/src/imports/import.rs | 6 ++-- ast/src/imports/import_symbol.rs | 6 ++-- ast/src/imports/package.rs | 6 ++-- ast/src/imports/package_access.rs | 3 +- ast/src/imports/star.rs | 6 ++-- ast/src/lib.rs | 20 +++++++++-- ast/src/macros/assert_eq.rs | 6 ++-- ast/src/macros/debug.rs | 6 ++-- ast/src/macros/error.rs | 6 ++-- ast/src/macros/formatted_container.rs | 6 ++-- ast/src/macros/formatted_macro.rs | 5 ++- ast/src/macros/formatted_parameter.rs | 6 ++-- ast/src/macros/formatted_string.rs | 5 ++- ast/src/macros/macro_name.rs | 3 +- ast/src/macros/macro_symbol.rs | 3 +- ast/src/macros/print.rs | 6 ++-- ast/src/operations/assign_operation.rs | 15 +++++---- ast/src/operations/binary_operation.rs | 3 +- ast/src/operations/not_operation.rs | 6 ++-- ast/src/span.rs | 33 +++++++++++++++++++ ast/src/statements/assign_statement.rs | 5 ++- .../conditional_nested_or_end_statement.rs | 3 +- ast/src/statements/conditional_statement.rs | 5 ++- ast/src/statements/definition_statement.rs | 5 ++- ast/src/statements/expression_statement.rs | 6 ++-- ast/src/statements/for_statement.rs | 6 ++-- ast/src/statements/macro_statement.rs | 3 +- .../multiple_assignment_statement.rs | 5 ++- ast/src/statements/return_statement.rs | 6 ++-- ast/src/statements/statement.rs | 3 +- ast/src/types/address_type.rs | 3 +- ast/src/types/array_type.rs | 6 ++-- ast/src/types/boolean_type.rs | 3 +- ast/src/types/circuit_type.rs | 6 ++-- ast/src/types/data_type.rs | 3 +- ast/src/types/field_type.rs | 3 +- ast/src/types/group_type.rs | 3 +- ast/src/types/integer_type.rs | 23 ++++++------- ast/src/types/self_type.rs | 3 +- ast/src/types/type_.rs | 3 +- ast/src/values/address.rs | 9 +++-- ast/src/values/address_value.rs | 6 ++-- ast/src/values/boolean_value.rs | 9 +++-- ast/src/values/field_value.rs | 6 ++-- ast/src/values/group_value.rs | 11 ++++--- ast/src/values/integer_value.rs | 6 ++-- ast/src/values/number_implicit_value.rs | 6 ++-- ast/src/values/number_value.rs | 9 +++-- ast/src/values/value.rs | 3 +- examples/foo/.gitignore | 1 + examples/foo/Leo.toml | 3 ++ examples/foo/inputs/foo.in | 4 +++ examples/foo/src/main.leo | 5 +++ examples/pedersen_hash/.theia/launch.json | 6 ++++ examples/test/.gitignore | 1 + examples/test/Leo.toml | 3 ++ examples/test/inputs/test.in | 4 +++ examples/test/src/main.leo | 5 +++ 99 files changed, 409 insertions(+), 153 deletions(-) create mode 100644 ast/src/span.rs create mode 100644 examples/foo/.gitignore create mode 100644 examples/foo/Leo.toml create mode 100644 examples/foo/inputs/foo.in create mode 100644 examples/foo/src/main.leo create mode 100644 examples/pedersen_hash/.theia/launch.json create mode 100644 examples/test/.gitignore create mode 100644 examples/test/Leo.toml create mode 100644 examples/test/inputs/test.in create mode 100644 examples/test/src/main.leo diff --git a/.cargo/config b/.cargo/config index ddff4407b9..61254264ce 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,2 +1,5 @@ [build] rustflags = ["-C", "target-cpu=native"] + +[net] +git-fetch-with-cli = true \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index da08621ef7..2594df9775 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -570,6 +570,8 @@ dependencies = [ "pest", "pest-ast", "pest_derive", + "serde", + "serde_json", "thiserror", ] diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 6e243e49d0..8a1eea319d 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -11,4 +11,6 @@ log = { version = "0.4" } pest = { version = "2.0" } pest-ast = { version = "0.3.3" } pest_derive = { version = "2.0" } +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0" } thiserror = { version = "1.0" } diff --git a/ast/src/access/access.rs b/ast/src/access/access.rs index bc4e6404be..77e95a0603 100644 --- a/ast/src/access/access.rs +++ b/ast/src/access/access.rs @@ -1,8 +1,9 @@ use crate::{access::*, ast::Rule}; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::access))] pub enum Access<'ast> { Array(ArrayAccess<'ast>), diff --git a/ast/src/access/array_access.rs b/ast/src/access/array_access.rs index dc459ec1d3..87553d6a71 100644 --- a/ast/src/access/array_access.rs +++ b/ast/src/access/array_access.rs @@ -1,12 +1,14 @@ -use crate::{ast::Rule, common::RangeOrExpression}; +use crate::{ast::Rule, common::RangeOrExpression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::access_array))] pub struct ArrayAccess<'ast> { pub expression: RangeOrExpression<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/access/assignee_access.rs b/ast/src/access/assignee_access.rs index 7a067c574b..6ae0b7f305 100644 --- a/ast/src/access/assignee_access.rs +++ b/ast/src/access/assignee_access.rs @@ -4,9 +4,10 @@ use crate::{ }; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::access_assignee))] pub enum AssigneeAccess<'ast> { Array(ArrayAccess<'ast>), diff --git a/ast/src/access/call_access.rs b/ast/src/access/call_access.rs index c8849e7bf7..ba32a3d28c 100644 --- a/ast/src/access/call_access.rs +++ b/ast/src/access/call_access.rs @@ -1,12 +1,14 @@ -use crate::{ast::Rule, expressions::Expression}; +use crate::{ast::Rule, expressions::Expression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::access_call))] pub struct CallAccess<'ast> { pub expressions: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/access/member_access.rs b/ast/src/access/member_access.rs index f3f1bfe5d6..83cd90d767 100644 --- a/ast/src/access/member_access.rs +++ b/ast/src/access/member_access.rs @@ -1,12 +1,14 @@ -use crate::{ast::Rule, common::Identifier}; +use crate::{ast::Rule, common::Identifier, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::access_member))] pub struct MemberAccess<'ast> { pub identifier: Identifier<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/access/static_member_access.rs b/ast/src/access/static_member_access.rs index 71e3ef3c21..63c1712bf0 100644 --- a/ast/src/access/static_member_access.rs +++ b/ast/src/access/static_member_access.rs @@ -1,12 +1,14 @@ -use crate::{ast::Rule, common::Identifier}; +use crate::{ast::Rule, common::Identifier, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::access_static_member))] pub struct StaticMemberAccess<'ast> { pub identifier: Identifier<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/circuits/circuit.rs b/ast/src/circuits/circuit.rs index 1fea0bd3d9..011cc7066b 100644 --- a/ast/src/circuits/circuit.rs +++ b/ast/src/circuits/circuit.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, circuits::CircuitMember, common::Identifier}; +use crate::{ast::Rule, circuits::CircuitMember, common::Identifier, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::circuit))] pub struct Circuit<'ast> { pub identifier: Identifier<'ast>, pub members: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/circuits/circuit_field.rs b/ast/src/circuits/circuit_field.rs index 0c48dec655..270d7b7308 100644 --- a/ast/src/circuits/circuit_field.rs +++ b/ast/src/circuits/circuit_field.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, common::Identifier, expressions::Expression}; +use crate::{ast::Rule, common::Identifier, expressions::Expression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::circuit_field))] pub struct CircuitField<'ast> { pub identifier: Identifier<'ast>, pub expression: Expression<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/circuits/circuit_field_definition.rs b/ast/src/circuits/circuit_field_definition.rs index 9a707934d0..331ff3599a 100644 --- a/ast/src/circuits/circuit_field_definition.rs +++ b/ast/src/circuits/circuit_field_definition.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, common::Identifier, types::Type}; +use crate::{ast::Rule, common::Identifier, types::Type, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::circuit_field_definition))] pub struct CircuitFieldDefinition<'ast> { pub identifier: Identifier<'ast>, pub _type: Type<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/circuits/circuit_function.rs b/ast/src/circuits/circuit_function.rs index a97e06ec59..5a10a8c818 100644 --- a/ast/src/circuits/circuit_function.rs +++ b/ast/src/circuits/circuit_function.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, common::Static, functions::Function}; +use crate::{ast::Rule, common::Static, functions::Function, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::circuit_function))] pub struct CircuitFunction<'ast> { pub _static: Option, pub function: Function<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/circuits/circuit_member.rs b/ast/src/circuits/circuit_member.rs index 1cae858a64..294d619659 100644 --- a/ast/src/circuits/circuit_member.rs +++ b/ast/src/circuits/circuit_member.rs @@ -4,8 +4,9 @@ use crate::{ }; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::circuit_member))] pub enum CircuitMember<'ast> { CircuitFieldDefinition(CircuitFieldDefinition<'ast>), diff --git a/ast/src/common/assignee.rs b/ast/src/common/assignee.rs index c5bb4b850b..e72b527193 100644 --- a/ast/src/common/assignee.rs +++ b/ast/src/common/assignee.rs @@ -1,15 +1,17 @@ -use crate::{access::AssigneeAccess, ast::Rule, common::Identifier}; +use crate::{access::AssigneeAccess, ast::Rule, common::Identifier, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::assignee))] pub struct Assignee<'ast> { pub identifier: Identifier<'ast>, pub accesses: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/common/declare.rs b/ast/src/common/declare.rs index 344f9c5c73..e4c06c2097 100644 --- a/ast/src/common/declare.rs +++ b/ast/src/common/declare.rs @@ -1,18 +1,19 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::declare))] pub enum Declare { Const(Const), Let(Let), } -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::const_))] pub struct Const {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::let_))] pub struct Let {} diff --git a/ast/src/common/eoi.rs b/ast/src/common/eoi.rs index 1293320f1a..e167d29937 100644 --- a/ast/src/common/eoi.rs +++ b/ast/src/common/eoi.rs @@ -1,7 +1,8 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::EOI))] pub struct EOI; diff --git a/ast/src/common/identifier.rs b/ast/src/common/identifier.rs index 35c74e30be..c6adf81e56 100644 --- a/ast/src/common/identifier.rs +++ b/ast/src/common/identifier.rs @@ -1,15 +1,20 @@ -use crate::ast::{span_into_string, Rule}; +use crate::{ + ast::{span_into_string, Rule}, + SpanDef, +}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::identifier))] pub struct Identifier<'ast> { #[pest_ast(outer(with(span_into_string)))] pub value: String, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/common/line_end.rs b/ast/src/common/line_end.rs index 10a8b5396f..fec2a1432e 100644 --- a/ast/src/common/line_end.rs +++ b/ast/src/common/line_end.rs @@ -1,9 +1,10 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::LINE_END))] pub struct LineEnd; diff --git a/ast/src/common/mutable.rs b/ast/src/common/mutable.rs index 58cac1b8ea..3d8b9ebbf5 100644 --- a/ast/src/common/mutable.rs +++ b/ast/src/common/mutable.rs @@ -1,7 +1,8 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::mutable))] pub struct Mutable {} diff --git a/ast/src/common/range.rs b/ast/src/common/range.rs index 0c272ef26d..8aabb966ce 100644 --- a/ast/src/common/range.rs +++ b/ast/src/common/range.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, expressions::Expression}; +use crate::{ast::Rule, expressions::Expression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::range))] pub struct Range<'ast> { pub from: Option>, pub to: Option>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/common/range_or_expression.rs b/ast/src/common/range_or_expression.rs index f41dc4a776..e0faf4adb5 100644 --- a/ast/src/common/range_or_expression.rs +++ b/ast/src/common/range_or_expression.rs @@ -1,9 +1,10 @@ use crate::{ast::Rule, common::Range, expressions::Expression}; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::range_or_expression))] pub enum RangeOrExpression<'ast> { Range(Range<'ast>), diff --git a/ast/src/common/return_.rs b/ast/src/common/return_.rs index 58455b88df..a1c22f888b 100644 --- a/ast/src/common/return_.rs +++ b/ast/src/common/return_.rs @@ -1,9 +1,10 @@ use crate::{ast::Rule, common::ReturnTuple, expressions::Expression}; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::return_))] pub enum Return<'ast> { Single(Expression<'ast>), diff --git a/ast/src/common/return_tuple.rs b/ast/src/common/return_tuple.rs index 80ac040956..0db2cb8756 100644 --- a/ast/src/common/return_tuple.rs +++ b/ast/src/common/return_tuple.rs @@ -1,14 +1,16 @@ -use crate::{ast::Rule, expressions::Expression}; +use crate::{ast::Rule, expressions::Expression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::return_tuple))] pub struct ReturnTuple<'ast> { pub expressions: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/common/spread.rs b/ast/src/common/spread.rs index 3fe206281b..e73b0010da 100644 --- a/ast/src/common/spread.rs +++ b/ast/src/common/spread.rs @@ -1,14 +1,16 @@ -use crate::{ast::Rule, expressions::Expression}; +use crate::{ast::Rule, expressions::Expression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::spread))] pub struct Spread<'ast> { pub expression: Expression<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/common/spread_or_expression.rs b/ast/src/common/spread_or_expression.rs index d1a3f86605..2065b6fd53 100644 --- a/ast/src/common/spread_or_expression.rs +++ b/ast/src/common/spread_or_expression.rs @@ -1,9 +1,10 @@ use crate::{ast::Rule, common::Spread, expressions::Expression}; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::spread_or_expression))] pub enum SpreadOrExpression<'ast> { Spread(Spread<'ast>), diff --git a/ast/src/common/static_.rs b/ast/src/common/static_.rs index a3e604909d..070a18664b 100644 --- a/ast/src/common/static_.rs +++ b/ast/src/common/static_.rs @@ -1,7 +1,8 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::static_))] pub struct Static {} diff --git a/ast/src/common/variable.rs b/ast/src/common/variable.rs index 98cc9fe4a7..5119795f43 100644 --- a/ast/src/common/variable.rs +++ b/ast/src/common/variable.rs @@ -2,19 +2,22 @@ use crate::{ ast::Rule, common::{Identifier, Mutable}, types::Type, + SpanDef, }; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::variable))] pub struct Variable<'ast> { pub mutable: Option, pub identifier: Identifier<'ast>, pub _type: Option>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/errors/parser.rs b/ast/src/errors/parser.rs index 3bce388a25..fa5c985a66 100644 --- a/ast/src/errors/parser.rs +++ b/ast/src/errors/parser.rs @@ -5,6 +5,9 @@ use std::path::PathBuf; #[derive(Debug, Error)] pub enum ParserError { + #[error("{}: {}", _0, _1)] + Crate(&'static str, String), + #[error("Cannot read from the provided file path - {:?}", _0)] FileReadError(PathBuf), @@ -20,3 +23,9 @@ impl From> for ParserError { ParserError::SyntaxError(SyntaxError::from(error)) } } + +impl From for ParserError { + fn from(error: std::io::Error) -> Self { + ParserError::Crate("std::io", format!("{}", error)) + } +} diff --git a/ast/src/expressions/array_initializer_expression.rs b/ast/src/expressions/array_initializer_expression.rs index 28051a9fa0..10b8b2bf1b 100644 --- a/ast/src/expressions/array_initializer_expression.rs +++ b/ast/src/expressions/array_initializer_expression.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, common::SpreadOrExpression, values::Value}; +use crate::{ast::Rule, common::SpreadOrExpression, values::Value, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::expression_array_initializer))] pub struct ArrayInitializerExpression<'ast> { pub expression: Box>, pub count: Value<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/expressions/array_inline_expression.rs b/ast/src/expressions/array_inline_expression.rs index 4ec4ff79b3..c43a1b0a5c 100644 --- a/ast/src/expressions/array_inline_expression.rs +++ b/ast/src/expressions/array_inline_expression.rs @@ -1,12 +1,14 @@ -use crate::{ast::Rule, common::SpreadOrExpression}; +use crate::{ast::Rule, common::SpreadOrExpression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::expression_array_inline))] pub struct ArrayInlineExpression<'ast> { pub expressions: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/expressions/binary_expression.rs b/ast/src/expressions/binary_expression.rs index 9c1f9e5f3a..f04efb6c60 100644 --- a/ast/src/expressions/binary_expression.rs +++ b/ast/src/expressions/binary_expression.rs @@ -1,11 +1,13 @@ -use crate::{expressions::Expression, operations::BinaryOperation}; +use crate::{expressions::Expression, operations::BinaryOperation, SpanDef}; use pest::Span; +use serde::Serialize; -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Serialize)] pub struct BinaryExpression<'ast> { pub operation: BinaryOperation, pub left: Box>, pub right: Box>, + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/expressions/circuit_inline_expression.rs b/ast/src/expressions/circuit_inline_expression.rs index e276373f18..7e0fb83de5 100644 --- a/ast/src/expressions/circuit_inline_expression.rs +++ b/ast/src/expressions/circuit_inline_expression.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, circuits::CircuitField, common::Identifier}; +use crate::{ast::Rule, circuits::CircuitField, common::Identifier, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::expression_circuit_inline))] pub struct CircuitInlineExpression<'ast> { pub identifier: Identifier<'ast>, pub members: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/expressions/expression.rs b/ast/src/expressions/expression.rs index 043c4fc049..561a0517f1 100644 --- a/ast/src/expressions/expression.rs +++ b/ast/src/expressions/expression.rs @@ -1,9 +1,10 @@ use crate::{common::Identifier, expressions::*, operations::BinaryOperation, values::Value}; use pest::Span; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Serialize)] pub enum Expression<'ast> { Value(Value<'ast>), Identifier(Identifier<'ast>), diff --git a/ast/src/expressions/not_expression.rs b/ast/src/expressions/not_expression.rs index 0e960f4532..a2f9ddf127 100644 --- a/ast/src/expressions/not_expression.rs +++ b/ast/src/expressions/not_expression.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, expressions::Expression, operations::NotOperation}; +use crate::{ast::Rule, expressions::Expression, operations::NotOperation, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::expression_not))] pub struct NotExpression<'ast> { pub operation: NotOperation<'ast>, pub expression: Box>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/expressions/postfix_expression.rs b/ast/src/expressions/postfix_expression.rs index 52a549f458..d578fa0350 100644 --- a/ast/src/expressions/postfix_expression.rs +++ b/ast/src/expressions/postfix_expression.rs @@ -1,13 +1,15 @@ -use crate::{access::Access, ast::Rule, common::Identifier}; +use crate::{access::Access, ast::Rule, common::Identifier, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::expression_postfix))] pub struct PostfixExpression<'ast> { pub identifier: Identifier<'ast>, pub accesses: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/expressions/ternary_expression.rs b/ast/src/expressions/ternary_expression.rs index 19f27207a6..63ff4e62eb 100644 --- a/ast/src/expressions/ternary_expression.rs +++ b/ast/src/expressions/ternary_expression.rs @@ -1,14 +1,16 @@ -use crate::{ast::Rule, expressions::Expression}; +use crate::{ast::Rule, expressions::Expression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::expression_conditional))] pub struct TernaryExpression<'ast> { pub first: Box>, pub second: Box>, pub third: Box>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/files/file.rs b/ast/src/files/file.rs index 87641a33cf..4cf4dfc204 100644 --- a/ast/src/files/file.rs +++ b/ast/src/files/file.rs @@ -4,12 +4,14 @@ use crate::{ common::EOI, functions::{Function, TestFunction}, imports::Import, + SpanDef, }; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::file))] pub struct File<'ast> { pub imports: Vec>, @@ -18,5 +20,6 @@ pub struct File<'ast> { pub tests: Vec>, pub eoi: EOI, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/functions/function.rs b/ast/src/functions/function.rs index 46fb34abbb..4ddb1938b9 100644 --- a/ast/src/functions/function.rs +++ b/ast/src/functions/function.rs @@ -1,9 +1,10 @@ -use crate::{ast::Rule, common::Identifier, functions::FunctionInput, statements::Statement, types::Type}; +use crate::{ast::Rule, common::Identifier, functions::FunctionInput, statements::Statement, types::Type, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::function_definition))] pub struct Function<'ast> { pub function_name: Identifier<'ast>, @@ -11,5 +12,6 @@ pub struct Function<'ast> { pub returns: Vec>, pub statements: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/functions/function_input.rs b/ast/src/functions/function_input.rs index 42a9bf8dda..127bd13502 100644 --- a/ast/src/functions/function_input.rs +++ b/ast/src/functions/function_input.rs @@ -2,17 +2,20 @@ use crate::{ ast::Rule, common::{Identifier, Mutable}, types::Type, + SpanDef, }; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::function_input))] pub struct FunctionInput<'ast> { pub mutable: Option, pub identifier: Identifier<'ast>, pub _type: Type<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/functions/test_function.rs b/ast/src/functions/test_function.rs index cdf3f752a7..d3f89f9df8 100644 --- a/ast/src/functions/test_function.rs +++ b/ast/src/functions/test_function.rs @@ -1,12 +1,14 @@ -use crate::{ast::Rule, functions::Function}; +use crate::{ast::Rule, functions::Function, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::test_function))] pub struct TestFunction<'ast> { pub function: Function<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/imports/import.rs b/ast/src/imports/import.rs index dbecc1b8fc..74a8255e5e 100644 --- a/ast/src/imports/import.rs +++ b/ast/src/imports/import.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, common::LineEnd, imports::Package}; +use crate::{ast::Rule, common::LineEnd, imports::Package, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::import))] pub struct Import<'ast> { pub package: Package<'ast>, pub line_end: LineEnd, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/imports/import_symbol.rs b/ast/src/imports/import_symbol.rs index 14be2896fe..61f0acbc1a 100644 --- a/ast/src/imports/import_symbol.rs +++ b/ast/src/imports/import_symbol.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, common::Identifier}; +use crate::{ast::Rule, common::Identifier, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::import_symbol))] pub struct ImportSymbol<'ast> { pub value: Identifier<'ast>, pub alias: Option>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/imports/package.rs b/ast/src/imports/package.rs index 42ac528961..b93d1de982 100644 --- a/ast/src/imports/package.rs +++ b/ast/src/imports/package.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, common::Identifier, imports::PackageAccess}; +use crate::{ast::Rule, common::Identifier, imports::PackageAccess, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::package))] pub struct Package<'ast> { pub name: Identifier<'ast>, pub access: PackageAccess<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/imports/package_access.rs b/ast/src/imports/package_access.rs index 0574dc94a4..612aa23683 100644 --- a/ast/src/imports/package_access.rs +++ b/ast/src/imports/package_access.rs @@ -4,8 +4,9 @@ use crate::{ }; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::package_access))] pub enum PackageAccess<'ast> { Star(Star<'ast>), diff --git a/ast/src/imports/star.rs b/ast/src/imports/star.rs index 4f4882801e..962aabf7eb 100644 --- a/ast/src/imports/star.rs +++ b/ast/src/imports/star.rs @@ -1,11 +1,13 @@ -use crate::ast::Rule; +use crate::{ast::Rule, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::star))] pub struct Star<'ast> { #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 8addca6e21..784413208e 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -5,11 +5,9 @@ extern crate pest_derive; #[macro_use] extern crate thiserror; -pub mod errors; -pub use errors::*; +mod ast; pub mod access; -mod ast; pub mod circuits; pub mod common; pub mod expressions; @@ -22,6 +20,12 @@ pub mod statements; pub mod types; pub mod values; +pub mod errors; +pub use errors::*; + +pub(crate) mod span; +pub(crate) use span::*; + use from_pest::FromPest; use std::{fs, path::PathBuf}; @@ -45,4 +49,14 @@ impl LeoParser { Ok(syntax_tree) } + + /// Serializes and stores a given syntax tree in the output file. + pub fn store_syntax_tree<'a>(syntax_tree: files::File<'a>, output_file: &'a str) -> Result<(), ParserError> { + // Serialize and store the syntax tree to the given filepath. + let serialized_syntax_tree = serde_json::to_string(&syntax_tree).unwrap(); + println!("serialized = {}", serialized_syntax_tree); + fs::write(output_file, serialized_syntax_tree)?; + + Ok(()) + } } diff --git a/ast/src/macros/assert_eq.rs b/ast/src/macros/assert_eq.rs index 1b7f9b498e..680710d1af 100644 --- a/ast/src/macros/assert_eq.rs +++ b/ast/src/macros/assert_eq.rs @@ -1,16 +1,18 @@ -use crate::{ast::Rule, common::LineEnd, expressions::Expression}; +use crate::{ast::Rule, common::LineEnd, expressions::Expression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::assert_eq))] pub struct AssertEq<'ast> { pub left: Expression<'ast>, pub right: Expression<'ast>, pub line_end: LineEnd, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/macros/debug.rs b/ast/src/macros/debug.rs index 163cd0d311..2bfcf0e2aa 100644 --- a/ast/src/macros/debug.rs +++ b/ast/src/macros/debug.rs @@ -1,13 +1,15 @@ -use crate::ast::Rule; +use crate::{ast::Rule, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::debug))] pub struct Debug<'ast> { #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/macros/error.rs b/ast/src/macros/error.rs index 10111619df..b43205cba3 100644 --- a/ast/src/macros/error.rs +++ b/ast/src/macros/error.rs @@ -1,13 +1,15 @@ -use crate::ast::Rule; +use crate::{ast::Rule, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::error))] pub struct Error<'ast> { #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/macros/formatted_container.rs b/ast/src/macros/formatted_container.rs index 0623ac8499..dc6565db52 100644 --- a/ast/src/macros/formatted_container.rs +++ b/ast/src/macros/formatted_container.rs @@ -1,13 +1,15 @@ -use crate::ast::Rule; +use crate::{ast::Rule, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::formatted_container))] pub struct FormattedContainer<'ast> { #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/macros/formatted_macro.rs b/ast/src/macros/formatted_macro.rs index c1404c9e74..928aa49d4c 100644 --- a/ast/src/macros/formatted_macro.rs +++ b/ast/src/macros/formatted_macro.rs @@ -2,13 +2,15 @@ use crate::{ ast::Rule, common::LineEnd, macros::{FormattedString, MacroName, MacroSymbol}, + SpanDef, }; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::formatted_macro))] pub struct FormattedMacro<'ast> { pub name: MacroName<'ast>, @@ -16,6 +18,7 @@ pub struct FormattedMacro<'ast> { pub string: Option>, pub line_end: LineEnd, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/macros/formatted_parameter.rs b/ast/src/macros/formatted_parameter.rs index d69359638c..dcdb3ba055 100644 --- a/ast/src/macros/formatted_parameter.rs +++ b/ast/src/macros/formatted_parameter.rs @@ -1,14 +1,16 @@ -use crate::{ast::Rule, expressions::Expression}; +use crate::{ast::Rule, expressions::Expression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::formatted_parameter))] pub struct FormattedParameter<'ast> { pub expression: Expression<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/macros/formatted_string.rs b/ast/src/macros/formatted_string.rs index 4dbdac79cd..cfa5fddbcc 100644 --- a/ast/src/macros/formatted_string.rs +++ b/ast/src/macros/formatted_string.rs @@ -1,13 +1,15 @@ use crate::{ ast::{span_into_string, Rule}, macros::{FormattedContainer, FormattedParameter}, + SpanDef, }; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::formatted_string))] pub struct FormattedString<'ast> { #[pest_ast(outer(with(span_into_string)))] @@ -15,6 +17,7 @@ pub struct FormattedString<'ast> { pub containers: Vec>, pub parameters: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/macros/macro_name.rs b/ast/src/macros/macro_name.rs index 3c7056373f..320f42b134 100644 --- a/ast/src/macros/macro_name.rs +++ b/ast/src/macros/macro_name.rs @@ -4,9 +4,10 @@ use crate::{ }; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::macro_name))] pub enum MacroName<'ast> { Debug(Debug<'ast>), diff --git a/ast/src/macros/macro_symbol.rs b/ast/src/macros/macro_symbol.rs index e7e1c3b73a..517bf711a2 100644 --- a/ast/src/macros/macro_symbol.rs +++ b/ast/src/macros/macro_symbol.rs @@ -1,9 +1,10 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::macro_symbol))] pub struct MacroSymbol {} diff --git a/ast/src/macros/print.rs b/ast/src/macros/print.rs index d9f657cb77..f98b3da6e8 100644 --- a/ast/src/macros/print.rs +++ b/ast/src/macros/print.rs @@ -1,13 +1,15 @@ -use crate::ast::Rule; +use crate::{ast::Rule, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::print))] pub struct Print<'ast> { #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/operations/assign_operation.rs b/ast/src/operations/assign_operation.rs index 69894e7c70..da23acc91d 100644 --- a/ast/src/operations/assign_operation.rs +++ b/ast/src/operations/assign_operation.rs @@ -1,8 +1,9 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::operation_assign))] pub enum AssignOperation { Assign(Assign), @@ -13,26 +14,26 @@ pub enum AssignOperation { PowAssign(PowAssign), } -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::assign))] pub struct Assign {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::operation_add_assign))] pub struct AddAssign {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::operation_sub_assign))] pub struct SubAssign {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::operation_mul_assign))] pub struct MulAssign {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::operation_div_assign))] pub struct DivAssign {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::operation_pow_assign))] pub struct PowAssign {} diff --git a/ast/src/operations/binary_operation.rs b/ast/src/operations/binary_operation.rs index 143e8e9b96..448e627dfe 100644 --- a/ast/src/operations/binary_operation.rs +++ b/ast/src/operations/binary_operation.rs @@ -1,8 +1,9 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::operation_binary))] pub enum BinaryOperation { Or, diff --git a/ast/src/operations/not_operation.rs b/ast/src/operations/not_operation.rs index 012f682a3d..37ee552251 100644 --- a/ast/src/operations/not_operation.rs +++ b/ast/src/operations/not_operation.rs @@ -1,11 +1,13 @@ -use crate::ast::Rule; +use crate::{ast::Rule, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::operation_not))] pub struct NotOperation<'ast> { #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/span.rs b/ast/src/span.rs new file mode 100644 index 0000000000..c0708a37c8 --- /dev/null +++ b/ast/src/span.rs @@ -0,0 +1,33 @@ +use pest::Span; +use serde::Serialize; + +// Provide getters for every private field of the remote struct. The getter must +// return either `T` or `&T` where `T` is the type of the field. +#[derive(Serialize)] +#[serde(remote = "Span")] +pub(crate) struct SpanDef<'i> { + /// # Attention + /// + /// This getter only returns a subset of the input. + /// Namely, it returns `self.input[self.start..self.end]`. + /// This means you can only accurate serialize (and not deserialize). + #[serde(getter = "Span::as_str")] + input: &'i str, + /// # Safety + /// + /// Must be a valid character boundary index into `input`. + #[serde(getter = "Span::start")] + start: usize, + /// # Safety + /// + /// Must be a valid character boundary index into `input`. + #[serde(getter = "Span::end")] + end: usize, +} + +// Provide a conversion to construct the remote type. +impl<'i> From> for Span<'i> { + fn from(def: SpanDef) -> Span { + Span::new(def.input, def.start, def.end).unwrap() + } +} diff --git a/ast/src/statements/assign_statement.rs b/ast/src/statements/assign_statement.rs index 530bb74e9b..1196d77c89 100644 --- a/ast/src/statements/assign_statement.rs +++ b/ast/src/statements/assign_statement.rs @@ -3,13 +3,15 @@ use crate::{ common::{Assignee, LineEnd}, expressions::Expression, operations::AssignOperation, + SpanDef, }; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::statement_assign))] pub struct AssignStatement<'ast> { pub assignee: Assignee<'ast>, @@ -17,6 +19,7 @@ pub struct AssignStatement<'ast> { pub expression: Expression<'ast>, pub line_end: LineEnd, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/statements/conditional_nested_or_end_statement.rs b/ast/src/statements/conditional_nested_or_end_statement.rs index 1f89364362..41121f3ff9 100644 --- a/ast/src/statements/conditional_nested_or_end_statement.rs +++ b/ast/src/statements/conditional_nested_or_end_statement.rs @@ -4,9 +4,10 @@ use crate::{ }; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::conditional_nested_or_end_statement))] pub enum ConditionalNestedOrEndStatement<'ast> { Nested(Box>), diff --git a/ast/src/statements/conditional_statement.rs b/ast/src/statements/conditional_statement.rs index 09200b10a7..b6d4c9a157 100644 --- a/ast/src/statements/conditional_statement.rs +++ b/ast/src/statements/conditional_statement.rs @@ -2,19 +2,22 @@ use crate::{ ast::Rule, expressions::Expression, statements::{ConditionalNestedOrEndStatement, Statement}, + SpanDef, }; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::statement_conditional))] pub struct ConditionalStatement<'ast> { pub condition: Expression<'ast>, pub statements: Vec>, pub next: Option>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/statements/definition_statement.rs b/ast/src/statements/definition_statement.rs index a3ad1e11e4..2b321a5418 100644 --- a/ast/src/statements/definition_statement.rs +++ b/ast/src/statements/definition_statement.rs @@ -2,13 +2,15 @@ use crate::{ ast::Rule, common::{Declare, LineEnd, Variable}, expressions::Expression, + SpanDef, }; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::statement_definition))] pub struct DefinitionStatement<'ast> { pub declare: Declare, @@ -16,6 +18,7 @@ pub struct DefinitionStatement<'ast> { pub expression: Expression<'ast>, pub line_end: LineEnd, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/statements/expression_statement.rs b/ast/src/statements/expression_statement.rs index 81bc5bc837..2ec81401bc 100644 --- a/ast/src/statements/expression_statement.rs +++ b/ast/src/statements/expression_statement.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, common::LineEnd, expressions::Expression}; +use crate::{ast::Rule, common::LineEnd, expressions::Expression, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::statement_expression))] pub struct ExpressionStatement<'ast> { pub expression: Expression<'ast>, pub line_end: LineEnd, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/statements/for_statement.rs b/ast/src/statements/for_statement.rs index f560af9b36..49985791c5 100644 --- a/ast/src/statements/for_statement.rs +++ b/ast/src/statements/for_statement.rs @@ -1,10 +1,11 @@ -use crate::{ast::Rule, common::Identifier, expressions::Expression, statements::Statement}; +use crate::{ast::Rule, common::Identifier, expressions::Expression, statements::Statement, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::statement_for))] pub struct ForStatement<'ast> { pub index: Identifier<'ast>, @@ -12,6 +13,7 @@ pub struct ForStatement<'ast> { pub stop: Expression<'ast>, pub statements: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/statements/macro_statement.rs b/ast/src/statements/macro_statement.rs index 490c3e525a..d75a87efd6 100644 --- a/ast/src/statements/macro_statement.rs +++ b/ast/src/statements/macro_statement.rs @@ -4,9 +4,10 @@ use crate::{ }; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::statement_macro))] pub enum MacroStatement<'ast> { AssertEq(AssertEq<'ast>), diff --git a/ast/src/statements/multiple_assignment_statement.rs b/ast/src/statements/multiple_assignment_statement.rs index f64b811726..17a6dd99ee 100644 --- a/ast/src/statements/multiple_assignment_statement.rs +++ b/ast/src/statements/multiple_assignment_statement.rs @@ -2,13 +2,15 @@ use crate::{ ast::Rule, common::{Declare, Identifier, LineEnd, Variable}, expressions::Expression, + SpanDef, }; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::statement_multiple_assignment))] pub struct MultipleAssignmentStatement<'ast> { pub declare: Declare, @@ -17,6 +19,7 @@ pub struct MultipleAssignmentStatement<'ast> { pub arguments: Vec>, pub line_end: LineEnd, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/statements/return_statement.rs b/ast/src/statements/return_statement.rs index f22b070e22..3fbf78c6d2 100644 --- a/ast/src/statements/return_statement.rs +++ b/ast/src/statements/return_statement.rs @@ -1,14 +1,16 @@ -use crate::{ast::Rule, common::Return}; +use crate::{ast::Rule, common::Return, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::statement_return))] pub struct ReturnStatement<'ast> { pub return_: Return<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/statements/statement.rs b/ast/src/statements/statement.rs index c4635363d9..0297d29366 100644 --- a/ast/src/statements/statement.rs +++ b/ast/src/statements/statement.rs @@ -1,9 +1,10 @@ use crate::{ast::Rule, statements::*}; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::statement))] pub enum Statement<'ast> { Return(ReturnStatement<'ast>), diff --git a/ast/src/types/address_type.rs b/ast/src/types/address_type.rs index cfba85e343..9760d7763c 100644 --- a/ast/src/types/address_type.rs +++ b/ast/src/types/address_type.rs @@ -1,7 +1,8 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_address))] pub struct AddressType {} diff --git a/ast/src/types/array_type.rs b/ast/src/types/array_type.rs index 01650cdfb3..bc5b04dd7b 100644 --- a/ast/src/types/array_type.rs +++ b/ast/src/types/array_type.rs @@ -1,13 +1,15 @@ -use crate::{ast::Rule, types::DataType, values::Value}; +use crate::{ast::Rule, types::DataType, values::Value, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_array))] pub struct ArrayType<'ast> { pub _type: DataType, pub dimensions: Vec>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/types/boolean_type.rs b/ast/src/types/boolean_type.rs index 9abd021ffa..2639cf2b48 100644 --- a/ast/src/types/boolean_type.rs +++ b/ast/src/types/boolean_type.rs @@ -1,7 +1,8 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_boolean))] pub struct BooleanType {} diff --git a/ast/src/types/circuit_type.rs b/ast/src/types/circuit_type.rs index fa8acf3e78..3326b7d39a 100644 --- a/ast/src/types/circuit_type.rs +++ b/ast/src/types/circuit_type.rs @@ -1,12 +1,14 @@ -use crate::{ast::Rule, common::Identifier}; +use crate::{ast::Rule, common::Identifier, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_circuit))] pub struct CircuitType<'ast> { pub identifier: Identifier<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/types/data_type.rs b/ast/src/types/data_type.rs index 320396ed20..65e90e5307 100644 --- a/ast/src/types/data_type.rs +++ b/ast/src/types/data_type.rs @@ -4,8 +4,9 @@ use crate::{ }; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_data))] pub enum DataType { Address(AddressType), diff --git a/ast/src/types/field_type.rs b/ast/src/types/field_type.rs index d3751a2432..5afc41ff4c 100644 --- a/ast/src/types/field_type.rs +++ b/ast/src/types/field_type.rs @@ -1,7 +1,8 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_field))] pub struct FieldType {} diff --git a/ast/src/types/group_type.rs b/ast/src/types/group_type.rs index c099ab778a..c8f8397b69 100644 --- a/ast/src/types/group_type.rs +++ b/ast/src/types/group_type.rs @@ -1,7 +1,8 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_group))] pub struct GroupType {} diff --git a/ast/src/types/integer_type.rs b/ast/src/types/integer_type.rs index b0895f073b..716353fd2e 100644 --- a/ast/src/types/integer_type.rs +++ b/ast/src/types/integer_type.rs @@ -1,8 +1,9 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_integer))] pub enum IntegerType { U8Type(U8Type), @@ -20,44 +21,44 @@ pub enum IntegerType { // Unsigned -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_u8))] pub struct U8Type {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_u16))] pub struct U16Type {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_u32))] pub struct U32Type {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_u64))] pub struct U64Type {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_u128))] pub struct U128Type {} // Signed -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_i8))] pub struct I8Type {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_i16))] pub struct I16Type {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_i32))] pub struct I32Type {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_i64))] pub struct I64Type {} -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_i128))] pub struct I128Type {} diff --git a/ast/src/types/self_type.rs b/ast/src/types/self_type.rs index b1e57bbee5..53fc667c6a 100644 --- a/ast/src/types/self_type.rs +++ b/ast/src/types/self_type.rs @@ -1,7 +1,8 @@ use crate::ast::Rule; use pest_ast::FromPest; +use serde::Serialize; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_self))] pub struct SelfType {} diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index cc300b51b2..9b5dfa46ef 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -1,9 +1,10 @@ use crate::{ast::Rule, types::*}; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::type_))] pub enum Type<'ast> { Basic(DataType), diff --git a/ast/src/values/address.rs b/ast/src/values/address.rs index 9e981b31b0..34549f46f4 100644 --- a/ast/src/values/address.rs +++ b/ast/src/values/address.rs @@ -1,15 +1,20 @@ -use crate::ast::{span_into_string, Rule}; +use crate::{ + ast::{span_into_string, Rule}, + SpanDef, +}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::address))] pub struct Address<'ast> { #[pest_ast(outer(with(span_into_string)))] pub value: String, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/values/address_value.rs b/ast/src/values/address_value.rs index 9df9857222..7e0dd10329 100644 --- a/ast/src/values/address_value.rs +++ b/ast/src/values/address_value.rs @@ -1,15 +1,17 @@ -use crate::{ast::Rule, types::AddressType, values::address::Address}; +use crate::{ast::Rule, types::AddressType, values::address::Address, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::value_address))] pub struct AddressValue<'ast> { pub _type: AddressType, pub address: Address<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/values/boolean_value.rs b/ast/src/values/boolean_value.rs index c16b9be740..0e65e6ebd2 100644 --- a/ast/src/values/boolean_value.rs +++ b/ast/src/values/boolean_value.rs @@ -1,15 +1,20 @@ -use crate::ast::{span_into_string, Rule}; +use crate::{ + ast::{span_into_string, Rule}, + SpanDef, +}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::value_boolean))] pub struct BooleanValue<'ast> { #[pest_ast(outer(with(span_into_string)))] pub value: String, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/values/field_value.rs b/ast/src/values/field_value.rs index 3c21e56cc8..b67d455ddf 100644 --- a/ast/src/values/field_value.rs +++ b/ast/src/values/field_value.rs @@ -1,15 +1,17 @@ -use crate::{ast::Rule, types::FieldType, values::NumberValue}; +use crate::{ast::Rule, types::FieldType, values::NumberValue, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::value_field))] pub struct FieldValue<'ast> { pub number: NumberValue<'ast>, pub _type: FieldType, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/values/group_value.rs b/ast/src/values/group_value.rs index 365954e5ed..606940bd36 100644 --- a/ast/src/values/group_value.rs +++ b/ast/src/values/group_value.rs @@ -1,15 +1,17 @@ -use crate::{ast::Rule, types::GroupType, values::NumberValue}; +use crate::{ast::Rule, types::GroupType, values::NumberValue, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::value_group))] pub struct GroupValue<'ast> { pub value: GroupRepresentation<'ast>, pub _type: GroupType, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } @@ -19,7 +21,7 @@ impl<'ast> fmt::Display for GroupValue<'ast> { } } -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::group_single_or_tuple))] pub enum GroupRepresentation<'ast> { Single(NumberValue<'ast>), @@ -35,12 +37,13 @@ impl<'ast> fmt::Display for GroupRepresentation<'ast> { } } -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::group_tuple))] pub struct GroupTuple<'ast> { pub x: NumberValue<'ast>, pub y: NumberValue<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/values/integer_value.rs b/ast/src/values/integer_value.rs index 141cb9aab6..a36183034f 100644 --- a/ast/src/values/integer_value.rs +++ b/ast/src/values/integer_value.rs @@ -1,15 +1,17 @@ -use crate::{ast::Rule, types::IntegerType, values::NumberValue}; +use crate::{ast::Rule, types::IntegerType, values::NumberValue, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::value_integer))] pub struct IntegerValue<'ast> { pub number: NumberValue<'ast>, pub _type: IntegerType, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/values/number_implicit_value.rs b/ast/src/values/number_implicit_value.rs index 0aae2cc51e..caa55f9a1a 100644 --- a/ast/src/values/number_implicit_value.rs +++ b/ast/src/values/number_implicit_value.rs @@ -1,14 +1,16 @@ -use crate::{ast::Rule, values::NumberValue}; +use crate::{ast::Rule, values::NumberValue, SpanDef}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::value_implicit))] pub struct NumberImplicitValue<'ast> { pub number: NumberValue<'ast>, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/values/number_value.rs b/ast/src/values/number_value.rs index 1054911286..4bb64fef90 100644 --- a/ast/src/values/number_value.rs +++ b/ast/src/values/number_value.rs @@ -1,15 +1,20 @@ -use crate::ast::{span_into_string, Rule}; +use crate::{ + ast::{span_into_string, Rule}, + span::SpanDef, +}; use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::value_number))] pub struct NumberValue<'ast> { #[pest_ast(outer(with(span_into_string)))] pub value: String, #[pest_ast(outer())] + #[serde(with = "SpanDef")] pub span: Span<'ast>, } diff --git a/ast/src/values/value.rs b/ast/src/values/value.rs index c36fe2d997..37c932d356 100644 --- a/ast/src/values/value.rs +++ b/ast/src/values/value.rs @@ -5,9 +5,10 @@ use crate::{ use pest::Span; use pest_ast::FromPest; +use serde::Serialize; use std::fmt; -#[derive(Clone, Debug, FromPest, PartialEq)] +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::value))] pub enum Value<'ast> { Address(AddressValue<'ast>), diff --git a/examples/foo/.gitignore b/examples/foo/.gitignore new file mode 100644 index 0000000000..17aa483ab4 --- /dev/null +++ b/examples/foo/.gitignore @@ -0,0 +1 @@ +outputs/ diff --git a/examples/foo/Leo.toml b/examples/foo/Leo.toml new file mode 100644 index 0000000000..c35d63273a --- /dev/null +++ b/examples/foo/Leo.toml @@ -0,0 +1,3 @@ +[package] +name = "foo" +version = "0.1.0" diff --git a/examples/foo/inputs/foo.in b/examples/foo/inputs/foo.in new file mode 100644 index 0000000000..e0d16cf97a --- /dev/null +++ b/examples/foo/inputs/foo.in @@ -0,0 +1,4 @@ +// The program inputs for foo/src/main.leo +[main] +a: u32 = 1; +b: u32 = 2; diff --git a/examples/foo/src/main.leo b/examples/foo/src/main.leo new file mode 100644 index 0000000000..0198b1c3fb --- /dev/null +++ b/examples/foo/src/main.leo @@ -0,0 +1,5 @@ +// The 'foo' main function. +function main(a: u32, b: u32) -> u32 { + let c: u32 = a + b; + return c +} diff --git a/examples/pedersen_hash/.theia/launch.json b/examples/pedersen_hash/.theia/launch.json new file mode 100644 index 0000000000..a2ea02c468 --- /dev/null +++ b/examples/pedersen_hash/.theia/launch.json @@ -0,0 +1,6 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + "version": "0.2.0", + "configurations": [] +} diff --git a/examples/test/.gitignore b/examples/test/.gitignore new file mode 100644 index 0000000000..17aa483ab4 --- /dev/null +++ b/examples/test/.gitignore @@ -0,0 +1 @@ +outputs/ diff --git a/examples/test/Leo.toml b/examples/test/Leo.toml new file mode 100644 index 0000000000..f18a42ff37 --- /dev/null +++ b/examples/test/Leo.toml @@ -0,0 +1,3 @@ +[package] +name = "test" +version = "0.1.0" diff --git a/examples/test/inputs/test.in b/examples/test/inputs/test.in new file mode 100644 index 0000000000..9f7c94c12f --- /dev/null +++ b/examples/test/inputs/test.in @@ -0,0 +1,4 @@ +// The program inputs for test/src/main.leo +[main] +a: u32 = 1; +b: u32 = 2; diff --git a/examples/test/src/main.leo b/examples/test/src/main.leo new file mode 100644 index 0000000000..f5d7f2b03c --- /dev/null +++ b/examples/test/src/main.leo @@ -0,0 +1,5 @@ +// The 'test' main function. +function main(a: u32, b: u32) -> u32 { + let c: u32 = a + b; + return c +} From d3894ff5461d65a2ba1d6690e0167e17fc4ea95e Mon Sep 17 00:00:00 2001 From: howardwu Date: Tue, 28 Jul 2020 22:26:28 -0700 Subject: [PATCH 2/5] Adds AST JSON generator --- ast/Cargo.toml | 4 ++++ ast/src/errors/parser.rs | 3 +++ ast/src/lib.rs | 21 +++++++---------- ast/src/main.rs | 50 ++++++++++++++++++++++++++++++++++++++++ compiler/src/compiler.rs | 3 ++- 5 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 ast/src/main.rs diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 8a1eea319d..7050904de1 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -4,6 +4,10 @@ version = "0.1.0" authors = ["The Aleo Team "] edition = "2018" +[[bin]] +name = "leo_ast" +path = "src/main.rs" + [dependencies] from-pest = { version = "0.3.1" } lazy_static = { version = "1.3.0" } diff --git a/ast/src/errors/parser.rs b/ast/src/errors/parser.rs index fa5c985a66..c0726896cc 100644 --- a/ast/src/errors/parser.rs +++ b/ast/src/errors/parser.rs @@ -11,6 +11,9 @@ pub enum ParserError { #[error("Cannot read from the provided file path - {:?}", _0)] FileReadError(PathBuf), + #[error("{}", _0)] + JsonError(#[from] serde_json::error::Error), + #[error("{}", _0)] SyntaxError(#[from] SyntaxError), diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 784413208e..7907a140dd 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -32,16 +32,16 @@ use std::{fs, path::PathBuf}; pub struct LeoParser; impl LeoParser { - /// Reads in the given file path into a string. + /// Loads the Leo code as a string from the given file path. pub fn load_file(file_path: &PathBuf) -> Result { Ok(fs::read_to_string(file_path).map_err(|_| ParserError::FileReadError(file_path.clone()))?) } - /// Parses the input file and constructs a syntax tree. - pub fn parse_file<'a>(file_path: &'a PathBuf, input_file: &'a str) -> Result, ParserError> { + /// Parses the Leo program string and constructs an abstract syntax tree. + pub fn parse_file<'a>(file_path: &'a PathBuf, program_string: &'a str) -> Result, ParserError> { // Parse the file using leo.pest - let mut file = - ast::parse(input_file).map_err(|error| ParserError::from(error.with_path(file_path.to_str().unwrap())))?; + let mut file = ast::parse(program_string) + .map_err(|error| ParserError::from(error.with_path(file_path.to_str().unwrap())))?; // Build the abstract syntax tree let syntax_tree = files::File::from_pest(&mut file).map_err(|_| ParserError::SyntaxTreeError)?; @@ -50,13 +50,8 @@ impl LeoParser { Ok(syntax_tree) } - /// Serializes and stores a given syntax tree in the output file. - pub fn store_syntax_tree<'a>(syntax_tree: files::File<'a>, output_file: &'a str) -> Result<(), ParserError> { - // Serialize and store the syntax tree to the given filepath. - let serialized_syntax_tree = serde_json::to_string(&syntax_tree).unwrap(); - println!("serialized = {}", serialized_syntax_tree); - fs::write(output_file, serialized_syntax_tree)?; - - Ok(()) + /// Serializes a given abstract syntax tree into a JSON string. + pub fn to_json_string(syntax_tree: &files::File) -> Result { + Ok(serde_json::to_string_pretty(syntax_tree)?) } } diff --git a/ast/src/main.rs b/ast/src/main.rs new file mode 100644 index 0000000000..9c288c18d2 --- /dev/null +++ b/ast/src/main.rs @@ -0,0 +1,50 @@ +use leo_ast::{LeoParser, ParserError}; +use std::{env, fs, path::Path}; + +fn to_leo_ast(filepath: &Path) -> Result { + // Loads the Leo code as a string from the given file path. + let program_filepath = filepath.to_path_buf(); + let program_string = LeoParser::load_file(&program_filepath)?; + + // Parses the Leo program string and constructs an abstract syntax tree. + let abstract_syntax_tree = LeoParser::parse_file(&program_filepath, &program_string)?; + + // Serializes the abstract syntax tree into JSON format. + let serialized_ast = LeoParser::to_json_string(&abstract_syntax_tree)?; + + Ok(serialized_ast) +} + +fn main() -> Result<(), ParserError> { + // Parse the command-line arguments as strings. + let cli_arguments = env::args().collect::>(); + + // Check that the correct number of command-line arguments were passed in. + if cli_arguments.len() < 2 || cli_arguments.len() > 3 { + eprintln!("Error - invalid number of command-line arguments"); + println!("\nCommand-line usage:\n\n\tleo_ast {{input_filename}}.leo {{optional_output_filepath}}\n"); + return Ok(()); // Exit innocently + } + + // Create the input filepath. + let input_filepath = Path::new(&cli_arguments[1]); + + // Create the serialized abstract syntax tree. + let serialized_ast = to_leo_ast(&input_filepath)?; + println!("{}", serialized_ast); + + // Create the output filepath. + let output_filepath = match cli_arguments.len() == 3 { + true => format!( + "{}/{}.json", + cli_arguments[2], + input_filepath.file_stem().unwrap().to_str().unwrap() + ), + false => format!("./{}.json", input_filepath.file_stem().unwrap().to_str().unwrap()), + }; + + // Write the serialized abstract syntax tree to the output filepath. + fs::write(Path::new(&output_filepath), serialized_ast)?; + + Ok(()) +} diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 5f4718875c..1006480e0f 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -94,11 +94,12 @@ impl> Compiler { generate_test_constraints::(cs, self.program, &self.imported_programs) } + /// Loads the Leo code as a string from the given file path. fn load_program(&mut self) -> Result { - // Load the program syntax tree from the file path Ok(LeoParser::load_file(&self.main_file_path)?) } + /// Parses the Leo program string, constructs a syntax tree, and generates a program. pub fn parse_program(&mut self, program_string: &str) -> Result<(), CompilerError> { // Parse the program syntax tree let syntax_tree = LeoParser::parse_file(&self.main_file_path, program_string)?; From d440c2b57e5330ed5f9e6df6feb80691300f15b7 Mon Sep 17 00:00:00 2001 From: howardwu Date: Tue, 28 Jul 2020 22:36:10 -0700 Subject: [PATCH 3/5] Update documentation --- ast/README.md | 8 ++++++++ ast/src/main.rs | 18 ++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/ast/README.md b/ast/README.md index 99f60d0df8..1752725766 100644 --- a/ast/README.md +++ b/ast/README.md @@ -1 +1,9 @@ # leo-ast + +## Command-line instructions + +To generate an AST of the Leo program and save it as a JSON file , run: +``` +leo_ast {PATH/TO/INPUT_FILENAME}.leo {PATH/TO/OUTPUT_DIRECTORY (optional)} +``` +If no output directory is provided, then the program will store the JSON file in the local working directory. diff --git a/ast/src/main.rs b/ast/src/main.rs index 9c288c18d2..04c082da1b 100644 --- a/ast/src/main.rs +++ b/ast/src/main.rs @@ -21,20 +21,22 @@ fn main() -> Result<(), ParserError> { // Check that the correct number of command-line arguments were passed in. if cli_arguments.len() < 2 || cli_arguments.len() > 3 { - eprintln!("Error - invalid number of command-line arguments"); - println!("\nCommand-line usage:\n\n\tleo_ast {{input_filename}}.leo {{optional_output_filepath}}\n"); + eprintln!("Warning - an invalid number of command-line arguments were provided."); + println!( + "\nCommand-line usage:\n\n\tleo_ast {{PATH/TO/INPUT_FILENAME}}.leo {{PATH/TO/OUTPUT_DIRECTORY (optional)}}\n" + ); return Ok(()); // Exit innocently } - // Create the input filepath. + // Construct the input filepath. let input_filepath = Path::new(&cli_arguments[1]); - // Create the serialized abstract syntax tree. + // Construct the serialized abstract syntax tree. let serialized_ast = to_leo_ast(&input_filepath)?; println!("{}", serialized_ast); - // Create the output filepath. - let output_filepath = match cli_arguments.len() == 3 { + // Determine the output directory. + let output_directory = match cli_arguments.len() == 3 { true => format!( "{}/{}.json", cli_arguments[2], @@ -43,8 +45,8 @@ fn main() -> Result<(), ParserError> { false => format!("./{}.json", input_filepath.file_stem().unwrap().to_str().unwrap()), }; - // Write the serialized abstract syntax tree to the output filepath. - fs::write(Path::new(&output_filepath), serialized_ast)?; + // Write the serialized abstract syntax tree to the output directory. + fs::write(Path::new(&output_directory), serialized_ast)?; Ok(()) } From 695ca8d99862d3971158b2d9b3e1b12f2a37e295 Mon Sep 17 00:00:00 2001 From: howardwu Date: Tue, 28 Jul 2020 22:46:38 -0700 Subject: [PATCH 4/5] Unintended commits removed --- examples/foo/.gitignore | 1 - examples/foo/Leo.toml | 3 --- examples/foo/inputs/foo.in | 4 ---- examples/foo/src/main.leo | 5 ----- examples/pedersen_hash/.theia/launch.json | 6 ------ examples/test/.gitignore | 1 - examples/test/Leo.toml | 3 --- examples/test/inputs/test.in | 4 ---- examples/test/src/main.leo | 5 ----- 9 files changed, 32 deletions(-) delete mode 100644 examples/foo/.gitignore delete mode 100644 examples/foo/Leo.toml delete mode 100644 examples/foo/inputs/foo.in delete mode 100644 examples/foo/src/main.leo delete mode 100644 examples/pedersen_hash/.theia/launch.json delete mode 100644 examples/test/.gitignore delete mode 100644 examples/test/Leo.toml delete mode 100644 examples/test/inputs/test.in delete mode 100644 examples/test/src/main.leo diff --git a/examples/foo/.gitignore b/examples/foo/.gitignore deleted file mode 100644 index 17aa483ab4..0000000000 --- a/examples/foo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -outputs/ diff --git a/examples/foo/Leo.toml b/examples/foo/Leo.toml deleted file mode 100644 index c35d63273a..0000000000 --- a/examples/foo/Leo.toml +++ /dev/null @@ -1,3 +0,0 @@ -[package] -name = "foo" -version = "0.1.0" diff --git a/examples/foo/inputs/foo.in b/examples/foo/inputs/foo.in deleted file mode 100644 index e0d16cf97a..0000000000 --- a/examples/foo/inputs/foo.in +++ /dev/null @@ -1,4 +0,0 @@ -// The program inputs for foo/src/main.leo -[main] -a: u32 = 1; -b: u32 = 2; diff --git a/examples/foo/src/main.leo b/examples/foo/src/main.leo deleted file mode 100644 index 0198b1c3fb..0000000000 --- a/examples/foo/src/main.leo +++ /dev/null @@ -1,5 +0,0 @@ -// The 'foo' main function. -function main(a: u32, b: u32) -> u32 { - let c: u32 = a + b; - return c -} diff --git a/examples/pedersen_hash/.theia/launch.json b/examples/pedersen_hash/.theia/launch.json deleted file mode 100644 index a2ea02c468..0000000000 --- a/examples/pedersen_hash/.theia/launch.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - "version": "0.2.0", - "configurations": [] -} diff --git a/examples/test/.gitignore b/examples/test/.gitignore deleted file mode 100644 index 17aa483ab4..0000000000 --- a/examples/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -outputs/ diff --git a/examples/test/Leo.toml b/examples/test/Leo.toml deleted file mode 100644 index f18a42ff37..0000000000 --- a/examples/test/Leo.toml +++ /dev/null @@ -1,3 +0,0 @@ -[package] -name = "test" -version = "0.1.0" diff --git a/examples/test/inputs/test.in b/examples/test/inputs/test.in deleted file mode 100644 index 9f7c94c12f..0000000000 --- a/examples/test/inputs/test.in +++ /dev/null @@ -1,4 +0,0 @@ -// The program inputs for test/src/main.leo -[main] -a: u32 = 1; -b: u32 = 2; diff --git a/examples/test/src/main.leo b/examples/test/src/main.leo deleted file mode 100644 index f5d7f2b03c..0000000000 --- a/examples/test/src/main.leo +++ /dev/null @@ -1,5 +0,0 @@ -// The 'test' main function. -function main(a: u32, b: u32) -> u32 { - let c: u32 = a + b; - return c -} From 6a199d1256c07f9a3c91dd1f758093483dcbddf5 Mon Sep 17 00:00:00 2001 From: howardwu Date: Tue, 28 Jul 2020 22:54:32 -0700 Subject: [PATCH 5/5] Add test for span --- ast/src/span.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ast/src/span.rs b/ast/src/span.rs index c0708a37c8..28c35f9247 100644 --- a/ast/src/span.rs +++ b/ast/src/span.rs @@ -31,3 +31,23 @@ impl<'i> From> for Span<'i> { Span::new(def.input, def.start, def.end).unwrap() } } + +#[test] +fn test_span_def() { + // Wrapper serializable JSON struct + #[derive(Serialize)] + struct Element<'ast> { + #[serde(with = "SpanDef")] + span: Span<'ast>, + } + + // Starting value + let span = Span::new("hello world", 1, 5).unwrap(); + let element = Element { span }; + + // Attempt to serialize span to string. + let output = serde_json::to_string(&element).unwrap(); + + let expected_output = "{\"span\":{\"input\":\"ello\",\"start\":1,\"end\":5}}"; + assert_eq!(expected_output, output); +}