evaluate println, debug, error macros

This commit is contained in:
collin 2020-07-09 05:03:10 -07:00
parent 364e7684ac
commit 7ae351c0c6
12 changed files with 147 additions and 12 deletions

View File

@ -0,0 +1,35 @@
use crate::errors::ExpressionError;
use leo_types::{Error as FormattedError, Span};
use std::path::PathBuf;
#[derive(Debug, Error)]
pub enum MacroError {
#[error("{}", _0)]
Error(#[from] FormattedError),
#[error("{}", _0)]
Expression(#[from] ExpressionError),
}
impl MacroError {
pub fn set_path(&mut self, path: PathBuf) {
match self {
MacroError::Expression(error) => error.set_path(path),
MacroError::Error(error) => error.set_path(path),
}
}
fn new_from_span(message: String, span: Span) -> Self {
MacroError::Error(FormattedError::new_from_span(message, span))
}
pub fn length(containers: usize, parameters: usize, span: Span) -> Self {
let message = format!(
"Formatter given {} containers and found {} parameters",
containers, parameters
);
Self::new_from_span(message, span)
}
}

View File

@ -10,6 +10,9 @@ pub use self::function::*;
pub mod import;
pub use self::import::*;
pub mod macro_;
pub use self::macro_::*;
pub mod statement;
pub use self::statement::*;

View File

@ -1,4 +1,4 @@
use crate::errors::{AddressError, BooleanError, ExpressionError, IntegerError, ValueError};
use crate::errors::{AddressError, BooleanError, ExpressionError, IntegerError, MacroError, ValueError};
use leo_types::{Error as FormattedError, Span, Type};
use std::path::PathBuf;
@ -20,6 +20,9 @@ pub enum StatementError {
#[error("{}", _0)]
IntegerError(#[from] IntegerError),
#[error("{}", _0)]
MacroError(#[from] MacroError),
#[error("{}", _0)]
ValueError(#[from] ValueError),
}
@ -32,6 +35,7 @@ impl StatementError {
StatementError::Error(error) => error.set_path(path),
StatementError::ExpressionError(error) => error.set_path(path),
StatementError::IntegerError(error) => error.set_path(path),
StatementError::MacroError(error) => error.set_path(path),
StatementError::ValueError(error) => error.set_path(path),
}
}

View File

@ -21,6 +21,9 @@ pub use self::function::*;
pub mod import;
pub use self::import::*;
pub mod macro_;
pub use self::macro_::*;
pub mod program;
pub use self::program::*;

View File

@ -0,0 +1,53 @@
//! Evaluates a macro in a compiled Leo program.
use crate::{errors::MacroError, program::ConstrainedProgram, GroupType};
use leo_types::FormattedString;
use snarkos_models::{
curves::{Field, PrimeField},
gadgets::r1cs::ConstraintSystem,
};
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub fn format<CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
file_scope: String,
function_scope: String,
formatted: FormattedString,
) -> Result<String, MacroError> {
// Check that containers and parameters match
if formatted.containers.len() != formatted.parameters.len() {
return Err(MacroError::length(
formatted.containers.len(),
formatted.parameters.len(),
formatted.span.clone(),
));
}
// Trim starting double quote `"`
let mut string = formatted.string.as_str();
string = string.trim_start_matches("\"");
// Trim everything after the ending double quote `"`
let parts: Vec<&str> = string.split("\"").collect();
string = parts[0];
// Insert the parameter for each container `{}`
let mut result = string.to_string();
for parameter in formatted.parameters.into_iter() {
let parameter_value = self.enforce_expression(
cs,
file_scope.clone(),
function_scope.clone(),
&vec![],
parameter.expression,
)?;
result = result.replacen("{}", &parameter_value.to_string(), 1);
}
Ok(result)
}
}

View File

@ -0,0 +1,32 @@
//! Evaluates a macro in a compiled Leo program.
use crate::{errors::MacroError, program::ConstrainedProgram, GroupType};
use leo_types::{FormattedMacro, MacroName};
use snarkos_models::{
curves::{Field, PrimeField},
gadgets::r1cs::ConstraintSystem,
};
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub fn evaluate_macro<CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
file_scope: String,
function_scope: String,
macro_: FormattedMacro,
) -> Result<(), MacroError> {
let string = macro_
.string
.map(|string| self.format(cs, file_scope, function_scope, string))
.unwrap_or(Ok("".to_string()))?;
match macro_.name {
MacroName::Debug(_) => log::debug!("{}\n", string),
MacroName::Error(_) => log::error!("{}\n", string),
MacroName::PrintLine(_) => println!("{}\n", string),
}
Ok(())
}
}

View File

@ -0,0 +1,5 @@
pub mod format;
pub use self::format::*;
pub mod macro_;
pub use self::macro_::*;

View File

@ -79,7 +79,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
self.enforce_assert_eq_statement(cs, indicator, &resolved_left, &resolved_right, span)?;
}
Statement::Macro(macro_) => {
println!("{}", macro_);
self.evaluate_macro(cs, file_scope, function_scope, macro_)?;
}
Statement::Expression(expression, span) => {
let expression_string = expression.to_string();

View File

@ -1,4 +1,4 @@
use crate::{Error as FormattedError, Expression, Span};
use crate::{Error, Expression, Span};
use leo_ast::{common::RangeOrExpression as AstRangeOrExpression, values::NumberValue};
use serde::{Deserialize, Serialize};
@ -14,7 +14,7 @@ pub enum RangeOrExpression {
pub fn unwrap_bound(bound: Option<NumberValue>) -> Option<usize> {
bound.map(|number| {
let message = format!("Range bounds should be integers");
let error = FormattedError::new_from_span(message, Span::from(number.span.clone()));
let error = Error::new_from_span(message, Span::from(number.span.clone()));
number.value.parse::<usize>().expect(&error.to_string())
})

View File

@ -4,15 +4,15 @@ use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FormattedError {}
pub struct ErrorMacro {}
impl<'ast> From<AstError<'ast>> for FormattedError {
impl<'ast> From<AstError<'ast>> for ErrorMacro {
fn from(_error: AstError<'ast>) -> Self {
Self {}
}
}
impl fmt::Display for FormattedError {
impl fmt::Display for ErrorMacro {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "error")
}

View File

@ -1,4 +1,4 @@
use crate::{Debug, FormattedError, PrintLine};
use crate::{Debug, ErrorMacro, PrintLine};
use leo_ast::macros::MacroName as AstMacroName;
use serde::{Deserialize, Serialize};
@ -7,7 +7,7 @@ use std::fmt;
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum MacroName {
Debug(Debug),
Error(FormattedError),
Error(ErrorMacro),
PrintLine(PrintLine),
}
@ -15,7 +15,7 @@ impl<'ast> From<AstMacroName<'ast>> for MacroName {
fn from(name: AstMacroName<'ast>) -> Self {
match name {
AstMacroName::Debug(debug) => MacroName::Debug(Debug::from(debug)),
AstMacroName::Error(error) => MacroName::Error(FormattedError::from(error)),
AstMacroName::Error(error) => MacroName::Error(ErrorMacro::from(error)),
AstMacroName::PrintLine(print_line) => MacroName::PrintLine(PrintLine::from(print_line)),
}
}

View File

@ -4,8 +4,8 @@ pub use debug::*;
pub mod formatted_container;
pub use formatted_container::*;
pub mod formatted_error;
pub use formatted_error::*;
pub mod error_macro;
pub use error_macro::*;
pub mod formatted_macro;
pub use formatted_macro::*;