Skip to main content

atmos/os_lib/js/
ast.rs

1//! JavaScript の抽象構文木(実用コア相当)。
2//!
3//! Phase 1 のスコープ: 関数/クロージャ・制御構文・全演算子・オブジェクト/配列・
4//! メンバ/添字/呼出/new・三項・論理・代入・try/catch/throw。
5//! 分割代入・デフォルト引数・class などのモダン構文は Phase 4 で拡張する。
6
7use alloc::boxed::Box;
8use alloc::string::String;
9use alloc::vec::Vec;
10
11#[derive(Debug, Clone, PartialEq)]
12pub enum BinaryOp {
13    Add,
14    Sub,
15    Mul,
16    Div,
17    Mod,
18    Pow,
19    Eq,
20    NotEq,
21    StrictEq,
22    StrictNotEq,
23    Lt,
24    Gt,
25    LtEq,
26    GtEq,
27    BitAnd,
28    BitOr,
29    BitXor,
30    Shl,
31    Shr,
32    UShr,
33    InstanceOf,
34    In,
35}
36
37#[derive(Debug, Clone, PartialEq)]
38pub enum LogicalOp {
39    And,     // &&
40    Or,      // ||
41    Nullish, // ??
42}
43
44#[derive(Debug, Clone, PartialEq)]
45pub enum UnaryOp {
46    Neg,    // -x
47    Pos,    // +x
48    Not,    // !x
49    BitNot, // ~x
50    TypeOf, // typeof x
51    Void,   // void x
52    Delete, // delete x
53}
54
55/// オブジェクトリテラルのプロパティ。
56#[derive(Debug, Clone, PartialEq)]
57pub struct Property {
58    pub key: String,
59    pub value: Expression,
60    /// 算出キー `{[expr]: v}` の場合のキー式。None なら `key` を使う。
61    pub computed: Option<Expression>,
62    /// `{get x(){...}}`/`{set x(v){...}}` アクセサの場合 `Some(true)`/`Some(false)`。
63    /// 通常のプロパティ(値/メソッド短縮/短縮プロパティ)は `None`。
64    pub accessor: Option<bool>,
65}
66
67/// オブジェクトスプレッド `{...o}` を表す Property.key の番兵(通常キーと衝突しない制御文字)。
68pub const OBJECT_SPREAD_KEY: &str = "\u{0}spread";
69
70#[derive(Debug, Clone, PartialEq)]
71pub enum Expression {
72    Number(f64),
73    /// BigInt リテラル(数値部分の文字列。0x/0o/0b 接頭辞を含み得る)。
74    BigIntLit(String),
75    Str(String),
76    Bool(bool),
77    Null,
78    Undefined,
79    Identifier(String),
80    This,
81    TemplateLiteral {
82        // quasis.len() == exprs.len() + 1
83        quasis: Vec<String>,
84        exprs: Vec<Expression>,
85    },
86    /// タグ付きテンプレート `` tag`...${e}...` ``(ES2015)。`quasis`/`raw` は
87    /// `TemplateLiteral` と同様 exprs より1つ多い。`tag(strings, ...values)` 呼出しで
88    /// `strings` は `quasis` の配列に `.raw`(`raw` の配列)を added property として持つ。
89    TaggedTemplate {
90        tag: Box<Expression>,
91        quasis: Vec<String>,
92        raw: Vec<String>,
93        exprs: Vec<Expression>,
94    },
95    Array(Vec<Expression>),
96    Object(Vec<Property>),
97    Function {
98        name: Option<String>,
99        params: Vec<Param>,
100        body: Vec<Statement>,
101        is_arrow: bool,
102        is_async: bool,
103        is_generator: bool,
104    },
105    /// `await expr`。
106    Await(Box<Expression>),
107    /// `yield expr` / `yield* expr`。
108    Yield {
109        argument: Option<Box<Expression>>,
110        delegate: bool,
111    },
112    Unary {
113        op: UnaryOp,
114        expr: Box<Expression>,
115    },
116    Update {
117        op: String, // "++" / "--"
118        prefix: bool,
119        target: Box<Expression>,
120    },
121    Binary {
122        op: BinaryOp,
123        left: Box<Expression>,
124        right: Box<Expression>,
125    },
126    Logical {
127        op: LogicalOp,
128        left: Box<Expression>,
129        right: Box<Expression>,
130    },
131    Assign {
132        op: String, // "=", "+=", "-=", ...
133        target: Box<Expression>,
134        value: Box<Expression>,
135    },
136    Conditional {
137        test: Box<Expression>,
138        consequent: Box<Expression>,
139        alternate: Box<Expression>,
140    },
141    Member {
142        object: Box<Expression>,
143        property: String,
144        optional: bool, // a?.b
145    },
146    Index {
147        object: Box<Expression>,
148        index: Box<Expression>,
149        optional: bool, // a?.[b]
150    },
151    Call {
152        callee: Box<Expression>,
153        arguments: Vec<Expression>,
154        optional: bool, // a?.()
155    },
156    New {
157        callee: Box<Expression>,
158        arguments: Vec<Expression>,
159    },
160    /// スプレッド要素 `...expr`(配列リテラル/呼出引数/オブジェクト内で展開される)。
161    Spread(Box<Expression>),
162    /// `class` 式/宣言。
163    Class {
164        name: Option<String>,
165        superclass: Option<Box<Expression>>,
166        members: Vec<ClassMember>,
167    },
168    /// `super`(`super(...)` / `super.x`)。
169    Super,
170    /// カンマ演算子 `a, b, c`。全要素を順に評価し、最後の値を返す
171    /// (途中の要素の副作用も実行する。`for(i=0,j=10; ...)` 等で使われる)。
172    Sequence(Vec<Expression>),
173    /// `new.target`(MetaProperty。`new` 経由の呼び出しではコンストラクタ関数自身、
174    /// 通常呼び出しでは `undefined`)。
175    NewTarget,
176    /// 正規表現リテラル `/pattern/flags`。
177    Regex(String, String),
178}
179
180/// クラスメンバの種別。
181#[derive(Debug, Clone, PartialEq)]
182pub enum MethodKind {
183    Method,
184    Constructor,
185    /// フィールド宣言(`x = expr;` または `x;`、`#x = expr;` を含む)。
186    /// params/body は使わず、初期化式は ClassMember::field_init に持つ。
187    Field,
188    /// `get name() {...}`(アクセサ getter)。
189    Getter,
190    /// `set name(v) {...}`(アクセサ setter)。
191    Setter,
192    /// `static { ... }`(ES2022 静的初期化ブロック)。`body` に文の列を持つ
193    /// (`key`/`params`/`field_init` は使わない)。
194    StaticBlock,
195}
196
197/// クラスのメソッド/静的メソッド/フィールド宣言。
198#[derive(Debug, Clone, PartialEq)]
199pub struct ClassMember {
200    pub key: String,
201    /// 算出メソッド名 `[expr](){}`(`[Symbol.iterator]` 等)。Some の場合、実際のキーは
202    /// クラス定義時にこれを評価して得る(`key` フィールドは無視される)。
203    pub computed_key: Option<Expression>,
204    pub kind: MethodKind,
205    pub params: Vec<Param>,
206    pub body: Vec<Statement>,
207    pub is_static: bool,
208    /// kind == Field のときのみ Some(初期化式。省略時は None → undefined 初期化)。
209    pub field_init: Option<Expression>,
210    /// `async method(){}`(kind == Method のときのみ意味を持つ)。
211    pub is_async: bool,
212    /// `*method(){}`/`async *method(){}`(kind == Method のときのみ意味を持つ)。
213    pub is_generator: bool,
214}
215
216#[derive(Debug, Clone, PartialEq)]
217pub enum VarKind {
218    Var,
219    Let,
220    Const,
221    /// `using x = expr;`(Explicit Resource Management)。囲むブロック実行終了時に
222    /// `x[Symbol.dispose]()` を宣言の逆順で呼ぶ。
223    Using,
224    /// `await using x = expr;`。`x[Symbol.asyncDispose]()` の戻り値を await する。
225    AwaitUsing,
226}
227
228/// 束縛パターン(分割代入・引数)。
229#[derive(Debug, Clone, PartialEq)]
230pub enum Pattern {
231    Identifier(String),
232    /// `{ a, b: c, d = 1, ...rest }`
233    Object(Vec<ObjPatProp>),
234    /// `[ a, , b = 1, ...rest ]`
235    Array(Vec<ArrPatElem>),
236    /// メンバー/添字式への代入ターゲット(`for (obj.prop of arr)` / `for (obj[k] of arr)` 用)。
237    /// 分割代入の宣言では使わず、非宣言形式 for-of/for-in の代入先としてのみ生成される。
238    Expr(Box<Expression>),
239}
240
241/// オブジェクトパターンの 1 プロパティ。
242#[derive(Debug, Clone, PartialEq)]
243pub struct ObjPatProp {
244    /// 取り出すソースキー(`is_rest` の場合は未使用。`computed_key` が Some の場合も
245    /// 未使用で、実際のキーは束縛時に `computed_key` を評価して得る)。
246    pub key: String,
247    /// 算出プロパティ名 `{[expr]: target}`。Some の場合、`key` フィールドは無視される。
248    pub computed_key: Option<Expression>,
249    /// 束縛先パターン(`{a}` なら Identifier("a")、`{a: {b}}` ならネスト)。
250    pub value: Pattern,
251    pub default: Option<Expression>,
252    pub is_rest: bool,
253}
254
255/// 配列パターンの 1 要素。
256#[derive(Debug, Clone, PartialEq)]
257pub struct ArrPatElem {
258    /// None は穴 `[a, , b]`。
259    pub pattern: Option<Pattern>,
260    pub default: Option<Expression>,
261    pub is_rest: bool,
262}
263
264/// 関数パラメータ(パターン+デフォルト+レスト)。
265#[derive(Debug, Clone, PartialEq)]
266pub struct Param {
267    pub pattern: Pattern,
268    pub default: Option<Expression>,
269    pub is_rest: bool,
270}
271
272#[derive(Debug, Clone, PartialEq)]
273pub enum Statement {
274    Expression(Expression),
275    VarDeclaration {
276        kind: VarKind,
277        // 1 文で複数宣言可能: `let a = 1, b = 2;`。分割代入のため左辺は Pattern。
278        decls: Vec<(Pattern, Option<Expression>)>,
279    },
280    Block(Vec<Statement>),
281    If {
282        test: Expression,
283        consequent: Box<Statement>,
284        alternate: Option<Box<Statement>>,
285    },
286    While {
287        test: Expression,
288        body: Box<Statement>,
289    },
290    DoWhile {
291        body: Box<Statement>,
292        test: Expression,
293    },
294    For {
295        init: Option<Box<Statement>>,
296        test: Option<Expression>,
297        update: Option<Expression>,
298        body: Box<Statement>,
299    },
300    ForIn {
301        decl_kind: Option<VarKind>,
302        pattern: Pattern,
303        object: Expression,
304        body: Box<Statement>,
305        of: bool, // true: for-of, false: for-in
306        /// `for await (x of iterable)`。`Symbol.asyncIterator` があればそれを駆動し、
307        /// 無ければ同期イテラブルの各要素を await するフォールバック(`of` の時のみ意味を持つ)。
308        is_await: bool,
309    },
310    FunctionDeclaration {
311        name: String,
312        params: Vec<Param>,
313        body: Vec<Statement>,
314        is_async: bool,
315        is_generator: bool,
316    },
317    Return(Option<Expression>),
318    /// `break;` / `break label;`。
319    Break(Option<String>),
320    /// `continue;` / `continue label;`。
321    Continue(Option<String>),
322    /// `label: statement`(ラベル付き文。主にループの `break label`/`continue label` の
323    /// ターゲットとして使う)。
324    Labeled(String, Box<Statement>),
325    Throw(Expression),
326    Switch {
327        discriminant: Expression,
328        cases: Vec<SwitchCase>,
329    },
330    Try {
331        block: Vec<Statement>,
332        /// `catch (e)`/`catch ({message})` 等。分割代入パターンにも対応(ES2015)。
333        catch_param: Option<Pattern>,
334        catch_block: Option<Vec<Statement>>,
335        finally_block: Option<Vec<Statement>>,
336    },
337    /// `import ... from "spec"` 宣言。
338    /// 例: `import def, { a, b as c }, * as ns from "mod"`。
339    Import {
340        /// モジュール指定子(指定子文字列)。
341        source: String,
342        /// default インポートの束縛名(`import def from ...`)。
343        default: Option<String>,
344        /// 名前空間インポートの束縛名(`import * as ns from ...`)。
345        namespace: Option<String>,
346        /// 名前付きインポート: (元の export 名, ローカル束縛名)。
347        named: Vec<(String, String)>,
348        /// 副作用のみ `import "mod"`(束縛なし)。
349        side_effect_only: bool,
350    },
351    /// `export { a, b as c }` / `export { x } from "mod"`(再エクスポート)。
352    ExportNamed {
353        /// (ローカル名 or 元名, 公開する export 名)。
354        specifiers: Vec<(String, String)>,
355        /// 再エクスポート元の指定子(`export { x } from "mod"`)。None なら自モジュール。
356        source: Option<String>,
357    },
358    /// `export default <expr>`。
359    ExportDefault(Expression),
360    /// `export var/let/const/function/class ...`(宣言を実行しつつ名前を export)。
361    /// 内側の宣言文と、そこから公開する名前のリストを保持する。
362    ExportDecl {
363        declaration: Box<Statement>,
364        names: Vec<String>,
365    },
366    /// `export * from "mod"`(全名前の再エクスポート)。
367    ExportAll {
368        source: String,
369    },
370    Empty,
371}
372
373/// switch の 1 ケース。`test` が None なら default。
374#[derive(Debug, Clone, PartialEq)]
375pub struct SwitchCase {
376    pub test: Option<Expression>,
377    pub body: Vec<Statement>,
378}
379
380#[derive(Debug, Clone, PartialEq)]
381pub struct Program {
382    pub body: Vec<Statement>,
383}