Make Meta<Expression> exist everywhere it needs to
This commit is contained in:
parent
8b87945bee
commit
b4da57f5c5
@ -154,7 +154,7 @@ pub enum ExpressionKind {
|
|||||||
},
|
},
|
||||||
Call {
|
Call {
|
||||||
f: Box<Meta<Expression>>,
|
f: Box<Meta<Expression>>,
|
||||||
arguments: Vec<Meta<InvocationArgument>>,
|
arguments: Vec<InvocationArgument>,
|
||||||
},
|
},
|
||||||
Index {
|
Index {
|
||||||
indexee: Box<Meta<Expression>>,
|
indexee: Box<Meta<Expression>>,
|
||||||
|
@ -640,7 +640,7 @@ impl Parser {
|
|||||||
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, invocation_argument, 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().collect();
|
||||||
expr = Expression::new(ExpressionKind::Call { f: bx!(expr.into()), arguments }); //TODO no type anno is incorrect
|
expr = Expression::new(ExpressionKind::Call { f: bx!(expr.into()), arguments }); //TODO no type anno is incorrect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ macro_rules! ex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! inv {
|
macro_rules! inv {
|
||||||
($expr_type:expr) => { Meta::new(InvocationArgument::Positional($expr_type)) }
|
($expr_type:expr) => { InvocationArgument::Positional($expr_type) }
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! binexp {
|
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()", 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![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)");
|
parse_error!("a(b,,c)");
|
||||||
|
|
||||||
|
@ -111,31 +111,31 @@ impl AST {
|
|||||||
pub fn reduce(&self, symbol_table: &SymbolTable) -> ReducedAST {
|
pub fn reduce(&self, symbol_table: &SymbolTable) -> ReducedAST {
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
for statement in self.0.iter() {
|
for statement in self.0.iter() {
|
||||||
output.push(statement.node().reduce(symbol_table));
|
output.push(statement.reduce(symbol_table));
|
||||||
}
|
}
|
||||||
ReducedAST(output)
|
ReducedAST(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Statement {
|
impl Meta<Statement> {
|
||||||
fn reduce(&self, symbol_table: &SymbolTable) -> Stmt {
|
fn reduce(&self, symbol_table: &SymbolTable) -> Stmt {
|
||||||
use crate::ast::Statement::*;
|
use crate::ast::Statement::*;
|
||||||
match self {
|
match self.node() {
|
||||||
ExpressionStatement(expr) => Stmt::Expr(expr.node().reduce(symbol_table)),
|
ExpressionStatement(expr) => Stmt::Expr(expr.reduce(symbol_table)),
|
||||||
Declaration(decl) => decl.reduce(symbol_table),
|
Declaration(decl) => decl.reduce(symbol_table),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_block(block: &Block, symbol_table: &SymbolTable) -> Vec<Stmt> {
|
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 {
|
impl InvocationArgument {
|
||||||
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
||||||
use crate::ast::InvocationArgument::*;
|
use crate::ast::InvocationArgument::*;
|
||||||
match self {
|
match self {
|
||||||
Positional(ex) => ex.node().reduce(symbol_table),
|
Positional(ex) => ex.reduce(symbol_table),
|
||||||
Keyword { .. } => Expr::UnimplementedSigilValue,
|
Keyword { .. } => Expr::UnimplementedSigilValue,
|
||||||
Ignored => Expr::UnimplementedSigilValue,
|
Ignored => Expr::UnimplementedSigilValue,
|
||||||
}
|
}
|
||||||
@ -157,10 +157,11 @@ fn lookup_name_in_scope(sym_name: &QualifiedName) -> FullyQualifiedSymbolName {
|
|||||||
FullyQualifiedSymbolName(new_vec)
|
FullyQualifiedSymbolName(new_vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Meta<Expression> {
|
||||||
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
||||||
use crate::ast::ExpressionKind::*;
|
use crate::ast::ExpressionKind::*;
|
||||||
let ref input = self.kind;
|
let ref node = self.node();
|
||||||
|
let ref input = node.kind;
|
||||||
match input {
|
match input {
|
||||||
NatLiteral(n) => Expr::Lit(Lit::Nat(*n)),
|
NatLiteral(n) => Expr::Lit(Lit::Nat(*n)),
|
||||||
FloatLiteral(f) => Expr::Lit(Lit::Float(*f)),
|
FloatLiteral(f) => Expr::Lit(Lit::Float(*f)),
|
||||||
@ -183,7 +184,7 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Call { f, arguments } => reduce_call_expression(f, arguments, symbol_table),
|
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),
|
IfExpression { discriminator, body } => reduce_if_expression(discriminator, body, symbol_table),
|
||||||
Lambda { params, body, .. } => reduce_lambda(params, body, symbol_table),
|
Lambda { params, body, .. } => reduce_lambda(params, body, symbol_table),
|
||||||
NamedStruct { name, fields } => reduce_named_struct(name, fields, 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 arity = members_from_table.len();
|
||||||
|
|
||||||
let mut args: Vec<(Rc<String>, Expr)> = fields.iter()
|
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();
|
.collect();
|
||||||
|
|
||||||
args.as_mut_slice()
|
args.as_mut_slice()
|
||||||
@ -228,16 +229,16 @@ fn reduce_named_struct(name: &QualifiedName, fields: &Vec<(Rc<String>, Meta<Expr
|
|||||||
Expr::Call { f, args }
|
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 {
|
Expr::Call {
|
||||||
f: Box::new(func.node().reduce(symbol_table)),
|
f: Box::new(func.reduce(symbol_table)),
|
||||||
args: arguments.iter().map(|arg| arg.node().reduce(symbol_table)).collect(),
|
args: arguments.iter().map(|arg| arg.reduce(symbol_table)).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, symbol_table: &SymbolTable) -> Expr {
|
fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, symbol_table: &SymbolTable) -> Expr {
|
||||||
let cond = Box::new(match *discriminator {
|
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")
|
Discriminator::BinOp(ref _expr, ref _binop) => panic!("Can't yet handle binop discriminators")
|
||||||
});
|
});
|
||||||
match *body {
|
match *body {
|
||||||
@ -434,7 +435,7 @@ impl Declaration {
|
|||||||
fn reduce(&self, symbol_table: &SymbolTable) -> Stmt {
|
fn reduce(&self, symbol_table: &SymbolTable) -> Stmt {
|
||||||
use self::Declaration::*;
|
use self::Declaration::*;
|
||||||
match self {
|
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 {
|
FuncDecl(Signature { name, params, .. }, statements) => Stmt::PreBinding {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
func: Func::UserDefined {
|
func: Func::UserDefined {
|
||||||
@ -457,12 +458,12 @@ impl BinOp {
|
|||||||
let operation = Builtin::from_str(self.sigil()).ok();
|
let operation = Builtin::from_str(self.sigil()).ok();
|
||||||
match operation {
|
match operation {
|
||||||
Some(Builtin::Assignment) => Expr::Assign {
|
Some(Builtin::Assignment) => Expr::Assign {
|
||||||
val: Box::new(lhs.node().reduce(symbol_table)),
|
val: Box::new(lhs.reduce(symbol_table)),
|
||||||
expr: Box::new(rhs.node().reduce(symbol_table)),
|
expr: Box::new(rhs.reduce(symbol_table)),
|
||||||
},
|
},
|
||||||
Some(op) => {
|
Some(op) => {
|
||||||
let f = Box::new(Expr::Func(Func::BuiltIn(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 => {
|
None => {
|
||||||
//TODO handle a user-defined operation
|
//TODO handle a user-defined operation
|
||||||
@ -477,7 +478,7 @@ impl PrefixOp {
|
|||||||
match self.builtin {
|
match self.builtin {
|
||||||
Some(op) => {
|
Some(op) => {
|
||||||
let f = Box::new(Expr::Func(Func::BuiltIn(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
|
None => { //TODO need this for custom prefix ops
|
||||||
Expr::UnimplementedSigilValue
|
Expr::UnimplementedSigilValue
|
||||||
|
@ -318,7 +318,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
BinExp(op, lhs, rhs) => self.binexp(op, lhs.node(), rhs.node())?,
|
BinExp(op, lhs, rhs) => self.binexp(op, lhs.node(), rhs.node())?,
|
||||||
IfExpression { discriminator, body } => self.if_expr(discriminator, body)?,
|
IfExpression { discriminator, body } => self.if_expr(discriminator, body)?,
|
||||||
Value(val) => self.handle_value(val)?,
|
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)?,
|
Lambda { params, type_anno, body } => self.lambda(params, type_anno, body)?,
|
||||||
_ => ty!(Unit),
|
_ => ty!(Unit),
|
||||||
})
|
})
|
||||||
@ -383,9 +383,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<InvocationArgument>>) -> InferResult<Type> {
|
fn call(&mut self, f: &Meta<Expression>, args: &Vec<InvocationArgument>) -> InferResult<Type> {
|
||||||
let tf = self.expr(f)?;
|
let tf = self.expr(f.node())?;
|
||||||
let arg_types: InferResult<Vec<Type>> = args.iter().map(|ex| self.invoc(ex.node())).collect();
|
let arg_types: InferResult<Vec<Type>> = args.iter().map(|ex| self.invoc(ex)).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