mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 02:31:44 +03:00
commit
754a3ce685
@ -13,7 +13,9 @@
|
||||
|
||||
// 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 super::*;
|
||||
use leo_span::sym;
|
||||
|
||||
/// An initializer for a single field / variable of a circuit initializer expression.
|
||||
/// That is, in `Foo { bar: 42, baz }`, this is either `bar: 42`, or `baz`.
|
||||
@ -50,6 +52,34 @@ pub struct CircuitExpression {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl CircuitExpression {
|
||||
/// Returns true if the record has all required fields and visibility.
|
||||
pub fn check_record(&self) -> bool {
|
||||
let has_member = |symbol| self.members.iter().any(|variable| variable.identifier.name == symbol);
|
||||
|
||||
has_member(sym::owner) && has_member(sym::gates) && has_member(sym::_nonce)
|
||||
}
|
||||
|
||||
/// Returns the circuit as a record interface with visibility.
|
||||
pub fn to_record_string(&self) -> String {
|
||||
format!(
|
||||
"{{{}}}",
|
||||
self.members
|
||||
.iter()
|
||||
.map(|variable| {
|
||||
// Write default visibility.
|
||||
if variable.identifier.name == sym::_nonce {
|
||||
format!("{}.public", variable)
|
||||
} else {
|
||||
format!("{}.private", variable)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CircuitExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
|
@ -58,17 +58,8 @@ impl InputAst {
|
||||
Some(circuit) => match circuit.is_record {
|
||||
false => definition.value.to_string(),
|
||||
true => match &definition.value {
|
||||
Expression::Circuit(circuit_expression) => {
|
||||
format!(
|
||||
"{{{}}}",
|
||||
circuit_expression
|
||||
.members
|
||||
.iter()
|
||||
.map(|x| format!("{}.private", x))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
}
|
||||
// Print out the record interface with visibility.
|
||||
Expression::Circuit(circuit_expression) => circuit_expression.to_record_string(),
|
||||
_ => panic!("Input error: Expected a circuit expression."),
|
||||
},
|
||||
},
|
||||
|
@ -39,6 +39,8 @@ pub(crate) struct ParserContext<'a> {
|
||||
pub(crate) prev_token: SpannedToken,
|
||||
/// true if parsing an expression for if and loop statements -- means circuit inits are not legal
|
||||
pub(crate) disallow_circuit_construction: bool,
|
||||
/// true if parsing an identifier inside an input file.
|
||||
pub(crate) allow_identifier_underscores: bool,
|
||||
}
|
||||
|
||||
/// Dummy span used to appease borrow checker.
|
||||
@ -59,6 +61,7 @@ impl<'a> ParserContext<'a> {
|
||||
let mut p = Self {
|
||||
handler,
|
||||
disallow_circuit_construction: false,
|
||||
allow_identifier_underscores: false,
|
||||
prev_token: token.clone(),
|
||||
token,
|
||||
tokens,
|
||||
|
@ -17,6 +17,7 @@
|
||||
use super::*;
|
||||
use leo_errors::{ParserError, Result};
|
||||
|
||||
use leo_span::Symbol;
|
||||
use snarkvm_console::{account::Address, network::Testnet3};
|
||||
|
||||
const INT_TYPES: &[Token] = &[
|
||||
@ -463,7 +464,14 @@ impl ParserContext<'_> {
|
||||
}
|
||||
|
||||
fn parse_circuit_member(&mut self) -> Result<CircuitVariableInitializer> {
|
||||
let identifier = self.expect_identifier()?;
|
||||
let identifier = if self.allow_identifier_underscores && self.eat(&Token::Underscore) {
|
||||
// Allow `_nonce` for circuit records.
|
||||
let identifier_without_underscore = self.expect_identifier()?;
|
||||
Identifier::new(Symbol::intern(&format!("_{}", identifier_without_underscore.name)))
|
||||
} else {
|
||||
self.expect_identifier()?
|
||||
};
|
||||
|
||||
let expression = if self.eat(&Token::Colon) {
|
||||
// Parse individual circuit variable declarations.
|
||||
Some(self.parse_expression()?)
|
||||
@ -547,11 +555,11 @@ impl ParserContext<'_> {
|
||||
}
|
||||
Token::True => Expression::Literal(Literal::Boolean(true, span)),
|
||||
Token::False => Expression::Literal(Literal::Boolean(false, span)),
|
||||
Token::AddressLit(addr) => {
|
||||
if addr.parse::<Address<Testnet3>>().is_err() {
|
||||
self.emit_err(ParserError::invalid_address_lit(&addr, span));
|
||||
Token::AddressLit(address_string) => {
|
||||
if address_string.parse::<Address<Testnet3>>().is_err() {
|
||||
self.emit_err(ParserError::invalid_address_lit(&address_string, span));
|
||||
}
|
||||
Expression::Literal(Literal::Address(addr, span))
|
||||
Expression::Literal(Literal::Address(address_string, span))
|
||||
}
|
||||
Token::StaticString(value) => Expression::Literal(Literal::String(value, span)),
|
||||
Token::Identifier(name) => {
|
||||
|
@ -21,6 +21,8 @@ use leo_errors::{ParserError, Result};
|
||||
impl ParserContext<'_> {
|
||||
/// Returns a [`ParsedInputFile`] struct filled with the data acquired in the file.
|
||||
pub(crate) fn parse_input(&mut self) -> Result<InputAst> {
|
||||
// Allow underscores in identifiers for input record declarations.
|
||||
self.allow_identifier_underscores = true;
|
||||
let mut sections = Vec::new();
|
||||
|
||||
while self.has_next() {
|
||||
@ -31,6 +33,9 @@ impl ParserContext<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
// Do not allow underscores in identifiers outside of input files.
|
||||
self.allow_identifier_underscores = false;
|
||||
|
||||
Ok(InputAst { sections })
|
||||
}
|
||||
|
||||
|
@ -386,12 +386,12 @@ impl Token {
|
||||
'^' => return match_two(&mut input, Token::BitXor, '=', Token::BitXorAssign),
|
||||
_ => (),
|
||||
}
|
||||
if let Some(ident) = eat_identifier(&mut input) {
|
||||
if let Some(identifier) = eat_identifier(&mut input) {
|
||||
return Ok((
|
||||
ident.len(),
|
||||
identifier.len(),
|
||||
// todo: match on symbols instead of hard-coded &str's
|
||||
match &*ident {
|
||||
x if x.starts_with("aleo1") => Token::AddressLit(ident),
|
||||
match &*identifier {
|
||||
x if x.starts_with("aleo1") => Token::AddressLit(identifier),
|
||||
"address" => Token::Address,
|
||||
"bool" => Token::Bool,
|
||||
"circuit" => Token::Circuit,
|
||||
@ -424,7 +424,7 @@ impl Token {
|
||||
"u32" => Token::U32,
|
||||
"u64" => Token::U64,
|
||||
"u128" => Token::U128,
|
||||
_ => Token::Identifier(Symbol::intern(&ident)),
|
||||
_ => Token::Identifier(Symbol::intern(&identifier)),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
@ -217,6 +217,7 @@ symbols! {
|
||||
private,
|
||||
owner,
|
||||
gates,
|
||||
_nonce,
|
||||
|
||||
// input file
|
||||
registers,
|
||||
|
@ -8,6 +8,7 @@ token: Token = Token {
|
||||
owner: aleo1ht2a9q0gsd38j0se4t9lsfulxgqrens2vgzgry3pkvs93xrrzu8s892zn7,
|
||||
gates: 0u64,
|
||||
amount: 100u64,
|
||||
_nonce: 0group,
|
||||
};
|
||||
to: address = aleo1mgfq6g40l6zkhsm063n3uhr43qk5e0zsua5aszeq5080dsvlcvxsn0rrau;
|
||||
amount: u64 = 50u64;
|
Loading…
Reference in New Issue
Block a user