nanvm_lib/parser/
shared.rs

1use crate::{
2    big_numbers::big_int::{BigInt, Sign},
3    common::default::default,
4    js::{
5        any::Any,
6        js_bigint::{new_bigint, JsBigintRef},
7        js_string::{new_string, JsStringRef},
8        null::Null,
9    },
10    mem::manager::{Dealloc, Manager},
11    tokenizer::JsonToken,
12};
13use std::collections::{BTreeMap, BTreeSet};
14use std::fmt::Display;
15
16#[derive(Debug, Default, PartialEq)]
17pub enum DataType {
18    #[default]
19    Json,
20    Djs,
21    Cjs,
22    Mjs,
23}
24
25impl DataType {
26    pub fn to_djs(&self) -> DataType {
27        match self {
28            DataType::Json | DataType::Djs => DataType::Djs,
29            DataType::Cjs => DataType::Cjs,
30            DataType::Mjs => DataType::Mjs,
31        }
32    }
33
34    pub fn is_djs(&self) -> bool {
35        matches!(self, DataType::Djs | DataType::Cjs | DataType::Mjs)
36    }
37
38    pub fn is_cjs_compatible(&self) -> bool {
39        matches!(self, DataType::Json | DataType::Djs | DataType::Cjs)
40    }
41
42    pub fn is_mjs_compatible(&self) -> bool {
43        matches!(self, DataType::Json | DataType::Djs | DataType::Mjs)
44    }
45}
46
47#[derive(Default, Debug)]
48pub enum ParsingStatus {
49    #[default]
50    Initial,
51    ArrayBegin,
52    ArrayValue,
53    ArrayComma,
54    ObjectBegin,
55    ObjectKey,
56    ObjectColon,
57    ObjectValue,
58    ObjectComma,
59    ImportBegin,
60    ImportValue,
61    ImportEnd,
62}
63
64#[derive(Debug, PartialEq)]
65pub enum ParseError {
66    UnexpectedToken,
67    UnexpectedEnd,
68    WrongExportStatement,
69    WrongConstStatement,
70    WrongRequireStatement,
71    WrongImportStatement,
72    CannotReadFile,
73    CircularDependency,
74    NewLineExpected,
75}
76
77impl Display for ParseError {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        f.write_str(match self {
80            ParseError::UnexpectedToken => "UnexpectedToken",
81            ParseError::UnexpectedEnd => "UnexpectedEnd",
82            ParseError::WrongExportStatement => "WrongExportStatement",
83            ParseError::WrongConstStatement => "WrongConstStatement",
84            ParseError::WrongRequireStatement => "WrongRequireStatement",
85            ParseError::WrongImportStatement => "WrongImportStatement",
86            ParseError::CannotReadFile => "CannotReadFile",
87            ParseError::CircularDependency => "CircularDependency",
88            ParseError::NewLineExpected => "NewLineExpected",
89        })
90    }
91}
92
93pub struct ModuleCache<D: Dealloc> {
94    pub complete: BTreeMap<String, Any<D>>,
95    pub progress: BTreeSet<String>,
96}
97
98impl<D: Dealloc> Default for ModuleCache<D> {
99    fn default() -> Self {
100        Self {
101            complete: default(),
102            progress: default(),
103        }
104    }
105}
106
107pub enum JsonStackElement<D: Dealloc> {
108    Object(JsonStackObject<D>),
109    Array(Vec<Any<D>>),
110}
111
112pub struct JsonStackObject<D: Dealloc> {
113    pub map: BTreeMap<String, Any<D>>,
114    pub key: String,
115}
116
117pub enum JsonElement<D: Dealloc> {
118    None,
119    Stack(JsonStackElement<D>),
120    Any(Any<D>),
121}
122
123#[derive(Debug)]
124pub struct ParseResult<D: Dealloc> {
125    pub data_type: DataType,
126    pub any: Any<D>,
127}
128
129pub fn to_js_string<M: Manager>(manager: M, s: String) -> JsStringRef<M::Dealloc> {
130    new_string(manager, s.encode_utf16().collect::<Vec<_>>()).to_ref()
131}
132
133pub fn to_js_bigint<M: Manager>(manager: M, b: BigInt) -> JsBigintRef<M::Dealloc> {
134    let sign = match b.sign {
135        Sign::Positive => crate::js::js_bigint::Sign::Positive,
136        Sign::Negative => crate::js::js_bigint::Sign::Negative,
137    };
138    new_bigint(manager, sign, b.value.value).to_ref()
139}
140
141fn try_id_to_any<M: Manager>(
142    s: &str,
143    _manager: M,
144    consts: &BTreeMap<String, Any<M::Dealloc>>,
145) -> Option<Any<M::Dealloc>> {
146    match s {
147        "null" => Some(Any::move_from(Null())),
148        "true" => Some(Any::move_from(true)),
149        "false" => Some(Any::move_from(false)),
150        s if consts.contains_key(s) => Some(consts.get(s).unwrap().clone()),
151        _ => None,
152    }
153}
154
155impl<D: Dealloc> JsonToken<D> {
156    pub fn try_to_any<M: Manager<Dealloc = D>>(
157        self,
158        manager: M,
159        consts: &BTreeMap<String, Any<M::Dealloc>>,
160    ) -> Option<Any<M::Dealloc>> {
161        match self {
162            JsonToken::Number(f) => Some(Any::move_from(f)),
163            JsonToken::String(s) => Some(Any::move_from(to_js_string(manager, s))),
164            JsonToken::Id(s) => try_id_to_any(&s, manager, consts),
165            JsonToken::BigInt(b) => Some(Any::move_from(b.to_ref())),
166            _ => None,
167        }
168    }
169}