const_ self as function input properly

This commit is contained in:
gluax 2021-03-23 11:49:27 -04:00
parent fe8eae981d
commit 0ea4f1e0e3
6 changed files with 77 additions and 4 deletions

View File

@ -37,6 +37,7 @@ use std::cell::{Cell, RefCell};
#[derive(Clone, Copy, PartialEq)]
pub enum FunctionQualifier {
SelfRef,
ConstSelfRef,
MutSelfRef,
Static,
}
@ -89,6 +90,9 @@ impl<'a> Function<'a> {
FunctionInput::SelfKeyword(_) => {
qualifier = FunctionQualifier::SelfRef;
}
FunctionInput::ConstSelfKeyword(_) => {
qualifier = FunctionQualifier::ConstSelfRef;
}
FunctionInput::MutSelfKeyword(_) => {
qualifier = FunctionQualifier::MutSelfRef;
}

View File

@ -0,0 +1,44 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{Identifier, Node, Span};
use serde::{Deserialize, Serialize};
use std::fmt;
/// The `self` keyword can view circuit values inside of a circuit function.
/// Circuit values cannot be modified. To modify values use the `mut self` [MutSelfKeyword].
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[serde(transparent)]
pub struct ConstSelfKeyword {
pub identifier: Identifier,
}
impl fmt::Display for ConstSelfKeyword {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "const self")
}
}
impl Node for ConstSelfKeyword {
fn span(&self) -> &Span {
&self.identifier.span
}
fn set_span(&mut self, span: Span) {
self.identifier.span = span;
}
}

View File

@ -17,6 +17,9 @@
pub mod array_dimensions;
pub use array_dimensions::*;
pub mod const_self_keyword;
pub use const_self_keyword::*;
pub mod identifier;
pub use identifier::*;

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{FunctionInputVariable, InputKeyword, MutSelfKeyword, Node, SelfKeyword, Span};
use crate::{ConstSelfKeyword, FunctionInputVariable, InputKeyword, MutSelfKeyword, Node, SelfKeyword, Span};
use serde::{Deserialize, Serialize};
use std::fmt;
@ -24,6 +24,7 @@ use std::fmt;
pub enum FunctionInput {
InputKeyword(InputKeyword),
SelfKeyword(SelfKeyword),
ConstSelfKeyword(ConstSelfKeyword),
MutSelfKeyword(MutSelfKeyword),
Variable(FunctionInputVariable),
}
@ -37,11 +38,26 @@ impl FunctionInput {
match self {
FunctionInput::InputKeyword(_) => false,
FunctionInput::SelfKeyword(_) => true,
FunctionInput::ConstSelfKeyword(_) => true,
FunctionInput::MutSelfKeyword(_) => true,
FunctionInput::Variable(_) => false,
}
}
///
/// Returns `true` if the function input is the `const self` keyword.
/// Returns `false` otherwise.
///
pub fn is_const_self(&self) -> bool {
match self {
FunctionInput::InputKeyword(_) => false,
FunctionInput::SelfKeyword(_) => false,
FunctionInput::ConstSelfKeyword(_) => true,
FunctionInput::MutSelfKeyword(_) => false,
FunctionInput::Variable(_) => false,
}
}
///
/// Returns `true` if the function input is the `mut self` keyword.
/// Returns `false` otherwise.
@ -50,6 +66,7 @@ impl FunctionInput {
match self {
FunctionInput::InputKeyword(_) => false,
FunctionInput::SelfKeyword(_) => false,
FunctionInput::ConstSelfKeyword(_) => false,
FunctionInput::MutSelfKeyword(_) => true,
FunctionInput::Variable(_) => false,
}
@ -59,6 +76,7 @@ impl FunctionInput {
match self {
FunctionInput::InputKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::SelfKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::ConstSelfKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::MutSelfKeyword(keyword) => write!(f, "{}", keyword),
FunctionInput::Variable(function_input) => write!(f, "{}", function_input),
}
@ -83,6 +101,7 @@ impl PartialEq for FunctionInput {
match (self, other) {
(FunctionInput::InputKeyword(_), FunctionInput::InputKeyword(_)) => true,
(FunctionInput::SelfKeyword(_), FunctionInput::SelfKeyword(_)) => true,
(FunctionInput::ConstSelfKeyword(_), FunctionInput::ConstSelfKeyword(_)) => true,
(FunctionInput::MutSelfKeyword(_), FunctionInput::MutSelfKeyword(_)) => true,
(FunctionInput::Variable(left), FunctionInput::Variable(right)) => left.eq(right),
_ => false,
@ -98,6 +117,7 @@ impl Node for FunctionInput {
match self {
InputKeyword(keyword) => &keyword.identifier.span,
SelfKeyword(keyword) => &keyword.identifier.span,
ConstSelfKeyword(keyword) => &keyword.identifier.span,
MutSelfKeyword(keyword) => &keyword.identifier.span,
Variable(variable) => &variable.span,
}
@ -108,6 +128,7 @@ impl Node for FunctionInput {
match self {
InputKeyword(keyword) => keyword.identifier.span = span,
SelfKeyword(keyword) => keyword.identifier.span = span,
ConstSelfKeyword(keyword) => keyword.identifier.span = span,
MutSelfKeyword(keyword) => keyword.identifier.span = span,
Variable(variable) => variable.span = span,
}

View File

@ -49,7 +49,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
}
match function.qualifier {
FunctionQualifier::SelfRef | FunctionQualifier::MutSelfRef => {
FunctionQualifier::SelfRef | FunctionQualifier::ConstSelfRef | FunctionQualifier::MutSelfRef => {
unimplemented!("cannot access self variable in main function")
}
FunctionQualifier::Static => (),

View File

@ -334,6 +334,7 @@ impl ParserContext {
} else if let Some(const_) = &const_ {
name.span = &const_.span + &name.span;
name.name = "const self".to_string();
return Ok(FunctionInput::ConstSelfKeyword(ConstSelfKeyword { identifier: name }));
}
return Ok(FunctionInput::SelfKeyword(SelfKeyword { identifier: name }));
}
@ -347,8 +348,8 @@ impl ParserContext {
self.expect(Token::Colon)?;
let type_ = self.parse_type()?.0;
Ok(FunctionInput::Variable(FunctionInputVariable {
const_: const_.is_some() || (const_.is_none() && mutable.is_none()),
mutable: mutable.is_some(),
const_: const_.is_some(),
mutable: const_.is_none(),
type_,
span: name.span.clone(),
identifier: name,