| author | |
| committer | |
| log | d0e4a653989fb012e7b7c01eebb76c655c3393a1 |
| tree | d1875641207065e29bb81390922e43bef1b86585 |
| parent | aeeab025ce0b9698e869be9a04033dd327cb0ad0 |
* chore: remove top level statement and add some more things
* revisions11 files changed, 60 insertions(+), 73 deletions(-)
Cargo.toml+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | [workspace.package] |
| 2 | 2 | version = "0.1.0" |
| 3 | edition = "2023" | |
| 3 | edition = "2021" | |
| 4 | 4 | license = "MIT" |
| 5 | 5 | authors = ["Lino Le Van", "Dave Caruso"] |
| 6 | 6 | repository = "https://github.com/lino-levan/blight" |
crates/ast/ast.rs+1-39| ... | ... | @@ -11,7 +11,7 @@ pub enum BuiltinId { |
| 11 | 11 | #[derive(Debug, Clone)] |
| 12 | 12 | pub struct Module { |
| 13 | 13 | pub comment: Option<DocComment>, |
| 14 | pub statements: Vec<TopLevelStatement>, | |
| 14 | pub statements: Vec<Statement>, | |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | #[derive(Debug, Clone)] |
| ... | ... | @@ -177,14 +177,6 @@ pub enum Statement { |
| 177 | 177 | Comment(Comment), |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | #[derive(Debug, Clone)] | |
| 181 | pub enum TopLevelStatement { | |
| 182 | Expr(Expr), | |
| 183 | VarDecl(VarDecl), | |
| 184 | FnDecl(FnDecl), | |
| 185 | Comment(Comment), | |
| 186 | } | |
| 187 | ||
| 188 | 180 | impl BuiltinId { |
| 189 | 181 | pub fn display_name(&self) -> &'static str { |
| 190 | 182 | match self { |
| ... | ... | @@ -201,15 +193,6 @@ impl BuiltinId { |
| 201 | 193 | } |
| 202 | 194 | |
| 203 | 195 | impl Statement { |
| 204 | pub fn to_top_level(self) -> TopLevelStatement { | |
| 205 | match self { | |
| 206 | Statement::Expr(expr) => TopLevelStatement::Expr(expr), | |
| 207 | Statement::VarDecl(decl) => TopLevelStatement::VarDecl(decl), | |
| 208 | Statement::FnDecl(decl) => TopLevelStatement::FnDecl(decl), | |
| 209 | Statement::Comment(comment) => TopLevelStatement::Comment(comment), | |
| 210 | } | |
| 211 | } | |
| 212 | ||
| 213 | 196 | /// This is stupid function im sorry |
| 214 | 197 | pub fn require_semicolon(&self, semicolon_hint: bool) -> bool { |
| 215 | 198 | match &self { |
| ... | ... | @@ -226,24 +209,3 @@ impl Statement { |
| 226 | 209 | } |
| 227 | 210 | } |
| 228 | 211 | } |
| 229 | ||
| 230 | impl TopLevelStatement { | |
| 231 | /// This is stupid function im sorry | |
| 232 | pub fn require_semicolon(&self, earlier_hint: bool) -> bool { | |
| 233 | match &self { | |
| 234 | TopLevelStatement::Expr(_) => !earlier_hint, | |
| 235 | TopLevelStatement::VarDecl(_) => true, | |
| 236 | TopLevelStatement::FnDecl(_) => false, | |
| 237 | _ => false, | |
| 238 | } | |
| 239 | } | |
| 240 | ||
| 241 | pub fn to_statement(self) -> Option<Statement> { | |
| 242 | match self { | |
| 243 | TopLevelStatement::Expr(expr) => Some(Statement::Expr(expr)), | |
| 244 | TopLevelStatement::VarDecl(decl) => Some(Statement::VarDecl(decl)), | |
| 245 | TopLevelStatement::FnDecl(decl) => Some(Statement::FnDecl(decl)), | |
| 246 | TopLevelStatement::Comment(comment) => Some(Statement::Comment(comment)), | |
| 247 | } | |
| 248 | } | |
| 249 | } |
crates/js_ast/convert/mod.rs+1-1| ... | ... | @@ -35,7 +35,7 @@ pub fn blight_to_js(blight: Module) -> JsModule { |
| 35 | 35 | let mut root_context = BlockConvertContext::new(); |
| 36 | 36 | |
| 37 | 37 | for statement in blight.statements { |
| 38 | process_top_level_statement(&mut root_context, statement).unwrap(); | |
| 38 | process_statement(&mut root_context, statement).unwrap(); | |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | root_context.into() |
crates/js_ast/convert/process_statement.rs-10| ... | ... | @@ -96,13 +96,3 @@ pub fn process_statement(ctx: &mut BlockConvertContext, statement: Statement) -> |
| 96 | 96 | Statement::Comment(_) => Some(()), |
| 97 | 97 | } |
| 98 | 98 | } |
| 99 | ||
| 100 | pub fn process_top_level_statement( | |
| 101 | ctx: &mut BlockConvertContext, | |
| 102 | statement: TopLevelStatement, | |
| 103 | ) -> Option<()> { | |
| 104 | match statement.to_statement() { | |
| 105 | Some(stmt) => process_statement(ctx, stmt), | |
| 106 | None => todo!("process_top_level_statement"), | |
| 107 | } | |
| 108 | } |
crates/parser/parse_fn_declaration.rs+2-2| ... | ... | @@ -78,7 +78,7 @@ pub fn parse_fn_declaration( |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | 80 | let return_type = match p.peek() { |
| 81 | Some(TokenType::RightArrow) => { | |
| 81 | Some(TokenType::MinusLt) => { | |
| 82 | 82 | _ = p.next(); |
| 83 | 83 | parse_type(p)? |
| 84 | 84 | } |
| ... | ... | @@ -98,7 +98,7 @@ pub fn parse_fn_declaration( |
| 98 | 98 | None, |
| 99 | 99 | ) |
| 100 | 100 | } |
| 101 | Some(TokenType::BigRightArrow) => { | |
| 101 | Some(TokenType::EqualLt) => { | |
| 102 | 102 | _ = p.next(); |
| 103 | 103 | parse_expr(p)? |
| 104 | 104 | } |
crates/parser/parse_module.rs+2-2| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | use crate::parse_doc_comment::maybe_read_doc_comment; |
| 2 | use crate::parse_top_level_statement::parse_top_level_statement; | |
| 2 | use crate::parse_statement::parse_statement; | |
| 3 | 3 | use crate::Parser; |
| 4 | 4 | use ast::Module; |
| 5 | 5 | use miette::Result; |
| ... | ... | @@ -15,7 +15,7 @@ pub fn parse_module(p: &mut Parser) -> Result<Module> { |
| 15 | 15 | .peek() |
| 16 | 16 | .map_or(false, |x| x.is_start_of_statement_like_expression()); |
| 17 | 17 | |
| 18 | let statement = parse_top_level_statement(p)?; | |
| 18 | let statement = parse_statement(p)?; | |
| 19 | 19 | |
| 20 | 20 | match p.peek() { |
| 21 | 21 | Some(TokenType::Semicolon) => { |
crates/parser/parse_statement.rs+20-1| ... | ... | @@ -28,7 +28,7 @@ pub fn parse_statement(p: &mut Parser) -> Result<Statement> { |
| 28 | 28 | Some(TokenType::Pub) => { |
| 29 | 29 | if !p.is_top_level { |
| 30 | 30 | return Err(p |
| 31 | .error("Public declarations are not allowed inside of functions".to_string()) | |
| 31 | .error("Public declarations are only allowed at the top level".to_string()) | |
| 32 | 32 | .into()); |
| 33 | 33 | } |
| 34 | 34 | _ = p.next(); |
| ... | ... | @@ -55,6 +55,25 @@ pub fn parse_statement(p: &mut Parser) -> Result<Statement> { |
| 55 | 55 | false, |
| 56 | 56 | m_doc_comment, |
| 57 | 57 | )?)), |
| 58 | Some(TokenType::Defer) => { | |
| 59 | let label = p.peek().unwrap(); | |
| 60 | Err(p | |
| 61 | .error(format!("'{}' is not yet implemented", label)) | |
| 62 | .into()) | |
| 63 | } | |
| 64 | Some(TokenType::Struct | TokenType::Enum | TokenType::Trait | TokenType::Impl) => { | |
| 65 | let label = p.peek().unwrap(); | |
| 66 | if !p.is_top_level { | |
| 67 | return Err(p | |
| 68 | .error(format!("'{}' is only allowed at the top level", label)) | |
| 69 | .into()); | |
| 70 | } | |
| 71 | ||
| 72 | Err(p | |
| 73 | .error(format!("'{}' is not yet implemented", label)) | |
| 74 | .into()) | |
| 75 | } | |
| 76 | ||
| 58 | 77 | Some(_) => { |
| 59 | 78 | if let Some(doc_comment) = m_doc_comment { |
| 60 | 79 | Err(p |
crates/parser/parse_top_level_statement.rs deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | use ast::TopLevelStatement; | |
| 2 | use miette::Result; | |
| 3 | ||
| 4 | use crate::{parse_statement::parse_statement, Parser}; | |
| 5 | ||
| 6 | /// Precondition: the next token exists | |
| 7 | pub fn parse_top_level_statement(p: &mut Parser) -> Result<TopLevelStatement> { | |
| 8 | // TODO: we will eventually have real statements that are exclusive to top-level | |
| 9 | Ok(parse_statement(p)?.to_top_level()) | |
| 10 | } |
crates/parser/parser.rs-1| ... | ... | @@ -9,7 +9,6 @@ mod parse_fn_declaration; |
| 9 | 9 | mod parse_module; |
| 10 | 10 | mod parse_param; |
| 11 | 11 | mod parse_statement; |
| 12 | mod parse_top_level_statement; | |
| 13 | 12 | mod parse_type; |
| 14 | 13 | |
| 15 | 14 | use ast::Comment; |
crates/tokenizer/tokenizer.rs+21-6| ... | ... | @@ -19,13 +19,18 @@ pub enum TokenType { |
| 19 | 19 | Comment(String), |
| 20 | 20 | DocComment(String), |
| 21 | 21 | // Keywords |
| 22 | Defer, | |
| 22 | 23 | Else, |
| 24 | Enum, | |
| 23 | 25 | False, |
| 24 | 26 | Fn, |
| 25 | 27 | If, |
| 28 | Impl, | |
| 26 | 29 | Let, |
| 27 | 30 | Pub, |
| 28 | 31 | Return, |
| 32 | Struct, | |
| 33 | Trait, | |
| 29 | 34 | True, |
| 30 | 35 | Var, |
| 31 | 36 | Void, |
| ... | ... | @@ -34,7 +39,7 @@ pub enum TokenType { |
| 34 | 39 | AndAnd, // && |
| 35 | 40 | Bang, // ! |
| 36 | 41 | BangEqual, // != |
| 37 | BigRightArrow, // => | |
| 42 | EqualLt, // => | |
| 38 | 43 | Caret, // ^ |
| 39 | 44 | ClosedBrace, // } |
| 40 | 45 | ClosedBracket, // ] |
| ... | ... | @@ -59,7 +64,7 @@ pub enum TokenType { |
| 59 | 64 | OrOr, // || |
| 60 | 65 | Percent, // % |
| 61 | 66 | Plus, // + |
| 62 | RightArrow, // -> | |
| 67 | MinusLt, // -> | |
| 63 | 68 | Semicolon, // ; |
| 64 | 69 | Slash, // / |
| 65 | 70 | Star, // * |
| ... | ... | @@ -86,13 +91,18 @@ impl std::fmt::Display for TokenType { |
| 86 | 91 | TokenType::Comment(_) => "comment".to_string(), |
| 87 | 92 | TokenType::DocComment(_) => "documentation comment".to_string(), |
| 88 | 93 | |
| 94 | TokenType::Defer => "defer".to_string(), | |
| 89 | 95 | TokenType::Else => "else".to_string(), |
| 96 | TokenType::Enum => "enum".to_string(), | |
| 90 | 97 | TokenType::False => "false".to_string(), |
| 91 | 98 | TokenType::Fn => "fn".to_string(), |
| 92 | 99 | TokenType::If => "if".to_string(), |
| 100 | TokenType::Impl => "impl".to_string(), | |
| 93 | 101 | TokenType::Let => "let".to_string(), |
| 94 | 102 | TokenType::Pub => "pub".to_string(), |
| 95 | 103 | TokenType::Return => "return".to_string(), |
| 104 | TokenType::Struct => "struct".to_string(), | |
| 105 | TokenType::Trait => "trait".to_string(), | |
| 96 | 106 | TokenType::True => "true".to_string(), |
| 97 | 107 | TokenType::Var => "var".to_string(), |
| 98 | 108 | TokenType::Void => "void".to_string(), |
| ... | ... | @@ -101,7 +111,7 @@ impl std::fmt::Display for TokenType { |
| 101 | 111 | TokenType::AndAnd => "&&".to_string(), |
| 102 | 112 | TokenType::Bang => "!".to_string(), |
| 103 | 113 | TokenType::BangEqual => "!=".to_string(), |
| 104 | TokenType::BigRightArrow => "=>".to_string(), | |
| 114 | TokenType::EqualLt => "=>".to_string(), | |
| 105 | 115 | TokenType::Caret => "^".to_string(), |
| 106 | 116 | TokenType::ClosedBrace => "}".to_string(), |
| 107 | 117 | TokenType::ClosedBracket => "]".to_string(), |
| ... | ... | @@ -126,7 +136,7 @@ impl std::fmt::Display for TokenType { |
| 126 | 136 | TokenType::OrOr => "||".to_string(), |
| 127 | 137 | TokenType::Percent => "%".to_string(), |
| 128 | 138 | TokenType::Plus => "+".to_string(), |
| 129 | TokenType::RightArrow => "->".to_string(), | |
| 139 | TokenType::MinusLt => "->".to_string(), | |
| 130 | 140 | TokenType::Semicolon => ";".to_string(), |
| 131 | 141 | TokenType::Slash => "/".to_string(), |
| 132 | 142 | TokenType::Star => "*".to_string(), |
| ... | ... | @@ -183,13 +193,18 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> { |
| 183 | 193 | let length = current_token.len(); |
| 184 | 194 | |
| 185 | 195 | let variant = match current_token.as_str() { |
| 196 | "defer" => TokenType::Defer, | |
| 186 | 197 | "else" => TokenType::Else, |
| 198 | "enum" => TokenType::Enum, | |
| 187 | 199 | "false" => TokenType::False, |
| 188 | 200 | "fn" => TokenType::Fn, |
| 189 | 201 | "if" => TokenType::If, |
| 202 | "impl" => TokenType::Impl, | |
| 190 | 203 | "let" => TokenType::Let, |
| 191 | 204 | "pub" => TokenType::Pub, |
| 192 | 205 | "return" => TokenType::Return, |
| 206 | "struct" => TokenType::Struct, | |
| 207 | "trait" => TokenType::Trait, | |
| 193 | 208 | "true" => TokenType::True, |
| 194 | 209 | "var" => TokenType::Var, |
| 195 | 210 | "void" => TokenType::Void, |
| ... | ... | @@ -250,7 +265,7 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> { |
| 250 | 265 | } |
| 251 | 266 | Some((_, '>')) => { |
| 252 | 267 | chars.next(); |
| 253 | Token::new(TokenType::BigRightArrow, start, 2) | |
| 268 | Token::new(TokenType::EqualLt, start, 2) | |
| 254 | 269 | } |
| 255 | 270 | _ => Token::new(TokenType::Equal, start, 1), |
| 256 | 271 | }, |
| ... | ... | @@ -287,7 +302,7 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> { |
| 287 | 302 | '-' => match chars.peek() { |
| 288 | 303 | Some((_, '>')) => { |
| 289 | 304 | chars.next(); |
| 290 | Token::new(TokenType::RightArrow, start, 2) | |
| 305 | Token::new(TokenType::MinusLt, start, 2) | |
| 291 | 306 | } |
| 292 | 307 | _ => Token::new(TokenType::Minus, start, 1), |
| 293 | 308 | }, |
examples/basics/defer.blight created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | let print = @raw("console.log"); | |
| 2 | ||
| 3 | { | |
| 4 | print("1"); | |
| 5 | defer print("6"); | |
| 6 | { | |
| 7 | print("2"); | |
| 8 | defer print("4"); | |
| 9 | print("3"); | |
| 10 | } | |
| 11 | print("5"); | |
| 12 | } |