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