authorgravatar for me@paperdave.netdave caruso <me@paperdave.net> 2024-02-02 22:30:49-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-02-02 22:30:49-08:00
logf7fcc6aa17b5528e2cecce40d36fd37840f80dd1
tree53bb8692a45fd848c0677a61378cf91d9e177757
parentb417db0d1e1f2ce026092e1b310e2c98e7de265f
signature Signed by PGP key B5690EEEBB952194

chore: rename tokenizer::Loc -> log::Range (#15)


34 files changed, 362 insertions(+), 255 deletions(-)

Cargo.lock+80-2
......@@ -69,6 +69,7 @@ dependencies = [
6969name = "ast"
7070version = "0.1.0"
7171dependencies = [
72 "log",
7273 "miette",
7374 "num",
7475 "thiserror",
......@@ -174,6 +175,7 @@ dependencies = [
174175 "clap",
175176 "js_ast",
176177 "js_printer",
178 "log",
177179 "miette",
178180 "parser",
179181 "sema",
......@@ -197,6 +199,15 @@ dependencies = [
197199 "windows-sys",
198200]
199201
202[[package]]
203name = "form_urlencoded"
204version = "1.2.1"
205source = "registry+https://github.com/rust-lang/crates.io-index"
206checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
207dependencies = [
208 "percent-encoding",
209]
210
200211[[package]]
201212name = "gimli"
202213version = "0.28.1"
......@@ -215,6 +226,16 @@ version = "0.3.3"
215226source = "registry+https://github.com/rust-lang/crates.io-index"
216227checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
217228
229[[package]]
230name = "idna"
231version = "0.5.0"
232source = "registry+https://github.com/rust-lang/crates.io-index"
233checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
234dependencies = [
235 "unicode-bidi",
236 "unicode-normalization",
237]
238
218239[[package]]
219240name = "is-terminal"
220241version = "0.4.10"
......@@ -237,11 +258,10 @@ name = "js_ast"
237258version = "0.1.0"
238259dependencies = [
239260 "ast",
261 "log",
240262 "miette",
241263 "num",
242 "parser",
243264 "thiserror",
244 "tokenizer",
245265]
246266
247267[[package]]
......@@ -266,6 +286,15 @@ version = "0.4.12"
266286source = "registry+https://github.com/rust-lang/crates.io-index"
267287checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
268288
289[[package]]
290name = "log"
291version = "0.0.0"
292dependencies = [
293 "miette",
294 "thiserror",
295 "url",
296]
297
269298[[package]]
270299name = "memchr"
271300version = "2.7.1"
......@@ -415,12 +444,19 @@ name = "parser"
415444version = "0.1.0"
416445dependencies = [
417446 "ast",
447 "log",
418448 "miette",
419449 "num",
420450 "thiserror",
421451 "tokenizer",
422452]
423453
454[[package]]
455name = "percent-encoding"
456version = "2.3.1"
457source = "registry+https://github.com/rust-lang/crates.io-index"
458checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
459
424460[[package]]
425461name = "proc-macro2"
426462version = "1.0.76"
......@@ -560,14 +596,36 @@ dependencies = [
560596 "syn",
561597]
562598
599[[package]]
600name = "tinyvec"
601version = "1.6.0"
602source = "registry+https://github.com/rust-lang/crates.io-index"
603checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
604dependencies = [
605 "tinyvec_macros",
606]
607
608[[package]]
609name = "tinyvec_macros"
610version = "0.1.1"
611source = "registry+https://github.com/rust-lang/crates.io-index"
612checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
613
563614[[package]]
564615name = "tokenizer"
565616version = "0.1.0"
566617dependencies = [
618 "log",
567619 "miette",
568620 "thiserror",
569621]
570622
623[[package]]
624name = "unicode-bidi"
625version = "0.3.15"
626source = "registry+https://github.com/rust-lang/crates.io-index"
627checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
628
571629[[package]]
572630name = "unicode-ident"
573631version = "1.0.12"
......@@ -580,12 +638,32 @@ version = "0.1.5"
580638source = "registry+https://github.com/rust-lang/crates.io-index"
581639checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
582640
641[[package]]
642name = "unicode-normalization"
643version = "0.1.22"
644source = "registry+https://github.com/rust-lang/crates.io-index"
645checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
646dependencies = [
647 "tinyvec",
648]
649
583650[[package]]
584651name = "unicode-width"
585652version = "0.1.11"
586653source = "registry+https://github.com/rust-lang/crates.io-index"
587654checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
588655
656[[package]]
657name = "url"
658version = "2.5.0"
659source = "registry+https://github.com/rust-lang/crates.io-index"
660checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
661dependencies = [
662 "form_urlencoded",
663 "idna",
664 "percent-encoding",
665]
666
589667[[package]]
590668name = "utf8parse"
591669version = "0.2.1"
Cargo.toml+3-1
......@@ -9,11 +9,12 @@ repository = "https://github.com/lino-levan/blight"
99resolver = "2"
1010members = [
1111 "crates/ast",
12 "crates/sema",
1312 "crates/cli",
1413 "crates/js_ast",
1514 "crates/js_printer",
15 "crates/log",
1616 "crates/parser",
17 "crates/sema",
1718 "crates/tokenizer",
1819]
1920
......@@ -22,3 +23,4 @@ clap = { version = "4.4.12", features = ["derive"] }
2223miette = { version = "5.10.0", features = ["fancy"] }
2324thiserror = "1.0.53"
2425num = "0.4.1"
26url = "2.2.2"
crates/ast/Cargo.toml+2-1
......@@ -11,4 +11,5 @@ miette.workspace = true
1111thiserror.workspace = true
1212num.workspace = true
1313
14tokenizer = { path = "../tokenizer" }
14tokenizer = { path = "../tokenizer" } # Do not depend on the tokenizer
15log = { path = "../log" }
crates/ast/ast.rs+19-17
......@@ -1,9 +1,7 @@
1use tokenizer::Loc;
1use log::Range;
22
3use crate::{
4 types::{Literal, Type},
5 BinaryOperator, UnaryOperator,
6};
3use crate::types::{Literal, Type};
4use crate::{BinaryOperator, UnaryOperator};
75
86#[derive(Debug, Clone)]
97pub enum BuiltinId {
......@@ -36,7 +34,7 @@ pub struct VarDecl {
3634 pub init: Expr,
3735 pub is_constant: bool,
3836 pub is_pub: bool,
39 pub loc: Loc,
37 pub range: Range,
4038 pub comment: Option<DocComment>,
4139}
4240
......@@ -47,27 +45,31 @@ pub struct FnDecl {
4745 pub params: Vec<Param>,
4846 pub body: Expr,
4947 pub is_pub: bool,
50 pub loc: Loc,
48 pub range: Range,
5149 pub comment: Option<DocComment>,
5250}
5351
5452#[derive(Debug, Clone)]
5553pub struct Expr {
5654 pub data: ExprData,
57 pub loc: Loc,
55 pub range: Range,
5856 pub comment: Option<Comment>,
5957}
6058
6159impl Expr {
62 pub fn new(data: ExprData, loc: Loc, comment: Option<Comment>) -> Self {
63 Self { data, loc, comment }
60 pub fn new(data: ExprData, range: Range, comment: Option<Comment>) -> Self {
61 Self {
62 data,
63 range,
64 comment,
65 }
6466 }
6567}
6668
6769#[derive(Debug, Clone)]
6870pub struct DocComment {
6971 pub data: String,
70 pub loc: Loc,
72 pub range: Range,
7173}
7274
7375#[derive(Debug, PartialEq, Clone)]
......@@ -86,10 +88,10 @@ impl Comment {
8688 result
8789 }
8890
89 pub fn to_doc_comment(self, loc: Loc) -> DocComment {
91 pub fn to_doc_comment(self, range: Range) -> DocComment {
9092 DocComment {
9193 data: self.data,
92 loc,
94 range,
9395 }
9496 }
9597}
......@@ -113,21 +115,21 @@ impl DocComment {
113115}
114116
115117#[derive(Debug, Clone)]
116pub struct BlockWithLoc {
118pub struct BlockWithRange {
117119 pub block: Block,
118 pub loc: Loc,
120 pub range: Range,
119121}
120122
121123#[derive(Debug, Clone)]
122124pub struct If {
123125 pub condition: Box<Expr>,
124 pub yes: BlockWithLoc,
126 pub yes: BlockWithRange,
125127 pub no: Option<BlockOrIf>,
126128}
127129
128130#[derive(Debug, Clone)]
129131pub enum BlockOrIf {
130 Block(BlockWithLoc),
132 Block(BlockWithRange),
131133 If(Box<If>),
132134}
133135
crates/ast/types.rs-74
......@@ -120,80 +120,6 @@ pub fn merge_types(a: Type, b: Type) -> Result<Type> {
120120 Err(TypeError::new(format!("TODO: Implement type merging for {} and {}", a, b)).into())
121121}
122122
123// pub fn coerce_type(target: Type, source: Type) -> Result<Type> {
124// match source {
125// Type::Any => return Ok(target),
126// _ => {}
127// }
128// match target {
129// Type::Infer => Ok(source),
130// Type::Any => Ok(Type::Any),
131
132// Type::Literal(_) => unreachable!(),
133
134// Type::Int => match source {
135// Type::Int => Ok(Type::Int),
136// Type::Float => Ok(Type::Int),
137// Type::Literal(value) => {
138// if value.fract() != 0.0 {
139// Err(
140// TypeError::new(format!("Numeric Literal '{}' is not an integer", value))
141// .into(),
142// )
143// } else if value > i32::MAX.into() || value < i32::MIN.into() {
144// Err(TypeError::new(format!(
145// "Numeric Literal '{}' is out of range for an integer ({}..{})",
146// value,
147// i32::MIN,
148// i32::MAX
149// ))
150// .into())
151// } else {
152// Ok(Type::Int)
153// }
154// }
155// t => Err(TypeError::new(format!("Cannot coerce {} to int", t)).into()),
156// },
157
158// Type::BigInt => match source {
159// Type::Int => Ok(Type::Int),
160// Type::Float => Ok(Type::Int),
161// Type::NumberLiteral(value) => {
162// if value.fract() != 0.0 {
163// Err(
164// TypeError::new(format!("Numeric Literal '{}' is not an integer", value))
165// .into(),
166// )
167// } else {
168// Ok(Type::BigInt)
169// }
170// }
171// t => Err(TypeError::new(format!("Cannot coerce {} to int", t)).into()),
172// },
173
174// Type::Float => match source {
175// Type::Int => Ok(Type::Float),
176// Type::Float => Ok(Type::Float),
177// Type::NumberLiteral(value) => {
178// if value.fract() == 0.0 && value <= f64::MAX.into() && value >= f64::MIN.into() {
179// Ok(Type::Float)
180// } else {
181// Err(TypeError::new(format!("Numeric Literal")).into())
182// }
183// }
184// _ => Err(TypeError::new(format!("Cannot coerce int to float")).into()),
185// },
186
187// other => {
188// if other == source {
189// Ok(other)
190// } else {
191// Err(TypeError::new(format!("Cannot coerce {} to {}", source, other)).into())
192// }
193// }
194// }
195// }
196
197123#[derive(Error, Diagnostic, Debug)]
198124#[error("TypeError")]
199125pub struct TypeError {
crates/cli/Cargo.toml+1
......@@ -18,3 +18,4 @@ parser = { path = "../parser" }
1818js_ast = { path = "../js_ast" }
1919js_printer = { path = "../js_printer" }
2020sema = { path = "../sema" }
21log = { path = "../log" }
crates/js_ast/Cargo.toml+1-2
......@@ -12,5 +12,4 @@ thiserror.workspace = true
1212num.workspace = true
1313
1414ast = { path = "../ast" }
15tokenizer = { path = "../tokenizer" } # TODO: move Loc out of the tokenizer
16parser = { path = "../parser" } # TODO: move Loc out of the tokenizer
15log = { path = "../log" }
crates/js_ast/convert/block_convert_context.rs+8-8
......@@ -1,8 +1,8 @@
11use crate::js_ast::*;
22use ast::*;
3use log::Range;
34use std::collections::{HashMap, HashSet};
45use std::vec;
5use tokenizer::Loc;
66
77use super::tree_shake_statement_list;
88
......@@ -198,33 +198,33 @@ impl BlockConvertContext {
198198 }
199199}
200200
201pub fn new_js_assignment_statement(expr: JsExpr, target: String, loc: Loc) -> JsStatement {
201pub fn new_js_assignment_statement(expr: JsExpr, target: String, range: Range) -> JsStatement {
202202 JsStatement::new(
203 JsStatementData::Expression(new_js_assignment_expr(expr, target, loc.clone())),
204 loc,
203 JsStatementData::Expression(new_js_assignment_expr(expr, target, range.clone())),
204 range,
205205 None,
206206 )
207207}
208208
209pub fn new_js_assignment_expr(expr: JsExpr, target: String, loc: Loc) -> JsExpr {
209pub fn new_js_assignment_expr(expr: JsExpr, target: String, range: Range) -> JsExpr {
210210 JsExpr::new(
211211 JsExprData::Binary {
212212 op: BinaryOperator::Assign,
213213 left: Box::new(JsExpr::new(
214214 JsExprData::Identifier(target),
215 loc.clone(),
215 range.clone(),
216216 None,
217217 )),
218218 right: Box::new(expr),
219219 },
220 loc,
220 range,
221221 None,
222222 )
223223}
224224
225225impl Into<JsBlock> for BlockConvertContext {
226226 fn into(self) -> JsBlock {
227 JsBlock::new(self.into(), Loc::EMPTY)
227 JsBlock::new(self.into(), Range::EMPTY)
228228 }
229229}
230230
crates/js_ast/convert/convert_valid_block.rs+6-7
......@@ -3,18 +3,18 @@ use super::BlockConvertContext;
33use super::IsValidJSExpression;
44use crate::js_ast::*;
55use ast::*;
6use tokenizer::Loc;
6use log::Range;
77
8pub fn convert_valid_block(ctx: &mut BlockConvertContext, block: Block, loc: Loc) -> JsExpr {
8pub fn convert_valid_block(ctx: &mut BlockConvertContext, block: Block, range: Range) -> JsExpr {
99 debug_assert!(
1010 block.is_valid_js_expression(),
1111 "must call convert_valid_block with valid js expression"
1212 );
1313
1414 let len = block.statements.len();
15 let loc = loc;
15 let range = range;
1616 let block_expr = match len {
17 0 => JsExpr::new(JsExprData::Null, loc.clone(), None),
17 0 => JsExpr::new(JsExprData::Null, range.clone(), None),
1818 // a block expression with a single expression is just that expression
1919 1 => convert_valid_statement_to_expr(ctx, block.statements.into_iter().next().unwrap()),
2020 // Since blocks are not valid expressions in JS, we create a
......@@ -24,14 +24,13 @@ pub fn convert_valid_block(ctx: &mut BlockConvertContext, block: Block, loc: Loc
2424 for statement in block.statements.into_iter() {
2525 items.push(convert_valid_statement_to_expr(ctx, statement));
2626 }
27 JsExpr::new(JsExprData::Comma { items }, loc.clone(), None)
27 JsExpr::new(JsExprData::Comma { items }, range.clone(), None)
2828 }
29 _ => todo!(),
3029 };
3130
3231 // a block without implicit return is to be type void, so we wrap in a void expression
3332 if !block.has_implicit_return && len > 0 {
34 JsExpr::new(JsExprData::Void(Box::new(block_expr)), loc, None)
33 JsExpr::new(JsExprData::Void(Box::new(block_expr)), range, None)
3534 } else {
3635 block_expr
3736 }
crates/js_ast/convert/convert_valid_expr.rs+14-14
......@@ -16,28 +16,28 @@ pub fn convert_valid_expr(ctx: &mut BlockConvertContext, expr: Expr) -> JsExpr {
1616 "must call convert_valid_expr with valid js expression (use hoist instead)"
1717 );
1818
19 let loc = expr.loc;
19 let range = expr.range;
2020 let comment = expr.comment;
2121
2222 match expr.data {
2323 ExprData::Identifier(str) => JsExpr::new(
2424 JsExprData::Identifier(ctx.remap_identifier(&str)),
25 loc,
25 range,
2626 comment,
2727 ),
2828
2929 ExprData::Literal(Literal::Bool(value)) => {
30 JsExpr::new(JsExprData::Bool(value), loc, comment)
30 JsExpr::new(JsExprData::Bool(value), range, comment)
3131 }
3232 ExprData::Literal(Literal::Number(value)) => {
33 JsExpr::new(JsExprData::Number(value), loc, comment)
33 JsExpr::new(JsExprData::Number(value), range, comment)
3434 }
3535 ExprData::Literal(Literal::String(value)) => {
36 JsExpr::new(JsExprData::String(value), loc, comment)
36 JsExpr::new(JsExprData::String(value), range, comment)
3737 }
38 ExprData::Literal(Literal::Void) => JsExpr::new(JsExprData::Null, loc, comment),
38 ExprData::Literal(Literal::Void) => JsExpr::new(JsExprData::Null, range, comment),
3939
40 ExprData::Block(block) => convert_valid_block(ctx, block, loc),
40 ExprData::Block(block) => convert_valid_block(ctx, block, range),
4141
4242 ExprData::Binary { op, left, right } => {
4343 let left = convert_valid_expr(ctx, *left);
......@@ -48,7 +48,7 @@ pub fn convert_valid_expr(ctx: &mut BlockConvertContext, expr: Expr) -> JsExpr {
4848 left: Box::new(left),
4949 right: Box::new(right),
5050 },
51 loc,
51 range,
5252 comment,
5353 )
5454 }
......@@ -59,12 +59,12 @@ pub fn convert_valid_expr(ctx: &mut BlockConvertContext, expr: Expr) -> JsExpr {
5959 op,
6060 value: Box::new(value),
6161 },
62 loc,
62 range,
6363 comment,
6464 )
6565 }
6666 ExprData::Fn { body, params, .. } => {
67 process_function_to_arrow(ctx, *body, params, loc, comment)
67 process_function_to_arrow(ctx, *body, params, range, comment)
6868 }
6969 ExprData::Builtin { id, arguments } => match id {
7070 BuiltinId::Raw => {
......@@ -74,10 +74,10 @@ pub fn convert_valid_expr(ctx: &mut BlockConvertContext, expr: Expr) -> JsExpr {
7474 ExprData::Literal(Literal::String(s)) => s,
7575 _ => panic!("raw expects a string"),
7676 };
77 JsExpr::new(JsExprData::Raw(str), loc, comment)
77 JsExpr::new(JsExprData::Raw(str), range, comment)
7878 }
7979 },
80 ExprData::If(expr) => convert_valid_if(ctx, expr, loc, comment),
80 ExprData::If(expr) => convert_valid_if(ctx, expr, range, comment),
8181
8282 ExprData::Call { base, arguments } => {
8383 let base = convert_valid_expr(ctx, *base);
......@@ -90,7 +90,7 @@ pub fn convert_valid_expr(ctx: &mut BlockConvertContext, expr: Expr) -> JsExpr {
9090 base: Box::new(base),
9191 arguments,
9292 },
93 loc,
93 range,
9494 comment,
9595 )
9696 }
......@@ -106,7 +106,7 @@ pub fn convert_valid_expr(ctx: &mut BlockConvertContext, expr: Expr) -> JsExpr {
106106 index: Box::new(convert_valid_expr(ctx, *field)),
107107 },
108108 },
109 loc,
109 range,
110110 comment,
111111 ),
112112
crates/js_ast/convert/convert_valid_if.rs+6-6
......@@ -4,13 +4,13 @@ use super::BlockConvertContext;
44use crate::convert::IsValidJSExpression;
55use crate::js_ast::*;
66use ast::*;
7use tokenizer::Loc;
7use log::Range;
88
99/// Convert a valid blight if statement to a JS expression
1010pub fn convert_valid_if(
1111 ctx: &mut BlockConvertContext,
1212 expr: If,
13 loc: Loc,
13 range: Range,
1414 comment: Option<Comment>,
1515) -> JsExpr {
1616 debug_assert!(
......@@ -19,10 +19,10 @@ pub fn convert_valid_if(
1919 );
2020 let condition = convert_valid_expr(ctx, *expr.condition);
2121
22 let yes = convert_valid_block(ctx, expr.yes.block, expr.yes.loc);
22 let yes = convert_valid_block(ctx, expr.yes.block, expr.yes.range);
2323 let no = match expr.no {
24 Some(BlockOrIf::Block(b)) => Some(convert_valid_block(ctx, b.block, b.loc)),
25 Some(BlockOrIf::If(else_if)) => Some(convert_valid_if(ctx, *else_if, Loc::EMPTY, None)),
24 Some(BlockOrIf::Block(b)) => Some(convert_valid_block(ctx, b.block, b.range)),
25 Some(BlockOrIf::If(else_if)) => Some(convert_valid_if(ctx, *else_if, Range::EMPTY, None)),
2626 None => None,
2727 };
2828
......@@ -32,7 +32,7 @@ pub fn convert_valid_if(
3232 yes: Box::new(yes),
3333 no: no.map(Box::new),
3434 },
35 loc,
35 range,
3636 comment,
3737 )
3838}
crates/js_ast/convert/convert_valid_statement.rs+2-2
......@@ -27,6 +27,6 @@ pub fn convert_valid_statement_to_expr(
2727/// TODO(@paperdave): Replace this with Into<JsStatement> for JsExpr
2828pub fn convert_valid_statement(ctx: &mut BlockConvertContext, statement: Statement) -> JsStatement {
2929 let expr = convert_valid_statement_to_expr(ctx, statement);
30 let loc = expr.loc.clone();
31 JsStatement::new(JsStatementData::Expression(expr), loc, None)
30 let range = expr.range.clone();
31 JsStatement::new(JsStatementData::Expression(expr), range, None)
3232}
crates/js_ast/convert/hoist_block_to_expr.rs+5-5
......@@ -3,7 +3,7 @@ use super::process_statement;
33use super::BlockConvertContext;
44use crate::js_ast::*;
55use ast::*;
6use tokenizer::Loc;
6use log::Range;
77
88/// This block hoist is used when we have a block in an expression context.
99///
......@@ -30,7 +30,7 @@ use tokenizer::Loc;
3030pub fn hoist_block_to_expr(
3131 ctx: &mut BlockConvertContext,
3232 block: Block,
33 loc: Loc,
33 range: Range,
3434 comment: Option<Comment>,
3535) -> Option<JsExpr> {
3636 debug_assert!(
......@@ -57,7 +57,7 @@ pub fn hoist_block_to_expr(
5757 _ => unreachable!(),
5858 }
5959 }
60 _ => JsExpr::new(JsExprData::Null, loc.clone(), None),
60 _ => JsExpr::new(JsExprData::Null, range.clone(), None),
6161 };
6262
6363 ctx.add_statement(JsStatement::new(
......@@ -66,13 +66,13 @@ pub fn hoist_block_to_expr(
6666 init: Some(result),
6767 is_constant: false,
6868 }),
69 loc.clone(),
69 range.clone(),
7070 comment,
7171 ));
7272
7373 Some(JsExpr::new(
7474 JsExprData::Identifier(temporary.get(&ctx)),
75 loc,
75 range,
7676 None,
7777 ))
7878}
crates/js_ast/convert/hoist_block_to_js_block.rs+6-6
......@@ -1,6 +1,6 @@
11use crate::js_ast::*;
22use ast::*;
3use tokenizer::Loc;
3use log::Range;
44
55use super::*;
66
......@@ -22,7 +22,7 @@ use super::*;
2222pub fn hoist_block_to_js_block(
2323 ctx: &mut BlockConvertContext,
2424 block: Block,
25 loc: Loc,
25 range: Range,
2626 target: &TempId,
2727 did_assign: &mut bool,
2828) -> JsBlock {
......@@ -34,11 +34,11 @@ pub fn hoist_block_to_js_block(
3434 if block.is_valid_js_expression() {
3535 return JsBlock::new(
3636 vec![new_js_assignment_statement(
37 convert_valid_block(ctx, block, loc.clone()),
37 convert_valid_block(ctx, block, range.clone()),
3838 target.get(ctx),
39 loc.clone(),
39 range.clone(),
4040 )],
41 loc,
41 range,
4242 );
4343 }
4444
......@@ -59,7 +59,7 @@ pub fn hoist_block_to_js_block(
5959 child.add_statement(new_js_assignment_statement(
6060 expr,
6161 target.get(ctx),
62 loc.clone(),
62 range.clone(),
6363 ));
6464 }
6565 _ => {}
crates/js_ast/convert/hoist_expr.rs+14-10
......@@ -18,7 +18,7 @@ pub fn hoist_expr_if_needed(ctx: &mut BlockConvertContext, expr: Expr) -> Option
1818 let init = hoist_expr_contents(ctx, expr)?;
1919
2020 let id = ctx.generate_temp_id("_");
21 let loc = init.loc.clone();
21 let range = init.range.clone();
2222
2323 ctx.add_statement(JsStatement::new(
2424 JsStatementData::Declaration(JSDeclaration {
......@@ -26,11 +26,15 @@ pub fn hoist_expr_if_needed(ctx: &mut BlockConvertContext, expr: Expr) -> Option
2626 init: Some(init),
2727 is_constant: true,
2828 }),
29 loc.clone(),
29 range.clone(),
3030 None,
3131 ));
3232
33 Some(JsExpr::new(JsExprData::Identifier(id.get(&ctx)), loc, None))
33 Some(JsExpr::new(
34 JsExprData::Identifier(id.get(&ctx)),
35 range,
36 None,
37 ))
3438}
3539
3640/// Returning `None` from this means that the expression is noreturn, and that
......@@ -51,7 +55,7 @@ pub fn hoist_expr_contents(ctx: &mut BlockConvertContext, expr: Expr) -> Option<
5155 left: Box::new(left),
5256 right: Box::new(right),
5357 },
54 expr.loc,
58 expr.range,
5559 expr.comment,
5660 ))
5761 }
......@@ -63,7 +67,7 @@ pub fn hoist_expr_contents(ctx: &mut BlockConvertContext, expr: Expr) -> Option<
6367 op,
6468 value: Box::new(value),
6569 },
66 expr.loc,
70 expr.range,
6771 expr.comment,
6872 ))
6973 }
......@@ -85,24 +89,24 @@ pub fn hoist_expr_contents(ctx: &mut BlockConvertContext, expr: Expr) -> Option<
8589 index: Box::new(field),
8690 },
8791 },
88 expr.loc,
92 expr.range,
8993 expr.comment,
9094 ))
9195 }
9296
93 ExprData::Block(block) => hoist_block_to_expr(ctx, block, expr.loc, expr.comment),
97 ExprData::Block(block) => hoist_block_to_expr(ctx, block, expr.range, expr.comment),
9498
9599 ExprData::If(_) => hoist_if_expr(ctx, expr),
96100
97101 ExprData::Return(maybe_expr) => {
98 let loc = expr.loc.clone();
102 let range = expr.range.clone();
99103 let return_value = match maybe_expr {
100104 Some(expr) => Some(hoist_expr_if_needed(ctx, *expr)?),
101105 None => None,
102106 };
103107 ctx.add_statement(JsStatement::new(
104108 JsStatementData::Return(return_value),
105 loc,
109 range,
106110 None,
107111 ));
108112 None
......@@ -120,7 +124,7 @@ pub fn hoist_expr_contents(ctx: &mut BlockConvertContext, expr: Expr) -> Option<
120124 base: Box::new(base),
121125 arguments,
122126 },
123 expr.loc,
127 expr.range,
124128 expr.comment,
125129 ))
126130 }
crates/js_ast/convert/hoist_if.rs+9-9
......@@ -6,7 +6,7 @@ use super::IsValidJSExpression;
66use super::TempId;
77use crate::js_ast::*;
88use ast::*;
9use tokenizer::Loc;
9use log::Range;
1010
1111pub fn hoist_if_expr(ctx: &mut BlockConvertContext, expr: Expr) -> Option<JsExpr> {
1212 let data = match expr.data {
......@@ -22,7 +22,7 @@ pub fn hoist_if_expr(ctx: &mut BlockConvertContext, expr: Expr) -> Option<JsExpr
2222 init: None,
2323 is_constant: false,
2424 }),
25 expr.loc.clone(),
25 expr.range.clone(),
2626 None,
2727 ));
2828
......@@ -40,35 +40,35 @@ pub fn hoist_if_expr(ctx: &mut BlockConvertContext, expr: Expr) -> Option<JsExpr
4040
4141 ctx.add_statement(JsStatement::new(
4242 JsStatementData::If(js_if),
43 expr.loc.clone(),
43 expr.range.clone(),
4444 None,
4545 ));
4646
4747 if did_assign {
4848 Some(JsExpr::new(
4949 JsExprData::Identifier(temporary.get(&ctx)),
50 expr.loc,
50 expr.range,
5151 expr.comment,
5252 ))
5353 } else {
5454 decl.delete(ctx);
55 Some(JsExpr::new(JsExprData::Null, expr.loc, expr.comment))
55 Some(JsExpr::new(JsExprData::Null, expr.range, expr.comment))
5656 }
5757}
5858
5959pub fn hoist_if_branch(
6060 ctx: &mut BlockConvertContext,
61 yes: BlockWithLoc,
61 yes: BlockWithRange,
6262 no: Option<BlockOrIf>,
6363 condition: JsExpr,
6464 did_assign: &mut bool,
6565 temporary: &TempId,
6666) -> JsIf {
67 let yes = hoist_block_to_js_block(ctx, yes.block, yes.loc, &temporary, did_assign);
67 let yes = hoist_block_to_js_block(ctx, yes.block, yes.range, &temporary, did_assign);
6868
6969 let no = match no {
7070 Some(BlockOrIf::Block(no)) => Some(JsElse::Block(hoist_block_to_js_block(
71 ctx, no.block, no.loc, &temporary, did_assign,
71 ctx, no.block, no.range, &temporary, did_assign,
7272 ))),
7373 Some(BlockOrIf::If(else_if)) => {
7474 // If the condition of this block has a side effect, we need to
......@@ -99,7 +99,7 @@ pub fn hoist_if_branch(
9999 did_assign,
100100 temporary,
101101 )),
102 Loc::EMPTY,
102 Range::EMPTY,
103103 None,
104104 ));
105105
crates/js_ast/convert/is_valid_js_expression.rs+1-1
......@@ -75,7 +75,7 @@ impl IsValidJSExpression for BlockOrIf {
7575 }
7676}
7777
78impl IsValidJSExpression for BlockWithLoc {
78impl IsValidJSExpression for BlockWithRange {
7979 fn is_valid_js_expression(&self) -> bool {
8080 self.block.is_valid_js_expression()
8181 }
crates/js_ast/convert/process_function.rs+5-5
......@@ -5,13 +5,13 @@ use super::BlockConvertContext;
55use super::IsValidJSExpression;
66use crate::js_ast::*;
77use ast::*;
8use tokenizer::Loc;
8use log::Range;
99
1010pub fn process_function_to_arrow(
1111 ctx: &mut BlockConvertContext,
1212 body: Expr,
1313 params: Vec<Param>,
14 loc: Loc,
14 range: Range,
1515 comment: Option<Comment>,
1616) -> JsExpr {
1717 // A block that is a valid expression will just become
......@@ -34,7 +34,7 @@ pub fn process_function_to_arrow(
3434 if let Some(expr) = child.take_last_statement_if_expr() {
3535 child.add_statement(JsStatement::new(
3636 JsStatementData::Return(Some(expr)),
37 loc.clone(),
37 range.clone(),
3838 None,
3939 ));
4040 }
......@@ -44,7 +44,7 @@ pub fn process_function_to_arrow(
4444 if let Some(expr) = hoist_expr_if_needed(&mut child, body) {
4545 child.add_statement(JsStatement::new(
4646 JsStatementData::Return(Some(expr)),
47 loc.clone(),
47 range.clone(),
4848 None,
4949 ));
5050 }
......@@ -59,7 +59,7 @@ pub fn process_function_to_arrow(
5959 params: params.into_iter().map(|x| x.name).collect(),
6060 body: Box::new(body),
6161 },
62 loc.clone(),
62 range.clone(),
6363 comment.map(|x| x.into()),
6464 )
6565}
crates/js_ast/convert/process_statement.rs+6-6
......@@ -35,7 +35,7 @@ pub fn process_statement(ctx: &mut BlockConvertContext, statement: Statement) ->
3535 } else {
3636 JsStatementData::Declaration(decl_data)
3737 },
38 decl.loc,
38 decl.range,
3939 decl.comment.map(|x| x.into()),
4040 );
4141
......@@ -45,10 +45,10 @@ pub fn process_statement(ctx: &mut BlockConvertContext, statement: Statement) ->
4545 }
4646 Statement::Expr(expr) => {
4747 if let Some(expr) = hoist_expr_contents(ctx, expr) {
48 let loc = expr.loc.clone();
48 let range = expr.range.clone();
4949 ctx.add_statement(JsStatement::new(
5050 JsStatementData::Expression(expr),
51 loc,
51 range,
5252 None,
5353 ));
5454 Some(())
......@@ -60,7 +60,7 @@ pub fn process_statement(ctx: &mut BlockConvertContext, statement: Statement) ->
6060 name,
6161 params,
6262 body,
63 loc,
63 range,
6464 comment,
6565 is_pub,
6666 ..
......@@ -71,7 +71,7 @@ pub fn process_statement(ctx: &mut BlockConvertContext, statement: Statement) ->
7171 ctx,
7272 body,
7373 params,
74 loc.clone(),
74 range.clone(),
7575 None,
7676 ));
7777
......@@ -87,7 +87,7 @@ pub fn process_statement(ctx: &mut BlockConvertContext, statement: Statement) ->
8787 } else {
8888 JsStatementData::Declaration(decl_data)
8989 },
90 loc,
90 range,
9191 comment.map(|x| x.into()),
9292 ));
9393
crates/js_ast/convert/side_effects.rs+1-1
......@@ -84,7 +84,7 @@ impl HasSideEffects for BlockOrIf {
8484 }
8585}
8686
87impl HasSideEffects for BlockWithLoc {
87impl HasSideEffects for BlockWithRange {
8888 fn has_side_effects(&self) -> bool {
8989 self.block.has_side_effects()
9090 }
crates/js_ast/js_ast.rs+18-10
......@@ -1,11 +1,11 @@
11use ast::{BinaryOperator, Comment, UnaryOperator};
2use log::Range;
23use num::bigint::BigInt;
3use tokenizer::Loc;
44
55#[derive(Debug, PartialEq, Clone)]
66pub struct JsExpr {
77 pub data: JsExprData,
8 pub loc: Loc,
8 pub range: Range,
99 pub comment: Option<Comment>,
1010}
1111
......@@ -74,7 +74,7 @@ pub enum JsExprData {
7474#[derive(Debug, PartialEq, Clone)]
7575pub struct JsStatement {
7676 pub data: JsStatementData,
77 pub loc: Loc,
77 pub range: Range,
7878 pub comment: Option<Comment>,
7979}
8080
......@@ -133,12 +133,16 @@ pub struct JSNamedExport {
133133#[derive(Debug, PartialEq, Clone)]
134134pub struct JsBlock {
135135 pub statements: Vec<JsStatement>,
136 pub loc: Loc,
136 pub range: Range,
137137}
138138
139139impl JsExpr {
140 pub fn new(data: JsExprData, loc: Loc, comment: Option<Comment>) -> Self {
141 Self { data, loc, comment }
140 pub fn new(data: JsExprData, range: Range, comment: Option<Comment>) -> Self {
141 Self {
142 data,
143 range,
144 comment,
145 }
142146 }
143147
144148 pub fn is_literal(&self) -> bool {
......@@ -167,14 +171,18 @@ impl JsExprData {
167171}
168172
169173impl JsBlock {
170 pub fn new(statements: Vec<JsStatement>, loc: Loc) -> Self {
171 Self { statements, loc }
174 pub fn new(statements: Vec<JsStatement>, range: Range) -> Self {
175 Self { statements, range }
172176 }
173177}
174178
175179impl JsStatement {
176 pub fn new(data: JsStatementData, loc: Loc, comment: Option<Comment>) -> Self {
177 Self { data, loc, comment }
180 pub fn new(data: JsStatementData, range: Range, comment: Option<Comment>) -> Self {
181 Self {
182 data,
183 range,
184 comment,
185 }
178186 }
179187}
180188
crates/log/Cargo.toml created+11
......@@ -0,0 +1,11 @@
1[package]
2name = "log"
3edition = "2021"
4
5[lib]
6path="./log.rs"
7
8[dependencies]
9miette.workspace = true
10thiserror.workspace = true
11url.workspace = true
crates/log/log.rs created+88
......@@ -0,0 +1,88 @@
1use std::{fs, path::Path, rc::Rc};
2
3use miette::{IntoDiagnostic, Result};
4use url::Url;
5
6#[derive(Debug, PartialEq, Clone, Copy)]
7pub struct Range {
8 pub start: usize,
9 pub length: usize,
10}
11
12impl Range {
13 /// TODO(@paperdave): Remove this. every usage of this is incorrect.
14 pub const EMPTY: Range = Range {
15 start: 0,
16 length: 0,
17 };
18
19 pub fn new(start: usize, length: usize) -> Self {
20 Self { start, length }
21 }
22
23 pub fn len(&self) -> usize {
24 self.length
25 }
26}
27
28// TODO(@lino-levan): make this loggable nicely
29#[derive(Debug, Clone)]
30pub struct Message<'a> {
31 pub source: &'a Source,
32 pub range: Range,
33 pub message: String,
34 pub notes: Vec<Note<'a>>,
35}
36
37#[derive(Debug, Clone)]
38pub struct Note<'a> {
39 pub location: Option<RangeAndSource<'a>>,
40 pub message: String,
41}
42
43#[derive(Debug, Clone)]
44pub struct RangeAndSource<'a> {
45 pub range: Range,
46 pub source: &'a Source,
47}
48
49#[derive(Debug)]
50pub struct Source {
51 pub url: Url,
52 pub code: String,
53}
54
55impl Source {
56 pub fn new(url: Url, source_code: String) -> Rc<Self> {
57 Rc::new(Source {
58 url,
59 code: source_code,
60 })
61 }
62
63 pub fn from_file(path: &Path) -> Result<Rc<Self>> {
64 let source_code = fs::read_to_string(path).into_diagnostic()?;
65 let url = Url::from_file_path(path).unwrap();
66 Ok(Rc::new(Source {
67 code: source_code,
68 url,
69 }))
70 }
71
72 pub fn from_url(url: Url) -> Result<Rc<Self>> {
73 match url.scheme() {
74 "file" => {
75 // TODO: how to return this error, into_diagnostic() doesn't exist
76 let file_path = url.to_file_path().unwrap();
77 let source_code = fs::read_to_string(file_path).into_diagnostic()?;
78 Ok(Rc::new(Source {
79 code: source_code,
80 url,
81 }))
82 }
83 _ => {
84 todo!("Fetch from URL: {}", url)
85 }
86 }
87 }
88}
crates/parser/Cargo.toml+1
......@@ -13,3 +13,4 @@ num.workspace = true
1313
1414ast = { path = "../ast" }
1515tokenizer = { path = "../tokenizer" }
16log = { path = "../log" }
crates/parser/parse_declaration.rs+3-2
......@@ -1,6 +1,7 @@
11use ast::{DocComment, Type, VarDecl};
2use log::Range;
23use miette::Result;
3use tokenizer::{Loc, TokenType};
4use tokenizer::TokenType;
45
56use crate::parse_expr::parse_expr;
67use crate::parse_type::parse_type;
......@@ -45,6 +46,6 @@ pub fn parse_declaration(
4546 is_constant,
4647 is_pub,
4748 comment,
48 loc: Loc::new(start, p.index - start),
49 range: Range::new(start, p.index - start),
4950 })
5051}
crates/parser/parse_doc_comment.rs+3-2
......@@ -1,5 +1,6 @@
11use ast::DocComment;
2use tokenizer::{Loc, TokenType};
2use log::Range;
3use tokenizer::TokenType;
34
45use crate::Parser;
56
......@@ -10,7 +11,7 @@ pub fn maybe_read_doc_comment(p: &mut Parser) -> Option<DocComment> {
1011 p.next();
1112 Some(DocComment {
1213 data,
13 loc: Loc::new(start, p.index - start),
14 range: Range::new(start, p.index - start),
1415 })
1516 }
1617 _ => None,
crates/parser/parse_expr.rs+2-2
......@@ -1,7 +1,7 @@
11use ast::Associativity::*;
22use ast::{BinaryOperator, Expr, ExprData, OperatorLevel};
3use log::Range;
34use miette::Result;
4use tokenizer::Loc;
55
66use crate::parse_expr_basic::parse_expr_basic;
77use crate::Parser;
......@@ -94,7 +94,7 @@ fn parse_expr_binary(
9494 left: Box::new(left),
9595 right: Box::new(right),
9696 },
97 Loc::new(start, p.index - start),
97 Range::new(start, p.index - start),
9898 None,
9999 ))
100100}
crates/parser/parse_expr_basic.rs+19-18
......@@ -1,6 +1,7 @@
11use ast::{BuiltinId, Expr, ExprData, Literal, UnaryOperator};
2use log::Range;
23use miette::Result;
3use tokenizer::{Loc, TokenType};
4use tokenizer::TokenType;
45
56use crate::{
67 parse_block::parse_block, parse_call_arguments::parse_call_arguments, parse_expr::parse_expr,
......@@ -15,7 +16,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
1516 _ = p.next();
1617 Expr::new(
1718 ExprData::Literal(Literal::Number(number.clone())),
18 Loc::new(start, p.index - start),
19 Range::new(start, p.index - start),
1920 comments,
2021 )
2122 }
......@@ -23,7 +24,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
2324 _ = p.next();
2425 Expr::new(
2526 ExprData::Literal(Literal::String(string.clone())),
26 Loc::new(start, p.index - start),
27 Range::new(start, p.index - start),
2728 comments,
2829 )
2930 }
......@@ -31,7 +32,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
3132 _ = p.next();
3233 Expr::new(
3334 ExprData::Literal(Literal::Bool(true)),
34 Loc::new(start, p.index - start),
35 Range::new(start, p.index - start),
3536 comments,
3637 )
3738 }
......@@ -39,7 +40,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
3940 _ = p.next();
4041 Expr::new(
4142 ExprData::Literal(Literal::Bool(false)),
42 Loc::new(start, p.index - start),
43 Range::new(start, p.index - start),
4344 comments,
4445 )
4546 }
......@@ -47,7 +48,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
4748 _ = p.next();
4849 Expr::new(
4950 ExprData::Literal(Literal::Void),
50 Loc::new(start, p.index - start),
51 Range::new(start, p.index - start),
5152 comments,
5253 )
5354 }
......@@ -60,14 +61,14 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
6061 let arguments = parse_call_arguments(p)?;
6162 Expr::new(
6263 ExprData::Builtin { id, arguments },
63 Loc::new(identifier_start, p.index - identifier_start),
64 Range::new(identifier_start, p.index - identifier_start),
6465 comments,
6566 )
6667 } else {
6768 return Err(p
6869 .error_at(
6970 format!("Built-in function '{}' must be called", name),
70 Loc::new(identifier_start, p.index - identifier_start),
71 Range::new(identifier_start, p.index - identifier_start),
7172 )
7273 .into());
7374 }
......@@ -75,14 +76,14 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
7576 return Err(p
7677 .error_at(
7778 format!("Non-existant built-in: '{}'", name),
78 Loc::new(identifier_start, p.index - identifier_start),
79 Range::new(identifier_start, p.index - identifier_start),
7980 )
8081 .into());
8182 }
8283 } else {
8384 Expr::new(
8485 ExprData::Identifier(name),
85 Loc::new(identifier_start, p.index - identifier_start),
86 Range::new(identifier_start, p.index - identifier_start),
8687 comments,
8788 )
8889 }
......@@ -99,7 +100,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
99100
100101 return Ok(Some(Expr::new(
101102 ExprData::Return(inner),
102 Loc::new(start, p.index - start),
103 Range::new(start, p.index - start),
103104 comments,
104105 )));
105106 }
......@@ -107,13 +108,13 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
107108
108109 Some(TokenType::If) => Expr::new(
109110 ExprData::If(parse_expr_if(p)?),
110 Loc::new(start, p.index - start),
111 Range::new(start, p.index - start),
111112 comments,
112113 ),
113114
114115 Some(TokenType::OpenBrace) => Expr::new(
115116 ExprData::Block(parse_block(p)?),
116 Loc::new(start, p.index - start),
117 Range::new(start, p.index - start),
117118 comments,
118119 ),
119120
......@@ -142,7 +143,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
142143 },
143144 value: Box::new(parse_expr_basic(p)?),
144145 },
145 Loc::new(start, p.index - start),
146 Range::new(start, p.index - start),
146147 comments,
147148 )
148149 }
......@@ -162,7 +163,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
162163 p.next();
163164 Expr::new(
164165 ExprData::Literal(Literal::String(name)),
165 Loc::new(field_start, p.index - field_start),
166 Range::new(field_start, p.index - field_start),
166167 None,
167168 )
168169 }
......@@ -175,7 +176,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
175176 base: Box::new(expr),
176177 field: Box::new(field),
177178 },
178 Loc::new(field_start, p.index - field_start),
179 Range::new(field_start, p.index - field_start),
179180 None,
180181 );
181182 }
......@@ -188,7 +189,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
188189 base: Box::new(expr),
189190 arguments,
190191 },
191 Loc::new(expr_start, p.index - expr_start),
192 Range::new(expr_start, p.index - expr_start),
192193 None,
193194 );
194195 }
......@@ -202,7 +203,7 @@ pub fn maybe_parse_expr_basic(p: &mut Parser) -> Result<Option<Expr>> {
202203 base: Box::new(expr),
203204 field: Box::new(index),
204205 },
205 Loc::new(expr_start, p.index - expr_start),
206 Range::new(expr_start, p.index - expr_start),
206207 None,
207208 );
208209 } else {
crates/parser/parse_expr_if.rs+8-7
......@@ -1,6 +1,7 @@
1use ast::{BlockOrIf, BlockWithLoc, If};
1use ast::{BlockOrIf, BlockWithRange, If};
2use log::Range;
23use miette::Result;
3use tokenizer::{Loc, TokenType};
4use tokenizer::TokenType;
45
56use crate::parse_block::parse_block;
67use crate::parse_expr::parse_expr;
......@@ -30,9 +31,9 @@ pub fn parse_expr_if(p: &mut Parser) -> Result<If> {
3031 let yes = match p.peek() {
3132 Some(TokenType::OpenBrace) => {
3233 let block_start = p.index;
33 BlockWithLoc {
34 BlockWithRange {
3435 block: parse_block(p)?,
35 loc: Loc::new(block_start, p.index - block_start),
36 range: Range::new(block_start, p.index - block_start),
3637 }
3738 }
3839 _ => {
......@@ -49,14 +50,14 @@ pub fn parse_expr_if(p: &mut Parser) -> Result<If> {
4950 Some(TokenType::OpenBrace) => {
5051 let block_start = p.index;
5152 // let comments = p.take_comments();
52 Some(BlockOrIf::Block(BlockWithLoc {
53 Some(BlockOrIf::Block(BlockWithRange {
5354 block: parse_block(p)?,
54 loc: Loc::new(block_start, p.index - block_start),
55 range: Range::new(block_start, p.index - block_start),
5556 }))
5657 }
5758 Some(TokenType::If) => {
5859 // TODO(@paperdave): Save location for the if
59 // let loc = p.loc();
60 // let range = p.range();
6061 // let comments = p.take_comments();
6162 Some(BlockOrIf::If(Box::new(parse_expr_if(p)?)))
6263 }
crates/parser/parse_fn_declaration.rs+4-3
......@@ -1,6 +1,7 @@
11use ast::{DocComment, Expr, ExprData, FnDecl, Type};
2use log::Range;
23use miette::Result;
3use tokenizer::{Loc, TokenType};
4use tokenizer::TokenType;
45
56use crate::parse_block::parse_block;
67use crate::parse_expr::parse_expr;
......@@ -93,7 +94,7 @@ pub fn parse_fn_declaration(
9394 let block = parse_block(p)?;
9495 Expr::new(
9596 ExprData::Block(block),
96 Loc::new(block_start, p.index - block_start),
97 Range::new(block_start, p.index - block_start),
9798 None,
9899 )
99100 }
......@@ -121,6 +122,6 @@ pub fn parse_fn_declaration(
121122 body,
122123 is_pub,
123124 comment,
124 loc: Loc::new(start, p.index - start),
125 range: Range::new(start, p.index - start),
125126 })
126127}
crates/parser/parse_statement.rs+2-2
......@@ -18,7 +18,7 @@ pub fn parse_statement(p: &mut Parser) -> Result<Statement> {
1818 if p.has_comments() {
1919 // this implies that comments are immediately after the doc
2020 return Err(p
21 .error_at(format!("Unattached doc comment"), doc_comment.loc)
21 .error_at(format!("Unattached doc comment"), doc_comment.range)
2222 .into());
2323 }
2424 }
......@@ -58,7 +58,7 @@ pub fn parse_statement(p: &mut Parser) -> Result<Statement> {
5858 Some(_) => {
5959 if let Some(doc_comment) = m_doc_comment {
6060 Err(p
61 .error_at(format!("Unattached doc comment"), doc_comment.loc)
61 .error_at(format!("Unattached doc comment"), doc_comment.range)
6262 .into())
6363 } else {
6464 Ok(Statement::Expr(parse_expr(p)?))
crates/parser/parser.rs+8-7
......@@ -14,13 +14,14 @@ mod parse_type;
1414
1515use ast::Comment;
1616use ast::Module;
17use log::Range;
1718use miette::Diagnostic;
1819use miette::Result;
1920use parse_module::parse_module;
2021use thiserror::Error;
2122use tokenizer::tokenize;
23use tokenizer::Token;
2224use tokenizer::TokenType;
23use tokenizer::{Loc, Token};
2425
2526pub fn parse(tokens: Vec<Token>) -> Result<Module> {
2627 let mut p = Parser::new(tokens);
......@@ -37,12 +38,12 @@ pub fn parse_from_string(string: String) -> Result<Module> {
3738pub struct ParseError {
3839 #[help]
3940 error: String,
40 loc: Option<Loc>,
41 range: Option<Range>,
4142}
4243
4344impl ParseError {
44 pub fn new(error: String, loc: Option<Loc>) -> ParseError {
45 ParseError { error, loc }
45 pub fn new(error: String, range: Option<Range>) -> ParseError {
46 ParseError { error, range }
4647 }
4748}
4849
......@@ -89,7 +90,7 @@ impl Parser {
8990
9091 loop {
9192 let token = self.tokens[self.cursor].clone();
92 self.index = token.loc.start;
93 self.index = token.range.start;
9394 match token.variant {
9495 TokenType::Comment(comment) => {
9596 self.comments.push(comment);
......@@ -144,7 +145,7 @@ impl Parser {
144145 ParseError::new(error, None)
145146 }
146147
147 fn error_at(&self, error: String, loc: Loc) -> ParseError {
148 ParseError::new(error, Some(loc))
148 fn error_at(&self, error: String, range: Range) -> ParseError {
149 ParseError::new(error, Some(range))
149150 }
150151}
crates/tokenizer/Cargo.toml+2
......@@ -9,3 +9,5 @@ path="./tokenizer.rs"
99[dependencies]
1010miette.workspace = true
1111thiserror.workspace = true
12
13log = { path = "../log" }
crates/tokenizer/tokenizer.rs+4-25
......@@ -1,28 +1,7 @@
1use log::Range;
12use miette::{Diagnostic, Result};
23use thiserror::Error;
34
4#[derive(Debug, PartialEq, Clone)]
5pub struct Loc {
6 pub start: usize,
7 pub length: usize,
8}
9
10impl Loc {
11 /// TODO(@paperdave): Remove this. every usage of this is incorrect.
12 pub const EMPTY: Loc = Loc {
13 start: 0,
14 length: 0,
15 };
16
17 pub fn new(start: usize, length: usize) -> Self {
18 Self { start, length }
19 }
20
21 pub fn len(&self) -> usize {
22 self.length
23 }
24}
25
265#[derive(Error, Diagnostic, Debug)]
276#[error("UnknownCharacter")]
287struct UnknownCharacter {
......@@ -162,19 +141,19 @@ impl std::fmt::Display for TokenType {
162141#[derive(Debug, Clone)]
163142pub struct Token {
164143 pub variant: TokenType,
165 pub loc: Loc,
144 pub range: Range,
166145}
167146
168147impl Token {
169148 pub fn new(variant: TokenType, start: usize, length: usize) -> Self {
170149 Self {
171150 variant,
172 loc: Loc::new(start, length),
151 range: Range::new(start, length),
173152 }
174153 }
175154}
176155
177// TODO(@paperdave): rewrite this to not use a Vec<Token>. we probably dont need it. also store Loc
156// TODO(@paperdave): rewrite this to not use a Vec<Token>. we probably dont need it. also store Range
178157pub fn tokenize(content: String) -> Result<Vec<Token>> {
179158 let mut tokens: Vec<Token> = Vec::new();
180159 let mut chars = content.chars().enumerate().peekable();