mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 13:56:58 +03:00
Add index assignments to AST; WIP tyc
This commit is contained in:
parent
af2447aa02
commit
337d7d301e
@ -25,7 +25,7 @@ use std::fmt;
|
|||||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||||
pub struct AssignStatement {
|
pub struct AssignStatement {
|
||||||
/// The place to assign to.
|
/// The place to assign to.
|
||||||
/// Note that `place` can either be an identifier or tuple.
|
/// Note that `place` can either be an identifier, tuple, or access expression.
|
||||||
pub place: Expression,
|
pub place: Expression,
|
||||||
/// The value to assign to the `assignee`.
|
/// The value to assign to the `assignee`.
|
||||||
pub value: Expression,
|
pub value: Expression,
|
||||||
|
@ -60,33 +60,44 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_assign(&mut self, input: &'a AssignStatement) {
|
fn visit_assign(&mut self, input: &'a AssignStatement) {
|
||||||
let var_name = match input.place {
|
let lookup_variable = |id: Identifier| -> Option<Type> {
|
||||||
Expression::Identifier(id) => id,
|
if let Some(var) = self.symbol_table.borrow_mut().lookup_variable(id.name) {
|
||||||
|
match &var.declaration {
|
||||||
|
VariableType::Const => self.emit_err(TypeCheckerError::cannot_assign_to_const_var(id, var.span)),
|
||||||
|
VariableType::Input(Mode::Constant) => {
|
||||||
|
self.emit_err(TypeCheckerError::cannot_assign_to_const_input(id, var.span))
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
Some(var.type_.clone())
|
||||||
|
} else {
|
||||||
|
self.emit_err(TypeCheckerError::unknown_sym("variable", id.name, id.span));
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let var_type = match &input.place {
|
||||||
|
Expression::Identifier(id) => lookup_variable(*id),
|
||||||
|
Expression::Access(AccessExpression::Array(array_access)) => match array_access.array.as_ref() {
|
||||||
|
Expression::Identifier(id) => match lookup_variable(*id) {
|
||||||
|
Some(Type::Array(array_type)) => Some(array_type.element_type().clone()),
|
||||||
|
type_ => {
|
||||||
|
self.assert_array_type(&type_, array_access.array.span());
|
||||||
|
None
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
self.emit_err(TypeCheckerError::invalid_assignment_target(array_access.array.span()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
self.emit_err(TypeCheckerError::invalid_assignment_target(input.place.span()));
|
self.emit_err(TypeCheckerError::invalid_assignment_target(input.place.span()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let var_type = if let Some(var) = self.symbol_table.borrow_mut().lookup_variable(var_name.name) {
|
self.visit_expression(&input.value, &var_type);
|
||||||
match &var.declaration {
|
|
||||||
VariableType::Const => self.emit_err(TypeCheckerError::cannot_assign_to_const_var(var_name, var.span)),
|
|
||||||
VariableType::Input(Mode::Constant) => {
|
|
||||||
self.emit_err(TypeCheckerError::cannot_assign_to_const_input(var_name, var.span))
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(var.type_.clone())
|
|
||||||
} else {
|
|
||||||
self.emit_err(TypeCheckerError::unknown_sym("variable", var_name.name, var_name.span));
|
|
||||||
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if var_type.is_some() {
|
|
||||||
self.visit_expression(&input.value, &var_type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_block(&mut self, input: &'a Block) {
|
fn visit_block(&mut self, input: &'a Block) {
|
||||||
|
Loading…
Reference in New Issue
Block a user