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

View File

@ -614,7 +614,7 @@ impl Parser {
None => unreachable!() None => unreachable!()
}; };
let rhs = self.precedence_expr(new_precedence)?; 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; self.parse_level -= 1;
Ok(lhs) Ok(lhs)
@ -631,6 +631,7 @@ impl Parser {
let expr = self.primary()?; let expr = self.primary()?;
let prefix_op = PrefixOp::from_str(sigil.as_str()).unwrap(); let prefix_op = PrefixOp::from_str(sigil.as_str()).unwrap();
Ok(Expression::new( Ok(Expression::new(
self.id_store.fresh(),
ExpressionKind::PrefixExp(prefix_op, bx!(expr.into())) ExpressionKind::PrefixExp(prefix_op, bx!(expr.into()))
)) ))
}, },
@ -644,7 +645,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().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(self.id_store.fresh(), ExpressionKind::Call { f: bx!(expr.into()), arguments }); //TODO no type anno is incorrect
} }
Ok(expr) Ok(expr)
@ -681,8 +682,8 @@ 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::new(ExpressionKind::Index { Expression::new(self.id_store.fresh(), ExpressionKind::Index {
indexee: bx!(Expression::new(primary.kind).into()), indexee: bx!(Expression::new(self.id_store.fresh(), primary.kind).into()),
indexers, indexers,
}) })
} else { } else {
@ -709,7 +710,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::new(ExpressionKind::ListLiteral(exprs))) Ok(Expression::new(self.id_store.fresh(), ExpressionKind::ListLiteral(exprs)))
} }
#[recursive_descent_method] #[recursive_descent_method]
@ -726,7 +727,7 @@ impl Parser {
_ => None, _ => None,
}; };
let body = self.nonempty_func_body()?; 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] #[recursive_descent_method]
@ -747,11 +748,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::new(TupleLiteral(vec![]))), 0 => Ok(Expression::new(self.id_store.fresh(), 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::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() { 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::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()? _ => self.guard_block()?
}); });
Ok(Expression::new(ExpressionKind::IfExpression { discriminator, body })) Ok(Expression::new(self.id_store.fresh(), ExpressionKind::IfExpression { discriminator, body }))
} }
#[recursive_descent_method] #[recursive_descent_method]
@ -1080,7 +1081,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::new(WhileExpression {condition, body})) Ok(Expression::new(self.id_store.fresh(), WhileExpression {condition, body}))
} }
#[recursive_descent_method] #[recursive_descent_method]
@ -1106,7 +1107,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::new(ExpressionKind::ForExpression { enumerators, body })) Ok(Expression::new(self.id_store.fresh(), ExpressionKind::ForExpression { enumerators, body }))
} }
#[recursive_descent_method] #[recursive_descent_method]
@ -1152,15 +1153,18 @@ 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::new(BoolLiteral(true))) let id = self.id_store.fresh();
Ok(Expression::new(id, BoolLiteral(true)))
}, },
Keyword(Kw::False) => { Keyword(Kw::False) => {
self.token_handler.next(); self.token_handler.next();
Ok(Expression::new(BoolLiteral(false))) let id = self.id_store.fresh();
Ok(Expression::new(id, BoolLiteral(false)))
}, },
StrLiteral(s) => { StrLiteral(s) => {
self.token_handler.next(); 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), e => ParseError::new_with_token(format!("Expected a literal expression, got {:?}", e), tok),
} }
@ -1182,12 +1186,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::new(NatLiteral(n))) Ok(Expression::new(self.id_store.fresh(), 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::new(NatLiteral(n))) Ok(Expression::new(self.id_store.fresh(), NatLiteral(n)))
}, },
_ => return ParseError::new_with_token("Expected '0x' or '0b'", tok), _ => return ParseError::new_with_token("Expected '0x' or '0b'", tok),
} }
@ -1203,13 +1207,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::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), 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::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), 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 { macro_rules! ex {
($expr_type:expr) => { Expression::new($expr_type) }; ($expr_type:expr) => { Expression::new(ItemIdStore::new_id(), $expr_type) };
(m $expr_type:expr) => { Meta::new(Expression::new($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($expr_type, $type_anno)) }; (m $expr_type:expr, $type_anno:expr) => { Meta::new(Expression::with_anno(ItemIdStore::new_id(), $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);
@ -64,14 +64,14 @@ macro_rules! inv {
} }
macro_rules! binexp { 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 { 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 { macro_rules! exst {
($expr_type:expr) => { Meta::new(Statement { id: ItemIdStore::new_id(), kind: StatementKind::Expression(Expression::new($expr_type).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($expr_type, $type_anno).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( ($op:expr, $lhs:expr, $rhs:expr) => { Meta::new(
Statement { id: ItemIdStore::new_id(), ,kind: StatementKind::Expression(ex!(binexp!($op, $lhs, $rhs)))} Statement { id: ItemIdStore::new_id(), ,kind: StatementKind::Expression(ex!(binexp!($op, $lhs, $rhs)))}
)}; )};
@ -179,7 +179,7 @@ fn qualified_identifiers() {
parse_test_wrap_ast! { parse_test_wrap_ast! {
"let q_q = Yolo::Swaggins", "let q_q = Yolo::Swaggins",
Meta::new(decl!(Binding { name: rc!(q_q), constant: true, type_anno: None, 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> { fn expr(&mut self, expr: &Expression) -> InferResult<Type> {
match expr { match expr {
Expression { kind, type_anno: Some(anno) } => { Expression { kind, type_anno: Some(anno), .. } => {
let t1 = self.expr_type(kind)?; 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 { kind, type_anno: None } => self.expr_type(kind) Expression { kind, type_anno: None, .. } => self.expr_type(kind)
} }
} }