feat: function calls and captures
This commit is contained in:
parent
1b61f4b25b
commit
fb1ff759e1
|
@ -7,6 +7,8 @@ use crate::{
|
||||||
tipo::{self, PatternConstructor, Type, ValueConstructor},
|
tipo::{self, PatternConstructor, Type, ValueConstructor},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const CAPTURE_VARIABLE: &str = "_capture";
|
||||||
|
|
||||||
pub type TypedModule = Module<tipo::Module, TypedDefinition>;
|
pub type TypedModule = Module<tipo::Module, TypedDefinition>;
|
||||||
pub type UntypedModule = Module<(), UntypedDefinition>;
|
pub type UntypedModule = Module<(), UntypedDefinition>;
|
||||||
|
|
||||||
|
@ -465,7 +467,6 @@ pub enum TodoKind {
|
||||||
pub struct SrcId(Intern<Vec<String>>);
|
pub struct SrcId(Intern<Vec<String>>);
|
||||||
|
|
||||||
impl SrcId {
|
impl SrcId {
|
||||||
#[cfg(test)]
|
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
SrcId(Intern::new(Vec::new()))
|
SrcId(Intern::new(Vec::new()))
|
||||||
}
|
}
|
||||||
|
@ -479,7 +480,6 @@ pub struct Span {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Span {
|
impl Span {
|
||||||
#[cfg(test)]
|
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
use chumsky::Span;
|
use chumsky::Span;
|
||||||
|
|
||||||
|
|
|
@ -2,22 +2,12 @@ use chumsky::prelude::*;
|
||||||
use vec1::Vec1;
|
use vec1::Vec1;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, BinOp, Span, TodoKind},
|
ast::{self, BinOp, Span, TodoKind, CAPTURE_VARIABLE},
|
||||||
error::ParseError,
|
error::ParseError,
|
||||||
expr,
|
expr,
|
||||||
token::Token,
|
token::Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parsing a function call into the appropriate structure
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ParserArg {
|
|
||||||
Arg(Box<ast::CallArg<expr::UntypedExpr>>),
|
|
||||||
Hole {
|
|
||||||
location: Span,
|
|
||||||
label: Option<String>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn module_parser(
|
pub fn module_parser(
|
||||||
kind: ast::ModuleKind,
|
kind: ast::ModuleKind,
|
||||||
) -> impl Parser<Token, ast::UntypedModule, Error = ParseError> {
|
) -> impl Parser<Token, ast::UntypedModule, Error = ParseError> {
|
||||||
|
@ -463,6 +453,16 @@ pub fn expr_parser(
|
||||||
assert_parser,
|
assert_parser,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// Parsing a function call into the appropriate structure
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum ParserArg {
|
||||||
|
Arg(Box<ast::CallArg<expr::UntypedExpr>>),
|
||||||
|
Hole {
|
||||||
|
location: Span,
|
||||||
|
label: Option<String>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
enum Chain {
|
enum Chain {
|
||||||
FieldAccess(String, Span),
|
FieldAccess(String, Span),
|
||||||
RecordUpdate,
|
RecordUpdate,
|
||||||
|
@ -511,6 +511,55 @@ pub fn expr_parser(
|
||||||
label,
|
label,
|
||||||
container: Box::new(e),
|
container: Box::new(e),
|
||||||
},
|
},
|
||||||
|
Chain::Call(args, span) => {
|
||||||
|
let mut holes = Vec::new();
|
||||||
|
|
||||||
|
let args = args
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(index, a)| match a {
|
||||||
|
ParserArg::Arg(arg) => *arg,
|
||||||
|
ParserArg::Hole { location, label } => {
|
||||||
|
holes.push(ast::Arg {
|
||||||
|
location: Span::empty(),
|
||||||
|
annotation: None,
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: format!("{}__{}", CAPTURE_VARIABLE, index),
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
tipo: (),
|
||||||
|
});
|
||||||
|
|
||||||
|
ast::CallArg {
|
||||||
|
label,
|
||||||
|
location,
|
||||||
|
value: expr::UntypedExpr::Var {
|
||||||
|
location,
|
||||||
|
name: format!("{}__{}", CAPTURE_VARIABLE, index),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let call = expr::UntypedExpr::Call {
|
||||||
|
location: span,
|
||||||
|
fun: Box::new(e),
|
||||||
|
arguments: args,
|
||||||
|
};
|
||||||
|
|
||||||
|
if holes.is_empty() {
|
||||||
|
call
|
||||||
|
} else {
|
||||||
|
expr::UntypedExpr::Fn {
|
||||||
|
location: call.location(),
|
||||||
|
is_capture: true,
|
||||||
|
arguments: holes,
|
||||||
|
body: Box::new(call),
|
||||||
|
return_annotation: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,14 @@ fn module() {
|
||||||
fn name(user: User) {
|
fn name(user: User) {
|
||||||
user.name
|
user.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calls() {
|
||||||
|
let x = add_one(3)
|
||||||
|
|
||||||
|
let map_add_x = list.map(_, fn (y) { x + y })
|
||||||
|
|
||||||
|
map_add_x([ 1, 2, 3 ])
|
||||||
|
}
|
||||||
"#;
|
"#;
|
||||||
let len = code.chars().count();
|
let len = code.chars().count();
|
||||||
|
|
||||||
|
@ -759,6 +767,162 @@ fn module() {
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
},
|
||||||
|
ast::UntypedDefinition::Fn {
|
||||||
|
arguments: vec![],
|
||||||
|
body: expr::UntypedExpr::Sequence {
|
||||||
|
location: Span::new(SrcId::empty(), 1521..1642),
|
||||||
|
expressions: vec![
|
||||||
|
expr::UntypedExpr::Assignment {
|
||||||
|
location: Span::new(SrcId::empty(), 1521..1539),
|
||||||
|
value: Box::new(expr::UntypedExpr::Call {
|
||||||
|
location: Span::new(SrcId::empty(), 1536..1539),
|
||||||
|
fun: Box::new(expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1529..1536),
|
||||||
|
name: "add_one".to_string(),
|
||||||
|
}),
|
||||||
|
arguments: vec![ast::CallArg {
|
||||||
|
label: None,
|
||||||
|
location: Span::new(SrcId::empty(), 1537..1538),
|
||||||
|
value: expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1537..1538),
|
||||||
|
value: "3".to_string(),
|
||||||
|
},
|
||||||
|
},],
|
||||||
|
}),
|
||||||
|
pattern: ast::Pattern::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1525..1526),
|
||||||
|
name: "x".to_string(),
|
||||||
|
},
|
||||||
|
kind: ast::AssignmentKind::Let,
|
||||||
|
annotation: None,
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Assignment {
|
||||||
|
location: Span::new(SrcId::empty(), 1557..1602),
|
||||||
|
value: Box::new(expr::UntypedExpr::Fn {
|
||||||
|
location: Span::new(SrcId::empty(), 1581..1602),
|
||||||
|
is_capture: true,
|
||||||
|
arguments: vec![ast::Arg {
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: "_capture__0".to_string(),
|
||||||
|
location: Span::new(SrcId::empty(), 0..0),
|
||||||
|
},
|
||||||
|
location: Span::new(SrcId::empty(), 0..0),
|
||||||
|
annotation: None,
|
||||||
|
tipo: (),
|
||||||
|
},],
|
||||||
|
body: Box::new(expr::UntypedExpr::Call {
|
||||||
|
location: Span::new(SrcId::empty(), 1581..1602),
|
||||||
|
fun: Box::new(expr::UntypedExpr::FieldAccess {
|
||||||
|
location: Span::new(SrcId::empty(), 1573..1581),
|
||||||
|
label: "map".to_string(),
|
||||||
|
container: Box::new(expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1573..1577),
|
||||||
|
name: "list".to_string(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
arguments: vec![
|
||||||
|
ast::CallArg {
|
||||||
|
label: None,
|
||||||
|
location: Span::new(SrcId::empty(), 1582..1583),
|
||||||
|
value: expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1582..1583),
|
||||||
|
name: "_capture__0".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ast::CallArg {
|
||||||
|
label: None,
|
||||||
|
location: Span::new(SrcId::empty(), 1585..1601),
|
||||||
|
value: expr::UntypedExpr::Fn {
|
||||||
|
location: Span::new(SrcId::empty(), 1585..1601),
|
||||||
|
is_capture: false,
|
||||||
|
arguments: vec![ast::Arg {
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: "y".to_string(),
|
||||||
|
location: Span::new(
|
||||||
|
SrcId::empty(),
|
||||||
|
1589..1590
|
||||||
|
),
|
||||||
|
},
|
||||||
|
location: Span::new(
|
||||||
|
SrcId::empty(),
|
||||||
|
1589..1590
|
||||||
|
),
|
||||||
|
annotation: None,
|
||||||
|
tipo: (),
|
||||||
|
},],
|
||||||
|
body: Box::new(expr::UntypedExpr::BinOp {
|
||||||
|
location: Span::new(
|
||||||
|
SrcId::empty(),
|
||||||
|
1594..1599
|
||||||
|
),
|
||||||
|
name: ast::BinOp::AddInt,
|
||||||
|
left: Box::new(expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(
|
||||||
|
SrcId::empty(),
|
||||||
|
1594..1595
|
||||||
|
),
|
||||||
|
name: "x".to_string(),
|
||||||
|
}),
|
||||||
|
right: Box::new(expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(
|
||||||
|
SrcId::empty(),
|
||||||
|
1598..1599
|
||||||
|
),
|
||||||
|
name: "y".to_string(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
return_annotation: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
return_annotation: None,
|
||||||
|
}),
|
||||||
|
pattern: ast::Pattern::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1561..1570),
|
||||||
|
name: "map_add_x".to_string(),
|
||||||
|
},
|
||||||
|
kind: ast::AssignmentKind::Let,
|
||||||
|
annotation: None,
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Call {
|
||||||
|
location: Span::new(SrcId::empty(), 1629..1642),
|
||||||
|
fun: Box::new(expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1620..1629),
|
||||||
|
name: "map_add_x".to_string(),
|
||||||
|
}),
|
||||||
|
arguments: vec![ast::CallArg {
|
||||||
|
label: None,
|
||||||
|
location: Span::new(SrcId::empty(), 1630..1641),
|
||||||
|
value: expr::UntypedExpr::List {
|
||||||
|
location: Span::new(SrcId::empty(), 1630..1641),
|
||||||
|
elements: vec![
|
||||||
|
expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1632..1633),
|
||||||
|
value: "1".to_string(),
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1635..1636),
|
||||||
|
value: "2".to_string(),
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1638..1639),
|
||||||
|
value: "3".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
tail: None,
|
||||||
|
},
|
||||||
|
},],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
doc: None,
|
||||||
|
location: Span::new(SrcId::empty(), 1492..1656),
|
||||||
|
name: "calls".to_string(),
|
||||||
|
public: false,
|
||||||
|
return_annotation: None,
|
||||||
|
return_type: (),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue