Skip to content

Commit d5fb4aa

Browse files
committed
Added while loop
1 parent 33d663a commit d5fb4aa

File tree

17 files changed

+72
-15
lines changed

17 files changed

+72
-15
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ edition = "2021"
88
[dependencies]
99
ash_core = { "path" = "./crates/ash_core" }
1010
argh = "0.1"
11-
ariadne = "0.1"
11+
ariadne = "0.1"
12+
anyhow = "1.0"

crates/ash_core/src/core/source.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::error::Error;
2-
use std::fs;
2+
use std::{fs, io};
33
use std::path::PathBuf;
44

55
use once_cell::sync::OnceCell;
@@ -13,7 +13,7 @@ pub struct Source {
1313
}
1414

1515
impl Source {
16-
pub fn from_file(path: PathBuf) -> Result<Self, Box<dyn Error>> {
16+
pub fn from_file(path: PathBuf) -> Result<Self, io::Error> {
1717
let source = fs::read_to_string(&path)?;
1818
let location = path.as_os_str().to_str().map(ToOwned::to_owned);
1919
let source = Self {

crates/ash_core/src/ir/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub(crate) enum Stmt {
2626
name: Spanned<String>,
2727
value: Expr,
2828
},
29+
While(Spanned<Expr>, Vec<Spanned<Stmt>>),
2930
If(If<Expr, Stmt>),
3031
Return(Option<Expr>, Ty),
3132
Expression(Expr, Ty),
@@ -40,7 +41,6 @@ pub(crate) enum Expr {
4041
args: Vec<Expr>,
4142
ty: Ty,
4243
},
43-
Block(Vec<Spanned<Stmt>>, Ty),
4444
Unary {
4545
op: UnaryOp,
4646
right: Box<Expr>,

crates/ash_core/src/ir/ir.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,13 @@ impl<'a> IR<'a> {
135135
let proto_stmt = ir::Stmt::ProtoFunction(proto);
136136
DesugaredAst::returns((proto_stmt, span))
137137
}
138+
ty::Stmt::While(mut cond, body) => {
139+
let cond_expr = self.desugar_expr(cond.0);
140+
let body = self.desugar_statements(body);
141+
let r#while = ir::Stmt::While((cond_expr.returns.unwrap(), cond.1), body);
142+
143+
DesugaredAst::new((r#while, span), cond_expr.rest)
144+
}
138145
ty::Stmt::Return(expr, ty) => match expr {
139146
Some(expr) => {
140147
let DesugaredAst { returns, rest } = self.desugar_expr(expr);

crates/ash_core/src/lexer/keyword.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub(super) fn keyword_lexer() -> impl Parser<char, Token, Error = Simple<char>>
1313
"let" => Token::Let,
1414
"if" => Token::If,
1515
"else" => Token::Else,
16+
"while" => Token::While,
1617
_ => Token::Identifier {
1718
value: ident,
1819
space_sufix: !space.is_empty(),

crates/ash_core/src/lexer/token.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub(crate) enum Token {
2929
Function,
3030
If,
3131
Else,
32+
While,
3233
Let,
3334
String(String),
3435
I32(String),
@@ -64,6 +65,7 @@ impl fmt::Display for Token {
6465
Token::Function => "fun",
6566
Token::If => "if",
6667
Token::Else => "else",
68+
Token::While => "while",
6769
Token::Let => "let",
6870
Token::String(_) => "String",
6971
Token::I32(_) => "I32",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use crate::{lexer::token::Token, core::Spanned};
2+
3+
use super::{common::block_parser, expression_parser, Stmt, StmtRecursive};
4+
use chumsky::prelude::*;
5+
6+
pub(super) fn while_parser<'a>(
7+
stmt: StmtRecursive<'a>,
8+
) -> impl Parser<Token, Spanned<Stmt>, Error = Simple<Token>> + 'a {
9+
just(Token::While)
10+
.ignore_then(expression_parser().map_with_span(|e, s| (e, s)))
11+
.then(block_parser(stmt))
12+
.map_with_span(|(cond, body), span| (Stmt::While(cond, body.block_data()), span))
13+
}

crates/ash_core/src/parser/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ pub(crate) mod operator;
1212
pub(crate) mod parser;
1313
pub(crate) mod stmt;
1414
mod variable;
15+
mod loops;

crates/ash_core/src/parser/stmt.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@ use super::{
1414
conditional::if_parser,
1515
expr::{expression_parser, Expr},
1616
function::{function_parser, function_proto_parser, return_parser},
17-
variable::{variable_assign_parse, variable_decl_parse},
17+
variable::{variable_assign_parse, variable_decl_parse}, loops::while_parser,
1818
};
1919

2020
#[derive(Debug, Clone)]
2121
pub(crate) enum Stmt {
2222
Annotation(Spanned<Annotation>, Box<Spanned<Stmt>>),
2323
ProtoFunction(ProtoFunction),
2424
Function(Box<Function<Stmt>>),
25+
While(Spanned<Expr>, Vec<Spanned<Stmt>>),
2526
VariableDecl {
2627
id: Id,
2728
name: String,
@@ -57,6 +58,7 @@ pub(super) fn statement_parser() -> impl Parser<Token, Spanned<Stmt>, Error = Si
5758
annotation_parser(stmt.clone())
5859
.or(function_parser(stmt.clone()))
5960
.or(function_proto_parser())
61+
.or(while_parser(stmt.clone()))
6062
.or(variable_decl_parse(stmt.clone()))
6163
.or(variable_assign_parse(stmt.clone()))
6264
.or(return_parser(stmt))

crates/ash_core/src/resolver/resolver.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ impl<'a> Resolver<'a> {
158158
}
159159
self.current_function = prev;
160160
}
161+
Stmt::While((cond, span), body) => {
162+
self.resolve_expr(cond, span);
163+
self.resolve_statements(body);
164+
}
161165
Stmt::Return(expr) => {
162166
if self.current_function.is_none() {
163167
self.new_error("return can not be used outside of function", span.clone())

0 commit comments

Comments
 (0)