Skip to content

Commit

Permalink
✨ (parser): Add enum parsing
Browse files Browse the repository at this point in the history
semver: minor
  • Loading branch information
Somfic committed Jun 12, 2024
1 parent 45f8c15 commit 6ee3332
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 4 deletions.
8 changes: 7 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ fn lexeme_range_to_source_range(lexemes: &[Lexeme], diagnostic: &parser::Diagnos

fn main() -> Result<()> {
let code = "
1 = (1));
enum result: success failure;
struct person:
name: string
age: int
;
";
let file: SimpleFile<&str, &str> = SimpleFile::new("main", code);

Expand Down
3 changes: 2 additions & 1 deletion src/parser/ast.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};

use crate::scanner::lexeme::Lexeme;

Expand Down Expand Up @@ -28,6 +28,7 @@ pub enum Statement {
Declaration(String, Option<Type>, Expression),
Expression(Expression),
Struct(String, HashMap<String, Type>),
Enum(String, HashSet<String>),
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down
4 changes: 3 additions & 1 deletion src/parser/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,11 @@ impl Default for Lookup {
);
lookup.add_type_handler(TokenType::Identifier, typing::parse_symbol);
lookup.add_type_handler(TokenType::SquareOpen, typing::parse_array);
lookup.add_statement_handler(TokenType::Struct, statement::parse_struct);
lookup.add_type_handler(TokenType::CurlyOpen, typing::parse_tuple);

lookup.add_statement_handler(TokenType::Struct, statement::parse_struct);
lookup.add_statement_handler(TokenType::Enum, statement::parse_enum);

lookup
}
}
41 changes: 40 additions & 1 deletion src/parser/statement.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::panic;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};

use crate::scanner::lexeme::{Lexeme, Range, TokenType, TokenValue};

Expand Down Expand Up @@ -110,3 +110,42 @@ pub fn parse_struct(parser: &Parser, cursor: usize) -> Result<(Statement, usize)

Ok((Statement::Struct(name, members), cursor))
}

pub fn parse_enum(parser: &Parser, cursor: usize) -> Result<(Statement, usize), Diagnostic> {
let (_, cursor) = expect_token!(parser, cursor, TokenType::Enum)?;
let (name, cursor) = expect_token!(parser, cursor, TokenType::Identifier)?;
let name = match &name.value {
TokenValue::Identifier(name) => name.clone(),
_ => panic!("expect_token! should return a valid token and handle the error case"),
};
let (_, cursor) = expect_token!(parser, cursor, TokenType::Colon)?;

let mut new_cursor = cursor;
let mut members: HashSet<String> = HashSet::new();

while let Some(Lexeme::Valid(token)) = parser.lexemes.get(new_cursor) {
let (member_name, cursor) = match token.token_type {
TokenType::Semicolon => break,
_ => {
let (field_name, cursor) =
expect_token!(parser, new_cursor, TokenType::Identifier)?;
let field_name = match &field_name.value {
TokenValue::Identifier(field_name) => field_name.clone(),
_ => panic!(
"expect_token! should return a valid token and handle the error case"
),
};

(field_name, cursor)
}
};

new_cursor = cursor;
// TODO: Handle warning for overwritten members
members.insert(member_name);
}

let (_, cursor) = expect_token!(parser, new_cursor, TokenType::Semicolon)?;

Ok((Statement::Enum(name, members), cursor))
}
9 changes: 9 additions & 0 deletions src/transpiler/bend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ fn transpile_statement(statement: &Statement) -> String {
output.push_str("}\n");
output
}
Statement::Enum(name, members) => {
let mut output = String::new();
output.push_str(&format!("enum {} {{\n", name));
for member in members {
output.push_str(&format!("{},\n", member));
}
output.push_str("}\n");
output
}
}
}

Expand Down

0 comments on commit 6ee3332

Please sign in to comment.