定位

确定当前词法,语法范围,帮助后面进行错误提醒,比如以下这种。

Line 3:8: 'React' is defined but never used
{{#include ../src/range.rs:range}}

这里通过 #[dirvie] 进行包裹的是 rust 的指令宏,这里简单介绍下 rust 的宏。

macro_rules! say_hello { (console.log("hello world")) => { println!("hello world"); }; } fn main(){ say_hello!(console.log("hello world")); }

点击左上角的运行按钮,你会发现这代码竟然能运行,我很简单的就实现了一个一个 js 解释器。

他的魔法在于在编译期将你的代码进行了替换,可以在 rust playground 中看下他的宏展开。

你会发现你的代码被替换成下面这种,这种编译器做的拦截对运行时毫无影响。

#![feature(prelude_import)] #[prelude_import] use std::prelude::rust_2021::*; #[macro_use] extern crate std; macro_rules! say_hello { (console.log("hello world")) => { println! ("hello world") ; } ; } fn main() { { ::std::io::_print(::core::fmt::Arguments::new_v1(&["hello world\n"], &[])); }; ; }

相比于 js 的拦截器的实现高出很多。有点类似 svelte 的原理。

当然 rust 的宏并不是完美的,它带来的代价就是增加包体积,代码编译慢。

接下来,为Range添加 new 的创建方法

{{#include ../src/range.rs:impl}}

好啦本节就到此结束啦。

后面我们开始介绍词法解析器部分。