Skip to content

Commit 4a27584

Browse files
committed
kLang: Now featuring basic parsing!
Added full support for my private parse test and benchmarks: ~ 61 ms / Mb with `-v 0` ~ 85 ms / Mb with `-v 3` ~ 120 ms / Mb with `--features slow_dev_debugging` and `-v 0` ~ 520 ms / Mb with `--features slow_dev_debugging` and `-v 3` Thats 1.6x the time compared to not parsing the AST, meaning that the tokenizer still uses up most of the performance
1 parent f2f3799 commit 4a27584

1 file changed

Lines changed: 38 additions & 27 deletions

File tree

src/parser.rs

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,6 @@ pub enum Stmt {
163163
r#type: Type,
164164
expr: Expr,
165165
},
166-
Mutate {
167-
name: String,
168-
expr: Expr,
169-
},
170166
Loop(Scope),
171167
Return(Option<Expr>),
172168
Break(Option<Expr>),
@@ -218,7 +214,7 @@ pub enum Lit {
218214
}
219215

220216
#[derive(Debug)]
221-
enum Type {
217+
pub enum Type {
222218
I16,
223219
I32,
224220
F32,
@@ -231,23 +227,32 @@ enum Type {
231227
}
232228

233229
#[derive(Debug)]
234-
struct Constant {
230+
pub struct Constant {
235231
name: String,
236232
r#type: Type,
237233
expr: Expr,
238234
}
239235

240-
pub fn parse_tokens(tokens: Vec<DataToken>) -> Result<Vec<(Stmt, (usize, usize))>, ParseError> {
236+
#[derive(Debug)]
237+
pub struct AST {
238+
statements: Vec<(Stmt, (usize, usize))>,
239+
consts: Vec<Constant>,
240+
macros: Vec<(String, Expr)>,
241+
types: Vec<(String, Type)>,
242+
}
243+
244+
pub fn parse_tokens(tokens: Vec<DataToken>) -> Result<AST, ParseError> {
241245
let mut tokenstream = tokens.into_iter().peekable();
242246

243247
parse_global(&mut tokenstream)
244248
}
245249

246-
fn parse_global(tokens: &mut tokenstream!()) -> Result<Vec<(Stmt, (usize, usize))>, ParseError> {
250+
fn parse_global(tokens: &mut tokenstream!()) -> Result<AST, ParseError> {
247251
let mut result: Vec<(Stmt, (usize, usize))> = Vec::new();
248252

249253
let mut consts: Vec<Constant> = Vec::new();
250-
let mut macros: Vec<(String, Vec<DataToken>)> = Vec::new();
254+
let mut macros: Vec<(String, Expr)> = Vec::new();
255+
let mut types: Vec<(String, Type)> = Vec::new();
251256

252257
loop {
253258
#[cfg(feature = "slow_dev_debugging")]
@@ -257,7 +262,7 @@ fn parse_global(tokens: &mut tokenstream!()) -> Result<Vec<(Stmt, (usize, usize)
257262
Some(t) => match t.inner() {
258263
Token::Const => consts.push(parse_constant(tokens)?),
259264
Token::Macro => macros.push(parse_macro(tokens)?),
260-
Token::Type => todo!("type statements"),
265+
Token::Type => types.push(parse_type_assign(tokens)?),
261266
Token::Func => result.push((Stmt::Func(parse_function(tokens)?), t.get_pos())),
262267
_ => return ParseError::new(&tokens.next().unwrap(), ParseErrorReason::UnexpectedToken, "An unexpected token in global scope, allowed tokens: `func`, `const`, `macro` and `type`")
263268
},
@@ -267,8 +272,14 @@ fn parse_global(tokens: &mut tokenstream!()) -> Result<Vec<(Stmt, (usize, usize)
267272

268273
super::LOG.debug(&format!("\nGot constants: {:?}", consts));
269274
super::LOG.debug(&format!("Got macros: {:?}", macros));
275+
super::LOG.debug(&format!("Got types: {:?}", types));
270276

271-
Ok(result)
277+
Ok(AST {
278+
statements: result,
279+
consts,
280+
macros,
281+
types,
282+
})
272283
}
273284

274285
fn parse_constant(tokens: &mut tokenstream!()) -> Result<Constant, ParseError> {
@@ -298,32 +309,32 @@ fn parse_constant(tokens: &mut tokenstream!()) -> Result<Constant, ParseError> {
298309
})
299310
}
300311

301-
fn parse_macro(tokens: &mut tokenstream!()) -> Result<(String, Vec<DataToken>), ParseError> {
312+
fn parse_macro(tokens: &mut tokenstream!()) -> Result<(String, Expr), ParseError> {
302313
// /* parse_global does this already */ consume!(tokens, Macro, "Macros must be started with `macro`");
303314

304315
let name = ident!(tokens);
305316

306317
consume!(tokens, OutputSpecifier, "Macros must have tokens after output specifier `->`");
307318

308-
let mut macro_tokens = Vec::new();
309-
let mut scope_lvl: usize = 0;
319+
let expr = parse_expr(tokens, 0)?;
310320

311-
loop {
312-
expect_token!(tokens, tok, {
313-
match tok.inner() {
314-
Token::BracesBegin => scope_lvl += 1,
315-
Token::BracesEnd => scope_lvl -= 1,
316-
Token::Terminator if scope_lvl == 0 => break,
317-
_ => {}
318-
}
321+
consume!(tokens, Terminator, "Macros must be properly terminated");
319322

320-
macro_tokens.push(tok.clone());
321-
});
322-
}
323+
Ok((name, expr))
324+
}
325+
326+
fn parse_type_assign(tokens: &mut tokenstream!()) -> Result<(String, Type), ParseError> {
327+
// /* parse_global does this already */ consume!(tokens, Const, "Constant expressions must be started with `const`");
328+
329+
let name = ident!(tokens);
330+
331+
consume!(tokens, TypeSeperator, "Type definitions must have their type specified with `:`");
323332

324-
// /* THE LOOP DOES THIS YOU APE */ consume!(tokens, Terminator, "Macros must be properly terminated");
333+
let r#type = parse_type(tokens)?;
334+
335+
consume!(tokens, Terminator, "Constants must be properly terminated");
325336

326-
Ok((name, macro_tokens))
337+
Ok((name, r#type))
327338
}
328339

329340
fn parse_function(tokens: &mut tokenstream!()) -> Result<Function, ParseError> {

0 commit comments

Comments
 (0)