diff --git a/Cargo.toml b/Cargo.toml index b0fa3a900bc6c3c38e33d6b3e6aa87a394d8667c..51b88c742a378171aa0093edefae5b956af2eb22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace.package] version = "0.1.0" -edition = "2023" +edition = "2021" license = "MIT" authors = ["Lino Le Van", "Dave Caruso"] repository = "https://github.com/lino-levan/blight" diff --git a/crates/ast/ast.rs b/crates/ast/ast.rs index f97d109f4f0d4c0f85e9e1bc2a85c3f185c3a74a..6a30596e334101be04882142df1432fa7ff1795c 100644 --- a/crates/ast/ast.rs +++ b/crates/ast/ast.rs @@ -11,7 +11,7 @@ pub enum BuiltinId { #[derive(Debug, Clone)] pub struct Module { pub comment: Option, - pub statements: Vec, + pub statements: Vec, } #[derive(Debug, Clone)] @@ -177,14 +177,6 @@ pub enum Statement { Comment(Comment), } -#[derive(Debug, Clone)] -pub enum TopLevelStatement { - Expr(Expr), - VarDecl(VarDecl), - FnDecl(FnDecl), - Comment(Comment), -} - impl BuiltinId { pub fn display_name(&self) -> &'static str { match self { @@ -201,15 +193,6 @@ impl BuiltinId { } impl Statement { - pub fn to_top_level(self) -> TopLevelStatement { - match self { - Statement::Expr(expr) => TopLevelStatement::Expr(expr), - Statement::VarDecl(decl) => TopLevelStatement::VarDecl(decl), - Statement::FnDecl(decl) => TopLevelStatement::FnDecl(decl), - Statement::Comment(comment) => TopLevelStatement::Comment(comment), - } - } - /// This is stupid function im sorry pub fn require_semicolon(&self, semicolon_hint: bool) -> bool { match &self { @@ -226,24 +209,3 @@ impl Statement { } } } - -impl TopLevelStatement { - /// This is stupid function im sorry - pub fn require_semicolon(&self, earlier_hint: bool) -> bool { - match &self { - TopLevelStatement::Expr(_) => !earlier_hint, - TopLevelStatement::VarDecl(_) => true, - TopLevelStatement::FnDecl(_) => false, - _ => false, - } - } - - pub fn to_statement(self) -> Option { - match self { - TopLevelStatement::Expr(expr) => Some(Statement::Expr(expr)), - TopLevelStatement::VarDecl(decl) => Some(Statement::VarDecl(decl)), - TopLevelStatement::FnDecl(decl) => Some(Statement::FnDecl(decl)), - TopLevelStatement::Comment(comment) => Some(Statement::Comment(comment)), - } - } -} diff --git a/crates/js_ast/convert/mod.rs b/crates/js_ast/convert/mod.rs index 870912a6c10fe558c69cde35f714fd9961f9497a..cbcbfa9d88f9eef36ca39764b0b587b63969fdb4 100644 --- a/crates/js_ast/convert/mod.rs +++ b/crates/js_ast/convert/mod.rs @@ -35,7 +35,7 @@ pub fn blight_to_js(blight: Module) -> JsModule { let mut root_context = BlockConvertContext::new(); for statement in blight.statements { - process_top_level_statement(&mut root_context, statement).unwrap(); + process_statement(&mut root_context, statement).unwrap(); } root_context.into() diff --git a/crates/js_ast/convert/process_statement.rs b/crates/js_ast/convert/process_statement.rs index 56354366133421783e025ddd47bb70d8313c79ee..fdf3d821643d979bfab14e1f3e903aa355a2d494 100644 --- a/crates/js_ast/convert/process_statement.rs +++ b/crates/js_ast/convert/process_statement.rs @@ -96,13 +96,3 @@ pub fn process_statement(ctx: &mut BlockConvertContext, statement: Statement) -> Statement::Comment(_) => Some(()), } } - -pub fn process_top_level_statement( - ctx: &mut BlockConvertContext, - statement: TopLevelStatement, -) -> Option<()> { - match statement.to_statement() { - Some(stmt) => process_statement(ctx, stmt), - None => todo!("process_top_level_statement"), - } -} diff --git a/crates/parser/parse_fn_declaration.rs b/crates/parser/parse_fn_declaration.rs index 9d1ccddba381832e9ccd2480af4bc4d862c552a4..50e99a9640c517feced1440f60c7ec494cf0747b 100644 --- a/crates/parser/parse_fn_declaration.rs +++ b/crates/parser/parse_fn_declaration.rs @@ -78,7 +78,7 @@ pub fn parse_fn_declaration( } let return_type = match p.peek() { - Some(TokenType::RightArrow) => { + Some(TokenType::MinusLt) => { _ = p.next(); parse_type(p)? } @@ -98,7 +98,7 @@ pub fn parse_fn_declaration( None, ) } - Some(TokenType::BigRightArrow) => { + Some(TokenType::EqualLt) => { _ = p.next(); parse_expr(p)? } diff --git a/crates/parser/parse_module.rs b/crates/parser/parse_module.rs index 11c0ba62456af2c17b034958b531200191c98a09..725507386a05fa9a56cb15234c7bce005352584b 100644 --- a/crates/parser/parse_module.rs +++ b/crates/parser/parse_module.rs @@ -1,5 +1,5 @@ use crate::parse_doc_comment::maybe_read_doc_comment; -use crate::parse_top_level_statement::parse_top_level_statement; +use crate::parse_statement::parse_statement; use crate::Parser; use ast::Module; use miette::Result; @@ -15,7 +15,7 @@ pub fn parse_module(p: &mut Parser) -> Result { .peek() .map_or(false, |x| x.is_start_of_statement_like_expression()); - let statement = parse_top_level_statement(p)?; + let statement = parse_statement(p)?; match p.peek() { Some(TokenType::Semicolon) => { diff --git a/crates/parser/parse_statement.rs b/crates/parser/parse_statement.rs index 55fddecad16f51aa231b44ed3fe8448dd809ecd0..c46427f7a549d2d07593fbc85d2446aae21f4297 100644 --- a/crates/parser/parse_statement.rs +++ b/crates/parser/parse_statement.rs @@ -28,7 +28,7 @@ pub fn parse_statement(p: &mut Parser) -> Result { Some(TokenType::Pub) => { if !p.is_top_level { return Err(p - .error("Public declarations are not allowed inside of functions".to_string()) + .error("Public declarations are only allowed at the top level".to_string()) .into()); } _ = p.next(); @@ -55,6 +55,25 @@ pub fn parse_statement(p: &mut Parser) -> Result { false, m_doc_comment, )?)), + Some(TokenType::Defer) => { + let label = p.peek().unwrap(); + Err(p + .error(format!("'{}' is not yet implemented", label)) + .into()) + } + Some(TokenType::Struct | TokenType::Enum | TokenType::Trait | TokenType::Impl) => { + let label = p.peek().unwrap(); + if !p.is_top_level { + return Err(p + .error(format!("'{}' is only allowed at the top level", label)) + .into()); + } + + Err(p + .error(format!("'{}' is not yet implemented", label)) + .into()) + } + Some(_) => { if let Some(doc_comment) = m_doc_comment { Err(p diff --git a/crates/parser/parse_top_level_statement.rs b/crates/parser/parse_top_level_statement.rs deleted file mode 100644 index b3383ecfa6134479f8e473c3e85f9023d58294ee..0000000000000000000000000000000000000000 --- a/crates/parser/parse_top_level_statement.rs +++ /dev/null @@ -1,10 +0,0 @@ -use ast::TopLevelStatement; -use miette::Result; - -use crate::{parse_statement::parse_statement, Parser}; - -/// Precondition: the next token exists -pub fn parse_top_level_statement(p: &mut Parser) -> Result { - // TODO: we will eventually have real statements that are exclusive to top-level - Ok(parse_statement(p)?.to_top_level()) -} diff --git a/crates/parser/parser.rs b/crates/parser/parser.rs index 12d58b41ee0d968f5b3ed722bed7e123b2ed4633..3d601ffe6451edfc46a0503906356360ee113047 100644 --- a/crates/parser/parser.rs +++ b/crates/parser/parser.rs @@ -9,7 +9,6 @@ mod parse_fn_declaration; mod parse_module; mod parse_param; mod parse_statement; -mod parse_top_level_statement; mod parse_type; use ast::Comment; diff --git a/crates/tokenizer/tokenizer.rs b/crates/tokenizer/tokenizer.rs index 522a1896152d3494c16cee7ed207904927cd28a2..8fdecab4fa033aaab86efd1aa178031f99011147 100644 --- a/crates/tokenizer/tokenizer.rs +++ b/crates/tokenizer/tokenizer.rs @@ -19,13 +19,18 @@ pub enum TokenType { Comment(String), DocComment(String), // Keywords + Defer, Else, + Enum, False, Fn, If, + Impl, Let, Pub, Return, + Struct, + Trait, True, Var, Void, @@ -34,7 +39,7 @@ pub enum TokenType { AndAnd, // && Bang, // ! BangEqual, // != - BigRightArrow, // => + EqualLt, // => Caret, // ^ ClosedBrace, // } ClosedBracket, // ] @@ -59,7 +64,7 @@ pub enum TokenType { OrOr, // || Percent, // % Plus, // + - RightArrow, // -> + MinusLt, // -> Semicolon, // ; Slash, // / Star, // * @@ -86,13 +91,18 @@ impl std::fmt::Display for TokenType { TokenType::Comment(_) => "comment".to_string(), TokenType::DocComment(_) => "documentation comment".to_string(), + TokenType::Defer => "defer".to_string(), TokenType::Else => "else".to_string(), + TokenType::Enum => "enum".to_string(), TokenType::False => "false".to_string(), TokenType::Fn => "fn".to_string(), TokenType::If => "if".to_string(), + TokenType::Impl => "impl".to_string(), TokenType::Let => "let".to_string(), TokenType::Pub => "pub".to_string(), TokenType::Return => "return".to_string(), + TokenType::Struct => "struct".to_string(), + TokenType::Trait => "trait".to_string(), TokenType::True => "true".to_string(), TokenType::Var => "var".to_string(), TokenType::Void => "void".to_string(), @@ -101,7 +111,7 @@ impl std::fmt::Display for TokenType { TokenType::AndAnd => "&&".to_string(), TokenType::Bang => "!".to_string(), TokenType::BangEqual => "!=".to_string(), - TokenType::BigRightArrow => "=>".to_string(), + TokenType::EqualLt => "=>".to_string(), TokenType::Caret => "^".to_string(), TokenType::ClosedBrace => "}".to_string(), TokenType::ClosedBracket => "]".to_string(), @@ -126,7 +136,7 @@ impl std::fmt::Display for TokenType { TokenType::OrOr => "||".to_string(), TokenType::Percent => "%".to_string(), TokenType::Plus => "+".to_string(), - TokenType::RightArrow => "->".to_string(), + TokenType::MinusLt => "->".to_string(), TokenType::Semicolon => ";".to_string(), TokenType::Slash => "/".to_string(), TokenType::Star => "*".to_string(), @@ -183,13 +193,18 @@ pub fn tokenize(content: String) -> Result> { let length = current_token.len(); let variant = match current_token.as_str() { + "defer" => TokenType::Defer, "else" => TokenType::Else, + "enum" => TokenType::Enum, "false" => TokenType::False, "fn" => TokenType::Fn, "if" => TokenType::If, + "impl" => TokenType::Impl, "let" => TokenType::Let, "pub" => TokenType::Pub, "return" => TokenType::Return, + "struct" => TokenType::Struct, + "trait" => TokenType::Trait, "true" => TokenType::True, "var" => TokenType::Var, "void" => TokenType::Void, @@ -250,7 +265,7 @@ pub fn tokenize(content: String) -> Result> { } Some((_, '>')) => { chars.next(); - Token::new(TokenType::BigRightArrow, start, 2) + Token::new(TokenType::EqualLt, start, 2) } _ => Token::new(TokenType::Equal, start, 1), }, @@ -287,7 +302,7 @@ pub fn tokenize(content: String) -> Result> { '-' => match chars.peek() { Some((_, '>')) => { chars.next(); - Token::new(TokenType::RightArrow, start, 2) + Token::new(TokenType::MinusLt, start, 2) } _ => Token::new(TokenType::Minus, start, 1), }, diff --git a/examples/basics/defer.blight b/examples/basics/defer.blight new file mode 100644 index 0000000000000000000000000000000000000000..c24839ea1ad2b81c5bbd49899ff13922ac5c4bd7 --- /dev/null +++ b/examples/basics/defer.blight @@ -0,0 +1,12 @@ +let print = @raw("console.log"); + +{ + print("1"); + defer print("6"); + { + print("2"); + defer print("4"); + print("3"); + } + print("5"); +}