Finish adding ItemId to Expression
This commit is contained in:
parent
642f21d298
commit
56e6eb44f9
@ -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>
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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)]))))),
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user