mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-23 15:15:47 +03:00
Support private mode in parser and passes
This commit is contained in:
parent
1b95340edc
commit
b16926449c
@ -279,7 +279,7 @@ impl ParserContext<'_> {
|
||||
|
||||
/// Returns a [`ParamMode`] AST node if the next tokens represent a function parameter mode.
|
||||
pub(super) fn parse_mode(&mut self) -> Result<Mode> {
|
||||
// TODO: Allow explicit "private" mode.
|
||||
let private = self.eat(&Token::Private).then_some(self.prev_token.span);
|
||||
let public = self.eat(&Token::Public).then_some(self.prev_token.span);
|
||||
let constant = self.eat(&Token::Constant).then_some(self.prev_token.span);
|
||||
let const_ = self.eat(&Token::Const).then_some(self.prev_token.span);
|
||||
@ -288,16 +288,21 @@ impl ParserContext<'_> {
|
||||
self.emit_warning(ParserWarning::const_parameter_or_input(span));
|
||||
}
|
||||
|
||||
match (public, constant, const_) {
|
||||
(None, Some(_), None) => Ok(Mode::Const),
|
||||
(None, None, Some(_)) => Ok(Mode::Const),
|
||||
(None, None, None) => Ok(Mode::None),
|
||||
(Some(_), None, None) => Ok(Mode::Public),
|
||||
(Some(m1), Some(m2), None) | (Some(m1), None, Some(m2)) | (None, Some(m1), Some(m2)) => {
|
||||
Err(ParserError::inputs_multiple_variable_types_specified(m1 + m2).into())
|
||||
}
|
||||
(Some(m1), Some(m2), Some(m3)) => {
|
||||
Err(ParserError::inputs_multiple_variable_types_specified(m1 + m2 + m3).into())
|
||||
match (private, public, constant, const_) {
|
||||
(None, None, None, None) => Ok(Mode::None),
|
||||
(Some(_), None, None, None) => Ok(Mode::Private),
|
||||
(None, Some(_), None, None) => Ok(Mode::Public),
|
||||
(None, None, Some(_), None) => Ok(Mode::Const),
|
||||
(None, None, None, Some(_)) => Ok(Mode::Const),
|
||||
_ => {
|
||||
let mut spans = [private, public, constant, const_].into_iter().flatten();
|
||||
|
||||
// There must exist at least one mode, since the none case is handled above.
|
||||
let starting_span = spans.next().unwrap();
|
||||
// Sum the spans.
|
||||
let summed_span = spans.fold(starting_span, |span, next| span + next);
|
||||
// Emit an error.
|
||||
Err(ParserError::inputs_multiple_variable_modes_specified(summed_span).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -420,6 +420,7 @@ impl Token {
|
||||
"let" => Token::Let,
|
||||
"leo" => Token::Leo,
|
||||
"mapping" => Token::Mapping,
|
||||
"private" => Token::Private,
|
||||
"program" => Token::Program,
|
||||
"public" => Token::Public,
|
||||
"record" => Token::Record,
|
||||
|
@ -103,7 +103,9 @@ mod tests {
|
||||
input
|
||||
let
|
||||
mut
|
||||
private
|
||||
program
|
||||
public
|
||||
return
|
||||
scalar
|
||||
self
|
||||
@ -161,7 +163,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
output,
|
||||
r#""test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" test_ident 12345 address async bool const else false field finalize for function group i128 i64 i32 i16 i8 if in input let mut program return scalar self string struct test transition true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> => _ . .. / : ; < <= = == > >= [ ] { { } } || ? @ // test
|
||||
r#""test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" test_ident 12345 address async bool const else false field finalize for function group i128 i64 i32 i16 i8 if in input let mut private program public return scalar self string struct test transition true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> => _ . .. / : ; < <= = == > >= [ ] { { } } || ? @ // test
|
||||
/* test */ // "#
|
||||
);
|
||||
});
|
||||
|
@ -126,6 +126,7 @@ pub enum Token {
|
||||
Increment,
|
||||
Let,
|
||||
Mapping,
|
||||
Private,
|
||||
Program,
|
||||
// For public inputs.
|
||||
Public,
|
||||
@ -171,6 +172,7 @@ pub const KEYWORD_TOKENS: &[Token] = &[
|
||||
Token::Increment,
|
||||
Token::Let,
|
||||
Token::Mapping,
|
||||
Token::Private,
|
||||
Token::Program,
|
||||
Token::Public,
|
||||
Token::Record,
|
||||
@ -224,8 +226,9 @@ impl Token {
|
||||
Token::Let => sym::Let,
|
||||
Token::Leo => sym::leo,
|
||||
Token::Mapping => sym::mapping,
|
||||
Token::Private => sym::private,
|
||||
Token::Program => sym::program,
|
||||
Token::Public => sym::Public,
|
||||
Token::Public => sym::public,
|
||||
Token::Record => sym::record,
|
||||
Token::Return => sym::Return,
|
||||
Token::Scalar => sym::scalar,
|
||||
@ -345,6 +348,7 @@ impl fmt::Display for Token {
|
||||
Increment => write!(f, "increment"),
|
||||
Let => write!(f, "let"),
|
||||
Mapping => write!(f, "mapping"),
|
||||
Private => write!(f, "private"),
|
||||
Program => write!(f, "program"),
|
||||
Public => write!(f, "public"),
|
||||
Return => write!(f, "return"),
|
||||
|
@ -143,7 +143,7 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
true if input_var.mode() == Mode::Const => self.emit_err(
|
||||
TypeCheckerError::transition_function_inputs_cannot_be_const(input_var.span()),
|
||||
),
|
||||
// If the function is not a program function, then check that the parameters do not have an associated mode.
|
||||
// If the function is not a transition function, then check that the parameters do not have an associated mode.
|
||||
false if input_var.mode() != Mode::None => self.emit_err(
|
||||
TypeCheckerError::regular_function_inputs_cannot_have_modes(input_var.span()),
|
||||
),
|
||||
@ -253,8 +253,8 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
self.assert_type_is_valid(output_type.span(), &output_type.type_());
|
||||
|
||||
// Check that the mode of the output is valid.
|
||||
if output_type.mode() == Mode::Const {
|
||||
self.emit_err(TypeCheckerError::finalize_input_mode_must_be_public(output_type.span()));
|
||||
if output_type.mode() == Mode::Const || output_type.mode() == Mode::Private {
|
||||
self.emit_err(TypeCheckerError::finalize_output_mode_must_be_public(output_type.span()));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -206,7 +206,6 @@ symbols! {
|
||||
mapping,
|
||||
Mut: "mut",
|
||||
prelude,
|
||||
Public,
|
||||
Return: "return",
|
||||
SelfLower: "self",
|
||||
SelfUpper: "Self",
|
||||
|
@ -183,12 +183,12 @@ create_messages!(
|
||||
help: None,
|
||||
}
|
||||
|
||||
/// For when a user specified more than a type on a parameter.
|
||||
/// For when a user specified more than one mode on a parameter.
|
||||
@formatted
|
||||
inputs_multiple_variable_types_specified {
|
||||
inputs_multiple_variable_modes_specified {
|
||||
args: (),
|
||||
msg: "A parameter cannot be both public and const.",
|
||||
help: None,
|
||||
msg: "A parameter cannot have multiple modes.",
|
||||
help: Some("Consider using either `constant`, `public`, `private`, or none at all.".to_string()),
|
||||
}
|
||||
|
||||
/// For when the lexer encountered a bidi override character
|
||||
|
@ -314,7 +314,14 @@ create_messages!(
|
||||
finalize_input_mode_must_be_public {
|
||||
args: (),
|
||||
msg: format!("An input to a finalize block must be public."),
|
||||
help: Some("Add a `public` modifier to the input variable declaration or remove the visibility modifier entirely.".to_string()),
|
||||
help: Some("Use a `public` modifier to the input variable declaration or remove the visibility modifier entirely.".to_string()),
|
||||
}
|
||||
|
||||
@formatted
|
||||
finalize_output_mode_must_be_public {
|
||||
args: (),
|
||||
msg: format!("An output from a finalize block must be public."),
|
||||
help: Some("Use a `public` modifier to the output variable declaration or remove the visibility modifier entirely.".to_string()),
|
||||
}
|
||||
|
||||
@formatted
|
||||
|
Loading…
Reference in New Issue
Block a user