Compare commits
3 Commits
ccb5741666
...
1a5e3ef1d9
Author | SHA1 | Date | |
---|---|---|---|
1a5e3ef1d9 | |||
ef4964ed86 | |||
431aae0b0d |
15
examples/loops.reid
Normal file
15
examples/loops.reid
Normal file
@ -0,0 +1,15 @@
|
||||
// Arithmetic, function calls and imports!
|
||||
|
||||
|
||||
fn main() -> u32 {
|
||||
for i in 0 to 10 {
|
||||
print("hello")
|
||||
}
|
||||
|
||||
let mut num = 0;
|
||||
while num < 10 {
|
||||
num = num + 1;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
@ -178,6 +178,8 @@ pub enum BlockLevelStatement {
|
||||
},
|
||||
Expression(Expression),
|
||||
Return(ReturnType, Expression),
|
||||
ForLoop(String, TokenRange, Expression, Expression, Block),
|
||||
WhileLoop(Expression, Block),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -231,10 +231,10 @@ impl Parse for PrimaryExpression {
|
||||
stream.expect(Token::BracketClose)?;
|
||||
Expression(Kind::Array(expressions), stream.get_range().unwrap())
|
||||
}
|
||||
_ => Err(stream.expected_err("expression inner")?)?,
|
||||
_ => Err(stream.expecting_err("expression")?)?,
|
||||
}
|
||||
} else {
|
||||
Err(stream.expected_err("expression")?)?
|
||||
Err(stream.expecting_err("expression")?)?
|
||||
};
|
||||
|
||||
while let Ok(index) = stream.parse::<ValueIndex>() {
|
||||
@ -667,6 +667,14 @@ impl Parse for BlockLevelStatement {
|
||||
stream.expect(Token::Semi)?;
|
||||
Stmt::Return(ReturnType::Hard, exp)
|
||||
}
|
||||
Some(Token::For) => {
|
||||
let for_stmt = stream.parse::<ForStatement>()?;
|
||||
Stmt::ForLoop(for_stmt.0, for_stmt.1, for_stmt.2, for_stmt.3, for_stmt.4)
|
||||
}
|
||||
Some(Token::While) => {
|
||||
let while_stmt = stream.parse::<WhileStatement>()?;
|
||||
Stmt::WhileLoop(while_stmt.0, while_stmt.1)
|
||||
}
|
||||
_ => {
|
||||
if let Ok(SetStatement(ident, expr, range)) = stream.parse() {
|
||||
Stmt::Set(ident, expr, range)
|
||||
@ -683,6 +691,35 @@ impl Parse for BlockLevelStatement {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ForStatement(String, TokenRange, Expression, Expression, Block);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WhileStatement(Expression, Block);
|
||||
|
||||
impl Parse for ForStatement {
|
||||
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
||||
stream.expect(Token::For)?;
|
||||
let Some(Token::Identifier(idx)) = stream.next() else {
|
||||
return Err(stream.expected_err("loop counter")?);
|
||||
};
|
||||
let start_range = stream.get_range().unwrap();
|
||||
stream.expect(Token::In)?;
|
||||
let start = stream.parse()?;
|
||||
stream.expect(Token::To)?;
|
||||
let end = stream.parse()?;
|
||||
|
||||
Ok(ForStatement(idx, start_range, start, end, stream.parse()?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for WhileStatement {
|
||||
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
||||
stream.expect(Token::While)?;
|
||||
|
||||
Ok(WhileStatement(stream.parse()?, stream.parse()?))
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct SetStatement(Expression, Expression, TokenRange);
|
||||
|
||||
|
@ -3,8 +3,8 @@ use std::path::PathBuf;
|
||||
use crate::{
|
||||
ast::{self},
|
||||
mir::{
|
||||
self, CustomTypeKey, ModuleMap, NamedVariableRef, SourceModuleId, StmtKind, StructField,
|
||||
StructType,
|
||||
self, CustomTypeKey, ForStatement, ModuleMap, NamedVariableRef, SourceModuleId, StmtKind,
|
||||
StructField, StructType, WhileStatement,
|
||||
},
|
||||
};
|
||||
|
||||
@ -148,6 +148,28 @@ impl ast::Block {
|
||||
ast::BlockLevelStatement::Return(_, e) => {
|
||||
(StmtKind::Expression(e.process(module_id)), e.1)
|
||||
}
|
||||
ast::BlockLevelStatement::ForLoop(counter, counter_range, start, end, block) => (
|
||||
StmtKind::For(ForStatement {
|
||||
counter: NamedVariableRef(
|
||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||
counter.clone(),
|
||||
counter_range.as_meta(module_id),
|
||||
),
|
||||
start: start.process(module_id),
|
||||
end: end.process(module_id),
|
||||
block: block.into_mir(module_id),
|
||||
meta: self.2.as_meta(module_id),
|
||||
}),
|
||||
self.2,
|
||||
),
|
||||
ast::BlockLevelStatement::WhileLoop(expression, block) => (
|
||||
StmtKind::While(WhileStatement {
|
||||
condition: expression.process(module_id),
|
||||
block: block.into_mir(module_id),
|
||||
meta: self.2.as_meta(module_id),
|
||||
}),
|
||||
self.2,
|
||||
),
|
||||
};
|
||||
|
||||
mir_statements.push(mir::Statement(kind, range.as_meta(module_id)));
|
||||
|
@ -598,6 +598,8 @@ impl mir::Statement {
|
||||
}
|
||||
mir::StmtKind::Import(_) => todo!(),
|
||||
mir::StmtKind::Expression(expression) => expression.codegen(scope, state),
|
||||
mir::StmtKind::For(for_statement) => todo!(),
|
||||
mir::StmtKind::While(while_statement) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,16 @@ pub enum Token {
|
||||
Extern,
|
||||
/// `struct`
|
||||
Struct,
|
||||
/// `while`
|
||||
While,
|
||||
/// `for`
|
||||
For,
|
||||
/// `from`
|
||||
From,
|
||||
/// `to`
|
||||
To,
|
||||
/// `to`
|
||||
In,
|
||||
|
||||
// Symbols
|
||||
/// `;`
|
||||
@ -136,6 +146,11 @@ impl ToString for Token {
|
||||
Token::Extern => String::from("extern"),
|
||||
Token::Struct => String::from("struct"),
|
||||
Token::AsKeyword => String::from("as"),
|
||||
Token::For => String::from("for"),
|
||||
Token::From => String::from("from"),
|
||||
Token::In => String::from("in"),
|
||||
Token::To => String::from("to"),
|
||||
Token::While => String::from("while"),
|
||||
Token::Semi => String::from(';'),
|
||||
Token::Equals => String::from('='),
|
||||
Token::Colon => String::from(':'),
|
||||
@ -322,6 +337,11 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
|
||||
"pub" => Token::PubKeyword,
|
||||
"struct" => Token::Struct,
|
||||
"as" => Token::AsKeyword,
|
||||
"for" => Token::For,
|
||||
"while" => Token::While,
|
||||
"in" => Token::In,
|
||||
"from" => Token::From,
|
||||
"to" => Token::To,
|
||||
_ => Token::Identifier(value),
|
||||
};
|
||||
variant
|
||||
|
@ -112,6 +112,9 @@ pub fn compile_module<'map>(
|
||||
is_main,
|
||||
};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
dbg!(&ast_module);
|
||||
|
||||
Ok(ast_module.process(module_id))
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ impl Display for Statement {
|
||||
impl Display for StmtKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Let(var, mutable, block) => {
|
||||
StmtKind::Let(var, mutable, block) => {
|
||||
write!(
|
||||
f,
|
||||
"let{} {} = {}",
|
||||
@ -156,9 +156,26 @@ impl Display for StmtKind {
|
||||
block
|
||||
)
|
||||
}
|
||||
Self::Set(var, expr) => write!(f, "{} = {}", var, expr),
|
||||
Self::Import(n) => write!(f, "import {}", n),
|
||||
Self::Expression(exp) => Display::fmt(exp, f),
|
||||
StmtKind::Set(var, expr) => write!(f, "{} = {}", var, expr),
|
||||
StmtKind::Import(n) => write!(f, "import {}", n),
|
||||
StmtKind::Expression(exp) => Display::fmt(exp, f),
|
||||
StmtKind::For(for_statement) => {
|
||||
write!(
|
||||
f,
|
||||
"for {} in {} to {} {}",
|
||||
for_statement.counter,
|
||||
for_statement.start,
|
||||
for_statement.end,
|
||||
for_statement.block
|
||||
)
|
||||
}
|
||||
StmtKind::While(while_statement) => {
|
||||
write!(
|
||||
f,
|
||||
"while {} {}",
|
||||
while_statement.condition, while_statement.block,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ pub enum ReturnTypeOther {
|
||||
NoBlockReturn(Metadata),
|
||||
IndexingNonArray(Metadata),
|
||||
DerefNonBorrow(Metadata),
|
||||
Loop,
|
||||
}
|
||||
|
||||
impl TypeKind {
|
||||
@ -374,6 +375,8 @@ impl Statement {
|
||||
),
|
||||
Import(_) => todo!(),
|
||||
Expression(expression) => expression.return_type(refs, mod_id),
|
||||
For(_) => Err(ReturnTypeOther::Loop),
|
||||
While(_) => Err(ReturnTypeOther::Loop),
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,6 +386,8 @@ impl Statement {
|
||||
StmtKind::Set(_, _) => None,
|
||||
StmtKind::Import(_) => None,
|
||||
StmtKind::Expression(expr) => expr.backing_var(),
|
||||
StmtKind::For(_) => None,
|
||||
StmtKind::While(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +188,6 @@ impl<'map> Pass for LinkerPass<'map> {
|
||||
.borrow_mut();
|
||||
|
||||
let func_name = unsafe { path.get_unchecked(1) };
|
||||
let imported_mod_name = imported.name.clone();
|
||||
|
||||
let Some(func) = imported.functions.iter_mut().find(|f| f.name == *func_name)
|
||||
else {
|
||||
|
@ -338,6 +338,24 @@ pub enum StmtKind {
|
||||
Set(Expression, Expression),
|
||||
Import(Import),
|
||||
Expression(Expression),
|
||||
For(ForStatement),
|
||||
While(WhileStatement),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ForStatement {
|
||||
pub counter: NamedVariableRef,
|
||||
pub start: Expression,
|
||||
pub end: Expression,
|
||||
pub block: Block,
|
||||
pub meta: Metadata,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WhileStatement {
|
||||
pub condition: Expression,
|
||||
pub block: Block,
|
||||
pub meta: Metadata,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -390,10 +390,19 @@ impl Statement {
|
||||
StmtKind::Set(_, expression) => {
|
||||
expression.pass(pass, state, scope, mod_id)?;
|
||||
}
|
||||
StmtKind::Import(_) => {} // Never exists at this stage
|
||||
StmtKind::Import(_) => {}
|
||||
StmtKind::Expression(expression) => {
|
||||
expression.pass(pass, state, scope, mod_id)?;
|
||||
}
|
||||
StmtKind::For(for_statement) => {
|
||||
for_statement.start.pass(pass, state, scope, mod_id);
|
||||
for_statement.end.pass(pass, state, scope, mod_id);
|
||||
for_statement.block.pass(pass, state, scope, mod_id);
|
||||
}
|
||||
StmtKind::While(while_statement) => {
|
||||
while_statement.condition.pass(pass, state, scope, mod_id);
|
||||
while_statement.block.pass(pass, state, scope, mod_id);
|
||||
}
|
||||
}
|
||||
|
||||
pass.stmt(self, PassState::from(state, scope, Some(mod_id)))?;
|
||||
@ -412,8 +421,10 @@ impl Statement {
|
||||
.ok();
|
||||
}
|
||||
StmtKind::Set(_, _) => {}
|
||||
StmtKind::Import(_) => {} // Never exists at this stage
|
||||
StmtKind::Import(_) => {}
|
||||
StmtKind::Expression(_) => {}
|
||||
StmtKind::For(_) => {}
|
||||
StmtKind::While(_) => {}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ impl Block {
|
||||
|
||||
None
|
||||
}
|
||||
StmtKind::Import(_) => todo!(), // TODO
|
||||
StmtKind::Import(_) => todo!(),
|
||||
StmtKind::Expression(expression) => {
|
||||
let res = expression.typecheck(&mut state, &typerefs, None);
|
||||
state.or_else(res, TypeKind::Void, expression.1);
|
||||
@ -335,6 +335,8 @@ impl Block {
|
||||
None
|
||||
}
|
||||
}
|
||||
StmtKind::For(for_statement) => todo!(),
|
||||
StmtKind::While(while_statement) => todo!(),
|
||||
};
|
||||
|
||||
if let Some((ReturnKind::Hard, _)) = ret {
|
||||
|
@ -126,6 +126,8 @@ impl Block {
|
||||
let expr_res = expr.infer_types(&mut state, &inner_refs);
|
||||
state.ok(expr_res, expr.1);
|
||||
}
|
||||
StmtKind::For(for_statement) => todo!(),
|
||||
StmtKind::While(while_statement) => todo!(),
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user