Make Meta<Expression> exist everywhere it needs to

This commit is contained in:
greg 2019-09-02 14:41:09 -07:00
parent 8b87945bee
commit b4da57f5c5
5 changed files with 28 additions and 27 deletions

View File

@ -154,7 +154,7 @@ pub enum ExpressionKind {
},
Call {
f: Box<Meta<Expression>>,
arguments: Vec<Meta<InvocationArgument>>,
arguments: Vec<InvocationArgument>,
},
Index {
indexee: Box<Meta<Expression>>,

View File

@ -640,7 +640,7 @@ impl Parser {
let mut expr = self.index_expr()?;
while let LParen = self.token_handler.peek_kind() {
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().collect();
expr = Expression::new(ExpressionKind::Call { f: bx!(expr.into()), arguments }); //TODO no type anno is incorrect
}

View File

@ -53,7 +53,7 @@ macro_rules! ex {
}
macro_rules! inv {
($expr_type:expr) => { Meta::new(InvocationArgument::Positional($expr_type)) }
($expr_type:expr) => { InvocationArgument::Positional($expr_type) }
}
macro_rules! binexp {
@ -209,7 +209,7 @@ fn parsing_functions() {
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![inv!(ex!(m val!("a"))).into(), inv!(ex!(m binexp!("+", NatLiteral(2), NatLiteral(2)))).into()]
arguments: vec![inv!(ex!(m val!("a"))), inv!(ex!(m binexp!("+", NatLiteral(2), NatLiteral(2)))).into()]
})]));
parse_error!("a(b,,c)");

View File

@ -111,31 +111,31 @@ impl AST {
pub fn reduce(&self, symbol_table: &SymbolTable) -> ReducedAST {
let mut output = vec![];
for statement in self.0.iter() {
output.push(statement.node().reduce(symbol_table));
output.push(statement.reduce(symbol_table));
}
ReducedAST(output)
}
}
impl Statement {
impl Meta<Statement> {
fn reduce(&self, symbol_table: &SymbolTable) -> Stmt {
use crate::ast::Statement::*;
match self {
ExpressionStatement(expr) => Stmt::Expr(expr.node().reduce(symbol_table)),
match self.node() {
ExpressionStatement(expr) => Stmt::Expr(expr.reduce(symbol_table)),
Declaration(decl) => decl.reduce(symbol_table),
}
}
}
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.reduce(symbol_table)).collect()
}
impl InvocationArgument {
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
use crate::ast::InvocationArgument::*;
match self {
Positional(ex) => ex.node().reduce(symbol_table),
Positional(ex) => ex.reduce(symbol_table),
Keyword { .. } => Expr::UnimplementedSigilValue,
Ignored => Expr::UnimplementedSigilValue,
}
@ -157,10 +157,11 @@ fn lookup_name_in_scope(sym_name: &QualifiedName) -> FullyQualifiedSymbolName {
FullyQualifiedSymbolName(new_vec)
}
impl Expression {
impl Meta<Expression> {
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
use crate::ast::ExpressionKind::*;
let ref input = self.kind;
let ref node = self.node();
let ref input = node.kind;
match input {
NatLiteral(n) => Expr::Lit(Lit::Nat(*n)),
FloatLiteral(f) => Expr::Lit(Lit::Float(*f)),
@ -183,7 +184,7 @@ impl Expression {
}
},
Call { f, arguments } => reduce_call_expression(f, arguments, symbol_table),
TupleLiteral(exprs) => Expr::Tuple(exprs.iter().map(|e| e.node().reduce(symbol_table)).collect()),
TupleLiteral(exprs) => Expr::Tuple(exprs.iter().map(|e| e.reduce(symbol_table)).collect()),
IfExpression { discriminator, body } => reduce_if_expression(discriminator, body, symbol_table),
Lambda { params, body, .. } => reduce_lambda(params, body, symbol_table),
NamedStruct { name, fields } => reduce_named_struct(name, fields, symbol_table),
@ -215,7 +216,7 @@ fn reduce_named_struct(name: &QualifiedName, fields: &Vec<(Rc<String>, Meta<Expr
let arity = members_from_table.len();
let mut args: Vec<(Rc<String>, Expr)> = fields.iter()
.map(|(name, expr)| (name.clone(), expr.node().reduce(symbol_table)))
.map(|(name, expr)| (name.clone(), expr.reduce(symbol_table)))
.collect();
args.as_mut_slice()
@ -228,16 +229,16 @@ fn reduce_named_struct(name: &QualifiedName, fields: &Vec<(Rc<String>, Meta<Expr
Expr::Call { f, args }
}
fn reduce_call_expression(func: &Meta<Expression>, arguments: &Vec<Meta<InvocationArgument>>, symbol_table: &SymbolTable) -> Expr {
fn reduce_call_expression(func: &Meta<Expression>, arguments: &Vec<InvocationArgument>, symbol_table: &SymbolTable) -> Expr {
Expr::Call {
f: Box::new(func.node().reduce(symbol_table)),
args: arguments.iter().map(|arg| arg.node().reduce(symbol_table)).collect(),
f: Box::new(func.reduce(symbol_table)),
args: arguments.iter().map(|arg| arg.reduce(symbol_table)).collect(),
}
}
fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, symbol_table: &SymbolTable) -> Expr {
let cond = Box::new(match *discriminator {
Discriminator::Simple(ref expr) => expr.node().reduce(symbol_table),
Discriminator::Simple(ref expr) => expr.reduce(symbol_table),
Discriminator::BinOp(ref _expr, ref _binop) => panic!("Can't yet handle binop discriminators")
});
match *body {
@ -434,7 +435,7 @@ impl Declaration {
fn reduce(&self, symbol_table: &SymbolTable) -> Stmt {
use self::Declaration::*;
match self {
Binding {name, constant, expr, .. } => Stmt::Binding { name: name.clone(), constant: *constant, expr: expr.node().reduce(symbol_table) },
Binding {name, constant, expr, .. } => Stmt::Binding { name: name.clone(), constant: *constant, expr: expr.reduce(symbol_table) },
FuncDecl(Signature { name, params, .. }, statements) => Stmt::PreBinding {
name: name.clone(),
func: Func::UserDefined {
@ -457,12 +458,12 @@ impl BinOp {
let operation = Builtin::from_str(self.sigil()).ok();
match operation {
Some(Builtin::Assignment) => Expr::Assign {
val: Box::new(lhs.node().reduce(symbol_table)),
expr: Box::new(rhs.node().reduce(symbol_table)),
val: Box::new(lhs.reduce(symbol_table)),
expr: Box::new(rhs.reduce(symbol_table)),
},
Some(op) => {
let f = Box::new(Expr::Func(Func::BuiltIn(op)));
Expr::Call { f, args: vec![lhs.node().reduce(symbol_table), rhs.node().reduce(symbol_table)]}
Expr::Call { f, args: vec![lhs.reduce(symbol_table), rhs.reduce(symbol_table)]}
},
None => {
//TODO handle a user-defined operation
@ -477,7 +478,7 @@ impl PrefixOp {
match self.builtin {
Some(op) => {
let f = Box::new(Expr::Func(Func::BuiltIn(op)));
Expr::Call { f, args: vec![arg.node().reduce(symbol_table)]}
Expr::Call { f, args: vec![arg.reduce(symbol_table)]}
},
None => { //TODO need this for custom prefix ops
Expr::UnimplementedSigilValue

View File

@ -318,7 +318,7 @@ impl<'a> TypeContext<'a> {
BinExp(op, lhs, rhs) => self.binexp(op, lhs.node(), rhs.node())?,
IfExpression { discriminator, body } => self.if_expr(discriminator, body)?,
Value(val) => self.handle_value(val)?,
Call { box ref f, arguments } => self.call(f.node(), arguments)?,
Call { box ref f, arguments } => self.call(f, arguments)?,
Lambda { params, type_anno, body } => self.lambda(params, type_anno, body)?,
_ => ty!(Unit),
})
@ -383,9 +383,9 @@ impl<'a> TypeContext<'a> {
Ok(ty!(argument_types, ret_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.invoc(ex.node())).collect();
fn call(&mut self, f: &Meta<Expression>, args: &Vec<InvocationArgument>) -> InferResult<Type> {
let tf = self.expr(f.node())?;
let arg_types: InferResult<Vec<Type>> = args.iter().map(|ex| self.invoc(ex)).collect();
let arg_types = arg_types?;
self.handle_apply(tf, arg_types)
}