mirror of
https://github.com/Dummi26/mers.git
synced 2025-12-28 17:16:31 +01:00
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:
38
mers_lib/src/program/parsed/as_type.rs
Executable file
38
mers_lib/src/program/parsed/as_type.rs
Executable 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
|
||||
}
|
||||
}
|
||||
46
mers_lib/src/program/parsed/custom_type.rs
Normal file
46
mers_lib/src/program/parsed/custom_type.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user