Some cleanup

This commit is contained in:
Pranav Gaddamadugu 2022-09-30 12:19:40 -07:00
parent c551179b42
commit eb8366badc
9 changed files with 40 additions and 34 deletions

View File

@ -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 { ... }`.

View File

@ -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,

View File

@ -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"),

View File

@ -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");
}

View File

@ -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)),
}
})

View File

@ -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,
}

View File

@ -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(),
));
};

View File

@ -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_);
}
}

View File

@ -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()),
}
);