More work on args

not quite done
This commit is contained in:
greg 2019-06-12 03:28:46 -07:00
parent fa1257e2cd
commit 40579d80ce
3 changed files with 52 additions and 9 deletions

View File

@ -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()],
}
}
])

View File

@ -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::*;

View File

@ -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)
}