Refactor Expression struct
to have explicit kind and type_anno fields, to make it clearer that this represents source-code level annotation and not any kind of type inference intermediate product
This commit is contained in:
parent
d9330bed26
commit
d67ccf5c7a
@ -100,8 +100,20 @@ pub enum Variant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Expression(pub ExpressionKind, pub Option<TypeIdentifier>);
|
pub struct Expression {
|
||||||
|
pub kind: ExpressionKind,
|
||||||
|
pub type_anno: Option<TypeIdentifier>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Expression {
|
||||||
|
pub fn new(kind: ExpressionKind) -> Expression {
|
||||||
|
Expression { kind, type_anno: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_anno(kind: ExpressionKind, type_anno: TypeIdentifier) -> Expression {
|
||||||
|
Expression { kind, type_anno: Some(type_anno) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum TypeIdentifier {
|
pub enum TypeIdentifier {
|
||||||
|
@ -549,10 +549,10 @@ impl Parser {
|
|||||||
Colon => Some(self.type_anno()?),
|
Colon => Some(self.type_anno()?),
|
||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
if let Some(_) = expr_body.1 {
|
if let Some(_) = expr_body.type_anno {
|
||||||
return ParseError::new_with_token("Bad parse state encountered", self.token_handler.peek());
|
return ParseError::new_with_token("Bad parse state encountered", self.token_handler.peek());
|
||||||
}
|
}
|
||||||
expr_body.1 = type_anno;
|
expr_body.type_anno = type_anno;
|
||||||
Ok(expr_body)
|
Ok(expr_body)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,7 +608,7 @@ impl Parser {
|
|||||||
None => unreachable!()
|
None => unreachable!()
|
||||||
};
|
};
|
||||||
let rhs = self.precedence_expr(new_precedence)?;
|
let rhs = self.precedence_expr(new_precedence)?;
|
||||||
lhs = Expression(ExpressionKind::BinExp(operation, bx!(lhs.into()), bx!(rhs.into())), None);
|
lhs = Expression::new(ExpressionKind::BinExp(operation, bx!(lhs.into()), bx!(rhs.into())));
|
||||||
}
|
}
|
||||||
self.parse_level -= 1;
|
self.parse_level -= 1;
|
||||||
Ok(lhs)
|
Ok(lhs)
|
||||||
@ -623,9 +623,8 @@ impl Parser {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let expr = self.primary()?;
|
let expr = self.primary()?;
|
||||||
Ok(Expression(
|
Ok(Expression::new(
|
||||||
ExpressionKind::PrefixExp(PrefixOp::from_sigil(sigil.as_str()), bx!(expr.into())),
|
ExpressionKind::PrefixExp(PrefixOp::from_sigil(sigil.as_str()), bx!(expr.into()))
|
||||||
None
|
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
_ => self.call_expr()
|
_ => self.call_expr()
|
||||||
@ -638,7 +637,7 @@ impl Parser {
|
|||||||
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().map(|s| Meta::new(s)).collect();
|
||||||
expr = Expression(ExpressionKind::Call { f: bx!(expr.into()), arguments }, None); //TODO none is incorrect
|
expr = Expression::new(ExpressionKind::Call { f: bx!(expr.into()), arguments }); //TODO no type anno is incorrect
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(expr)
|
Ok(expr)
|
||||||
@ -675,10 +674,10 @@ impl Parser {
|
|||||||
Ok(if let LSquareBracket = self.token_handler.peek_kind() {
|
Ok(if let LSquareBracket = self.token_handler.peek_kind() {
|
||||||
let indexers = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket)
|
let indexers = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket)
|
||||||
.into_iter().map(|ex| ex.into()).collect();
|
.into_iter().map(|ex| ex.into()).collect();
|
||||||
Expression(ExpressionKind::Index {
|
Expression::new(ExpressionKind::Index {
|
||||||
indexee: bx!(Expression(primary.0, None).into()),
|
indexee: bx!(Expression::new(primary.kind).into()),
|
||||||
indexers,
|
indexers,
|
||||||
}, None)
|
})
|
||||||
} else {
|
} else {
|
||||||
primary
|
primary
|
||||||
})
|
})
|
||||||
@ -703,7 +702,7 @@ impl Parser {
|
|||||||
fn list_expr(&mut self) -> ParseResult<Expression> {
|
fn list_expr(&mut self) -> ParseResult<Expression> {
|
||||||
let exprs = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket)
|
let exprs = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket)
|
||||||
.into_iter().map(|ex| ex.into()).collect();
|
.into_iter().map(|ex| ex.into()).collect();
|
||||||
Ok(Expression(ExpressionKind::ListLiteral(exprs), None))
|
Ok(Expression::new(ExpressionKind::ListLiteral(exprs)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -720,7 +719,7 @@ impl Parser {
|
|||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let body = self.nonempty_func_body()?;
|
let body = self.nonempty_func_body()?;
|
||||||
Ok(Expression(ExpressionKind::Lambda { params, type_anno, body }, None)) //TODO need to handle types somehow
|
Ok(Expression::new(ExpressionKind::Lambda { params, type_anno, body })) //TODO need to handle types somehow
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -741,11 +740,11 @@ impl Parser {
|
|||||||
let output = {
|
let output = {
|
||||||
let mut inner = delimited!(self, LParen, expression, Comma, RParen);
|
let mut inner = delimited!(self, LParen, expression, Comma, RParen);
|
||||||
match inner.len() {
|
match inner.len() {
|
||||||
0 => Ok(Expression(TupleLiteral(vec![]), None)),
|
0 => Ok(Expression::new(TupleLiteral(vec![]))),
|
||||||
1 => Ok(inner.pop().unwrap()),
|
1 => Ok(inner.pop().unwrap()),
|
||||||
_ => {
|
_ => {
|
||||||
let inner: Vec<Meta<Expression>> = inner.into_iter().map(|ex| ex.into()).collect();
|
let inner: Vec<Meta<Expression>> = inner.into_iter().map(|ex| ex.into()).collect();
|
||||||
Ok(Expression(TupleLiteral(inner), None))
|
Ok(Expression::new(TupleLiteral(inner)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -760,9 +759,9 @@ impl Parser {
|
|||||||
Ok(match self.token_handler.peek_kind() {
|
Ok(match self.token_handler.peek_kind() {
|
||||||
LCurlyBrace if !self.restrictions.no_struct_literal => {
|
LCurlyBrace if !self.restrictions.no_struct_literal => {
|
||||||
let fields = self.record_block()?;
|
let fields = self.record_block()?;
|
||||||
Expression(NamedStruct { name: identifier, fields }, None)
|
Expression::new(NamedStruct { name: identifier, fields })
|
||||||
},
|
},
|
||||||
_ => Expression(Value(identifier), None)
|
_ => Expression::new(Value(identifier))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,7 +797,7 @@ impl Parser {
|
|||||||
_ => self.guard_block()?
|
_ => self.guard_block()?
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Expression(ExpressionKind::IfExpression { discriminator, body }, None))
|
Ok(Expression::new(ExpressionKind::IfExpression { discriminator, body }))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -890,13 +889,13 @@ impl Parser {
|
|||||||
ref tok if BinOp::from_sigil_token(tok).is_some() => {
|
ref tok if BinOp::from_sigil_token(tok).is_some() => {
|
||||||
let op = BinOp::from_sigil_token(&self.token_handler.next().kind).unwrap();
|
let op = BinOp::from_sigil_token(&self.token_handler.next().kind).unwrap();
|
||||||
let precedence = op.get_precedence();
|
let precedence = op.get_precedence();
|
||||||
let Expression(expr, _) = self.precedence_expr(precedence)?;
|
let Expression { kind, .. } = self.precedence_expr(precedence)?;
|
||||||
Guard::HalfExpr(HalfExpr { op: Some(op), expr })
|
Guard::HalfExpr(HalfExpr { op: Some(op), expr: kind })
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
//TODO - I think there's a better way to do this involving the precedence of ->
|
//TODO - I think there's a better way to do this involving the precedence of ->
|
||||||
let Expression(expr, _) = self.prefix_expr()?;
|
let Expression { kind, .. } = self.prefix_expr()?;
|
||||||
Guard::HalfExpr(HalfExpr { op: None, expr })
|
Guard::HalfExpr(HalfExpr { op: None, expr: kind })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -962,8 +961,8 @@ impl Parser {
|
|||||||
},
|
},
|
||||||
_ => false
|
_ => false
|
||||||
};
|
};
|
||||||
let Expression(expr_type, _) = self.number_literal()?;
|
let Expression { kind, .. } = self.number_literal()?;
|
||||||
Ok(Pattern::Literal(PatternLiteral::NumPattern { neg, num: expr_type }))
|
Ok(Pattern::Literal(PatternLiteral::NumPattern { neg, num: kind }))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -1007,7 +1006,7 @@ impl Parser {
|
|||||||
x?.map(|expr| bx!(expr.into()))
|
x?.map(|expr| bx!(expr.into()))
|
||||||
};
|
};
|
||||||
let body = self.block()?;
|
let body = self.block()?;
|
||||||
Ok(Expression(WhileExpression {condition, body}, None))
|
Ok(Expression::new(WhileExpression {condition, body}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -1033,7 +1032,7 @@ impl Parser {
|
|||||||
vec![single_enum]
|
vec![single_enum]
|
||||||
};
|
};
|
||||||
let body = Box::new(self.for_expr_body()?);
|
let body = Box::new(self.for_expr_body()?);
|
||||||
Ok(Expression(ExpressionKind::ForExpression { enumerators, body }, None))
|
Ok(Expression::new(ExpressionKind::ForExpression { enumerators, body }))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -1079,15 +1078,15 @@ impl Parser {
|
|||||||
DigitGroup(_) | HexLiteral(_) | BinNumberSigil | Period => self.number_literal(),
|
DigitGroup(_) | HexLiteral(_) | BinNumberSigil | Period => self.number_literal(),
|
||||||
Keyword(Kw::True) => {
|
Keyword(Kw::True) => {
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
Ok(Expression(BoolLiteral(true), None))
|
Ok(Expression::new(BoolLiteral(true)))
|
||||||
},
|
},
|
||||||
Keyword(Kw::False) => {
|
Keyword(Kw::False) => {
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
Ok(Expression(BoolLiteral(false), None))
|
Ok(Expression::new(BoolLiteral(false)))
|
||||||
},
|
},
|
||||||
StrLiteral(s) => {
|
StrLiteral(s) => {
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
Ok(Expression(StringLiteral(s.clone()), None))
|
Ok(Expression::new(StringLiteral(s.clone())))
|
||||||
}
|
}
|
||||||
e => ParseError::new_with_token(format!("Expected a literal expression, got {:?}", e), tok),
|
e => ParseError::new_with_token(format!("Expected a literal expression, got {:?}", e), tok),
|
||||||
}
|
}
|
||||||
@ -1109,12 +1108,12 @@ impl Parser {
|
|||||||
BinNumberSigil => {
|
BinNumberSigil => {
|
||||||
let digits = self.digits()?;
|
let digits = self.digits()?;
|
||||||
let n = parse_binary(digits, tok)?;
|
let n = parse_binary(digits, tok)?;
|
||||||
Ok(Expression(NatLiteral(n), None))
|
Ok(Expression::new(NatLiteral(n)))
|
||||||
},
|
},
|
||||||
HexLiteral(text) => {
|
HexLiteral(text) => {
|
||||||
let digits: String = text.chars().filter(|c| c.is_digit(16)).collect();
|
let digits: String = text.chars().filter(|c| c.is_digit(16)).collect();
|
||||||
let n = parse_hex(digits, tok)?;
|
let n = parse_hex(digits, tok)?;
|
||||||
Ok(Expression(NatLiteral(n), None))
|
Ok(Expression::new(NatLiteral(n)))
|
||||||
},
|
},
|
||||||
_ => return ParseError::new_with_token("Expected '0x' or '0b'", tok),
|
_ => return ParseError::new_with_token("Expected '0x' or '0b'", tok),
|
||||||
}
|
}
|
||||||
@ -1130,13 +1129,13 @@ impl Parser {
|
|||||||
digits.push_str(".");
|
digits.push_str(".");
|
||||||
digits.push_str(&self.digits()?);
|
digits.push_str(&self.digits()?);
|
||||||
match digits.parse::<f64>() {
|
match digits.parse::<f64>() {
|
||||||
Ok(f) => Ok(Expression(FloatLiteral(f), None)),
|
Ok(f) => Ok(Expression::new(FloatLiteral(f))),
|
||||||
Err(e) => ParseError::new_with_token(format!("Float failed to parse with error: {}", e), tok),
|
Err(e) => ParseError::new_with_token(format!("Float failed to parse with error: {}", e), tok),
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match digits.parse::<u64>() {
|
match digits.parse::<u64>() {
|
||||||
Ok(d) => Ok(Expression(NatLiteral(d), None)),
|
Ok(d) => Ok(Expression::new(NatLiteral(d))),
|
||||||
Err(e) => ParseError::new_with_token(format!("Integer failed to parse with error: {}", e), tok),
|
Err(e) => ParseError::new_with_token(format!("Integer failed to parse with error: {}", e), tok),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,9 @@ macro_rules! tys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! ex {
|
macro_rules! ex {
|
||||||
($expr_type:expr) => { Expression($expr_type, None) };
|
($expr_type:expr) => { Expression::new($expr_type) };
|
||||||
(m $expr_type:expr) => { Meta::new(Expression($expr_type, None)) };
|
(m $expr_type:expr) => { Meta::new(Expression::new($expr_type)) };
|
||||||
(m $expr_type:expr, $type_anno:expr) => { Meta::new(Expression($expr_type, Some($type_anno))) };
|
(m $expr_type:expr, $type_anno:expr) => { Meta::new(Expression::with_anno($expr_type, $type_anno)) };
|
||||||
(s $expr_text:expr) => {
|
(s $expr_text:expr) => {
|
||||||
{
|
{
|
||||||
let tokens: Vec<crate::tokenizing::Token> = tokenize($expr_text);
|
let tokens: Vec<crate::tokenizing::Token> = tokenize($expr_text);
|
||||||
@ -56,14 +56,14 @@ macro_rules! inv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! binexp {
|
macro_rules! binexp {
|
||||||
($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression($lhs, None).into()), bx!(Expression($rhs, None).into())) }
|
($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression::new($lhs).into()), bx!(Expression::new($rhs).into())) }
|
||||||
}
|
}
|
||||||
macro_rules! prefexp {
|
macro_rules! prefexp {
|
||||||
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_sigil($op), bx!(Expression($lhs, None).into())) }
|
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_sigil($op), bx!(Expression::new($lhs).into())) }
|
||||||
}
|
}
|
||||||
macro_rules! exst {
|
macro_rules! exst {
|
||||||
($expr_type:expr) => { Meta::new(Statement::ExpressionStatement(Expression($expr_type, None).into())) };
|
($expr_type:expr) => { Meta::new(Statement::ExpressionStatement(Expression::new($expr_type).into())) };
|
||||||
($expr_type:expr, $type_anno:expr) => { Meta::new(Statement::ExpressionStatement(Expression($expr_type, Some($type_anno)).into())) };
|
($expr_type:expr, $type_anno:expr) => { Meta::new(Statement::ExpressionStatement(Expression::with_anno($expr_type, $type_anno).into())) };
|
||||||
($op:expr, $lhs:expr, $rhs:expr) => { Meta::new(Statement::ExpressionStatement(ex!(binexp!($op, $lhs, $rhs)))) };
|
($op:expr, $lhs:expr, $rhs:expr) => { Meta::new(Statement::ExpressionStatement(ex!(binexp!($op, $lhs, $rhs)))) };
|
||||||
(s $statement_text:expr) => {
|
(s $statement_text:expr) => {
|
||||||
{
|
{
|
||||||
|
@ -132,7 +132,7 @@ impl InvocationArgument {
|
|||||||
impl Expression {
|
impl 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.0;
|
let ref input = self.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)),
|
||||||
|
@ -299,12 +299,12 @@ impl<'a> TypeContext<'a> {
|
|||||||
|
|
||||||
fn expr(&mut self, expr: &Expression) -> InferResult<Type> {
|
fn expr(&mut self, expr: &Expression) -> InferResult<Type> {
|
||||||
match expr {
|
match expr {
|
||||||
Expression(expr_type, Some(anno)) => {
|
Expression { kind, type_anno: Some(anno) } => {
|
||||||
let t1 = self.expr_type(expr_type)?;
|
let t1 = self.expr_type(kind)?;
|
||||||
let t2 = self.get_type_from_name(anno)?;
|
let t2 = self.get_type_from_name(anno)?;
|
||||||
self.unify(t2, t1)
|
self.unify(t2, t1)
|
||||||
},
|
},
|
||||||
Expression(expr_type, None) => self.expr_type(expr_type)
|
Expression { kind, type_anno: None } => self.expr_type(kind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user