More work on args
not quite done
This commit is contained in:
parent
fa1257e2cd
commit
40579d80ce
@ -620,7 +620,7 @@ impl Parser {
|
|||||||
fn call_expr(&mut self) -> ParseResult<Expression> {
|
fn call_expr(&mut self) -> ParseResult<Expression> {
|
||||||
let mut expr = self.index_expr()?;
|
let mut expr = self.index_expr()?;
|
||||||
while let LParen = self.token_handler.peek_kind() {
|
while let LParen = self.token_handler.peek_kind() {
|
||||||
let arguments = delimited!(self, LParen, expression, Comma, RParen);
|
let arguments = delimited!(self, LParen, invocation_argument, Comma, RParen);
|
||||||
let arguments = arguments.into_iter().map(|s| Meta::new(s)).collect();
|
let arguments = arguments.into_iter().map(|s| Meta::new(s)).collect();
|
||||||
expr = Expression(ExpressionKind::Call { f: bx!(expr.into()), arguments }, None); //TODO none is incorrect
|
expr = Expression(ExpressionKind::Call { f: bx!(expr.into()), arguments }, None); //TODO none is incorrect
|
||||||
}
|
}
|
||||||
@ -629,8 +629,28 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn invocation_argument(&mut self) -> ParseResult<InvocationExpression> {
|
fn invocation_argument(&mut self) -> ParseResult<InvocationArgument> {
|
||||||
panic!()
|
Ok(match self.token_handler.peek_kind() {
|
||||||
|
Underscore => {
|
||||||
|
self.token_handler.next();
|
||||||
|
InvocationArgument::Ignored
|
||||||
|
},
|
||||||
|
Identifier(s) => {
|
||||||
|
self.token_handler.next();
|
||||||
|
match self.token_handler.peek_kind() {
|
||||||
|
Operator(ref op) if **op == "=" => {
|
||||||
|
self.token_handler.next();
|
||||||
|
let expr = self.expression()?;
|
||||||
|
InvocationArgument::Keyword { name: s.clone(), expr }
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
let expr = self.expression()?;
|
||||||
|
InvocationArgument::Positional(expr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => InvocationArgument::Positional(self.expression()?)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -1159,7 +1179,7 @@ mod parse_tests {
|
|||||||
use super::tokenize;
|
use super::tokenize;
|
||||||
use super::ParseResult;
|
use super::ParseResult;
|
||||||
use crate::builtin::{PrefixOp, BinOp};
|
use crate::builtin::{PrefixOp, BinOp};
|
||||||
use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody};
|
use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument};
|
||||||
use super::Statement::*;
|
use super::Statement::*;
|
||||||
use super::Declaration::*;
|
use super::Declaration::*;
|
||||||
use super::Signature;
|
use super::Signature;
|
||||||
@ -1207,6 +1227,10 @@ mod parse_tests {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! inv {
|
||||||
|
($expr_type:expr) => { Meta::new(InvocationArgument::Positional(ex!($expr_type))) }
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! binexp {
|
macro_rules! binexp {
|
||||||
($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression($lhs, None).into()), bx!(Expression($rhs, None).into())) }
|
($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression($lhs, None).into()), bx!(Expression($rhs, None).into())) }
|
||||||
}
|
}
|
||||||
@ -1339,7 +1363,7 @@ mod parse_tests {
|
|||||||
parse_test!("oi()", AST(vec![exst!(Call { f: bx!(ex!(m val!("oi"))), arguments: vec![] })]));
|
parse_test!("oi()", AST(vec![exst!(Call { f: bx!(ex!(m val!("oi"))), arguments: vec![] })]));
|
||||||
parse_test!("oi(a, 2 + 2)", AST(vec![exst!(Call
|
parse_test!("oi(a, 2 + 2)", AST(vec![exst!(Call
|
||||||
{ f: bx!(ex!(m val!("oi"))),
|
{ f: bx!(ex!(m val!("oi"))),
|
||||||
arguments: vec![ex!(val!("a")).into(), ex!(binexp!("+", NatLiteral(2), NatLiteral(2))).into()]
|
arguments: vec![inv!(val!("a")).into(), inv!(binexp!("+", NatLiteral(2), NatLiteral(2))).into()]
|
||||||
})]));
|
})]));
|
||||||
parse_error!("a(b,,c)");
|
parse_error!("a(b,,c)");
|
||||||
|
|
||||||
@ -1602,7 +1626,7 @@ fn a(x) {
|
|||||||
type_anno: None,
|
type_anno: None,
|
||||||
body: vec![exst!(s "y")] }
|
body: vec![exst!(s "y")] }
|
||||||
)),
|
)),
|
||||||
arguments: vec![ex!(NatLiteral(1)).into()] })]));
|
arguments: vec![inv!(NatLiteral(1)).into()] })]));
|
||||||
|
|
||||||
parse_test_wrap_ast! {
|
parse_test_wrap_ast! {
|
||||||
r#"\(x: Int): String { "q" }"#,
|
r#"\(x: Int): String { "q" }"#,
|
||||||
@ -1644,7 +1668,7 @@ fn a(x) {
|
|||||||
exst! {
|
exst! {
|
||||||
Call {
|
Call {
|
||||||
f: bx!(ex!(m Call { f: bx!(ex!(m val!("wahoo"))), arguments: vec![] })),
|
f: bx!(ex!(m Call { f: bx!(ex!(m val!("wahoo"))), arguments: vec![] })),
|
||||||
arguments: vec![ex!(s "3").into()],
|
arguments: vec![inv!(NatLiteral(3)).into()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -118,6 +118,17 @@ fn reduce_block(block: &Block, symbol_table: &SymbolTable) -> Vec<Stmt> {
|
|||||||
block.iter().map(|stmt| stmt.node().reduce(symbol_table)).collect()
|
block.iter().map(|stmt| stmt.node().reduce(symbol_table)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InvocationArgument {
|
||||||
|
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
||||||
|
use crate::ast::InvocationArgument::*;
|
||||||
|
match self {
|
||||||
|
Positional(ex) => ex.reduce(symbol_table),
|
||||||
|
Keyword { .. } => Expr::UnimplementedSigilValue,
|
||||||
|
Ignored => Expr::UnimplementedSigilValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
||||||
use crate::ast::ExpressionKind::*;
|
use crate::ast::ExpressionKind::*;
|
||||||
|
@ -289,6 +289,14 @@ impl<'a> TypeContext<'a> {
|
|||||||
Ok(ty!(Unit))
|
Ok(ty!(Unit))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn invoc(&mut self, invoc: &InvocationArgument) -> InferResult<Type> {
|
||||||
|
use InvocationArgument::*;
|
||||||
|
match invoc {
|
||||||
|
Positional(expr) => self.expr(expr),
|
||||||
|
_ => Ok(ty!(Nat)) //TODO this is wrong
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn expr(&mut self, expr: &Expression) -> InferResult<Type> {
|
fn expr(&mut self, expr: &Expression) -> InferResult<Type> {
|
||||||
match expr {
|
match expr {
|
||||||
Expression(expr_type, Some(anno)) => {
|
Expression(expr_type, Some(anno)) => {
|
||||||
@ -376,9 +384,9 @@ impl<'a> TypeContext<'a> {
|
|||||||
Ok(ty!(argument_types, ret_type))
|
Ok(ty!(argument_types, ret_type))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, f: &Expression, args: &Vec<Meta<Expression>>) -> InferResult<Type> {
|
fn call(&mut self, f: &Expression, args: &Vec<Meta<InvocationArgument>>) -> InferResult<Type> {
|
||||||
let tf = self.expr(f)?;
|
let tf = self.expr(f)?;
|
||||||
let arg_types: InferResult<Vec<Type>> = args.iter().map(|ex| self.expr(ex.node())).collect();
|
let arg_types: InferResult<Vec<Type>> = args.iter().map(|ex| self.invoc(ex.node())).collect();
|
||||||
let arg_types = arg_types?;
|
let arg_types = arg_types?;
|
||||||
self.handle_apply(tf, arg_types)
|
self.handle_apply(tf, arg_types)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user