1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

update parser and ast to be stricter, fix conversion to absy, wip

This commit is contained in:
schaeff 2021-05-26 15:22:23 +02:00
parent 6e1ce97162
commit e2878f19a3
6 changed files with 94 additions and 59 deletions

View file

@ -0,0 +1,11 @@
// def foo() -> u32:
// return 0
def bar() -> (u32, u32):
return 0, 0
def main(u32[1] a, u32 b):
//a[0] = foo()
a[0], b = bar()
return

View file

@ -239,54 +239,69 @@ fn statements_from_definition(definition: pest::DefinitionStatement) -> Vec<absy
let e: absy::ExpressionNode = absy::ExpressionNode::from(definition.expression);
let s = match e.value {
absy::Expression::FunctionCall(..) => absy::Statement::MultipleDefinition(
vec![absy::AssigneeNode::from(a.a.clone())],
e,
),
_ => absy::Statement::Definition(absy::AssigneeNode::from(a.a.clone()), e),
};
match a.ty {
Some(ty) => {
assert_eq!(a.a.accesses.len(), 0);
match a {
pest::TypedIdentifierOrAssignee::TypedIdentifier(i) => {
let declaration = absy::Statement::Declaration(
absy::Variable::new(
a.a.id.span.as_str(),
absy::UnresolvedTypeNode::from(ty),
i.identifier.span.as_str(),
absy::UnresolvedTypeNode::from(i.ty),
)
.span(a.a.id.span.clone()),
.span(i.identifier.span.clone()),
)
.span(definition.span.clone());
let s = match e.value {
absy::Expression::FunctionCall(..) => absy::Statement::MultipleDefinition(
vec![absy::AssigneeNode::from(i.identifier.clone())],
e,
),
_ => absy::Statement::Definition(absy::AssigneeNode::from(i.identifier.clone()), e),
};
vec![declaration, s.span(definition.span)]
}
None => {
// Assignment
},
pest::TypedIdentifierOrAssignee::Assignee(a) => {
let s = match e.value {
absy::Expression::FunctionCall(..) => absy::Statement::MultipleDefinition(
vec![absy::AssigneeNode::from(a)],
e,
),
_ => absy::Statement::Definition(absy::AssigneeNode::from(a), e),
};
vec![s.span(definition.span)]
}
}
}
_ => {
// Multidefinition
let declarations = lhs.clone().into_iter().filter(|i| i.ty.is_some()).map(|a| {
let ty = a.ty;
let a = a.a;
let declarations = lhs.clone().into_iter().filter_map(|i| match i {
pest::TypedIdentifierOrAssignee::TypedIdentifier(i) => {
let ty = i.ty;
let id = i.identifier;
assert_eq!(a.accesses.len(), 0);
absy::Statement::Declaration(
absy::Variable::new(
a.id.span.as_str(),
absy::UnresolvedTypeNode::from(ty.unwrap()),
Some(absy::Statement::Declaration(
absy::Variable::new(
id.span.as_str(),
absy::UnresolvedTypeNode::from(ty),
)
.span(id.span),
)
.span(a.id.span),
)
.span(a.span)
.span(i.span))
},
_ => None
});
let lhs = lhs
.into_iter()
.map(|i| absy::Assignee::Identifier(i.a.id.span.as_str()).span(i.a.id.span))
.map(|i| match i {
pest::TypedIdentifierOrAssignee::TypedIdentifier(i) => {
absy::Assignee::Identifier(i.identifier.span.as_str()).span(i.identifier.span)
},
pest::TypedIdentifierOrAssignee::Assignee(a) => {
absy::AssigneeNode::from(a)
}
})
.collect();
let multi_def = absy::Statement::MultipleDefinition(

View file

@ -237,6 +237,8 @@ fn check_with_arena<'ast, T: Field, E: Into<imports::Error>>(
let typed_ast = Checker::check(compiled)
.map_err(|errors| CompileErrors(errors.into_iter().map(CompileError::from).collect()))?;
println!("{}", typed_ast);
let main_module = typed_ast.main.clone();
// analyse (unroll and constant propagation)

View file

@ -1484,6 +1484,9 @@ impl<'ast, T: Field> Checker<'ast, T> {
res
}
Statement::MultipleDefinition(assignees, rhs) => {
println!("ASSIGNEES: {:?}", assignees);
match rhs.value {
// Right side has to be a function call
Expression::FunctionCall(fun_id, generics, arguments) => {
@ -1522,6 +1525,8 @@ impl<'ast, T: Field> Checker<'ast, T> {
let assignee_types: Vec<_> = assignees.iter().map(|a| Some(a.get_type().clone())).collect();
println!("{:?}", assignee_types);
// find argument types
let mut arguments_checked = vec![];
for arg in arguments {
@ -1534,6 +1539,8 @@ impl<'ast, T: Field> Checker<'ast, T> {
let query = FunctionQuery::new(&fun_id, &generics_checked, &arguments_types, &assignee_types);
println!("QUERY {:?}", query);
let functions = self.find_functions(&query);
match functions.len() {

View file

@ -54,11 +54,11 @@ statement = { (return_statement // does not require subsequent newline
iteration_statement = { "for" ~ ty ~ identifier ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"}
return_statement = { "return" ~ expression_list}
definition_statement = { optionally_typed_assignee_list ~ "=" ~ expression } // declare and assign, so only identifiers are allowed, unlike `assignment_statement`
definition_statement = { typed_identifier_or_assignee_list ~ "=" ~ expression } // declare and assign, so only identifiers are allowed, unlike `assignment_statement`
expression_statement = {"assert" ~ "(" ~ expression ~ ")"}
optionally_typed_assignee_list = _{ optionally_typed_assignee ~ ("," ~ optionally_typed_assignee)* }
optionally_typed_assignee = { (ty ~ assignee) | (assignee) } // we don't use { ty? ~ identifier } as with a single token, it gets parsed as `ty` but we want `identifier`
typed_identifier_or_assignee_list = _{ typed_identifier_or_assignee ~ ("," ~ typed_identifier_or_assignee)* }
typed_identifier_or_assignee = { typed_identifier | assignee } // we don't use { ty? ~ identifier } as with a single token, it gets parsed as `ty` but we want `identifier`
// Expressions
expression_list = _{(expression ~ ("," ~ expression)*)?}
@ -103,6 +103,7 @@ array_initializer_expression = { "[" ~ expression ~ ";" ~ expression ~ "]" }
// End Expressions
typed_identifier = { ty ~ identifier }
assignee = { identifier ~ assignee_access* }
assignee_access = { array_access | member_access }
identifier = @{ ((!keyword ~ ASCII_ALPHA) | (keyword ~ (ASCII_ALPHANUMERIC | "_"))) ~ (ASCII_ALPHANUMERIC | "_")* }

View file

@ -15,7 +15,7 @@ pub use ast::{
FromExpression, FunctionDefinition, HexLiteralExpression, HexNumberExpression,
IdentifierExpression, ImportDirective, ImportSource, ImportSymbol, InlineArrayExpression,
InlineStructExpression, InlineStructMember, IterationStatement, LiteralExpression,
OptionallyTypedAssignee, Parameter, PostfixExpression, Range, RangeOrExpression,
TypedIdentifierOrAssignee, Parameter, PostfixExpression, Range, RangeOrExpression,
ReturnStatement, Span, Spread, SpreadOrExpression, Statement, StructDefinition, StructField,
SymbolDeclaration, TernaryExpression, ToExpression, Type, UnaryExpression, UnaryOperator,
Underscore, Visibility,
@ -349,7 +349,7 @@ mod ast {
#[derive(Debug, FromPest, PartialEq, Clone)]
#[pest_ast(rule(Rule::definition_statement))]
pub struct DefinitionStatement<'ast> {
pub lhs: Vec<OptionallyTypedAssignee<'ast>>,
pub lhs: Vec<TypedIdentifierOrAssignee<'ast>>,
pub expression: Expression<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
@ -635,10 +635,17 @@ mod ast {
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[pest_ast(rule(Rule::optionally_typed_assignee))]
pub struct OptionallyTypedAssignee<'ast> {
pub ty: Option<Type<'ast>>,
pub a: Assignee<'ast>,
#[pest_ast(rule(Rule::typed_identifier_or_assignee))]
pub enum TypedIdentifierOrAssignee<'ast> {
Assignee(Assignee<'ast>),
TypedIdentifier(TypedIdentifier<'ast>)
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[pest_ast(rule(Rule::typed_identifier))]
pub struct TypedIdentifier<'ast> {
pub ty: Type<'ast>,
pub identifier: IdentifierExpression<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
@ -1330,32 +1337,24 @@ mod tests {
}))],
statements: vec![Statement::Definition(DefinitionStatement {
lhs: vec![
OptionallyTypedAssignee {
ty: Some(Type::Basic(BasicType::Field(FieldType {
TypedIdentifierOrAssignee::TypedIdentifier(TypedIdentifier {
ty: Type::Basic(BasicType::Field(FieldType {
span: Span::new(&source, 23, 28).unwrap()
}))),
a: Assignee {
id: IdentifierExpression {
})),
identifier: IdentifierExpression {
value: String::from("a"),
span: Span::new(&source, 29, 30).unwrap(),
},
accesses: vec![],
span: Span::new(&source, 29, 30).unwrap()
},
span: Span::new(&source, 23, 30).unwrap()
},
OptionallyTypedAssignee {
ty: None,
a: Assignee {
id: IdentifierExpression {
value: String::from("b"),
span: Span::new(&source, 32, 33).unwrap(),
},
accesses: vec![],
span: Span::new(&source, 32, 34).unwrap()
}),
TypedIdentifierOrAssignee::Assignee(Assignee {
id: IdentifierExpression {
value: String::from("b"),
span: Span::new(&source, 32, 33).unwrap(),
},
accesses: vec![],
span: Span::new(&source, 32, 34).unwrap()
},
}),
],
expression: Expression::Postfix(PostfixExpression {
id: IdentifierExpression {