mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
impl syntax error handling
This commit is contained in:
parent
0e8ee81108
commit
bd54f367cf
@ -85,7 +85,8 @@ pub struct Not<'ast> {
|
||||
|
||||
// Binary Operations
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::operation_binary))]
|
||||
pub enum BinaryOperator {
|
||||
Or,
|
||||
And,
|
||||
@ -1003,6 +1004,7 @@ pub struct MultipleAssignmentStatement<'ast> {
|
||||
pub variables: Vec<Variable<'ast>>,
|
||||
pub function_name: Identifier<'ast>,
|
||||
pub arguments: Vec<Expression<'ast>>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
@ -1012,6 +1014,7 @@ pub struct MultipleAssignmentStatement<'ast> {
|
||||
pub struct DefinitionStatement<'ast> {
|
||||
pub variable: Variable<'ast>,
|
||||
pub expression: Expression<'ast>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
@ -1022,6 +1025,7 @@ pub struct AssignStatement<'ast> {
|
||||
pub assignee: Assignee<'ast>,
|
||||
pub assign: OperationAssign,
|
||||
pub expression: Expression<'ast>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
@ -1031,6 +1035,7 @@ pub struct AssignStatement<'ast> {
|
||||
pub struct AssertEq<'ast> {
|
||||
pub left: Expression<'ast>,
|
||||
pub right: Expression<'ast>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
@ -1045,6 +1050,7 @@ pub enum AssertStatement<'ast> {
|
||||
#[pest_ast(rule(Rule::statement_expression))]
|
||||
pub struct ExpressionStatement<'ast> {
|
||||
pub expression: Expression<'ast>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
@ -1185,6 +1191,10 @@ pub struct Function<'ast> {
|
||||
#[pest_ast(rule(Rule::EOI))]
|
||||
pub struct EOI;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::LINE_END))]
|
||||
pub struct LineEnd;
|
||||
|
||||
// Imports
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
@ -1210,6 +1220,7 @@ pub struct ImportSymbol<'ast> {
|
||||
pub struct Import<'ast> {
|
||||
pub source: ImportSource<'ast>,
|
||||
pub symbols: Vec<ImportSymbol<'ast>>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
@ -88,7 +88,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
.map_err(|_| CompilerError::FileReadError(self.main_file_path.clone()))?;
|
||||
|
||||
// Parse the file using leo.pest
|
||||
let mut file = ast::parse(&unparsed_file).map_err(|_| CompilerError::FileParsingError)?;
|
||||
let mut file = ast::parse(&unparsed_file).map_err(|error| {
|
||||
CompilerError::from(error.with_path(&self.main_file_path.to_str().unwrap()))
|
||||
})?;
|
||||
|
||||
// Build the abstract syntax tree
|
||||
let syntax_tree =
|
||||
|
@ -427,11 +427,12 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
self.enforce_assert_eq_statement(cs, left, right)?;
|
||||
}
|
||||
}
|
||||
(val_1, val_2) => unimplemented!(
|
||||
"assert eq not supported for given types {} == {}",
|
||||
val_1,
|
||||
val_2
|
||||
),
|
||||
(val_1, val_2) => {
|
||||
return Err(StatementError::AssertEq(
|
||||
val_1.to_string(),
|
||||
val_2.to_string(),
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
44
compiler/src/errors/ast/mod.rs
Normal file
44
compiler/src/errors/ast/mod.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest::error::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SyntaxError {
|
||||
#[error("aborting due to syntax error")]
|
||||
Error,
|
||||
}
|
||||
|
||||
impl From<Error<Rule>> for SyntaxError {
|
||||
fn from(mut error: Error<Rule>) -> Self {
|
||||
error = error.renamed_rules(|rule| match *rule {
|
||||
Rule::LINE_END => "`;`".to_owned(),
|
||||
Rule::type_integer => "`u32`".to_owned(),
|
||||
Rule::type_field => "`field`".to_owned(),
|
||||
Rule::type_group => "`group`".to_owned(),
|
||||
Rule::file => "an import, circuit, or function".to_owned(),
|
||||
Rule::identifier => "a variable name".to_owned(),
|
||||
Rule::_type => "a type".to_owned(),
|
||||
Rule::access => "`.`, `::`, `()`".to_owned(),
|
||||
|
||||
Rule::operation_and => "`&&`".to_owned(),
|
||||
Rule::operation_or => "`||`".to_owned(),
|
||||
Rule::operation_eq => "`==`".to_owned(),
|
||||
Rule::operation_ne => "`!=`".to_owned(),
|
||||
Rule::operation_ge => "`>=`".to_owned(),
|
||||
Rule::operation_gt => "`>`".to_owned(),
|
||||
Rule::operation_le => "`<=`".to_owned(),
|
||||
Rule::operation_lt => "`<`".to_owned(),
|
||||
Rule::operation_add => "`+`".to_owned(),
|
||||
Rule::operation_sub => "`-`".to_owned(),
|
||||
Rule::operation_mul => "`*`".to_owned(),
|
||||
Rule::operation_div => "`/`".to_owned(),
|
||||
Rule::operation_pow => "`**`".to_owned(),
|
||||
|
||||
rule => format!("{:?}", rule),
|
||||
});
|
||||
|
||||
log::error!("{}\n", error);
|
||||
|
||||
SyntaxError::Error
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
use crate::errors::{FunctionError, ImportError, IntegerError};
|
||||
use crate::ast::Rule;
|
||||
use crate::errors::{FunctionError, ImportError, IntegerError, SyntaxError};
|
||||
|
||||
use pest::error::Error;
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@ -11,13 +13,13 @@ pub enum CompilerError {
|
||||
DirectoryError(io::Error),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ImportError(ImportError),
|
||||
ImportError(#[from] ImportError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(IntegerError),
|
||||
IntegerError(#[from] IntegerError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FunctionError(FunctionError),
|
||||
FunctionError(#[from] FunctionError),
|
||||
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
@ -31,6 +33,9 @@ pub enum CompilerError {
|
||||
#[error("Main must be a function")]
|
||||
NoMainFunction,
|
||||
|
||||
#[error("{}", _0)]
|
||||
SyntaxError(#[from] SyntaxError),
|
||||
|
||||
#[error("Unable to construct abstract syntax tree")]
|
||||
SyntaxTreeError,
|
||||
|
||||
@ -38,20 +43,8 @@ pub enum CompilerError {
|
||||
Writing(io::Error),
|
||||
}
|
||||
|
||||
impl From<ImportError> for CompilerError {
|
||||
fn from(error: ImportError) -> Self {
|
||||
CompilerError::ImportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IntegerError> for CompilerError {
|
||||
fn from(error: IntegerError) -> Self {
|
||||
CompilerError::IntegerError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FunctionError> for CompilerError {
|
||||
fn from(error: FunctionError) -> Self {
|
||||
CompilerError::FunctionError(error)
|
||||
impl From<Error<Rule>> for CompilerError {
|
||||
fn from(error: Error<Rule>) -> Self {
|
||||
CompilerError::SyntaxError(SyntaxError::from(error))
|
||||
}
|
||||
}
|
||||
|
@ -1,33 +1,16 @@
|
||||
use crate::errors::ValueError;
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum BooleanError {
|
||||
#[error("{}", _0)]
|
||||
ValueError(ValueError),
|
||||
|
||||
#[error("Expected boolean parameter, got {}", _0)]
|
||||
InvalidBoolean(String),
|
||||
|
||||
#[error("Cannot evaluate {}", _0)]
|
||||
CannotEvaluate(String),
|
||||
|
||||
#[error("Cannot enforce {}", _0)]
|
||||
CannotEnforce(String),
|
||||
|
||||
#[error("Expected boolean parameter, got {}", _0)]
|
||||
InvalidBoolean(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for BooleanError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
BooleanError::SynthesisError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValueError> for BooleanError {
|
||||
fn from(error: ValueError) -> Self {
|
||||
BooleanError::ValueError(error)
|
||||
}
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
@ -12,136 +12,88 @@ pub enum ExpressionError {
|
||||
UndefinedIdentifier(String),
|
||||
|
||||
// Types
|
||||
#[error("Expected single type for implicit number {}", _0)]
|
||||
SingleType(String),
|
||||
#[error("{}", _0)]
|
||||
BooleanError(#[from] BooleanError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IncompatibleTypes(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ValueError(ValueError),
|
||||
IntegerError(#[from] IntegerError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(IntegerError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ParseIntError(ParseIntError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FieldError(FieldError),
|
||||
FieldError(#[from] FieldError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
GroupError(#[from] GroupError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
BooleanError(BooleanError),
|
||||
ParseIntError(#[from] ParseIntError),
|
||||
|
||||
#[error("Exponent must be an integer, got field {}", _0)]
|
||||
InvalidExponent(String),
|
||||
#[error("{}", _0)]
|
||||
ValueError(#[from] ValueError),
|
||||
|
||||
// Arrays
|
||||
#[error(
|
||||
"Array {} must be declared before it is used in an inline expression",
|
||||
_0
|
||||
)]
|
||||
UndefinedArray(String),
|
||||
|
||||
#[error("Cannot access array {}", _0)]
|
||||
InvalidArrayAccess(String),
|
||||
|
||||
#[error("Spread should contain an array, got {}", _0)]
|
||||
InvalidSpread(String),
|
||||
|
||||
#[error("Index must resolve to an integer, got {}", _0)]
|
||||
InvalidIndex(String),
|
||||
|
||||
#[error("Expected array length {}, got {}", _0, _1)]
|
||||
InvalidLength(usize, usize),
|
||||
|
||||
#[error("Spread should contain an array, got {}", _0)]
|
||||
InvalidSpread(String),
|
||||
|
||||
#[error(
|
||||
"Array {} must be declared before it is used in an inline expression",
|
||||
_0
|
||||
)]
|
||||
UndefinedArray(String),
|
||||
|
||||
// Circuits
|
||||
#[error("Expected circuit member {}", _0)]
|
||||
ExpectedCircuitMember(String),
|
||||
|
||||
#[error("Cannot access circuit {}", _0)]
|
||||
InvalidCircuitAccess(String),
|
||||
|
||||
#[error("Non-static member {} must be accessed using `.` syntax", _0)]
|
||||
InvalidMemberAccess(String),
|
||||
|
||||
#[error("Static member {} must be accessed using `::` syntax", _0)]
|
||||
InvalidStaticAccess(String),
|
||||
|
||||
#[error(
|
||||
"Circuit {} must be declared before it is used in an inline expression",
|
||||
_0
|
||||
)]
|
||||
UndefinedCircuit(String),
|
||||
|
||||
#[error("Cannot access circuit {}", _0)]
|
||||
InvalidCircuitAccess(String),
|
||||
|
||||
#[error("Expected circuit member {}", _0)]
|
||||
ExpectedCircuitMember(String),
|
||||
|
||||
#[error("Circuit {} has no member {}", _0, _1)]
|
||||
UndefinedMemberAccess(String, String),
|
||||
|
||||
#[error("Non-static member {} must be accessed using `.` syntax", _0)]
|
||||
InvalidMemberAccess(String),
|
||||
|
||||
#[error("Circuit {} has no static member {}", _0, _1)]
|
||||
UndefinedStaticAccess(String, String),
|
||||
|
||||
#[error("Static member {} must be accessed using `::` syntax", _0)]
|
||||
InvalidStaticAccess(String),
|
||||
|
||||
// Functions
|
||||
#[error("Inline function call to {} did not return", _0)]
|
||||
FunctionDidNotReturn(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FunctionError(#[from] Box<FunctionError>),
|
||||
|
||||
#[error(
|
||||
"Function {} must be declared before it is used in an inline expression",
|
||||
_0
|
||||
)]
|
||||
UndefinedFunction(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FunctionError(Box<FunctionError>),
|
||||
|
||||
#[error("Inline function call to {} did not return", _0)]
|
||||
FunctionDidNotReturn(String),
|
||||
|
||||
// Conditionals
|
||||
#[error("If, else conditional must resolve to a boolean, got {}", _0)]
|
||||
IfElseConditional(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for ExpressionError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
ExpressionError::SynthesisError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValueError> for ExpressionError {
|
||||
fn from(error: ValueError) -> Self {
|
||||
ExpressionError::ValueError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IntegerError> for ExpressionError {
|
||||
fn from(error: IntegerError) -> Self {
|
||||
ExpressionError::IntegerError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParseIntError> for ExpressionError {
|
||||
fn from(error: ParseIntError) -> Self {
|
||||
ExpressionError::ParseIntError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FieldError> for ExpressionError {
|
||||
fn from(error: FieldError) -> Self {
|
||||
ExpressionError::FieldError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BooleanError> for ExpressionError {
|
||||
fn from(error: BooleanError) -> Self {
|
||||
ExpressionError::BooleanError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<FunctionError>> for ExpressionError {
|
||||
fn from(error: Box<FunctionError>) -> Self {
|
||||
ExpressionError::FunctionError(error)
|
||||
}
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
@ -9,11 +9,5 @@ pub enum FieldError {
|
||||
NoInverse(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for FieldError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
FieldError::SynthesisError(error)
|
||||
}
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
@ -7,78 +7,27 @@ pub enum FunctionError {
|
||||
#[error("Function expected {} inputs, got {}", _0, _1)]
|
||||
ArgumentsLength(usize, usize),
|
||||
|
||||
#[error("Function input type not defined {}", _0)]
|
||||
UndefinedInput(String),
|
||||
#[error("{}", _0)]
|
||||
BooleanError(#[from] BooleanError),
|
||||
|
||||
#[error("Function expected input type {}, got {}", _0, _1)]
|
||||
InvalidInput(String, String),
|
||||
#[error("{}", _0)]
|
||||
ExpressionError(#[from] ExpressionError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FieldError(#[from] FieldError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
GroupError(#[from] GroupError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(#[from] IntegerError),
|
||||
|
||||
#[error("Expected function input array, got {}", _0)]
|
||||
InvalidArray(String),
|
||||
|
||||
#[error("Expected function input array length {}, got length {}", _0, _1)]
|
||||
InvalidArrayLength(usize, usize),
|
||||
#[error("{}", _0)]
|
||||
StatementError(#[from] StatementError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ValueError(ValueError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(IntegerError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FieldError(FieldError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
GroupError(GroupError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
BooleanError(BooleanError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ExpressionError(ExpressionError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
StatementError(StatementError),
|
||||
}
|
||||
|
||||
impl From<ValueError> for FunctionError {
|
||||
fn from(error: ValueError) -> Self {
|
||||
FunctionError::ValueError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IntegerError> for FunctionError {
|
||||
fn from(error: IntegerError) -> Self {
|
||||
FunctionError::IntegerError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FieldError> for FunctionError {
|
||||
fn from(error: FieldError) -> Self {
|
||||
FunctionError::FieldError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GroupError> for FunctionError {
|
||||
fn from(error: GroupError) -> Self {
|
||||
FunctionError::GroupError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BooleanError> for FunctionError {
|
||||
fn from(error: BooleanError) -> Self {
|
||||
FunctionError::BooleanError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExpressionError> for FunctionError {
|
||||
fn from(error: ExpressionError) -> Self {
|
||||
FunctionError::ExpressionError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StatementError> for FunctionError {
|
||||
fn from(error: StatementError) -> Self {
|
||||
FunctionError::StatementError(error)
|
||||
}
|
||||
ValueError(#[from] ValueError),
|
||||
}
|
||||
|
@ -6,11 +6,5 @@ pub enum GroupError {
|
||||
Invalid(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for GroupError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
GroupError::SynthesisError(error)
|
||||
}
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
@ -5,12 +5,12 @@ pub enum ImportError {
|
||||
#[error("Attempt to access current directory failed - {:?}", _0)]
|
||||
DirectoryError(io::Error),
|
||||
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
|
||||
#[error("Syntax error. Cannot parse the file")]
|
||||
FileParsingError,
|
||||
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
|
||||
#[error("Unable to construct abstract syntax tree")]
|
||||
SyntaxTreeError,
|
||||
}
|
||||
|
@ -2,24 +2,12 @@ use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum IntegerError {
|
||||
#[error("expected integer parameter type, got {}", _0)]
|
||||
InvalidType(String),
|
||||
#[error("Cannot enforce {}", _0)]
|
||||
CannotEnforce(String),
|
||||
|
||||
#[error("Expected integer parameter, got {}", _0)]
|
||||
InvalidInteger(String),
|
||||
|
||||
#[error("Cannot evaluate {}", _0)]
|
||||
CannotEvaluate(String),
|
||||
|
||||
#[error("Cannot enforce {}", _0)]
|
||||
CannotEnforce(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for IntegerError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
IntegerError::SynthesisError(error)
|
||||
}
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
@ -1,27 +1,18 @@
|
||||
use crate::errors::{BooleanError, ExpressionError, FieldError, IntegerError, ValueError};
|
||||
use crate::errors::{BooleanError, ExpressionError};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum StatementError {
|
||||
#[error("{}", _0)]
|
||||
BooleanError(#[from] BooleanError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ExpressionError(#[from] ExpressionError),
|
||||
|
||||
#[error("Attempted to assign to unknown variable {}", _0)]
|
||||
UndefinedVariable(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ExpressionError(ExpressionError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(IntegerError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FieldError(FieldError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
BooleanError(BooleanError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ValueError(ValueError),
|
||||
|
||||
// Arrays
|
||||
#[error("Cannot assign single index to array of values")]
|
||||
ArrayAssignIndex,
|
||||
@ -29,9 +20,6 @@ pub enum StatementError {
|
||||
#[error("Cannot assign range of array values to single value")]
|
||||
ArrayAssignRange,
|
||||
|
||||
#[error("Cannot assign to unknown array {}", _0)]
|
||||
UndefinedArray(String),
|
||||
|
||||
// Circuits
|
||||
#[error("Cannot mutate circuit function, {}", _0)]
|
||||
ImmutableCircuitFunction(String),
|
||||
@ -43,6 +31,12 @@ pub enum StatementError {
|
||||
UndefinedCircuitObject(String),
|
||||
|
||||
// Statements
|
||||
#[error("Cannot assert equality between {} == {}", _0, _1)]
|
||||
AssertEq(String, String),
|
||||
|
||||
#[error("If, else conditional must resolve to a boolean, got {}", _0)]
|
||||
IfElseConditional(String),
|
||||
|
||||
#[error("Cannot assign to immutable variable {}", _0)]
|
||||
ImmutableAssign(String),
|
||||
|
||||
@ -56,45 +50,9 @@ pub enum StatementError {
|
||||
#[error("Function return statement expected {} return values, got {}", _0, _1)]
|
||||
InvalidNumberOfReturns(usize, usize),
|
||||
|
||||
#[error("If, else conditional must resolve to a boolean, got {}", _0)]
|
||||
IfElseConditional(String),
|
||||
|
||||
#[error("Cannot assert equality between {} == {}", _0, _1)]
|
||||
AssertEq(String, String),
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
|
||||
#[error("Expected assignment of return values for expression {}", _0)]
|
||||
Unassigned(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
||||
impl From<ExpressionError> for StatementError {
|
||||
fn from(error: ExpressionError) -> Self {
|
||||
StatementError::ExpressionError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IntegerError> for StatementError {
|
||||
fn from(error: IntegerError) -> Self {
|
||||
StatementError::IntegerError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FieldError> for StatementError {
|
||||
fn from(error: FieldError) -> Self {
|
||||
StatementError::FieldError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BooleanError> for StatementError {
|
||||
fn from(error: BooleanError) -> Self {
|
||||
StatementError::BooleanError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValueError> for StatementError {
|
||||
fn from(error: ValueError) -> Self {
|
||||
StatementError::ValueError(error)
|
||||
}
|
||||
}
|
||||
|
@ -5,49 +5,17 @@ use std::{num::ParseIntError, str::ParseBoolError};
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ValueError {
|
||||
#[error("{}", _0)]
|
||||
ParseIntError(ParseIntError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ParseBoolError(ParseBoolError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(IntegerError),
|
||||
/// Unexpected array length
|
||||
#[error("{}", _0)]
|
||||
ArrayLength(String),
|
||||
|
||||
#[error("Expected type array, got {}", _0)]
|
||||
ArrayModel(String),
|
||||
|
||||
/// Unexpected circuit name
|
||||
#[error("Expected circuit name {} got {}", _0, _1)]
|
||||
CircuitName(String, String),
|
||||
|
||||
/// Unexpected type
|
||||
#[error("{}", _0)]
|
||||
TypeError(String),
|
||||
FieldError(#[from] FieldError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
GroupError(#[from] GroupError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FieldError(#[from] FieldError),
|
||||
}
|
||||
IntegerError(#[from] IntegerError),
|
||||
|
||||
impl From<ParseIntError> for ValueError {
|
||||
fn from(error: ParseIntError) -> Self {
|
||||
ValueError::ParseIntError(error)
|
||||
}
|
||||
}
|
||||
#[error("{}", _0)]
|
||||
ParseBoolError(#[from] ParseBoolError),
|
||||
|
||||
impl From<ParseBoolError> for ValueError {
|
||||
fn from(error: ParseBoolError) -> Self {
|
||||
ValueError::ParseBoolError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IntegerError> for ValueError {
|
||||
fn from(error: IntegerError) -> Self {
|
||||
ValueError::IntegerError(error)
|
||||
}
|
||||
#[error("{}", _0)]
|
||||
ParseIntError(#[from] ParseIntError),
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
pub mod ast;
|
||||
pub use self::ast::*;
|
||||
|
||||
pub mod compiler;
|
||||
pub use self::compiler::*;
|
||||
|
||||
|
@ -173,7 +173,7 @@ expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
|
||||
|
||||
/// Asserts
|
||||
|
||||
assert_eq = {"assert_eq!" ~ "(" ~ NEWLINE* ~ expression ~ "," ~ NEWLINE* ~ expression ~ NEWLINE* ~ ")"}
|
||||
assert_eq = {"assert_eq!" ~ "(" ~ NEWLINE* ~ expression ~ "," ~ NEWLINE* ~ expression ~ NEWLINE* ~ ")" ~ LINE_END}
|
||||
// assert_true = {"assert"}
|
||||
|
||||
/// Conditionals
|
||||
@ -181,16 +181,16 @@ conditional_nested_or_end = { statement_conditional | "{" ~ NEWLINE* ~ statement
|
||||
|
||||
/// Statements
|
||||
statement_return = { "return" ~ expression_tuple }
|
||||
statement_definition = { "let" ~ variable ~ "=" ~ expression }
|
||||
statement_assign = { assignee ~ operation_assign ~ expression }
|
||||
statement_multiple_assignment = { "let" ~ "(" ~ variable_tuple ~ ")" ~ "=" ~ identifier ~ "(" ~ expression_tuple ~ ")" }
|
||||
statement_definition = { "let" ~ variable ~ "=" ~ expression ~ LINE_END}
|
||||
statement_assign = { assignee ~ operation_assign ~ expression ~ LINE_END}
|
||||
statement_multiple_assignment = { "let" ~ "(" ~ variable_tuple ~ ")" ~ "=" ~ identifier ~ "(" ~ expression_tuple ~ ")" ~ LINE_END}
|
||||
statement_conditional = {"if" ~ (expression | "(" ~ expression ~ ")") ~ "{" ~ NEWLINE* ~ statement+ ~ "}" ~ ("else" ~ conditional_nested_or_end)?}
|
||||
statement_for = { "for" ~ identifier ~ "in" ~ expression ~ ".." ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
statement_assert = {
|
||||
assert_eq
|
||||
// | assert_true |
|
||||
}
|
||||
statement_expression = { expression }
|
||||
statement_expression = { expression ~ LINE_END }
|
||||
|
||||
statement = {
|
||||
(statement_return
|
||||
@ -201,7 +201,7 @@ statement = {
|
||||
| statement_definition
|
||||
| statement_assign
|
||||
| statement_expression
|
||||
) ~ LINE_END
|
||||
)
|
||||
) ~ NEWLINE*
|
||||
}
|
||||
|
||||
@ -216,7 +216,7 @@ function_definition = {"function" ~ identifier ~ "(" ~ input_model_list ~ ")" ~
|
||||
|
||||
COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
|
||||
WHITESPACE = _{ " " | "\t" ~ (NEWLINE)* }
|
||||
LINE_END = _{";" ~ NEWLINE*}
|
||||
LINE_END = {";" ~ NEWLINE*}
|
||||
|
||||
/// Imports
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
@ -8,6 +8,7 @@ pub mod import;
|
||||
pub mod integer;
|
||||
pub mod mutability;
|
||||
pub mod statement;
|
||||
pub mod syntax;
|
||||
|
||||
use leo_compiler::{
|
||||
compiler::Compiler,
|
||||
|
16
compiler/tests/syntax/mod.rs
Normal file
16
compiler/tests/syntax/mod.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use crate::compile_program;
|
||||
use leo_compiler::errors::CompilerError;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/syntax/";
|
||||
|
||||
#[test]
|
||||
fn test_semicolon() {
|
||||
let error = compile_program(DIRECTORY_NAME, "semicolon.leo")
|
||||
.err()
|
||||
.unwrap();
|
||||
|
||||
match error {
|
||||
CompilerError::SyntaxError(_) => {}
|
||||
_ => panic!("wrong error"),
|
||||
}
|
||||
}
|
3
compiler/tests/syntax/semicolon.leo
Normal file
3
compiler/tests/syntax/semicolon.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main() {
|
||||
let a = 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user