mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-13 08:47:17 +03:00
Some cleanup
This commit is contained in:
parent
c551179b42
commit
eb8366badc
@ -60,6 +60,7 @@ impl ParserContext<'_> {
|
||||
let (id, function) = self.parse_function()?;
|
||||
functions.insert(id, function);
|
||||
}
|
||||
Token::Circuit => return Err(ParserError::circuit_is_deprecated(self.token.span).into()),
|
||||
_ => return Err(Self::unexpected_item(&self.token).into()),
|
||||
}
|
||||
}
|
||||
@ -173,9 +174,9 @@ impl ParserContext<'_> {
|
||||
|
||||
/// Returns a [`Member`] AST node if the next tokens represent a struct member variable.
|
||||
fn parse_member_variable_declaration(&mut self) -> Result<Member> {
|
||||
let (name, type_) = self.parse_typed_ident()?;
|
||||
let (identifier, type_) = self.parse_typed_ident()?;
|
||||
|
||||
Ok(Member::StructVariable(name, type_))
|
||||
Ok(Member { identifier, type_ })
|
||||
}
|
||||
|
||||
/// Parses a struct or record definition, e.g., `struct Foo { ... }` or `record Foo { ... }`.
|
||||
|
@ -396,6 +396,7 @@ impl Token {
|
||||
"address" => Token::Address,
|
||||
"async" => Token::Async,
|
||||
"bool" => Token::Bool,
|
||||
"circuit" => Token::Circuit,
|
||||
"console" => Token::Console,
|
||||
"const" => Token::Const,
|
||||
"constant" => Token::Constant,
|
||||
|
@ -324,6 +324,7 @@ impl fmt::Display for Token {
|
||||
Record => write!(f, "record"),
|
||||
|
||||
Async => write!(f, "async"),
|
||||
Circuit => write!(f, "circuit"),
|
||||
Console => write!(f, "console"),
|
||||
Const => write!(f, "const"),
|
||||
Constant => write!(f, "constant"),
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::CodeGenerator;
|
||||
|
||||
use leo_ast::{functions, Function, Identifier, Mapping, Member, Mode, Program, Struct, Type};
|
||||
use leo_ast::{functions, Function, Identifier, Mapping, Mode, Program, Struct, Type};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use itertools::Itertools;
|
||||
@ -131,11 +131,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
|
||||
// Construct and append the record variables.
|
||||
for var in struct_.members.iter() {
|
||||
let (name, type_) = match var {
|
||||
Member::StructVariable(name, type_) => (name, type_),
|
||||
};
|
||||
|
||||
writeln!(output_string, " {} as {};", name, type_,).expect("failed to write to string");
|
||||
writeln!(output_string, " {} as {};", var.identifier, var.type_,).expect("failed to write to string");
|
||||
}
|
||||
|
||||
output_string
|
||||
@ -150,14 +146,10 @@ impl<'a> CodeGenerator<'a> {
|
||||
|
||||
// Construct and append the record variables.
|
||||
for var in record.members.iter() {
|
||||
let (name, type_) = match var {
|
||||
Member::StructVariable(name, type_) => (name, type_),
|
||||
};
|
||||
|
||||
writeln!(
|
||||
output_string,
|
||||
" {} as {}.private;", // todo: CAUTION private record variables only.
|
||||
name, type_,
|
||||
var.identifier, var.type_,
|
||||
)
|
||||
.expect("failed to write to string");
|
||||
}
|
||||
|
@ -108,18 +108,18 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
let members = first_member_struct
|
||||
.members
|
||||
.iter()
|
||||
.map(|Member::StructVariable(id, _)| {
|
||||
.map(|Member { identifier, .. }| {
|
||||
// Construct a new ternary expression for the struct member.
|
||||
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression {
|
||||
condition: input.condition.clone(),
|
||||
if_true: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||
inner: Box::new(Expression::Access(AccessExpression::Member(first.clone()))),
|
||||
name: *id,
|
||||
name: *identifier,
|
||||
span: Default::default(),
|
||||
}))),
|
||||
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||
inner: Box::new(Expression::Access(AccessExpression::Member(second.clone()))),
|
||||
name: *id,
|
||||
name: *identifier,
|
||||
span: Default::default(),
|
||||
}))),
|
||||
span: Default::default(),
|
||||
@ -133,7 +133,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
statements.push(statement);
|
||||
|
||||
StructVariableInitializer {
|
||||
identifier: *id,
|
||||
identifier,
|
||||
expression: Some(Expression::Identifier(identifier)),
|
||||
}
|
||||
})
|
||||
@ -204,18 +204,18 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
let members = first_struct
|
||||
.members
|
||||
.iter()
|
||||
.map(|Member::StructVariable(id, _)| {
|
||||
.map(|Member { identifier, .. }| {
|
||||
// Construct a new ternary expression for the struct member.
|
||||
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression {
|
||||
condition: input.condition.clone(),
|
||||
if_true: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||
inner: Box::new(Expression::Identifier(first)),
|
||||
name: *id,
|
||||
name: *identifier,
|
||||
span: Default::default(),
|
||||
}))),
|
||||
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||
inner: Box::new(Expression::Identifier(second)),
|
||||
name: *id,
|
||||
name: *identifier,
|
||||
span: Default::default(),
|
||||
}))),
|
||||
span: Default::default(),
|
||||
@ -229,7 +229,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
statements.push(statement);
|
||||
|
||||
StructVariableInitializer {
|
||||
identifier: *id,
|
||||
identifier,
|
||||
expression: Some(Expression::Identifier(identifier)),
|
||||
}
|
||||
})
|
||||
|
@ -126,12 +126,12 @@ impl<'a> Flattener<'a> {
|
||||
// The inner expression of an access expression is either an identifier or another access expression.
|
||||
let name = self.lookup_struct_symbol(&access.inner).unwrap();
|
||||
let struct_ = self.symbol_table.lookup_struct(name).unwrap();
|
||||
let Member::StructVariable(_, member_type) = struct_
|
||||
let Member { type_, .. } = struct_
|
||||
.members
|
||||
.iter()
|
||||
.find(|member| member.name() == access.name.name)
|
||||
.unwrap();
|
||||
match member_type {
|
||||
match type_ {
|
||||
Type::Identifier(identifier) => Some(identifier.name),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
||||
// Check that `access.name` is a member of the struct.
|
||||
match struct_.members.iter().find(|member| member.name() == access.name.name) {
|
||||
// Case where `access.name` is a member of the struct.
|
||||
Some(Member::StructVariable(_, type_)) => return Some(type_.clone()),
|
||||
Some(Member { type_, .. }) => return Some(type_.clone()),
|
||||
// Case where `access.name` is not a member of the struct.
|
||||
None => {
|
||||
self.emit_err(TypeCheckerError::invalid_struct_variable(
|
||||
@ -482,16 +482,20 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
||||
}
|
||||
|
||||
// Check struct member types.
|
||||
struct_.members.iter().for_each(|Member::StructVariable(name, ty)| {
|
||||
struct_.members.iter().for_each(|Member { identifier, type_ }| {
|
||||
// Lookup struct variable name.
|
||||
if let Some(actual) = input.members.iter().find(|member| member.identifier.name == name.name) {
|
||||
if let Some(actual) = input
|
||||
.members
|
||||
.iter()
|
||||
.find(|member| member.identifier.name == identifier.name)
|
||||
{
|
||||
if let Some(expr) = &actual.expression {
|
||||
self.visit_expression(expr, &Some(ty.clone()));
|
||||
self.visit_expression(expr, &Some(type_.clone()));
|
||||
}
|
||||
} else {
|
||||
self.emit_err(TypeCheckerError::missing_struct_member(
|
||||
struct_.identifier,
|
||||
name,
|
||||
identifier,
|
||||
input.span(),
|
||||
));
|
||||
};
|
||||
|
@ -29,11 +29,11 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
fn visit_struct(&mut self, input: &'a Struct) {
|
||||
// Check for conflicting struct/record member names.
|
||||
let mut used = HashSet::new();
|
||||
if !input.members.iter().all(|Member::StructVariable(ident, type_)| {
|
||||
if !input.members.iter().all(|Member { identifier, type_ }| {
|
||||
// TODO: Better spans.
|
||||
// Check that the member types are valid.
|
||||
self.assert_type_is_valid(input.span, type_);
|
||||
used.insert(ident.name)
|
||||
used.insert(identifier.name)
|
||||
}) {
|
||||
self.emit_err(if input.is_record {
|
||||
TypeCheckerError::duplicate_record_variable(input.name(), input.span())
|
||||
@ -47,7 +47,7 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
let check_has_field = |need, expected_ty: Type| match input
|
||||
.members
|
||||
.iter()
|
||||
.find_map(|Member::StructVariable(v, t)| (v.name == need).then_some((v, t)))
|
||||
.find_map(|Member { identifier, type_ }| (identifier.name == need).then_some((identifier, type_)))
|
||||
{
|
||||
Some((_, actual_ty)) if expected_ty.eq_flat(actual_ty) => {} // All good, found + right type!
|
||||
Some((field, _)) => {
|
||||
@ -69,11 +69,11 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
check_has_field(sym::gates, Type::Integer(IntegerType::U64));
|
||||
}
|
||||
|
||||
for Member::StructVariable(v, type_) in input.members.iter() {
|
||||
for Member { identifier, type_ } in input.members.iter() {
|
||||
// Ensure there are no tuple typed members.
|
||||
self.assert_not_tuple(v.span, type_);
|
||||
self.assert_not_tuple(identifier.span, type_);
|
||||
// Ensure that there are no record members.
|
||||
self.assert_member_is_not_record(v.span, input.identifier.name, type_);
|
||||
self.assert_member_is_not_record(identifier.span, input.identifier.name, type_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,4 +251,11 @@ create_messages!(
|
||||
msg: "A finalize statement must be preceded by the `async` keyword.",
|
||||
help: Some("Add the `async` keyword before the `finalize` keyword.".to_string()),
|
||||
}
|
||||
|
||||
@formatted
|
||||
circuit_is_deprecated {
|
||||
args: (),
|
||||
msg: "The keyword `circuit` is deprecated.",
|
||||
help: Some("Use `struct` instead.".to_string()),
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user