Add Not-Unary
This commit is contained in:
parent
bf878c02a7
commit
12e2851a8b
@ -47,13 +47,13 @@ Currently missing big features (TODOs) are:
|
|||||||
- ~~Intrinsic functions~~ (DONE)
|
- ~~Intrinsic functions~~ (DONE)
|
||||||
- ~~Ability to specify types in literals and variable definitions~~ (DONE)
|
- ~~Ability to specify types in literals and variable definitions~~ (DONE)
|
||||||
- ~~Debug Information~~ (DONE)
|
- ~~Debug Information~~ (DONE)
|
||||||
- Fix struct initialization (wrong order and missing fields allowed now)
|
- ~~Fix struct initialization (wrong order and missing fields allowed now)~~
|
||||||
- Not-Unary
|
- ~~Not-Unary~~
|
||||||
- Importing types from other modules
|
- Importing types from other modules
|
||||||
- Importable binops?
|
- Importable binops?
|
||||||
|
- Associated functions (for e.g. sizeof)
|
||||||
|
|
||||||
Big features that I want later but are not necessary:
|
Big features that I want later but are not necessary:
|
||||||
- Associated functions (for e.g. sizeof)
|
|
||||||
- ~~User-defined binary operations~~ (DONE)
|
- ~~User-defined binary operations~~ (DONE)
|
||||||
- ~~Asymmetric binary operations (e.g. string + u32)~~ (DONE)
|
- ~~Asymmetric binary operations (e.g. string + u32)~~ (DONE)
|
||||||
- Error handling
|
- Error handling
|
||||||
|
@ -11,6 +11,8 @@ fn main() -> u32 {
|
|||||||
second: 3,
|
second: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
value.second = 17;
|
||||||
|
|
||||||
|
|
||||||
return value.second;
|
return value.second;
|
||||||
}
|
}
|
||||||
|
@ -298,9 +298,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
|
|||||||
'\"' | '\'' => {
|
'\"' | '\'' => {
|
||||||
let mut value = String::new();
|
let mut value = String::new();
|
||||||
let mut escape_next = false;
|
let mut escape_next = false;
|
||||||
while cursor.first().is_some()
|
while cursor.first().is_some() && (cursor.first() != Some(*character) || escape_next) {
|
||||||
&& (cursor.first() != Some(*character) || escape_next)
|
|
||||||
{
|
|
||||||
if cursor.first() == Some('\\') && !escape_next {
|
if cursor.first() == Some('\\') && !escape_next {
|
||||||
cursor.next(); // Consume backslash and always add next character
|
cursor.next(); // Consume backslash and always add next character
|
||||||
escape_next = true;
|
escape_next = true;
|
||||||
@ -366,8 +364,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
|
|||||||
let mut numerics = DECIMAL_NUMERICS;
|
let mut numerics = DECIMAL_NUMERICS;
|
||||||
if let Some(second) = cursor.second() {
|
if let Some(second) = cursor.second() {
|
||||||
if cursor.first() == Some('x')
|
if cursor.first() == Some('x')
|
||||||
&& HEXADECIMAL_NUMERICS
|
&& HEXADECIMAL_NUMERICS.contains(&second.to_lowercase().next().unwrap_or('.'))
|
||||||
.contains(&second.to_lowercase().next().unwrap_or('.'))
|
|
||||||
{
|
{
|
||||||
cursor.next();
|
cursor.next();
|
||||||
value = NumberType::Hexadecimal(String::new());
|
value = NumberType::Hexadecimal(String::new());
|
||||||
@ -464,9 +461,7 @@ impl AddAssign<char> for NumberType {
|
|||||||
fn add_assign(&mut self, rhs: char) {
|
fn add_assign(&mut self, rhs: char) {
|
||||||
*self = match self {
|
*self = match self {
|
||||||
NumberType::Decimal(val) => NumberType::Decimal(val.to_owned() + &rhs.to_string()),
|
NumberType::Decimal(val) => NumberType::Decimal(val.to_owned() + &rhs.to_string()),
|
||||||
NumberType::Hexadecimal(val) => {
|
NumberType::Hexadecimal(val) => NumberType::Hexadecimal(val.to_owned() + &rhs.to_string()),
|
||||||
NumberType::Hexadecimal(val.to_owned() + &rhs.to_string())
|
|
||||||
}
|
|
||||||
NumberType::Octal(val) => NumberType::Octal(val.to_owned() + &rhs.to_string()),
|
NumberType::Octal(val) => NumberType::Octal(val.to_owned() + &rhs.to_string()),
|
||||||
NumberType::Binary(val) => NumberType::Binary(val.to_owned() + &rhs.to_string()),
|
NumberType::Binary(val) => NumberType::Binary(val.to_owned() + &rhs.to_string()),
|
||||||
};
|
};
|
||||||
|
@ -101,6 +101,7 @@ pub enum ExpressionKind {
|
|||||||
pub enum UnaryOperator {
|
pub enum UnaryOperator {
|
||||||
Plus,
|
Plus,
|
||||||
Minus,
|
Minus,
|
||||||
|
Not,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
@ -87,6 +87,7 @@ impl Parse for UnaryOperator {
|
|||||||
match token {
|
match token {
|
||||||
Token::Plus => Ok(UnaryOperator::Plus),
|
Token::Plus => Ok(UnaryOperator::Plus),
|
||||||
Token::Minus => Ok(UnaryOperator::Minus),
|
Token::Minus => Ok(UnaryOperator::Minus),
|
||||||
|
Token::Exclamation => Ok(UnaryOperator::Not),
|
||||||
_ => Err(stream.expected_err("unary operator")?),
|
_ => Err(stream.expected_err("unary operator")?),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -174,20 +175,11 @@ impl Parse for PrimaryExpression {
|
|||||||
use ExpressionKind as Kind;
|
use ExpressionKind as Kind;
|
||||||
|
|
||||||
let mut expr = if let Ok(exp) = stream.parse() {
|
let mut expr = if let Ok(exp) = stream.parse() {
|
||||||
Expression(
|
Expression(Kind::FunctionCall(Box::new(exp)), stream.get_range().unwrap())
|
||||||
Kind::FunctionCall(Box::new(exp)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
} else if let Ok(block) = stream.parse() {
|
} else if let Ok(block) = stream.parse() {
|
||||||
Expression(
|
Expression(Kind::BlockExpr(Box::new(block)), stream.get_range().unwrap())
|
||||||
Kind::BlockExpr(Box::new(block)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
} else if let Some(Token::If) = stream.peek() {
|
} else if let Some(Token::If) = stream.peek() {
|
||||||
Expression(
|
Expression(Kind::IfExpr(Box::new(stream.parse()?)), stream.get_range().unwrap())
|
||||||
Kind::IfExpr(Box::new(stream.parse()?)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
} else if let (Some(Token::Et), Some(Token::MutKeyword)) = (stream.peek(), stream.peek2()) {
|
} else if let (Some(Token::Et), Some(Token::MutKeyword)) = (stream.peek(), stream.peek2()) {
|
||||||
stream.next(); // Consume Et
|
stream.next(); // Consume Et
|
||||||
stream.next(); // Consume mut
|
stream.next(); // Consume mut
|
||||||
@ -195,15 +187,11 @@ impl Parse for PrimaryExpression {
|
|||||||
return Err(stream.expected_err("identifier")?);
|
return Err(stream.expected_err("identifier")?);
|
||||||
};
|
};
|
||||||
Expression(Kind::Borrow(name, true), stream.get_range().unwrap())
|
Expression(Kind::Borrow(name, true), stream.get_range().unwrap())
|
||||||
} else if let (Some(Token::Et), Some(Token::Identifier(name))) =
|
} else if let (Some(Token::Et), Some(Token::Identifier(name))) = (stream.peek(), stream.peek2()) {
|
||||||
(stream.peek(), stream.peek2())
|
|
||||||
{
|
|
||||||
stream.next(); // Consume Et
|
stream.next(); // Consume Et
|
||||||
stream.next(); // Consume identifier
|
stream.next(); // Consume identifier
|
||||||
Expression(Kind::Borrow(name, false), stream.get_range().unwrap())
|
Expression(Kind::Borrow(name, false), stream.get_range().unwrap())
|
||||||
} else if let (Some(Token::Star), Some(Token::Identifier(name))) =
|
} else if let (Some(Token::Star), Some(Token::Identifier(name))) = (stream.peek(), stream.peek2()) {
|
||||||
(stream.peek(), stream.peek2())
|
|
||||||
{
|
|
||||||
stream.next(); // Consume Et
|
stream.next(); // Consume Et
|
||||||
stream.next(); // Consume identifier
|
stream.next(); // Consume identifier
|
||||||
Expression(Kind::Deref(name), stream.get_range().unwrap())
|
Expression(Kind::Deref(name), stream.get_range().unwrap())
|
||||||
@ -225,49 +213,35 @@ impl Parse for PrimaryExpression {
|
|||||||
}
|
}
|
||||||
Token::BinaryValue(v) => {
|
Token::BinaryValue(v) => {
|
||||||
stream.next(); // Consume binary
|
stream.next(); // Consume binary
|
||||||
let value =
|
let value = u128::from_str_radix(&v, 2).expect("Value is not parseable as u128!");
|
||||||
u128::from_str_radix(&v, 2).expect("Value is not parseable as u128!");
|
|
||||||
if let Ok(expr) = specific_int_lit(value, &mut stream) {
|
if let Ok(expr) = specific_int_lit(value, &mut stream) {
|
||||||
expr
|
expr
|
||||||
} else {
|
} else {
|
||||||
Expression(
|
Expression(Kind::Literal(Literal::Integer(value)), stream.get_range().unwrap())
|
||||||
Kind::Literal(Literal::Integer(value)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::OctalValue(v) => {
|
Token::OctalValue(v) => {
|
||||||
stream.next(); // Consume octal
|
stream.next(); // Consume octal
|
||||||
let value =
|
let value = u128::from_str_radix(&v, 8).expect("Value is not parseable as u128!");
|
||||||
u128::from_str_radix(&v, 8).expect("Value is not parseable as u128!");
|
|
||||||
if let Ok(expr) = specific_int_lit(value, &mut stream) {
|
if let Ok(expr) = specific_int_lit(value, &mut stream) {
|
||||||
expr
|
expr
|
||||||
} else {
|
} else {
|
||||||
Expression(
|
Expression(Kind::Literal(Literal::Integer(value)), stream.get_range().unwrap())
|
||||||
Kind::Literal(Literal::Integer(value)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::HexadecimalValue(v) => {
|
Token::HexadecimalValue(v) => {
|
||||||
stream.next(); // Consume hexadecimal
|
stream.next(); // Consume hexadecimal
|
||||||
|
|
||||||
let value =
|
let value = u128::from_str_radix(&v, 16).expect("Value is not parseable as u128!");
|
||||||
u128::from_str_radix(&v, 16).expect("Value is not parseable as u128!");
|
|
||||||
if let Ok(expr) = specific_int_lit(value, &mut stream) {
|
if let Ok(expr) = specific_int_lit(value, &mut stream) {
|
||||||
expr
|
expr
|
||||||
} else {
|
} else {
|
||||||
Expression(
|
Expression(Kind::Literal(Literal::Integer(value)), stream.get_range().unwrap())
|
||||||
Kind::Literal(Literal::Integer(value)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::DecimalValue(v) => {
|
Token::DecimalValue(v) => {
|
||||||
stream.next(); // Consume decimal
|
stream.next(); // Consume decimal
|
||||||
if let (Some(Token::Dot), Some(Token::DecimalValue(fractional))) =
|
if let (Some(Token::Dot), Some(Token::DecimalValue(fractional))) = (stream.peek(), stream.peek2()) {
|
||||||
(stream.peek(), stream.peek2())
|
|
||||||
{
|
|
||||||
stream.next(); // Consume dot
|
stream.next(); // Consume dot
|
||||||
stream.next(); // Consume fractional
|
stream.next(); // Consume fractional
|
||||||
|
|
||||||
@ -278,30 +252,20 @@ impl Parse for PrimaryExpression {
|
|||||||
if let Ok(expr) = specific_float_lit(value, &mut stream) {
|
if let Ok(expr) = specific_float_lit(value, &mut stream) {
|
||||||
expr
|
expr
|
||||||
} else {
|
} else {
|
||||||
Expression(
|
Expression(Kind::Literal(Literal::Decimal(value)), stream.get_range().unwrap())
|
||||||
Kind::Literal(Literal::Decimal(value)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let value =
|
let value = u128::from_str_radix(&v, 10).expect("Value is not parseable as u128!");
|
||||||
u128::from_str_radix(&v, 10).expect("Value is not parseable as u128!");
|
|
||||||
if let Ok(expr) = specific_int_lit(value, &mut stream) {
|
if let Ok(expr) = specific_int_lit(value, &mut stream) {
|
||||||
expr
|
expr
|
||||||
} else {
|
} else {
|
||||||
Expression(
|
Expression(Kind::Literal(Literal::Integer(value)), stream.get_range().unwrap())
|
||||||
Kind::Literal(Literal::Integer(value)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::StringLit(v) => {
|
Token::StringLit(v) => {
|
||||||
stream.next(); // Consume
|
stream.next(); // Consume
|
||||||
Expression(
|
Expression(Kind::Literal(Literal::String(v.clone())), stream.get_range().unwrap())
|
||||||
Kind::Literal(Literal::String(v.clone())),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Token::CharLit(v) => {
|
Token::CharLit(v) => {
|
||||||
stream.next(); // Consume
|
stream.next(); // Consume
|
||||||
@ -319,17 +283,11 @@ impl Parse for PrimaryExpression {
|
|||||||
}
|
}
|
||||||
Token::True => {
|
Token::True => {
|
||||||
stream.next(); // Consume
|
stream.next(); // Consume
|
||||||
Expression(
|
Expression(Kind::Literal(Literal::Bool(true)), stream.get_range().unwrap())
|
||||||
Kind::Literal(Literal::Bool(true)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Token::False => {
|
Token::False => {
|
||||||
stream.next(); // Consume
|
stream.next(); // Consume
|
||||||
Expression(
|
Expression(Kind::Literal(Literal::Bool(false)), stream.get_range().unwrap())
|
||||||
Kind::Literal(Literal::Bool(false)),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Token::ParenOpen => {
|
Token::ParenOpen => {
|
||||||
stream.next(); // Consume
|
stream.next(); // Consume
|
||||||
@ -343,16 +301,14 @@ impl Parse for PrimaryExpression {
|
|||||||
if let Some(Token::Semi) = stream.peek() {
|
if let Some(Token::Semi) = stream.peek() {
|
||||||
stream.next(); // Consume colon
|
stream.next(); // Consume colon
|
||||||
let Some(Token::DecimalValue(val)) = stream.next() else {
|
let Some(Token::DecimalValue(val)) = stream.next() else {
|
||||||
return Err(stream
|
return Err(stream.expecting_err("decimal value describing array length")?);
|
||||||
.expecting_err("decimal value describing array length")?);
|
|
||||||
};
|
};
|
||||||
stream.expect(Token::BracketClose)?;
|
stream.expect(Token::BracketClose)?;
|
||||||
Expression(
|
Expression(
|
||||||
Kind::ArrayShort(
|
Kind::ArrayShort(
|
||||||
Box::new(exp),
|
Box::new(exp),
|
||||||
u64::from_str_radix(&val, 10).expect(
|
u64::from_str_radix(&val, 10)
|
||||||
"Unable to parse array length to 64-bit decimal value",
|
.expect("Unable to parse array length to 64-bit decimal value"),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
stream.get_range().unwrap(),
|
stream.get_range().unwrap(),
|
||||||
)
|
)
|
||||||
@ -514,11 +470,7 @@ impl Parse for FunctionCallExpression {
|
|||||||
|
|
||||||
stream.expect(Token::ParenClose)?;
|
stream.expect(Token::ParenClose)?;
|
||||||
|
|
||||||
Ok(FunctionCallExpression(
|
Ok(FunctionCallExpression(name, args, stream.get_range().unwrap()))
|
||||||
name,
|
|
||||||
args,
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
Err(stream.expected_err("identifier")?)
|
Err(stream.expected_err("identifier")?)
|
||||||
}
|
}
|
||||||
@ -535,12 +487,7 @@ impl Parse for IfExpression {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Ok(IfExpression(
|
Ok(IfExpression(cond, then_b, else_b, stream.get_range().unwrap()))
|
||||||
cond,
|
|
||||||
then_b,
|
|
||||||
else_b,
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,11 +647,7 @@ impl Parse for Block {
|
|||||||
statements.push(statement);
|
statements.push(statement);
|
||||||
}
|
}
|
||||||
stream.expect(Token::BraceClose)?;
|
stream.expect(Token::BraceClose)?;
|
||||||
Ok(Block(
|
Ok(Block(statements, return_stmt, stream.get_range_prev().unwrap()))
|
||||||
statements,
|
|
||||||
return_stmt,
|
|
||||||
stream.get_range_prev().unwrap(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,9 +752,7 @@ impl Parse for BlockLevelStatement {
|
|||||||
use BlockLevelStatement as Stmt;
|
use BlockLevelStatement as Stmt;
|
||||||
Ok(match stream.peek() {
|
Ok(match stream.peek() {
|
||||||
Some(Token::LetKeyword) => Stmt::Let(stream.parse()?),
|
Some(Token::LetKeyword) => Stmt::Let(stream.parse()?),
|
||||||
Some(Token::ImportKeyword) => Stmt::Import {
|
Some(Token::ImportKeyword) => Stmt::Import { _i: stream.parse()? },
|
||||||
_i: stream.parse()?,
|
|
||||||
},
|
|
||||||
Some(Token::ReturnKeyword) => {
|
Some(Token::ReturnKeyword) => {
|
||||||
stream.next();
|
stream.next();
|
||||||
let exp = stream.parse().ok();
|
let exp = stream.parse().ok();
|
||||||
@ -924,9 +865,7 @@ impl Parse for TopLevelStatement {
|
|||||||
stream.expect(Token::Semi)?;
|
stream.expect(Token::Semi)?;
|
||||||
extern_fn
|
extern_fn
|
||||||
}
|
}
|
||||||
Some(Token::FnKeyword) | Some(Token::PubKeyword) => {
|
Some(Token::FnKeyword) | Some(Token::PubKeyword) => Stmt::FunctionDefinition(stream.parse()?),
|
||||||
Stmt::FunctionDefinition(stream.parse()?)
|
|
||||||
}
|
|
||||||
Some(Token::Struct) => {
|
Some(Token::Struct) => {
|
||||||
let StructDefinition(name, fields, range) = stream.parse::<StructDefinition>()?;
|
let StructDefinition(name, fields, range) = stream.parse::<StructDefinition>()?;
|
||||||
Stmt::TypeDefinition(TypeDefinition {
|
Stmt::TypeDefinition(TypeDefinition {
|
||||||
|
@ -366,6 +366,15 @@ impl ast::Expression {
|
|||||||
Box::new(expr.process(module_id)),
|
Box::new(expr.process(module_id)),
|
||||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||||
),
|
),
|
||||||
|
ast::UnaryOperator::Not => mir::ExprKind::BinOp(
|
||||||
|
mir::BinaryOperator::Cmp(mir::CmpOperator::EQ),
|
||||||
|
Box::new(expr.process(module_id)),
|
||||||
|
Box::new(mir::Expression(
|
||||||
|
mir::ExprKind::Literal(mir::Literal::Bool(false)),
|
||||||
|
expr.1.as_meta(module_id),
|
||||||
|
)),
|
||||||
|
mir::TypeKind::Bool,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
ast::ExpressionKind::CastTo(expression, ty) => mir::ExprKind::CastTo(
|
ast::ExpressionKind::CastTo(expression, ty) => mir::ExprKind::CastTo(
|
||||||
Box::new(expression.process(module_id)),
|
Box::new(expression.process(module_id)),
|
||||||
|
Loading…
Reference in New Issue
Block a user