Compare commits
2 Commits
b84672ef8c
...
257496aae2
Author | SHA1 | Date | |
---|---|---|---|
257496aae2 | |||
197f0b22f3 |
@ -1,6 +1,6 @@
|
|||||||
// Main
|
// Main
|
||||||
fn main() -> bool {
|
fn main() -> bool {
|
||||||
return (5 == fibonacci(5)) && (2 == fibonacci(3));
|
return (5 == fibonacci(5)) && false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fibonacci
|
// Fibonacci
|
||||||
|
@ -17,7 +17,7 @@ fn main() {
|
|||||||
// If N < 3
|
// If N < 3
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExprKind::BinOp(
|
ExprKind::BinOp(
|
||||||
BinaryOperator::Logic(LogicOperator::GT),
|
BinaryOperator::Cmp(CmpOperator::GT),
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExprKind::Variable(VariableReference(
|
ExprKind::Variable(VariableReference(
|
||||||
TypeKind::I32,
|
TypeKind::I32,
|
||||||
|
@ -24,6 +24,7 @@ pub enum TypeKind {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Literal {
|
pub enum Literal {
|
||||||
Number(u64),
|
Number(u64),
|
||||||
|
Bool(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -71,6 +71,14 @@ impl Parse for PrimaryExpression {
|
|||||||
Kind::Literal(Literal::Number(v.parse().unwrap())),
|
Kind::Literal(Literal::Number(v.parse().unwrap())),
|
||||||
stream.get_range().unwrap(),
|
stream.get_range().unwrap(),
|
||||||
),
|
),
|
||||||
|
Token::True => Expression(
|
||||||
|
Kind::Literal(Literal::Bool(true)),
|
||||||
|
stream.get_range().unwrap(),
|
||||||
|
),
|
||||||
|
Token::False => Expression(
|
||||||
|
Kind::Literal(Literal::Bool(false)),
|
||||||
|
stream.get_range().unwrap(),
|
||||||
|
),
|
||||||
Token::ParenOpen => {
|
Token::ParenOpen => {
|
||||||
let exp = stream.parse()?;
|
let exp = stream.parse()?;
|
||||||
stream.expect(Token::ParenClose)?;
|
stream.expect(Token::ParenClose)?;
|
||||||
|
@ -150,12 +150,12 @@ impl ast::BinaryOperator {
|
|||||||
ast::BinaryOperator::Minus => mir::BinaryOperator::Minus,
|
ast::BinaryOperator::Minus => mir::BinaryOperator::Minus,
|
||||||
ast::BinaryOperator::Mult => mir::BinaryOperator::Mult,
|
ast::BinaryOperator::Mult => mir::BinaryOperator::Mult,
|
||||||
ast::BinaryOperator::And => mir::BinaryOperator::And,
|
ast::BinaryOperator::And => mir::BinaryOperator::And,
|
||||||
ast::BinaryOperator::LT => mir::BinaryOperator::Logic(mir::LogicOperator::LT),
|
ast::BinaryOperator::LT => mir::BinaryOperator::Cmp(mir::CmpOperator::LT),
|
||||||
ast::BinaryOperator::LE => mir::BinaryOperator::Logic(mir::LogicOperator::LE),
|
ast::BinaryOperator::LE => mir::BinaryOperator::Cmp(mir::CmpOperator::LE),
|
||||||
ast::BinaryOperator::GT => mir::BinaryOperator::Logic(mir::LogicOperator::GT),
|
ast::BinaryOperator::GT => mir::BinaryOperator::Cmp(mir::CmpOperator::GT),
|
||||||
ast::BinaryOperator::GE => mir::BinaryOperator::Logic(mir::LogicOperator::GE),
|
ast::BinaryOperator::GE => mir::BinaryOperator::Cmp(mir::CmpOperator::GE),
|
||||||
ast::BinaryOperator::EQ => mir::BinaryOperator::Logic(mir::LogicOperator::EQ),
|
ast::BinaryOperator::EQ => mir::BinaryOperator::Cmp(mir::CmpOperator::EQ),
|
||||||
ast::BinaryOperator::NE => mir::BinaryOperator::Logic(mir::LogicOperator::NE),
|
ast::BinaryOperator::NE => mir::BinaryOperator::Cmp(mir::CmpOperator::NE),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,6 +164,7 @@ impl ast::Literal {
|
|||||||
fn mir(&self) -> mir::Literal {
|
fn mir(&self) -> mir::Literal {
|
||||||
match *self {
|
match *self {
|
||||||
ast::Literal::Number(v) => mir::Literal::Vague(mir::VagueLiteral::Number(v)),
|
ast::Literal::Number(v) => mir::Literal::Vague(mir::VagueLiteral::Number(v)),
|
||||||
|
ast::Literal::Bool(v) => mir::Literal::Bool(v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ impl mir::Expression {
|
|||||||
mir::BinaryOperator::And => {
|
mir::BinaryOperator::And => {
|
||||||
scope.block.build(InstructionKind::And(lhs, rhs)).unwrap()
|
scope.block.build(InstructionKind::And(lhs, rhs)).unwrap()
|
||||||
}
|
}
|
||||||
mir::BinaryOperator::Logic(l) => scope
|
mir::BinaryOperator::Cmp(l) => scope
|
||||||
.block
|
.block
|
||||||
.build(InstructionKind::ICmp(l.int_predicate(), lhs, rhs))
|
.build(InstructionKind::ICmp(l.int_predicate(), lhs, rhs))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -290,15 +290,15 @@ impl mir::Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mir::LogicOperator {
|
impl mir::CmpOperator {
|
||||||
fn int_predicate(&self) -> CmpPredicate {
|
fn int_predicate(&self) -> CmpPredicate {
|
||||||
match self {
|
match self {
|
||||||
mir::LogicOperator::LT => CmpPredicate::LT,
|
mir::CmpOperator::LT => CmpPredicate::LT,
|
||||||
mir::LogicOperator::GT => CmpPredicate::GT,
|
mir::CmpOperator::GT => CmpPredicate::GT,
|
||||||
mir::LogicOperator::LE => CmpPredicate::LE,
|
mir::CmpOperator::LE => CmpPredicate::LE,
|
||||||
mir::LogicOperator::GE => CmpPredicate::GE,
|
mir::CmpOperator::GE => CmpPredicate::GE,
|
||||||
mir::LogicOperator::EQ => CmpPredicate::EQ,
|
mir::CmpOperator::EQ => CmpPredicate::EQ,
|
||||||
mir::LogicOperator::NE => CmpPredicate::NE,
|
mir::CmpOperator::NE => CmpPredicate::NE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,6 +341,7 @@ impl mir::Literal {
|
|||||||
mir::Literal::U32(val) => ConstValue::U32(val),
|
mir::Literal::U32(val) => ConstValue::U32(val),
|
||||||
mir::Literal::U64(val) => ConstValue::U64(val),
|
mir::Literal::U64(val) => ConstValue::U64(val),
|
||||||
mir::Literal::U128(val) => ConstValue::U128(val),
|
mir::Literal::U128(val) => ConstValue::U128(val),
|
||||||
|
mir::Literal::Bool(val) => ConstValue::Bool(val),
|
||||||
mir::Literal::Vague(_) => panic!("Got vague literal!"),
|
mir::Literal::Vague(_) => panic!("Got vague literal!"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,10 @@ pub enum Token {
|
|||||||
Arrow,
|
Arrow,
|
||||||
/// `if`
|
/// `if`
|
||||||
If,
|
If,
|
||||||
|
/// `true`
|
||||||
|
True,
|
||||||
|
/// `false`
|
||||||
|
False,
|
||||||
|
|
||||||
// Symbols
|
// Symbols
|
||||||
/// `;`
|
/// `;`
|
||||||
@ -165,6 +169,8 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
|
|||||||
"return" => Token::ReturnKeyword,
|
"return" => Token::ReturnKeyword,
|
||||||
"fn" => Token::FnKeyword,
|
"fn" => Token::FnKeyword,
|
||||||
"if" => Token::If,
|
"if" => Token::If,
|
||||||
|
"true" => Token::True,
|
||||||
|
"false" => Token::False,
|
||||||
_ => Token::Identifier(value),
|
_ => Token::Identifier(value),
|
||||||
};
|
};
|
||||||
variant
|
variant
|
||||||
|
@ -166,6 +166,7 @@ impl Display for Literal {
|
|||||||
Self::U32(val) => write!(f, "{}u32", val),
|
Self::U32(val) => write!(f, "{}u32", val),
|
||||||
Self::U64(val) => write!(f, "{}u64", val),
|
Self::U64(val) => write!(f, "{}u64", val),
|
||||||
Self::U128(val) => write!(f, "{}u128", val),
|
Self::U128(val) => write!(f, "{}u128", val),
|
||||||
|
Self::Bool(val) => write!(f, "{}", val),
|
||||||
Self::Vague(val) => val.fmt(f),
|
Self::Vague(val) => val.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,20 +179,20 @@ impl Display for BinaryOperator {
|
|||||||
BinaryOperator::Minus => write!(f, "-"),
|
BinaryOperator::Minus => write!(f, "-"),
|
||||||
BinaryOperator::Mult => write!(f, "*"),
|
BinaryOperator::Mult => write!(f, "*"),
|
||||||
BinaryOperator::And => write!(f, "&&"),
|
BinaryOperator::And => write!(f, "&&"),
|
||||||
BinaryOperator::Logic(op) => Display::fmt(op, f),
|
BinaryOperator::Cmp(op) => Display::fmt(op, f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for LogicOperator {
|
impl Display for CmpOperator {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
LogicOperator::LT => write!(f, "<"),
|
CmpOperator::LT => write!(f, "<"),
|
||||||
LogicOperator::LE => write!(f, "<="),
|
CmpOperator::LE => write!(f, "<="),
|
||||||
LogicOperator::GT => write!(f, ">"),
|
CmpOperator::GT => write!(f, ">"),
|
||||||
LogicOperator::GE => write!(f, ">="),
|
CmpOperator::GE => write!(f, ">="),
|
||||||
LogicOperator::EQ => write!(f, "=="),
|
CmpOperator::EQ => write!(f, "=="),
|
||||||
LogicOperator::NE => write!(f, "!="),
|
CmpOperator::NE => write!(f, "!="),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,7 @@ pub enum Literal {
|
|||||||
U32(u32),
|
U32(u32),
|
||||||
U64(u64),
|
U64(u64),
|
||||||
U128(u128),
|
U128(u128),
|
||||||
|
Bool(bool),
|
||||||
Vague(VagueLiteral),
|
Vague(VagueLiteral),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +150,7 @@ impl Literal {
|
|||||||
Literal::U32(_) => TypeKind::U32,
|
Literal::U32(_) => TypeKind::U32,
|
||||||
Literal::U64(_) => TypeKind::U64,
|
Literal::U64(_) => TypeKind::U64,
|
||||||
Literal::U128(_) => TypeKind::U128,
|
Literal::U128(_) => TypeKind::U128,
|
||||||
|
Literal::Bool(_) => TypeKind::Bool,
|
||||||
Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Number),
|
Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Number),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,11 +162,12 @@ pub enum BinaryOperator {
|
|||||||
Minus,
|
Minus,
|
||||||
Mult,
|
Mult,
|
||||||
And,
|
And,
|
||||||
Logic(LogicOperator),
|
Cmp(CmpOperator),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Specifically the operators that LLVM likes to take in as "icmp" parameters
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum LogicOperator {
|
pub enum CmpOperator {
|
||||||
LT,
|
LT,
|
||||||
LE,
|
LE,
|
||||||
GT,
|
GT,
|
||||||
|
@ -15,6 +15,8 @@ pub enum ErrorKind {
|
|||||||
TypeIsVague(VagueType),
|
TypeIsVague(VagueType),
|
||||||
#[error("Can not coerce {0} to vague type {1}")]
|
#[error("Can not coerce {0} to vague type {1}")]
|
||||||
HintIsVague(TypeKind, VagueType),
|
HintIsVague(TypeKind, VagueType),
|
||||||
|
#[error("Literal {0} can not be coerced to type {1}")]
|
||||||
|
LiteralIncompatible(Literal, TypeKind),
|
||||||
#[error("Types {0} and {1} are incompatible")]
|
#[error("Types {0} and {1} are incompatible")]
|
||||||
TypesIncompatible(TypeKind, TypeKind),
|
TypesIncompatible(TypeKind, TypeKind),
|
||||||
#[error("Variable not defined: {0}")]
|
#[error("Variable not defined: {0}")]
|
||||||
@ -252,6 +254,7 @@ impl Literal {
|
|||||||
(L::U32(_), U32) => self,
|
(L::U32(_), U32) => self,
|
||||||
(L::U64(_), U64) => self,
|
(L::U64(_), U64) => self,
|
||||||
(L::U128(_), U128) => self,
|
(L::U128(_), U128) => self,
|
||||||
|
(L::Bool(_), Bool) => self,
|
||||||
(L::Vague(VagueL::Number(v)), I8) => L::I8(v as i8),
|
(L::Vague(VagueL::Number(v)), I8) => L::I8(v as i8),
|
||||||
(L::Vague(VagueL::Number(v)), I16) => L::I16(v as i16),
|
(L::Vague(VagueL::Number(v)), I16) => L::I16(v as i16),
|
||||||
(L::Vague(VagueL::Number(v)), I32) => L::I32(v as i32),
|
(L::Vague(VagueL::Number(v)), I32) => L::I32(v as i32),
|
||||||
@ -265,7 +268,7 @@ impl Literal {
|
|||||||
// Default type for number literal if unable to find true type.
|
// Default type for number literal if unable to find true type.
|
||||||
(L::Vague(VagueL::Number(v)), Vague(Number)) => L::I32(v as i32),
|
(L::Vague(VagueL::Number(v)), Vague(Number)) => L::I32(v as i32),
|
||||||
(_, Vague(_)) => self,
|
(_, Vague(_)) => self,
|
||||||
_ => Err(ErrorKind::TypesIncompatible(self.as_type(), hint))?,
|
_ => Err(ErrorKind::LiteralIncompatible(self, hint))?,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
@ -299,7 +302,7 @@ impl TypeKind {
|
|||||||
BinaryOperator::Minus => res,
|
BinaryOperator::Minus => res,
|
||||||
BinaryOperator::Mult => res,
|
BinaryOperator::Mult => res,
|
||||||
BinaryOperator::And => res,
|
BinaryOperator::And => res,
|
||||||
BinaryOperator::Logic(_) => Bool,
|
BinaryOperator::Cmp(_) => Bool,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user