authorchloe caruso <git@paperclover.net> 2024-02-04 10:10:09-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-02-04 10:10:09-08:00
logd0e4a653989fb012e7b7c01eebb76c655c3393a1
treed1875641207065e29bb81390922e43bef1b86585
parentaeeab025ce0b9698e869be9a04033dd327cb0ad0

chore: remove top level statement and add some new tokens (#18)

* chore: remove top level statement and add some more things * revisions

11 files changed, 60 insertions(+), 73 deletions(-)

Cargo.toml+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1[workspace.package]1[workspace.package]
2version = "0.1.0"2version = "0.1.0"
3edition = "2023"3edition = "2021"
4license = "MIT"4license = "MIT"
5authors = ["Lino Le Van", "Dave Caruso"]5authors = ["Lino Le Van", "Dave Caruso"]
6repository = "https://github.com/lino-levan/blight"6repository = "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)]
12pub struct Module {12pub struct Module {
13 pub comment: Option<DocComment>,13 pub comment: Option<DocComment>,
14 pub statements: Vec<TopLevelStatement>,14 pub statements: Vec<Statement>,
15}15}
1616
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}
179179
180#[derive(Debug, Clone)]
181pub enum TopLevelStatement {
182 Expr(Expr),
183 VarDecl(VarDecl),
184 FnDecl(FnDecl),
185 Comment(Comment),
186}
187
188impl BuiltinId {180impl 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}
202194
203impl Statement {195impl 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 sorry196 /// 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
230impl 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();
3636
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 }
4040
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
100pub 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 }
7979
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 @@
1use crate::parse_doc_comment::maybe_read_doc_comment;1use crate::parse_doc_comment::maybe_read_doc_comment;
2use crate::parse_top_level_statement::parse_top_level_statement;2use crate::parse_statement::parse_statement;
3use crate::Parser;3use crate::Parser;
4use ast::Module;4use ast::Module;
5use miette::Result;5use 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());
1717
18 let statement = parse_top_level_statement(p)?;18 let statement = parse_statement(p)?;
1919
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(p30 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(p79 Err(p
crates/parser/parse_top_level_statement.rs deleted-10
...@@ -1,10 +0,0 @@
1use ast::TopLevelStatement;
2use miette::Result;
3
4use crate::{parse_statement::parse_statement, Parser};
5
6/// Precondition: the next token exists
7pub 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;
9mod parse_module;9mod parse_module;
10mod parse_param;10mod parse_param;
11mod parse_statement;11mod parse_statement;
12mod parse_top_level_statement;
13mod parse_type;12mod parse_type;
1413
15use ast::Comment;14use 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 // Keywords21 // 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(),
8893
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();
184194
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 @@
1let 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}