Type Annotations

- Add type annotations: [type] statement
- Add type definitions: [[name] type], [[name] := statement]
- Add type annotations example (08)
- add Quickstart.md, reference it from README
This commit is contained in:
Mark
2023-11-21 22:10:58 +01:00
parent b6d708db3d
commit 4144d6cf71
21 changed files with 756 additions and 63 deletions

View File

@@ -11,7 +11,8 @@ use super::MersStatement;
pub struct Variable {
pub pos_in_src: SourceRange,
pub is_init: bool,
pub is_ref: bool,
// if `is_init` is true, this must also be true unless using the "ignore" `_` pattern
pub is_ref_not_ignore: bool,
pub var: (usize, usize),
}
@@ -25,14 +26,22 @@ impl MersStatement for Variable {
init_to: Option<&Type>,
) -> Result<data::Type, super::CheckError> {
if self.is_init {
while info.scopes[self.var.0].vars.len() <= self.var.1 {
info.scopes[self.var.0].vars.push(Type::empty());
if self.is_ref_not_ignore {
while info.scopes[self.var.0].vars.len() <= self.var.1 {
info.scopes[self.var.0].vars.push(Type::empty());
}
info.scopes[self.var.0].vars[self.var.1] = init_to
.expect("variable's is_init was true, but check_custom's assign was None? How?")
.clone();
} else {
return Ok(Type::new(data::reference::ReferenceT(
init_to
.expect("var's is_init was true, but init_to was None???")
.clone(),
)));
}
info.scopes[self.var.0].vars[self.var.1] = init_to
.expect("variable's is_init was true, but check_custom's assign was None? How?")
.clone();
}
let val = if self.is_ref {
let val = if self.is_ref_not_ignore {
Type::new(data::reference::ReferenceT(
info.scopes[self.var.0].vars[self.var.1].clone(),
))
@@ -43,13 +52,20 @@ impl MersStatement for Variable {
}
fn run_custom(&self, info: &mut super::Info) -> Data {
if self.is_init {
let nothing = Arc::new(RwLock::new(Data::new(data::bool::Bool(false))));
while info.scopes[self.var.0].vars.len() <= self.var.1 {
info.scopes[self.var.0].vars.push(Arc::clone(&nothing));
if self.is_ref_not_ignore {
let nothing = Arc::new(RwLock::new(Data::new(data::bool::Bool(false))));
while info.scopes[self.var.0].vars.len() <= self.var.1 {
info.scopes[self.var.0].vars.push(Arc::clone(&nothing));
}
info.scopes[self.var.0].vars[self.var.1] = nothing;
} else {
// (reference to) data which will never be referenced again
return Data::new(data::reference::Reference(Arc::new(RwLock::new(
Data::empty_tuple(),
))));
}
info.scopes[self.var.0].vars[self.var.1] = nothing;
}
if self.is_ref {
if self.is_ref_not_ignore {
Data::new(data::reference::Reference(Arc::clone(
&info.scopes[self.var.0].vars[self.var.1],
)))