mirror of
https://github.com/Dummi26/mers.git
synced 2025-12-16 03:57:50 +01:00
add function type annotation (Input1 -> Output1, Input2 -> Output2)
This commit is contained in:
@@ -13,8 +13,8 @@ pub enum ParsedType {
|
||||
Reference(Vec<Self>),
|
||||
Tuple(Vec<Vec<Self>>),
|
||||
Object(Vec<(String, Vec<Self>)>),
|
||||
Function(Vec<(Vec<Self>, Vec<Self>)>),
|
||||
Type(String),
|
||||
Function(Vec<(Self, Self)>),
|
||||
TypeWithInfo(String, String),
|
||||
}
|
||||
|
||||
@@ -44,19 +44,20 @@ pub fn parse_single_type(src: &mut Source, srca: &Arc<Source>) -> Result<ParsedT
|
||||
ParsedType::Reference(vec![parse_single_type(src, srca)?])
|
||||
}
|
||||
}
|
||||
// Tuple
|
||||
// Tuple or Function
|
||||
Some('(') => {
|
||||
let pos_in_src = src.get_pos();
|
||||
src.next_char();
|
||||
src.section_begin("parse tuple's inner types".to_string());
|
||||
let mut inner = vec![];
|
||||
let mut inner_t = vec![];
|
||||
let mut inner_f = vec![];
|
||||
src.skip_whitespace();
|
||||
if let Some(')') = src.peek_char() {
|
||||
src.next_char();
|
||||
// empty tuple, don't even start the loop
|
||||
} else {
|
||||
loop {
|
||||
inner.push(parse_type(src, srca)?);
|
||||
let t = parse_type(src, srca)?;
|
||||
src.skip_whitespace();
|
||||
match src.peek_char() {
|
||||
Some(')') => {
|
||||
@@ -64,7 +65,48 @@ pub fn parse_single_type(src: &mut Source, srca: &Arc<Source>) -> Result<ParsedT
|
||||
break;
|
||||
}
|
||||
Some(',') => {
|
||||
src.next_char();
|
||||
if inner_f.is_empty() {
|
||||
inner_t.push(t);
|
||||
src.next_char();
|
||||
} else {
|
||||
let pos1 = src.get_pos();
|
||||
src.next_char();
|
||||
return Err(CheckError::new().src(vec![
|
||||
((pos_in_src, src.get_pos(), srca).into(), None),
|
||||
(
|
||||
(pos1, src.get_pos(), srca).into(),
|
||||
Some(error_colors::BadCharInFunctionType),
|
||||
),
|
||||
]).msg(format!("Unexpected character in function type, expected arrow `->` but found `,`."))
|
||||
.msg(format!("If you wanted this to be a tuple type instead, you may have used `Input -> Output` instead of `(Input -> Output)` for a function type somewhere.")));
|
||||
}
|
||||
}
|
||||
Some('-') if src.peek_word() == "->" => {
|
||||
if inner_t.is_empty() {
|
||||
src.next_word();
|
||||
inner_f.push((t, parse_type(src, srca)?));
|
||||
let pos2 = src.get_pos();
|
||||
src.skip_whitespace();
|
||||
match src.next_char() {
|
||||
Some(',') => (),
|
||||
Some(')') => break,
|
||||
_ => return Err(CheckError::new().src(vec![
|
||||
((pos_in_src, src.get_pos(), srca).into(), None),
|
||||
((pos2, src.get_pos(), srca).into(), Some(error_colors::BadCharInFunctionType)),
|
||||
]).msg(format!("Expected comma `,` after `In -> Out` part of function type")))
|
||||
}
|
||||
} else {
|
||||
let pos1 = src.get_pos();
|
||||
src.next_word();
|
||||
return Err(CheckError::new().src(vec![
|
||||
((pos_in_src, src.get_pos(), srca).into(), None),
|
||||
(
|
||||
(pos1, src.get_pos(), srca).into(),
|
||||
Some(error_colors::BadCharInTupleType),
|
||||
),
|
||||
]).msg(format!("Unexpected character in tuple type, expected comma `,` but found arrow `->`."))
|
||||
.msg(format!("If you wanted to write a function type, use `(Input -> Output)` instead of `Input -> Output`.")));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let ppos = src.get_pos();
|
||||
@@ -84,7 +126,11 @@ pub fn parse_single_type(src: &mut Source, srca: &Arc<Source>) -> Result<ParsedT
|
||||
}
|
||||
}
|
||||
}
|
||||
ParsedType::Tuple(inner)
|
||||
if inner_f.is_empty() {
|
||||
ParsedType::Tuple(inner_t)
|
||||
} else {
|
||||
ParsedType::Function(inner_f)
|
||||
}
|
||||
}
|
||||
// Object
|
||||
Some('{') => {
|
||||
@@ -179,6 +225,10 @@ pub fn type_from_parsed(
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
)),
|
||||
ParsedType::Function(v) => Arc::new(data::function::FunctionT(Err(v
|
||||
.iter()
|
||||
.map(|(i, o)| Ok((type_from_parsed(i, info)?, type_from_parsed(o, info)?)))
|
||||
.collect::<Result<_, CheckError>>()?))),
|
||||
ParsedType::Type(name) => match info
|
||||
.scopes
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user