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> {
|
||||
let mut expr = self.index_expr()?;
|
||||
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();
|
||||
expr = Expression(ExpressionKind::Call { f: bx!(expr.into()), arguments }, None); //TODO none is incorrect
|
||||
}
|
||||
@ -629,8 +629,28 @@ impl Parser {
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn invocation_argument(&mut self) -> ParseResult<InvocationExpression> {
|
||||
panic!()
|
||||
fn invocation_argument(&mut self) -> ParseResult<InvocationArgument> {
|
||||
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]
|
||||
@ -1159,7 +1179,7 @@ mod parse_tests {
|
||||
use super::tokenize;
|
||||
use super::ParseResult;
|
||||
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::Declaration::*;
|
||||
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 {
|
||||
($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(a, 2 + 2)", AST(vec![exst!(Call
|
||||
{ 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)");
|
||||
|
||||
@ -1602,7 +1626,7 @@ fn a(x) {
|
||||
type_anno: None,
|
||||
body: vec![exst!(s "y")] }
|
||||
)),
|
||||
arguments: vec![ex!(NatLiteral(1)).into()] })]));
|
||||
arguments: vec![inv!(NatLiteral(1)).into()] })]));
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
r#"\(x: Int): String { "q" }"#,
|
||||
@ -1644,7 +1668,7 @@ fn a(x) {
|
||||
exst! {
|
||||
Call {
|
||||
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()
|
||||
}
|
||||
|
||||
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 {
|
||||
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
||||
use crate::ast::ExpressionKind::*;
|
||||
|
@ -289,6 +289,14 @@ impl<'a> TypeContext<'a> {
|
||||
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> {
|
||||
match expr {
|
||||
Expression(expr_type, Some(anno)) => {
|
||||
@ -376,9 +384,9 @@ impl<'a> TypeContext<'a> {
|
||||
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 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?;
|
||||
self.handle_apply(tf, arg_types)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user