| author | |
| committer | |
| log | 8e08f65f07fb0df63708095fd4537dd2c0fee7fb |
| tree | d1875641207065e29bb81390922e43bef1b86585 |
| parent | 7bdbb637854c6c3568f62baebcf5f9c53e8dda56 |
| signature | Signed by PGP key B5690EEEBB952194 |
* 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,6 +1,6 @@ |
| 1 | [workspace.package] | 1 | [workspace.package] |
| 2 | version = "0.1.0" | 2 | version = "0.1.0" |
| 3 | edition = "2023" | 3 | edition = "2021" |
| 4 | license = "MIT" | 4 | license = "MIT" |
| 5 | authors = ["Lino Le Van", "Dave Caruso"] | 5 | authors = ["Lino Le Van", "Dave Caruso"] |
| 6 | repository = "https://github.com/lino-levan/blight" | 6 | repository = "https://github.com/lino-levan/blight" |
crates/ast/ast.rs+1-39| ... | @@ -11,7 +11,7 @@ pub enum BuiltinId { | ... | @@ -11,7 +11,7 @@ pub enum BuiltinId { |
| 11 | #[derive(Debug, Clone)] | 11 | #[derive(Debug, Clone)] |
| 12 | pub struct Module { | 12 | pub struct Module { |
| 13 | pub comment: Option<DocComment>, | 13 | pub comment: Option<DocComment>, |
| 14 | pub statements: Vec<TopLevelStatement>, | 14 | pub statements: Vec<Statement>, |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | #[derive(Debug, Clone)] | 17 | #[derive(Debug, Clone)] |
| ... | @@ -177,14 +177,6 @@ pub enum Statement { | ... | @@ -177,14 +177,6 @@ pub enum Statement { |
| 177 | Comment(Comment), | 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 | impl BuiltinId { | 180 | impl BuiltinId { |
| 189 | pub fn display_name(&self) -> &'static str { | 181 | pub fn display_name(&self) -> &'static str { |
| 190 | match self { | 182 | match self { |
| ... | @@ -201,15 +193,6 @@ impl BuiltinId { | ... | @@ -201,15 +193,6 @@ impl BuiltinId { |
| 201 | } | 193 | } |
| 202 | 194 | ||
| 203 | impl Statement { | 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 | /// This is stupid function im sorry | 196 | /// This is stupid function im sorry |
| 214 | pub fn require_semicolon(&self, semicolon_hint: bool) -> bool { | 197 | pub fn require_semicolon(&self, semicolon_hint: bool) -> bool { |
| 215 | match &self { | 198 | match &self { |
| ... | @@ -226,24 +209,3 @@ impl Statement { | ... | @@ -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,7 +35,7 @@ pub fn blight_to_js(blight: Module) -> JsModule { |
| 35 | let mut root_context = BlockConvertContext::new(); | 35 | let mut root_context = BlockConvertContext::new(); |
| 36 | 36 | ||
| 37 | for statement in blight.statements { | 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 | root_context.into() | 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,13 +96,3 @@ pub fn process_statement(ctx: &mut BlockConvertContext, statement: Statement) -> |
| 96 | Statement::Comment(_) => Some(()), | 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,7 +78,7 @@ pub fn parse_fn_declaration( |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | let return_type = match p.peek() { | 80 | let return_type = match p.peek() { |
| 81 | Some(TokenType::RightArrow) => { | 81 | Some(TokenType::MinusLt) => { |
| 82 | _ = p.next(); | 82 | _ = p.next(); |
| 83 | parse_type(p)? | 83 | parse_type(p)? |
| 84 | } | 84 | } |
| ... | @@ -98,7 +98,7 @@ pub fn parse_fn_declaration( | ... | @@ -98,7 +98,7 @@ pub fn parse_fn_declaration( |
| 98 | None, | 98 | None, |
| 99 | ) | 99 | ) |
| 100 | } | 100 | } |
| 101 | Some(TokenType::BigRightArrow) => { | 101 | Some(TokenType::EqualLt) => { |
| 102 | _ = p.next(); | 102 | _ = p.next(); |
| 103 | parse_expr(p)? | 103 | parse_expr(p)? |
| 104 | } | 104 | } |
crates/parser/parse_module.rs+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | use crate::parse_doc_comment::maybe_read_doc_comment; | 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 | use crate::Parser; | 3 | use crate::Parser; |
| 4 | use ast::Module; | 4 | use ast::Module; |
| 5 | use miette::Result; | 5 | use miette::Result; |
| ... | @@ -15,7 +15,7 @@ pub fn parse_module(p: &mut Parser) -> Result<Module> { | ... | @@ -15,7 +15,7 @@ pub fn parse_module(p: &mut Parser) -> Result<Module> { |
| 15 | .peek() | 15 | .peek() |
| 16 | .map_or(false, |x| x.is_start_of_statement_like_expression()); | 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 | match p.peek() { | 20 | match p.peek() { |
| 21 | Some(TokenType::Semicolon) => { | 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,7 +28,7 @@ pub fn parse_statement(p: &mut Parser) -> Result<Statement> { |
| 28 | Some(TokenType::Pub) => { | 28 | Some(TokenType::Pub) => { |
| 29 | if !p.is_top_level { | 29 | if !p.is_top_level { |
| 30 | return Err(p | 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 | .into()); | 32 | .into()); |
| 33 | } | 33 | } |
| 34 | _ = p.next(); | 34 | _ = p.next(); |
| ... | @@ -55,6 +55,25 @@ pub fn parse_statement(p: &mut Parser) -> Result<Statement> { | ... | @@ -55,6 +55,25 @@ pub fn parse_statement(p: &mut Parser) -> Result<Statement> { |
| 55 | false, | 55 | false, |
| 56 | m_doc_comment, | 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 | Some(_) => { | 77 | Some(_) => { |
| 59 | if let Some(doc_comment) = m_doc_comment { | 78 | if let Some(doc_comment) = m_doc_comment { |
| 60 | Err(p | 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,7 +9,6 @@ mod parse_fn_declaration; |
| 9 | mod parse_module; | 9 | mod parse_module; |
| 10 | mod parse_param; | 10 | mod parse_param; |
| 11 | mod parse_statement; | 11 | mod parse_statement; |
| 12 | mod parse_top_level_statement; | ||
| 13 | mod parse_type; | 12 | mod parse_type; |
| 14 | 13 | ||
| 15 | use ast::Comment; | 14 | use ast::Comment; |
crates/tokenizer/tokenizer.rs+21-6| ... | @@ -19,13 +19,18 @@ pub enum TokenType { | ... | @@ -19,13 +19,18 @@ pub enum TokenType { |
| 19 | Comment(String), | 19 | Comment(String), |
| 20 | DocComment(String), | 20 | DocComment(String), |
| 21 | // Keywords | 21 | // Keywords |
| 22 | Defer, | ||
| 22 | Else, | 23 | Else, |
| 24 | Enum, | ||
| 23 | False, | 25 | False, |
| 24 | Fn, | 26 | Fn, |
| 25 | If, | 27 | If, |
| 28 | Impl, | ||
| 26 | Let, | 29 | Let, |
| 27 | Pub, | 30 | Pub, |
| 28 | Return, | 31 | Return, |
| 32 | Struct, | ||
| 33 | Trait, | ||
| 29 | True, | 34 | True, |
| 30 | Var, | 35 | Var, |
| 31 | Void, | 36 | Void, |
| ... | @@ -34,7 +39,7 @@ pub enum TokenType { | ... | @@ -34,7 +39,7 @@ pub enum TokenType { |
| 34 | AndAnd, // && | 39 | AndAnd, // && |
| 35 | Bang, // ! | 40 | Bang, // ! |
| 36 | BangEqual, // != | 41 | BangEqual, // != |
| 37 | BigRightArrow, // => | 42 | EqualLt, // => |
| 38 | Caret, // ^ | 43 | Caret, // ^ |
| 39 | ClosedBrace, // } | 44 | ClosedBrace, // } |
| 40 | ClosedBracket, // ] | 45 | ClosedBracket, // ] |
| ... | @@ -59,7 +64,7 @@ pub enum TokenType { | ... | @@ -59,7 +64,7 @@ pub enum TokenType { |
| 59 | OrOr, // || | 64 | OrOr, // || |
| 60 | Percent, // % | 65 | Percent, // % |
| 61 | Plus, // + | 66 | Plus, // + |
| 62 | RightArrow, // -> | 67 | MinusLt, // -> |
| 63 | Semicolon, // ; | 68 | Semicolon, // ; |
| 64 | Slash, // / | 69 | Slash, // / |
| 65 | Star, // * | 70 | Star, // * |
| ... | @@ -86,13 +91,18 @@ impl std::fmt::Display for TokenType { | ... | @@ -86,13 +91,18 @@ impl std::fmt::Display for TokenType { |
| 86 | TokenType::Comment(_) => "comment".to_string(), | 91 | TokenType::Comment(_) => "comment".to_string(), |
| 87 | TokenType::DocComment(_) => "documentation comment".to_string(), | 92 | TokenType::DocComment(_) => "documentation comment".to_string(), |
| 88 | 93 | ||
| 94 | TokenType::Defer => "defer".to_string(), | ||
| 89 | TokenType::Else => "else".to_string(), | 95 | TokenType::Else => "else".to_string(), |
| 96 | TokenType::Enum => "enum".to_string(), | ||
| 90 | TokenType::False => "false".to_string(), | 97 | TokenType::False => "false".to_string(), |
| 91 | TokenType::Fn => "fn".to_string(), | 98 | TokenType::Fn => "fn".to_string(), |
| 92 | TokenType::If => "if".to_string(), | 99 | TokenType::If => "if".to_string(), |
| 100 | TokenType::Impl => "impl".to_string(), | ||
| 93 | TokenType::Let => "let".to_string(), | 101 | TokenType::Let => "let".to_string(), |
| 94 | TokenType::Pub => "pub".to_string(), | 102 | TokenType::Pub => "pub".to_string(), |
| 95 | TokenType::Return => "return".to_string(), | 103 | TokenType::Return => "return".to_string(), |
| 104 | TokenType::Struct => "struct".to_string(), | ||
| 105 | TokenType::Trait => "trait".to_string(), | ||
| 96 | TokenType::True => "true".to_string(), | 106 | TokenType::True => "true".to_string(), |
| 97 | TokenType::Var => "var".to_string(), | 107 | TokenType::Var => "var".to_string(), |
| 98 | TokenType::Void => "void".to_string(), | 108 | TokenType::Void => "void".to_string(), |
| ... | @@ -101,7 +111,7 @@ impl std::fmt::Display for TokenType { | ... | @@ -101,7 +111,7 @@ impl std::fmt::Display for TokenType { |
| 101 | TokenType::AndAnd => "&&".to_string(), | 111 | TokenType::AndAnd => "&&".to_string(), |
| 102 | TokenType::Bang => "!".to_string(), | 112 | TokenType::Bang => "!".to_string(), |
| 103 | TokenType::BangEqual => "!=".to_string(), | 113 | TokenType::BangEqual => "!=".to_string(), |
| 104 | TokenType::BigRightArrow => "=>".to_string(), | 114 | TokenType::EqualLt => "=>".to_string(), |
| 105 | TokenType::Caret => "^".to_string(), | 115 | TokenType::Caret => "^".to_string(), |
| 106 | TokenType::ClosedBrace => "}".to_string(), | 116 | TokenType::ClosedBrace => "}".to_string(), |
| 107 | TokenType::ClosedBracket => "]".to_string(), | 117 | TokenType::ClosedBracket => "]".to_string(), |
| ... | @@ -126,7 +136,7 @@ impl std::fmt::Display for TokenType { | ... | @@ -126,7 +136,7 @@ impl std::fmt::Display for TokenType { |
| 126 | TokenType::OrOr => "||".to_string(), | 136 | TokenType::OrOr => "||".to_string(), |
| 127 | TokenType::Percent => "%".to_string(), | 137 | TokenType::Percent => "%".to_string(), |
| 128 | TokenType::Plus => "+".to_string(), | 138 | TokenType::Plus => "+".to_string(), |
| 129 | TokenType::RightArrow => "->".to_string(), | 139 | TokenType::MinusLt => "->".to_string(), |
| 130 | TokenType::Semicolon => ";".to_string(), | 140 | TokenType::Semicolon => ";".to_string(), |
| 131 | TokenType::Slash => "/".to_string(), | 141 | TokenType::Slash => "/".to_string(), |
| 132 | TokenType::Star => "*".to_string(), | 142 | TokenType::Star => "*".to_string(), |
| ... | @@ -183,13 +193,18 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> { | ... | @@ -183,13 +193,18 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> { |
| 183 | let length = current_token.len(); | 193 | let length = current_token.len(); |
| 184 | 194 | ||
| 185 | let variant = match current_token.as_str() { | 195 | let variant = match current_token.as_str() { |
| 196 | "defer" => TokenType::Defer, | ||
| 186 | "else" => TokenType::Else, | 197 | "else" => TokenType::Else, |
| 198 | "enum" => TokenType::Enum, | ||
| 187 | "false" => TokenType::False, | 199 | "false" => TokenType::False, |
| 188 | "fn" => TokenType::Fn, | 200 | "fn" => TokenType::Fn, |
| 189 | "if" => TokenType::If, | 201 | "if" => TokenType::If, |
| 202 | "impl" => TokenType::Impl, | ||
| 190 | "let" => TokenType::Let, | 203 | "let" => TokenType::Let, |
| 191 | "pub" => TokenType::Pub, | 204 | "pub" => TokenType::Pub, |
| 192 | "return" => TokenType::Return, | 205 | "return" => TokenType::Return, |
| 206 | "struct" => TokenType::Struct, | ||
| 207 | "trait" => TokenType::Trait, | ||
| 193 | "true" => TokenType::True, | 208 | "true" => TokenType::True, |
| 194 | "var" => TokenType::Var, | 209 | "var" => TokenType::Var, |
| 195 | "void" => TokenType::Void, | 210 | "void" => TokenType::Void, |
| ... | @@ -250,7 +265,7 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> { | ... | @@ -250,7 +265,7 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> { |
| 250 | } | 265 | } |
| 251 | Some((_, '>')) => { | 266 | Some((_, '>')) => { |
| 252 | chars.next(); | 267 | chars.next(); |
| 253 | Token::new(TokenType::BigRightArrow, start, 2) | 268 | Token::new(TokenType::EqualLt, start, 2) |
| 254 | } | 269 | } |
| 255 | _ => Token::new(TokenType::Equal, start, 1), | 270 | _ => Token::new(TokenType::Equal, start, 1), |
| 256 | }, | 271 | }, |
| ... | @@ -287,7 +302,7 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> { | ... | @@ -287,7 +302,7 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> { |
| 287 | '-' => match chars.peek() { | 302 | '-' => match chars.peek() { |
| 288 | Some((_, '>')) => { | 303 | Some((_, '>')) => { |
| 289 | chars.next(); | 304 | chars.next(); |
| 290 | Token::new(TokenType::RightArrow, start, 2) | 305 | Token::new(TokenType::MinusLt, start, 2) |
| 291 | } | 306 | } |
| 292 | _ => Token::new(TokenType::Minus, start, 1), | 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 | } | ||