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

@@ -0,0 +1,38 @@
use crate::{
errors::{CheckError, SourceRange},
parsing::types::ParsedType,
program::{self},
};
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct AsType {
pub pos_in_src: SourceRange,
pub statement: Box<dyn MersStatement>,
pub as_type: Vec<ParsedType>,
pub type_pos_in_src: SourceRange,
pub expand_type: bool,
}
impl MersStatement for AsType {
fn has_scope(&self) -> bool {
false
}
fn compile_custom(
&self,
info: &mut crate::info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, CheckError> {
Ok(Box::new(program::run::as_type::AsType {
pos_in_src: self.pos_in_src,
statement: self.statement.compile(info, comp)?,
as_type: self.as_type.clone(),
type_pos_in_src: self.type_pos_in_src,
expand_type: self.expand_type,
}))
}
fn source_range(&self) -> SourceRange {
self.pos_in_src
}
}

View File

@@ -0,0 +1,46 @@
use std::{fmt::Debug, sync::Arc};
use crate::{
errors::{CheckError, SourceRange},
parsing::types::{type_from_parsed, ParsedType},
};
use super::{CompInfo, Info, MersStatement};
pub struct CustomType {
pub pos_in_src: SourceRange,
pub name: String,
pub source: Result<Vec<ParsedType>, Box<dyn MersStatement>>,
}
impl MersStatement for CustomType {
fn compile_custom(
&self,
info: &mut Info,
comp: CompInfo,
) -> Result<Box<dyn crate::program::run::MersStatement>, CheckError> {
let src = match &self.source {
Ok(p) => Ok(p.clone()),
Err(s) => Err(s.compile(info, comp)?),
};
Ok(Box::new(crate::program::run::custom_type::CustomType {
pos_in_src: self.pos_in_src,
name: self.name.clone(),
source: Box::new(move |ci| match &src {
Ok(parsed) => Ok(Ok(Arc::new(type_from_parsed(parsed, ci)?))),
Err(statement) => Ok(Ok(Arc::new(statement.check(&mut ci.clone(), None)?))),
}),
}))
}
fn has_scope(&self) -> bool {
false
}
fn source_range(&self) -> SourceRange {
self.pos_in_src
}
}
impl Debug for CustomType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "type {} <...>", self.name)
}
}

View File

@@ -5,6 +5,8 @@ use crate::{
info,
};
#[cfg(feature = "parse")]
pub mod as_type;
#[cfg(feature = "parse")]
pub mod assign_to;
#[cfg(feature = "parse")]
@@ -12,6 +14,8 @@ pub mod block;
#[cfg(feature = "parse")]
pub mod chain;
#[cfg(feature = "parse")]
pub mod custom_type;
#[cfg(feature = "parse")]
pub mod function;
#[cfg(feature = "parse")]
pub mod r#if;
@@ -70,6 +74,7 @@ pub struct Local {
impl info::Local for Local {
type VariableIdentifier = String;
type VariableData = (usize, usize);
type Global = ();
fn init_var(&mut self, id: Self::VariableIdentifier, value: Self::VariableData) {
self.vars_count += 1;
self.vars.insert(id, value);

View File

@@ -22,20 +22,29 @@ impl MersStatement for Variable {
info: &mut crate::info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, CheckError> {
let init_and_ignore = comp.is_init && self.var == "_";
if comp.is_init {
info.init_var(
self.var.clone(),
(
info.scopes.len() - 1,
info.scopes.last().unwrap().vars_count,
),
)
if !init_and_ignore {
info.init_var(
self.var.clone(),
(
info.scopes.len() - 1,
info.scopes.last().unwrap().vars_count,
),
);
}
}
Ok(Box::new(program::run::variable::Variable {
pos_in_src: self.pos_in_src,
is_init: comp.is_init,
is_ref: comp.is_init || self.is_ref,
var: if let Some(v) = info.get_var(&self.var) {
is_ref_not_ignore: if comp.is_init {
!init_and_ignore
} else {
self.is_ref
},
var: if init_and_ignore {
(usize::MAX, usize::MAX)
} else if let Some(v) = info.get_var(&self.var) {
*v
} else {
return Err(CheckError::new()