Add mutability parsing

This commit is contained in:
Sofia 2025-07-11 21:32:20 +03:00
parent 615fec6e52
commit 85b2ebf04a
7 changed files with 67 additions and 28 deletions

View File

@ -1,9 +1,9 @@
use reid::compile;
pub static ARITHMETIC: &str = include_str!("./reid/arithmetic.reid");
pub static MUTABLE: &str = include_str!("./reid/mutable.reid");
fn main() {
let text = match compile(ARITHMETIC) {
let text = match compile(MUTABLE) {
Ok(t) => t,
Err(e) => panic!("{}", e),
};

View File

@ -1,13 +0,0 @@
// Arithmetic, function calls and imports!
fn main() {
let test = 9;
let simpleAdd = 2 + 2;
let simpleSub = 7 - 2; // 14
if simpleAdd < test {
return 3;
}
return arithmetic + simpleSub + boop;
}

View File

@ -0,0 +1,15 @@
// Arithmetic, function calls and imports!
fn indirection() -> bool {
return true;
}
fn main() -> u16 {
let mut test = 5;
if indirection() {
test = 11;
}
return test;
}

View File

@ -92,7 +92,14 @@ pub struct IfExpression(
);
#[derive(Debug, Clone)]
pub struct LetStatement(pub String, pub Option<Type>, pub Expression, pub TokenRange);
pub struct LetStatement(
pub String,
pub Option<Type>,
/// Mutability
pub bool,
pub Expression,
pub TokenRange,
);
#[derive(Debug, Clone)]
pub struct ImportStatement(pub Vec<String>, pub TokenRange);
@ -125,7 +132,11 @@ pub struct Block(
#[derive(Debug, Clone)]
pub enum BlockLevelStatement {
Let(LetStatement),
Import { _i: ImportStatement },
/// Try to set a variable to a specified expression value
Set(String, Expression),
Import {
_i: ImportStatement,
},
Expression(Expression),
Return(ReturnType, Expression),
}

View File

@ -223,6 +223,7 @@ impl Parse for IfExpression {
impl Parse for LetStatement {
fn parse(mut stream: TokenStream) -> Result<LetStatement, Error> {
stream.expect(Token::LetKeyword)?;
let mutability = stream.expect(Token::MutKeyword).is_ok();
if let Some(Token::Identifier(variable)) = stream.next() {
stream.expect(Token::Equals)?;
@ -232,6 +233,7 @@ impl Parse for LetStatement {
Ok(LetStatement(
variable,
None, // TODO add possibility to name type
mutability,
expression,
stream.get_range().unwrap(),
))
@ -331,7 +333,7 @@ impl Parse for Block {
ReturnType::Hard => {
return_stmt = Some((*r_type, e.clone()));
break; // Return has to be the last statement
// TODO: Make a mechanism that "can" parse even after this
// TODO: Make a mechanism that "can" parse even after this
}
ReturnType::Soft => {
return_stmt = Some((*r_type, e.clone()));
@ -361,20 +363,40 @@ impl Parse for BlockLevelStatement {
Stmt::Return(ReturnType::Hard, exp)
}
_ => {
if let Ok(e) = stream.parse() {
if stream.expect(Token::Semi).is_ok() {
Stmt::Expression(e)
} else {
Stmt::Return(ReturnType::Soft, e)
}
if let Ok(SetStatement(ident, expr)) = stream.parse() {
Stmt::Set(ident, expr)
} else {
Err(stream.expected_err("expression")?)?
if let Ok(e) = stream.parse() {
if stream.expect(Token::Semi).is_ok() {
Stmt::Expression(e)
} else {
Stmt::Return(ReturnType::Soft, e)
}
} else {
Err(stream.expected_err("expression")?)?
}
}
}
})
}
}
#[derive(Debug)]
pub struct SetStatement(String, Expression);
impl Parse for SetStatement {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
if let Some(Token::Identifier(ident)) = stream.next() {
stream.expect(Token::Equals)?;
let expr = stream.parse()?;
stream.expect(Token::Semi)?;
Ok(Self(ident, expr))
} else {
Err(stream.expected_err("identifier")?)?
}
}
}
impl Parse for TopLevelStatement {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
use TopLevelStatement as Stmt;

View File

@ -68,12 +68,13 @@ impl ast::Block {
.map(|t| t.0.into())
.unwrap_or(mir::TypeKind::Vague(mir::VagueType::Unknown)),
s_let.0.clone(),
s_let.3.into(),
s_let.4.into(),
),
s_let.2.process(),
s_let.3.process(),
),
s_let.3,
s_let.4,
),
ast::BlockLevelStatement::Set(_, expression) => todo!(),
ast::BlockLevelStatement::Import { _i } => todo!(),
ast::BlockLevelStatement::Expression(e) => (StmtKind::Expression(e.process()), e.1),
ast::BlockLevelStatement::Return(_, e) => (StmtKind::Expression(e.process()), e.1),

View File

@ -12,6 +12,8 @@ pub enum Token {
// Keywords
/// `let`
LetKeyword,
/// `mut`
MutKeyword,
/// `import`
ImportKeyword,
/// `return`
@ -170,6 +172,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
// Check for keywords
let variant = match value.as_str() {
"let" => Token::LetKeyword,
"mut" => Token::MutKeyword,
"import" => Token::ImportKeyword,
"return" => Token::ReturnKeyword,
"fn" => Token::FnKeyword,