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