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