🤔 Add a type inference engine, along with typed literals. #4
@@ -104,6 +104,8 @@ impl syntax::Expression {
|
||||
(vec![], ValueOrRef::Ref(loc, ArcIntern::new(name)))
|
||||
}
|
||||
|
||||
syntax::Expression::Cast(_, _, _) => unimplemented!(),
|
||||
|
||||
// Primitive expressions are where we do the real work.
|
||||
syntax::Expression::Primitive(loc, prim, mut expressions) => {
|
||||
// generate a fresh new name for the binding site we're going to
|
||||
|
||||
@@ -58,6 +58,7 @@ impl PartialEq for Statement {
|
||||
pub enum Expression {
|
||||
Value(Location, Value),
|
||||
Reference(Location, String),
|
||||
Cast(Location, String, Box<Expression>),
|
||||
Primitive(Location, String, Vec<Expression>),
|
||||
}
|
||||
|
||||
@@ -72,6 +73,10 @@ impl PartialEq for Expression {
|
||||
Expression::Reference(_, var2) => var1 == var2,
|
||||
_ => false,
|
||||
},
|
||||
Expression::Cast(_, t1, e1) => match other {
|
||||
Expression::Cast(_, t2, e2) => t1 == t2 && e1 == e2,
|
||||
_ => false,
|
||||
}
|
||||
Expression::Primitive(_, prim1, args1) => match other {
|
||||
Expression::Primitive(_, prim2, args2) => prim1 == prim2 && args1 == args2,
|
||||
_ => false,
|
||||
|
||||
@@ -48,6 +48,8 @@ impl Expression {
|
||||
|
||||
Expression::Reference(_, n) => Ok(env.lookup(ArcIntern::new(n.clone()))?),
|
||||
|
||||
Expression::Cast(_, _, _) => unimplemented!(),
|
||||
|
||||
Expression::Primitive(_, op, args) => {
|
||||
let mut arg_values = Vec::with_capacity(args.len());
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ extern {
|
||||
";" => Token::Semi,
|
||||
"(" => Token::LeftParen,
|
||||
")" => Token::RightParen,
|
||||
"<" => Token::LessThan,
|
||||
">" => Token::GreaterThan,
|
||||
|
||||
"print" => Token::Print,
|
||||
|
||||
@@ -136,6 +138,12 @@ MultiplicativeExpression: Expression = {
|
||||
AtomicExpression,
|
||||
}
|
||||
|
||||
UnaryExpression: Expression = {
|
||||
<l:@L> "-" <e:MultiplicativeExpression> => Expression::Primitive(Location::new(file_idx, l), "-".to_string(), vec![e]),
|
||||
<l:@L> "<" <v:"<var>"> ">" <e:MultiplicativeExpression> => Expression::Cast(Location::new(file_idx, l), v.to_string(), Box::new(e)),
|
||||
AtomicExpression,
|
||||
}
|
||||
|
||||
// finally, we describe our lowest-level expressions as "atomic", because
|
||||
// they cannot be further divided into parts
|
||||
AtomicExpression: Expression = {
|
||||
|
||||
@@ -50,6 +50,10 @@ where
|
||||
match self {
|
||||
Expression::Value(_, val) => val.pretty(allocator),
|
||||
Expression::Reference(_, var) => allocator.text(var.to_string()),
|
||||
Expression::Cast(_, t, e) =>
|
||||
allocator.text(t.clone())
|
||||
.angles()
|
||||
.append(e.pretty(allocator)),
|
||||
Expression::Primitive(_, op, exprs) if BINARY_OPERATORS.contains(&op.as_ref()) => {
|
||||
assert_eq!(
|
||||
exprs.len(),
|
||||
|
||||
@@ -127,6 +127,7 @@ impl Expression {
|
||||
vec![Error::UnboundVariable(loc.clone(), var.clone())],
|
||||
vec![],
|
||||
),
|
||||
Expression::Cast(_, _, _) => unimplemented!(),
|
||||
Expression::Primitive(_, _, args) => {
|
||||
let mut errors = vec![];
|
||||
let mut warnings = vec![];
|
||||
|
||||
Reference in New Issue
Block a user