Wrap remaining Expressions in Meta
This commit is contained in:
parent
f96469178d
commit
8b87945bee
@ -2,6 +2,7 @@ use std::rc::Rc;
|
|||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
|
||||||
use crate::typechecking::TypeData;
|
use crate::typechecking::TypeData;
|
||||||
|
use crate::symbol_table::FullyQualifiedSymbolName;
|
||||||
|
|
||||||
mod operators;
|
mod operators;
|
||||||
pub use operators::*;
|
pub use operators::*;
|
||||||
@ -11,11 +12,16 @@ pub struct Meta<T> {
|
|||||||
n: T,
|
n: T,
|
||||||
source_map: SourceMap,
|
source_map: SourceMap,
|
||||||
type_data: TypeData,
|
type_data: TypeData,
|
||||||
|
fqsn: Option<FullyQualifiedSymbolName>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Meta<T> {
|
impl<T> Meta<T> {
|
||||||
pub fn new(n: T) -> Meta<T> {
|
pub fn new(n: T) -> Meta<T> {
|
||||||
Meta { n, source_map: SourceMap::default(), type_data: TypeData::new() }
|
Meta { n,
|
||||||
|
source_map: SourceMap::default(),
|
||||||
|
type_data: TypeData::new(),
|
||||||
|
fqsn: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node(&self) -> &T {
|
pub fn node(&self) -> &T {
|
||||||
@ -30,7 +36,7 @@ struct SourceMap {
|
|||||||
|
|
||||||
impl From<Expression> for Meta<Expression> {
|
impl From<Expression> for Meta<Expression> {
|
||||||
fn from(expr: Expression) -> Meta<Expression> {
|
fn from(expr: Expression) -> Meta<Expression> {
|
||||||
Meta { n: expr, source_map: SourceMap::default(), type_data: TypeData::new() }
|
Meta::new(expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +58,7 @@ pub struct QualifiedName(pub Vec<Rc<String>>);
|
|||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct FormalParam {
|
pub struct FormalParam {
|
||||||
pub name: ParamName,
|
pub name: ParamName,
|
||||||
pub default: Option<Expression>,
|
pub default: Option<Meta<Expression>>,
|
||||||
pub anno: Option<TypeIdentifier>
|
pub anno: Option<TypeIdentifier>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,18 +182,18 @@ pub enum ExpressionKind {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum InvocationArgument {
|
pub enum InvocationArgument {
|
||||||
Positional(Expression),
|
Positional(Meta<Expression>),
|
||||||
Keyword {
|
Keyword {
|
||||||
name: Rc<String>,
|
name: Rc<String>,
|
||||||
expr: Expression,
|
expr: Meta<Expression>,
|
||||||
},
|
},
|
||||||
Ignored
|
Ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Discriminator {
|
pub enum Discriminator {
|
||||||
Simple(Expression),
|
Simple(Meta<Expression>),
|
||||||
BinOp(Expression, BinOp)
|
BinOp(Meta<Expression>, BinOp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
@ -477,7 +477,7 @@ impl Parser {
|
|||||||
let default = match self.token_handler.peek_kind() {
|
let default = match self.token_handler.peek_kind() {
|
||||||
Equals => {
|
Equals => {
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
Some(self.expression()?)
|
Some(self.expression()?.into())
|
||||||
},
|
},
|
||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
@ -659,16 +659,16 @@ impl Parser {
|
|||||||
Equals => {
|
Equals => {
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
let expr = self.expression()?;
|
let expr = self.expression()?.into();
|
||||||
InvocationArgument::Keyword { name: s.clone(), expr }
|
InvocationArgument::Keyword { name: s.clone(), expr }
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let expr = self.expression()?;
|
let expr = self.expression()?;
|
||||||
InvocationArgument::Positional(expr)
|
InvocationArgument::Positional(expr.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => InvocationArgument::Positional(self.expression()?)
|
_ => InvocationArgument::Positional(self.expression()?.into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,9 +824,9 @@ impl Parser {
|
|||||||
let lhs = self.prefix_expr()?;
|
let lhs = self.prefix_expr()?;
|
||||||
let ref next = self.token_handler.peek_kind();
|
let ref next = self.token_handler.peek_kind();
|
||||||
Ok(if let Some(op) = BinOp::from_sigil_token(next) {
|
Ok(if let Some(op) = BinOp::from_sigil_token(next) {
|
||||||
Discriminator::BinOp(lhs, op)
|
Discriminator::BinOp(lhs.into(), op)
|
||||||
} else {
|
} else {
|
||||||
Discriminator::Simple(lhs)
|
Discriminator::Simple(lhs.into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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!(val!("a"))).into(), inv!(ex!(binexp!("+", NatLiteral(2), NatLiteral(2)))).into()]
|
arguments: vec![inv!(ex!(m val!("a"))).into(), inv!(ex!(m binexp!("+", NatLiteral(2), NatLiteral(2)))).into()]
|
||||||
})]));
|
})]));
|
||||||
parse_error!("a(b,,c)");
|
parse_error!("a(b,,c)");
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ fn functions_with_default_args() {
|
|||||||
Meta::new(Declaration(
|
Meta::new(Declaration(
|
||||||
FuncDecl(Signature { name: rc!(func), operator: false, type_anno: None, params: vec![
|
FuncDecl(Signature { name: rc!(func), operator: false, type_anno: None, params: vec![
|
||||||
FormalParam { name: rc!(x), default: None, anno: Some(ty!("Int")) },
|
FormalParam { name: rc!(x), default: None, anno: Some(ty!("Int")) },
|
||||||
FormalParam { name: rc!(y), default: Some(ex!(s "4")), anno: Some(ty!("Int")) }
|
FormalParam { name: rc!(y), default: Some(Meta::new(ex!(s "4"))), anno: Some(ty!("Int")) }
|
||||||
]}, vec![])
|
]}, vec![])
|
||||||
))
|
))
|
||||||
])
|
])
|
||||||
@ -323,7 +323,7 @@ fn parsing_block_expressions() {
|
|||||||
"if a() then { b(); c() }", AST(vec![exst!(
|
"if a() then { b(); c() }", AST(vec![exst!(
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: bx! {
|
discriminator: bx! {
|
||||||
Discriminator::Simple(ex!(Call { f: bx!(ex!(m val!("a"))), arguments: vec![]}))
|
Discriminator::Simple(ex!(m Call { f: bx!(ex!(m val!("a"))), arguments: vec![]}))
|
||||||
},
|
},
|
||||||
body: bx! {
|
body: bx! {
|
||||||
IfExpressionBody::SimpleConditional(
|
IfExpressionBody::SimpleConditional(
|
||||||
@ -339,7 +339,7 @@ fn parsing_block_expressions() {
|
|||||||
"if a() then { b(); c() } else { q }", AST(vec![exst!(
|
"if a() then { b(); c() } else { q }", AST(vec![exst!(
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: bx! {
|
discriminator: bx! {
|
||||||
Discriminator::Simple(ex!(Call { f: bx!(ex!(m val!("a"))), arguments: vec![]}))
|
Discriminator::Simple(ex!(m Call { f: bx!(ex!(m val!("a"))), arguments: vec![]}))
|
||||||
},
|
},
|
||||||
body: bx! {
|
body: bx! {
|
||||||
IfExpressionBody::SimpleConditional(
|
IfExpressionBody::SimpleConditional(
|
||||||
@ -500,7 +500,7 @@ fn parsing_lambdas() {
|
|||||||
type_anno: None,
|
type_anno: None,
|
||||||
body: vec![exst!(s "y")] }
|
body: vec![exst!(s "y")] }
|
||||||
)),
|
)),
|
||||||
arguments: vec![inv!(ex!(NatLiteral(1))).into()] })]));
|
arguments: vec![inv!(ex!(m NatLiteral(1))).into()] })]));
|
||||||
|
|
||||||
parse_test_wrap_ast! {
|
parse_test_wrap_ast! {
|
||||||
r#"\(x: Int): String { "q" }"#,
|
r#"\(x: Int): String { "q" }"#,
|
||||||
@ -544,7 +544,7 @@ fn more_advanced_lambdas() {
|
|||||||
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![inv!(ex!(NatLiteral(3))).into()],
|
arguments: vec![inv!(ex!(m NatLiteral(3))).into()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
@ -595,7 +595,7 @@ fn patterns() {
|
|||||||
parse_test_wrap_ast! {
|
parse_test_wrap_ast! {
|
||||||
"if x is Some(a) then { 4 } else { 9 }", exst!(
|
"if x is Some(a) then { 4 } else { 9 }", exst!(
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: bx!(Discriminator::Simple(ex!(s "x"))),
|
discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))),
|
||||||
body: bx!(IfExpressionBody::SimplePatternMatch(Pattern::TupleStruct(rc!(Some), vec![Pattern::Literal(PatternLiteral::VarPattern(rc!(a)))]), vec![exst!(s "4")], Some(vec![exst!(s "9")]))) }
|
body: bx!(IfExpressionBody::SimplePatternMatch(Pattern::TupleStruct(rc!(Some), vec![Pattern::Literal(PatternLiteral::VarPattern(rc!(a)))]), vec![exst!(s "4")], Some(vec![exst!(s "9")]))) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -603,7 +603,7 @@ fn patterns() {
|
|||||||
parse_test_wrap_ast! {
|
parse_test_wrap_ast! {
|
||||||
"if x is Some(a) then 4 else 9", exst!(
|
"if x is Some(a) then 4 else 9", exst!(
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: bx!(Discriminator::Simple(ex!(s "x"))),
|
discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))),
|
||||||
body: bx!(IfExpressionBody::SimplePatternMatch(Pattern::TupleStruct(rc!(Some), vec![Pattern::Literal(PatternLiteral::VarPattern(rc!(a)))]), vec![exst!(s "4")], Some(vec![exst!(s "9")]))) }
|
body: bx!(IfExpressionBody::SimplePatternMatch(Pattern::TupleStruct(rc!(Some), vec![Pattern::Literal(PatternLiteral::VarPattern(rc!(a)))]), vec![exst!(s "4")], Some(vec![exst!(s "9")]))) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -611,7 +611,7 @@ fn patterns() {
|
|||||||
parse_test_wrap_ast! {
|
parse_test_wrap_ast! {
|
||||||
"if x is Something { a, b: x } then { 4 } else { 9 }", exst!(
|
"if x is Something { a, b: x } then { 4 } else { 9 }", exst!(
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: bx!(Discriminator::Simple(ex!(s "x"))),
|
discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))),
|
||||||
body: bx!(IfExpressionBody::SimplePatternMatch(
|
body: bx!(IfExpressionBody::SimplePatternMatch(
|
||||||
Pattern::Record(rc!(Something), vec![
|
Pattern::Record(rc!(Something), vec![
|
||||||
(rc!(a),Pattern::Literal(PatternLiteral::StringPattern(rc!(a)))),
|
(rc!(a),Pattern::Literal(PatternLiteral::StringPattern(rc!(a)))),
|
||||||
@ -629,7 +629,7 @@ fn pattern_literals() {
|
|||||||
"if x is -1 then 1 else 2",
|
"if x is -1 then 1 else 2",
|
||||||
exst!(
|
exst!(
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: bx!(Discriminator::Simple(ex!(s "x"))),
|
discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))),
|
||||||
body: bx!(IfExpressionBody::SimplePatternMatch(
|
body: bx!(IfExpressionBody::SimplePatternMatch(
|
||||||
Pattern::Literal(PatternLiteral::NumPattern { neg: true, num: NatLiteral(1) }),
|
Pattern::Literal(PatternLiteral::NumPattern { neg: true, num: NatLiteral(1) }),
|
||||||
vec![exst!(NatLiteral(1))],
|
vec![exst!(NatLiteral(1))],
|
||||||
@ -643,7 +643,7 @@ fn pattern_literals() {
|
|||||||
"if x is 1 then 1 else 2",
|
"if x is 1 then 1 else 2",
|
||||||
exst!(
|
exst!(
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: bx!(Discriminator::Simple(ex!(s "x"))),
|
discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))),
|
||||||
body: bx!(IfExpressionBody::SimplePatternMatch(
|
body: bx!(IfExpressionBody::SimplePatternMatch(
|
||||||
Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: NatLiteral(1) }),
|
Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: NatLiteral(1) }),
|
||||||
vec![exst!(s "1")],
|
vec![exst!(s "1")],
|
||||||
@ -657,7 +657,7 @@ fn pattern_literals() {
|
|||||||
"if x is true then 1 else 2", AST(vec![
|
"if x is true then 1 else 2", AST(vec![
|
||||||
exst!(
|
exst!(
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: bx!(Discriminator::Simple(ex!(s "x"))),
|
discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))),
|
||||||
body: bx!(IfExpressionBody::SimplePatternMatch(
|
body: bx!(IfExpressionBody::SimplePatternMatch(
|
||||||
Pattern::Literal(PatternLiteral::BoolPattern(true)),
|
Pattern::Literal(PatternLiteral::BoolPattern(true)),
|
||||||
vec![exst!(NatLiteral(1))],
|
vec![exst!(NatLiteral(1))],
|
||||||
@ -672,7 +672,7 @@ fn pattern_literals() {
|
|||||||
"if x is \"gnosticism\" then 1 else 2",
|
"if x is \"gnosticism\" then 1 else 2",
|
||||||
exst!(
|
exst!(
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: bx!(Discriminator::Simple(ex!(s "x"))),
|
discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))),
|
||||||
body: bx!(IfExpressionBody::SimplePatternMatch(
|
body: bx!(IfExpressionBody::SimplePatternMatch(
|
||||||
Pattern::Literal(PatternLiteral::StringPattern(rc!(gnosticism))),
|
Pattern::Literal(PatternLiteral::StringPattern(rc!(gnosticism))),
|
||||||
vec![exst!(s "1")],
|
vec![exst!(s "1")],
|
||||||
|
@ -135,7 +135,7 @@ 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.reduce(symbol_table),
|
Positional(ex) => ex.node().reduce(symbol_table),
|
||||||
Keyword { .. } => Expr::UnimplementedSigilValue,
|
Keyword { .. } => Expr::UnimplementedSigilValue,
|
||||||
Ignored => Expr::UnimplementedSigilValue,
|
Ignored => Expr::UnimplementedSigilValue,
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ fn reduce_call_expression(func: &Meta<Expression>, arguments: &Vec<Meta<Invocati
|
|||||||
|
|
||||||
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.reduce(symbol_table),
|
Discriminator::Simple(ref expr) => expr.node().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 {
|
||||||
|
@ -291,7 +291,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
fn invoc(&mut self, invoc: &InvocationArgument) -> InferResult<Type> {
|
fn invoc(&mut self, invoc: &InvocationArgument) -> InferResult<Type> {
|
||||||
use InvocationArgument::*;
|
use InvocationArgument::*;
|
||||||
match invoc {
|
match invoc {
|
||||||
Positional(expr) => self.expr(expr),
|
Positional(expr) => self.expr(expr.node()),
|
||||||
_ => Ok(ty!(Nat)) //TODO this is wrong
|
_ => Ok(ty!(Nat)) //TODO this is wrong
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,7 +349,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
fn if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type> {
|
fn if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type> {
|
||||||
use self::Discriminator::*; use self::IfExpressionBody::*;
|
use self::Discriminator::*; use self::IfExpressionBody::*;
|
||||||
match (discriminator, body) {
|
match (discriminator, body) {
|
||||||
(Simple(expr), SimpleConditional(then_clause, else_clause)) => self.handle_simple_if(expr, then_clause, else_clause),
|
(Simple(expr), SimpleConditional(then_clause, else_clause)) => self.handle_simple_if(expr.node(), then_clause, else_clause),
|
||||||
_ => TypeError::new(format!("Complex conditionals not supported"))
|
_ => TypeError::new(format!("Complex conditionals not supported"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user