Finish adding ItemId to Expression

This commit is contained in:
greg 2019-09-18 14:15:05 -07:00
parent 642f21d298
commit 56e6eb44f9
4 changed files with 38 additions and 31 deletions

View File

@ -29,6 +29,7 @@ impl ItemIdStore {
ItemIdStore { last_idx: 0 }
}
/// Always returns an ItemId with internal value zero
#[cfg(test)]
pub fn new_id() -> ItemId {
ItemId { idx: 0 }
}
@ -158,8 +159,10 @@ pub enum Variant {
}
}
#[derive(Debug, PartialEq, Clone)]
#[derive(Debug, Derivative, Clone)]
#[derivative(PartialEq)]
pub struct Expression {
#[derivative(PartialEq="ignore")]
pub id: ItemId,
pub kind: ExpressionKind,
pub type_anno: Option<TypeIdentifier>

View File

@ -614,7 +614,7 @@ impl Parser {
None => unreachable!()
};
let rhs = self.precedence_expr(new_precedence)?;
lhs = Expression::new(ExpressionKind::BinExp(operation, bx!(lhs.into()), bx!(rhs.into())));
lhs = Expression::new(self.id_store.fresh(), ExpressionKind::BinExp(operation, bx!(lhs.into()), bx!(rhs.into())));
}
self.parse_level -= 1;
Ok(lhs)
@ -631,6 +631,7 @@ impl Parser {
let expr = self.primary()?;
let prefix_op = PrefixOp::from_str(sigil.as_str()).unwrap();
Ok(Expression::new(
self.id_store.fresh(),
ExpressionKind::PrefixExp(prefix_op, bx!(expr.into()))
))
},
@ -644,7 +645,7 @@ impl Parser {
while let LParen = self.token_handler.peek_kind() {
let arguments = delimited!(self, LParen, invocation_argument, Comma, RParen);
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(self.id_store.fresh(), ExpressionKind::Call { f: bx!(expr.into()), arguments }); //TODO no type anno is incorrect
}
Ok(expr)
@ -681,8 +682,8 @@ impl Parser {
Ok(if let LSquareBracket = self.token_handler.peek_kind() {
let indexers = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket)
.into_iter().map(|ex| ex.into()).collect();
Expression::new(ExpressionKind::Index {
indexee: bx!(Expression::new(primary.kind).into()),
Expression::new(self.id_store.fresh(), ExpressionKind::Index {
indexee: bx!(Expression::new(self.id_store.fresh(), primary.kind).into()),
indexers,
})
} else {
@ -709,7 +710,7 @@ impl Parser {
fn list_expr(&mut self) -> ParseResult<Expression> {
let exprs = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket)
.into_iter().map(|ex| ex.into()).collect();
Ok(Expression::new(ExpressionKind::ListLiteral(exprs)))
Ok(Expression::new(self.id_store.fresh(), ExpressionKind::ListLiteral(exprs)))
}
#[recursive_descent_method]
@ -726,7 +727,7 @@ impl Parser {
_ => None,
};
let body = self.nonempty_func_body()?;
Ok(Expression::new(ExpressionKind::Lambda { params, type_anno, body })) //TODO need to handle types somehow
Ok(Expression::new(self.id_store.fresh(), ExpressionKind::Lambda { params, type_anno, body })) //TODO need to handle types somehow
}
#[recursive_descent_method]
@ -747,11 +748,11 @@ impl Parser {
let output = {
let mut inner = delimited!(self, LParen, expression, Comma, RParen);
match inner.len() {
0 => Ok(Expression::new(TupleLiteral(vec![]))),
0 => Ok(Expression::new(self.id_store.fresh(), TupleLiteral(vec![]))),
1 => Ok(inner.pop().unwrap()),
_ => {
let inner: Vec<Meta<Expression>> = inner.into_iter().map(|ex| ex.into()).collect();
Ok(Expression::new(TupleLiteral(inner)))
Ok(Expression::new(self.id_store.fresh(), TupleLiteral(inner)))
}
}
};
@ -766,9 +767,9 @@ impl Parser {
Ok(match self.token_handler.peek_kind() {
LCurlyBrace if !self.restrictions.no_struct_literal => {
let fields = self.record_block()?;
Expression::new(NamedStruct { name: Meta::new(qualified_identifier), fields })
Expression::new(self.id_store.fresh(), NamedStruct { name: Meta::new(qualified_identifier), fields })
},
_ => Expression::new(Value(Meta::new(qualified_identifier)))
_ => Expression::new(self.id_store.fresh(), Value(Meta::new(qualified_identifier)))
})
}
@ -819,7 +820,7 @@ impl Parser {
_ => self.guard_block()?
});
Ok(Expression::new(ExpressionKind::IfExpression { discriminator, body }))
Ok(Expression::new(self.id_store.fresh(), ExpressionKind::IfExpression { discriminator, body }))
}
#[recursive_descent_method]
@ -1080,7 +1081,7 @@ impl Parser {
x?.map(|expr| bx!(expr.into()))
};
let body = self.block()?;
Ok(Expression::new(WhileExpression {condition, body}))
Ok(Expression::new(self.id_store.fresh(), WhileExpression {condition, body}))
}
#[recursive_descent_method]
@ -1106,7 +1107,7 @@ impl Parser {
vec![single_enum]
};
let body = Box::new(self.for_expr_body()?);
Ok(Expression::new(ExpressionKind::ForExpression { enumerators, body }))
Ok(Expression::new(self.id_store.fresh(), ExpressionKind::ForExpression { enumerators, body }))
}
#[recursive_descent_method]
@ -1152,15 +1153,18 @@ impl Parser {
DigitGroup(_) | HexLiteral(_) | BinNumberSigil | Period => self.number_literal(),
Keyword(Kw::True) => {
self.token_handler.next();
Ok(Expression::new(BoolLiteral(true)))
let id = self.id_store.fresh();
Ok(Expression::new(id, BoolLiteral(true)))
},
Keyword(Kw::False) => {
self.token_handler.next();
Ok(Expression::new(BoolLiteral(false)))
let id = self.id_store.fresh();
Ok(Expression::new(id, BoolLiteral(false)))
},
StrLiteral(s) => {
self.token_handler.next();
Ok(Expression::new(StringLiteral(s.clone())))
let id = self.id_store.fresh();
Ok(Expression::new(id, StringLiteral(s.clone())))
}
e => ParseError::new_with_token(format!("Expected a literal expression, got {:?}", e), tok),
}
@ -1182,12 +1186,12 @@ impl Parser {
BinNumberSigil => {
let digits = self.digits()?;
let n = parse_binary(digits, tok)?;
Ok(Expression::new(NatLiteral(n)))
Ok(Expression::new(self.id_store.fresh(), NatLiteral(n)))
},
HexLiteral(text) => {
let digits: String = text.chars().filter(|c| c.is_digit(16)).collect();
let n = parse_hex(digits, tok)?;
Ok(Expression::new(NatLiteral(n)))
Ok(Expression::new(self.id_store.fresh(), NatLiteral(n)))
},
_ => return ParseError::new_with_token("Expected '0x' or '0b'", tok),
}
@ -1203,13 +1207,13 @@ impl Parser {
digits.push_str(".");
digits.push_str(&self.digits()?);
match digits.parse::<f64>() {
Ok(f) => Ok(Expression::new(FloatLiteral(f))),
Ok(f) => Ok(Expression::new(self.id_store.fresh(), FloatLiteral(f))),
Err(e) => ParseError::new_with_token(format!("Float failed to parse with error: {}", e), tok),
}
} else {
match digits.parse::<u64>() {
Ok(d) => Ok(Expression::new(NatLiteral(d))),
Ok(d) => Ok(Expression::new(self.id_store.fresh(), NatLiteral(d))),
Err(e) => ParseError::new_with_token(format!("Integer failed to parse with error: {}", e), tok),
}
}

View File

@ -47,9 +47,9 @@ macro_rules! decl {
}
macro_rules! ex {
($expr_type:expr) => { Expression::new($expr_type) };
(m $expr_type:expr) => { Meta::new(Expression::new($expr_type)) };
(m $expr_type:expr, $type_anno:expr) => { Meta::new(Expression::with_anno($expr_type, $type_anno)) };
($expr_type:expr) => { Expression::new(ItemIdStore::new_id(), $expr_type) };
(m $expr_type:expr) => { Meta::new(Expression::new(ItemIdStore::new_id(), $expr_type)) };
(m $expr_type:expr, $type_anno:expr) => { Meta::new(Expression::with_anno(ItemIdStore::new_id(), $expr_type, $type_anno)) };
(s $expr_text:expr) => {
{
let tokens: Vec<crate::tokenizing::Token> = tokenize($expr_text);
@ -64,14 +64,14 @@ macro_rules! inv {
}
macro_rules! binexp {
($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression::new($lhs).into()), bx!(Expression::new($rhs).into())) }
($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression::new(ItemIdStore::new_id(), $lhs).into()), bx!(Expression::new(ItemIdStore::new_id(), $rhs).into())) }
}
macro_rules! prefexp {
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_str($op).unwrap(), bx!(Expression::new($lhs).into())) }
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_str($op).unwrap(), bx!(Expression::new(ItemIdStore::new_id(), $lhs).into())) }
}
macro_rules! exst {
($expr_type:expr) => { Meta::new(Statement { id: ItemIdStore::new_id(), kind: StatementKind::Expression(Expression::new($expr_type).into())}) };
($expr_type:expr, $type_anno:expr) => { Meta::new(Statement { id: ItemIdStore::new_id(), kind: StatementKind::Expression(Expression::with_anno($expr_type, $type_anno).into())}) };
($expr_type:expr) => { Meta::new(Statement { id: ItemIdStore::new_id(), kind: StatementKind::Expression(Expression::new(ItemIdStore::new_id(), $expr_type).into())}) };
($expr_type:expr, $type_anno:expr) => { Meta::new(Statement { id: ItemIdStore::new_id(), kind: StatementKind::Expression(Expression::with_anno(ItemIdStore::new_id(), $expr_type, $type_anno).into())}) };
($op:expr, $lhs:expr, $rhs:expr) => { Meta::new(
Statement { id: ItemIdStore::new_id(), ,kind: StatementKind::Expression(ex!(binexp!($op, $lhs, $rhs)))}
)};
@ -179,7 +179,7 @@ fn qualified_identifiers() {
parse_test_wrap_ast! {
"let q_q = Yolo::Swaggins",
Meta::new(decl!(Binding { name: rc!(q_q), constant: true, type_anno: None,
expr: Meta::new(Expression::new(Value(Meta::new(QualifiedName(vec![rc!(Yolo), rc!(Swaggins)]))))),
expr: Meta::new(Expression::new(ItemIdStore::new_id(), Value(Meta::new(QualifiedName(vec![rc!(Yolo), rc!(Swaggins)]))))),
}))
}

View File

@ -299,12 +299,12 @@ impl<'a> TypeContext<'a> {
fn expr(&mut self, expr: &Expression) -> InferResult<Type> {
match expr {
Expression { kind, type_anno: Some(anno) } => {
Expression { kind, type_anno: Some(anno), .. } => {
let t1 = self.expr_type(kind)?;
let t2 = self.get_type_from_name(anno)?;
self.unify(t2, t1)
},
Expression { kind, type_anno: None } => self.expr_type(kind)
Expression { kind, type_anno: None, .. } => self.expr_type(kind)
}
}