mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 19:22:01 +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()?;
|
let (id, function) = self.parse_function()?;
|
||||||
functions.insert(id, 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()),
|
_ => 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.
|
/// Returns a [`Member`] AST node if the next tokens represent a struct member variable.
|
||||||
fn parse_member_variable_declaration(&mut self) -> Result<Member> {
|
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 { ... }`.
|
/// Parses a struct or record definition, e.g., `struct Foo { ... }` or `record Foo { ... }`.
|
||||||
|
@ -396,6 +396,7 @@ impl Token {
|
|||||||
"address" => Token::Address,
|
"address" => Token::Address,
|
||||||
"async" => Token::Async,
|
"async" => Token::Async,
|
||||||
"bool" => Token::Bool,
|
"bool" => Token::Bool,
|
||||||
|
"circuit" => Token::Circuit,
|
||||||
"console" => Token::Console,
|
"console" => Token::Console,
|
||||||
"const" => Token::Const,
|
"const" => Token::Const,
|
||||||
"constant" => Token::Constant,
|
"constant" => Token::Constant,
|
||||||
|
@ -324,6 +324,7 @@ impl fmt::Display for Token {
|
|||||||
Record => write!(f, "record"),
|
Record => write!(f, "record"),
|
||||||
|
|
||||||
Async => write!(f, "async"),
|
Async => write!(f, "async"),
|
||||||
|
Circuit => write!(f, "circuit"),
|
||||||
Console => write!(f, "console"),
|
Console => write!(f, "console"),
|
||||||
Const => write!(f, "const"),
|
Const => write!(f, "const"),
|
||||||
Constant => write!(f, "constant"),
|
Constant => write!(f, "constant"),
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use crate::CodeGenerator;
|
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 indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
@ -131,11 +131,7 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
|
|
||||||
// Construct and append the record variables.
|
// Construct and append the record variables.
|
||||||
for var in struct_.members.iter() {
|
for var in struct_.members.iter() {
|
||||||
let (name, type_) = match var {
|
writeln!(output_string, " {} as {};", var.identifier, var.type_,).expect("failed to write to string");
|
||||||
Member::StructVariable(name, type_) => (name, type_),
|
|
||||||
};
|
|
||||||
|
|
||||||
writeln!(output_string, " {} as {};", name, type_,).expect("failed to write to string");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
output_string
|
output_string
|
||||||
@ -150,14 +146,10 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
|
|
||||||
// Construct and append the record variables.
|
// Construct and append the record variables.
|
||||||
for var in record.members.iter() {
|
for var in record.members.iter() {
|
||||||
let (name, type_) = match var {
|
|
||||||
Member::StructVariable(name, type_) => (name, type_),
|
|
||||||
};
|
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
output_string,
|
output_string,
|
||||||
" {} as {}.private;", // todo: CAUTION private record variables only.
|
" {} as {}.private;", // todo: CAUTION private record variables only.
|
||||||
name, type_,
|
var.identifier, var.type_,
|
||||||
)
|
)
|
||||||
.expect("failed to write to string");
|
.expect("failed to write to string");
|
||||||
}
|
}
|
||||||
|
@ -108,18 +108,18 @@ impl ExpressionReconstructor for Flattener<'_> {
|
|||||||
let members = first_member_struct
|
let members = first_member_struct
|
||||||
.members
|
.members
|
||||||
.iter()
|
.iter()
|
||||||
.map(|Member::StructVariable(id, _)| {
|
.map(|Member { identifier, .. }| {
|
||||||
// Construct a new ternary expression for the struct member.
|
// Construct a new ternary expression for the struct member.
|
||||||
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression {
|
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression {
|
||||||
condition: input.condition.clone(),
|
condition: input.condition.clone(),
|
||||||
if_true: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
if_true: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||||
inner: Box::new(Expression::Access(AccessExpression::Member(first.clone()))),
|
inner: Box::new(Expression::Access(AccessExpression::Member(first.clone()))),
|
||||||
name: *id,
|
name: *identifier,
|
||||||
span: Default::default(),
|
span: Default::default(),
|
||||||
}))),
|
}))),
|
||||||
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||||
inner: Box::new(Expression::Access(AccessExpression::Member(second.clone()))),
|
inner: Box::new(Expression::Access(AccessExpression::Member(second.clone()))),
|
||||||
name: *id,
|
name: *identifier,
|
||||||
span: Default::default(),
|
span: Default::default(),
|
||||||
}))),
|
}))),
|
||||||
span: Default::default(),
|
span: Default::default(),
|
||||||
@ -133,7 +133,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
|||||||
statements.push(statement);
|
statements.push(statement);
|
||||||
|
|
||||||
StructVariableInitializer {
|
StructVariableInitializer {
|
||||||
identifier: *id,
|
identifier,
|
||||||
expression: Some(Expression::Identifier(identifier)),
|
expression: Some(Expression::Identifier(identifier)),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -204,18 +204,18 @@ impl ExpressionReconstructor for Flattener<'_> {
|
|||||||
let members = first_struct
|
let members = first_struct
|
||||||
.members
|
.members
|
||||||
.iter()
|
.iter()
|
||||||
.map(|Member::StructVariable(id, _)| {
|
.map(|Member { identifier, .. }| {
|
||||||
// Construct a new ternary expression for the struct member.
|
// Construct a new ternary expression for the struct member.
|
||||||
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression {
|
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression {
|
||||||
condition: input.condition.clone(),
|
condition: input.condition.clone(),
|
||||||
if_true: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
if_true: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||||
inner: Box::new(Expression::Identifier(first)),
|
inner: Box::new(Expression::Identifier(first)),
|
||||||
name: *id,
|
name: *identifier,
|
||||||
span: Default::default(),
|
span: Default::default(),
|
||||||
}))),
|
}))),
|
||||||
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||||
inner: Box::new(Expression::Identifier(second)),
|
inner: Box::new(Expression::Identifier(second)),
|
||||||
name: *id,
|
name: *identifier,
|
||||||
span: Default::default(),
|
span: Default::default(),
|
||||||
}))),
|
}))),
|
||||||
span: Default::default(),
|
span: Default::default(),
|
||||||
@ -229,7 +229,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
|||||||
statements.push(statement);
|
statements.push(statement);
|
||||||
|
|
||||||
StructVariableInitializer {
|
StructVariableInitializer {
|
||||||
identifier: *id,
|
identifier,
|
||||||
expression: Some(Expression::Identifier(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.
|
// 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 name = self.lookup_struct_symbol(&access.inner).unwrap();
|
||||||
let struct_ = self.symbol_table.lookup_struct(name).unwrap();
|
let struct_ = self.symbol_table.lookup_struct(name).unwrap();
|
||||||
let Member::StructVariable(_, member_type) = struct_
|
let Member { type_, .. } = struct_
|
||||||
.members
|
.members
|
||||||
.iter()
|
.iter()
|
||||||
.find(|member| member.name() == access.name.name)
|
.find(|member| member.name() == access.name.name)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
match member_type {
|
match type_ {
|
||||||
Type::Identifier(identifier) => Some(identifier.name),
|
Type::Identifier(identifier) => Some(identifier.name),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
|||||||
// Check that `access.name` is a member of the struct.
|
// Check that `access.name` is a member of the struct.
|
||||||
match struct_.members.iter().find(|member| member.name() == access.name.name) {
|
match struct_.members.iter().find(|member| member.name() == access.name.name) {
|
||||||
// Case where `access.name` is a member of the struct.
|
// 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.
|
// Case where `access.name` is not a member of the struct.
|
||||||
None => {
|
None => {
|
||||||
self.emit_err(TypeCheckerError::invalid_struct_variable(
|
self.emit_err(TypeCheckerError::invalid_struct_variable(
|
||||||
@ -482,16 +482,20 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check struct member types.
|
// 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.
|
// 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 {
|
if let Some(expr) = &actual.expression {
|
||||||
self.visit_expression(expr, &Some(ty.clone()));
|
self.visit_expression(expr, &Some(type_.clone()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.emit_err(TypeCheckerError::missing_struct_member(
|
self.emit_err(TypeCheckerError::missing_struct_member(
|
||||||
struct_.identifier,
|
struct_.identifier,
|
||||||
name,
|
identifier,
|
||||||
input.span(),
|
input.span(),
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
@ -29,11 +29,11 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
|||||||
fn visit_struct(&mut self, input: &'a Struct) {
|
fn visit_struct(&mut self, input: &'a Struct) {
|
||||||
// Check for conflicting struct/record member names.
|
// Check for conflicting struct/record member names.
|
||||||
let mut used = HashSet::new();
|
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.
|
// TODO: Better spans.
|
||||||
// Check that the member types are valid.
|
// Check that the member types are valid.
|
||||||
self.assert_type_is_valid(input.span, type_);
|
self.assert_type_is_valid(input.span, type_);
|
||||||
used.insert(ident.name)
|
used.insert(identifier.name)
|
||||||
}) {
|
}) {
|
||||||
self.emit_err(if input.is_record {
|
self.emit_err(if input.is_record {
|
||||||
TypeCheckerError::duplicate_record_variable(input.name(), input.span())
|
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
|
let check_has_field = |need, expected_ty: Type| match input
|
||||||
.members
|
.members
|
||||||
.iter()
|
.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((_, actual_ty)) if expected_ty.eq_flat(actual_ty) => {} // All good, found + right type!
|
||||||
Some((field, _)) => {
|
Some((field, _)) => {
|
||||||
@ -69,11 +69,11 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
|||||||
check_has_field(sym::gates, Type::Integer(IntegerType::U64));
|
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.
|
// 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.
|
// 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.",
|
msg: "A finalize statement must be preceded by the `async` keyword.",
|
||||||
help: Some("Add the `async` keyword before the `finalize` keyword.".to_string()),
|
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