js_parser/
lib.rs

1use aleph_syntax_tree::syntax::AlephTree as at;
2use rslint_parser::{parse_text, SyntaxNode};
3use rslint_parser::SyntaxKind as sk;
4
5fn is_operator(kind: sk) -> bool {
6    match kind {
7        sk::PLUS | sk::MINUS | sk::STAR | sk::SLASH 
8            | sk::EQ | sk::EQ2 | sk::EQ3 | sk::NEQ | sk::NEQ2 
9            | sk::AMP | sk::PIPE | sk::BANG => true,
10        _ => false
11    }
12}
13
14fn compute_stmt(node_list: Vec<at>) -> at {
15    let mut res = at::Unit;
16    for node in node_list {
17        res = match res {
18            at::Unit => node,
19            _ => at::Stmts{expr1: Box::new(res), expr2: Box::new(node)}
20        }
21    }
22    res
23
24}
25
26fn translate_ast(node: SyntaxNode) -> at {
27    match node.kind() {
28        sk::EMPTY_STMT => {
29            at::Unit
30        }
31        sk::NAME_REF | sk::NAME => {
32            let name = node.text();
33            at::Var{var: name.to_string(), is_pointer: "False".to_string()}
34        }
35        sk::LITERAL => {
36            let value = node.text();
37            let f = value.to_string().parse::<f64>();
38            match f {
39                Ok(_) => {
40                    let i = value.to_string().parse::<u64>();
41                    match i {
42                        Ok(_) => at::Int{value: value.to_string()},
43                        _ => at::Float{value: value.to_string()}
44                    }
45                },
46                _ => {
47                    match value.to_string().as_ref() {
48                        "true" | "t" | "True" | "TRUE" => at::Bool{value: "True".to_string()},
49                        "false" | "f" | "False" | "FALSE" => at::Bool{value: "False".to_string()},
50                        _ => at::Var{var: value.to_string(), is_pointer: "False".to_string()}
51                    }
52                }
53            }
54        }
55        sk::SCRIPT | sk::EXPR_STMT | sk::BLOCK_STMT | sk::GROUPING_EXPR => {
56            compute_stmt(node.children().map(translate_ast).collect())
57        }
58        sk::RETURN_STMT => {
59            at::Return{value: Box::new(compute_stmt(node.children().map(translate_ast).collect()))}
60        }
61        sk::UNARY_EXPR => {
62            let operator = node
63                .children_with_tokens()
64                .find(|child| is_operator(child.kind()))
65                .map(|token| token.kind())
66                .expect("Missing operator");
67            let operands: Vec<at> = node
68                .children()
69                .map(translate_ast)
70                .collect();
71            match operator {
72                sk::MINUS => at::Neg{expr: Box::new(operands[0].clone())},
73                sk::BANG => at::Not{bool_expr: Box::new(operands[0].clone())},
74                _ => at::String{value : "Unknown".to_string()}
75            }
76        }
77        sk::BIN_EXPR => {
78            let operator = node
79                .children_with_tokens()
80                .find(|child| is_operator(child.kind()))
81                .map(|token| token.kind())
82                .expect("Missing operator");
83            let operands: Vec<at> = node
84                .children()
85                .map(translate_ast)
86                .collect();
87            match operator {
88                sk::PLUS => at::Add{number_expr1: Box::new(operands[0].clone()), number_expr2: Box::new(operands[1].clone())},
89                sk::MINUS => at::Sub{number_expr1: Box::new(operands[0].clone()), number_expr2: Box::new(operands[1].clone())},
90                sk::STAR => at::Mul{number_expr1: Box::new(operands[0].clone()), number_expr2: Box::new(operands[1].clone())},
91                sk::SLASH => at::Div{number_expr1: Box::new(operands[0].clone()), number_expr2: Box::new(operands[1].clone())},
92                sk::AMP => at::And{bool_expr1: Box::new(operands[0].clone()), bool_expr2: Box::new(operands[1].clone())},
93                sk::PIPE => at::Or{bool_expr1: Box::new(operands[0].clone()), bool_expr2: Box::new(operands[1].clone())},
94                sk::EQ => at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())},
95                sk::EQ2 => at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())},
96                sk::EQ3 => at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())},
97                sk::NEQ => at::Not{bool_expr: Box::new(at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())})},
98                sk::NEQ2 => at::Not{bool_expr: Box::new(at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())})},
99                _ => at::String{value : "Unknown".to_string()}
100            }
101        }
102        sk::FN_DECL => {
103            let name = node
104                .children()
105                .find(|child| child.kind() == sk::NAME)
106                .and_then(|child| Some(child.text()))
107                .expect("Missing function name")
108                .to_string();
109
110            let parameters: Vec<Box<at>> = node
111                .children()
112                .find(|child| child.kind() == sk::PARAMETER_LIST)
113                .expect("Missing parameter list")
114                .children()
115                .map(|param| Box::new(at::Var{var: param.text().to_string(), is_pointer: "False".to_string()}))
116                .collect();
117
118            let body = node
119                .children()
120                .find(|child| child.kind() == sk::BLOCK_STMT)
121                .map(|block| Box::new(translate_ast(block)))
122                .expect("Missing function body");
123
124            at::LetRec{name: name, args: parameters, body: body}
125        }
126        sk::CALL_EXPR => {
127            let callee = node 
128                .children()
129                .find(|child| child.kind() == sk::DOT_EXPR)
130                .expect("Missing callee identifier")
131                .clone();
132
133            let parameters: Vec<Box<at>> = node
134                .children()
135                .filter(|child| child.kind() == sk::ARG_LIST)
136                .flat_map(|arg_list| arg_list.children())
137                .map(|arg| Box::new(translate_ast(arg)))
138                .collect();
139
140            let at::App{object_name, fun, param_list: _} = translate_ast(callee) else { todo!() };
141            at::App{object_name: object_name, fun: fun, param_list: parameters} 
142        }
143        sk::DOT_EXPR => {
144            if let Some(lhs) = node.children().next() {
145                if let Some(rhs) = node.children().nth(1) {
146                    at::App{object_name: lhs.to_string(), fun: Box::new(translate_ast(rhs)), param_list: Vec::new() }
147                } else {
148                    at::App{object_name: lhs.to_string(), fun: Box::new(at::Unit), param_list: Vec::new() }
149                } 
150            } else {
151                if let Some(rhs) = node.children().nth(1) {
152                    at::App{object_name: "".to_string(), fun: Box::new(translate_ast(rhs)), param_list: Vec::new() }
153                } else {
154                    at::App{object_name: "".to_string(), fun: Box::new(at::Unit), param_list: Vec::new() }
155                } 
156            }
157        }
158        sk::VAR_DECL => {
159            if let Some(identifier) = node.children().next() {
160                at::Var{var: identifier.text().to_string(), is_pointer: "False".to_string()}
161            } else { todo!() }
162        }
163        sk::ASSIGN_EXPR => {
164            if let Some(lhs) = node.children().next() {
165                if let Some(rhs) = node.children().nth(1) {
166                    at::Let{var: lhs.text().to_string(), is_pointer: "False".to_string(), value: Box::new(translate_ast(rhs)), expr: Box::new(at::Unit)}
167                } else { todo!() }
168            } else { todo!() }
169        }
170        sk::IF_STMT => {
171            let branches: Vec<Box<at>> = node.children()
172                .filter(|child| child.kind() == sk::BLOCK_STMT)
173                .map(|arg| Box::new(translate_ast(arg)))
174                .collect();
175
176            if let Some(condition) = node.children().find(|child| child.kind() == sk::CONDITION) {
177                let mut thn = Box::new(at::Unit);
178                if let Some(then_ast) = branches.get(0) {
179                    thn = then_ast.clone()
180                }
181                let mut els = Box::new(at::Unit);
182                if let Some(els_ast) = branches.get(1) {
183                    els = els_ast.clone()
184                }
185                at::If{condition: Box::new(translate_ast(condition)), then: thn, els: els}
186            } else { todo!() }
187        }
188        sk::CONDITION => {
189            if let Some(condition) = node.children().next() {
190                translate_ast(condition)
191            } else { todo!() }
192        }
193        sk::SEMICOLON | sk::COMMA | sk::L_PAREN | sk::R_PAREN | sk::L_CURLY | sk::R_CURLY | sk::BANG
194            | sk::L_BRACK | sk::R_BRACK | sk::L_ANGLE | sk::R_ANGLE | sk::TILDE | sk::QUESTION | sk::QUESTION2
195            | sk::PLUS | sk::MINUS | sk::STAR | sk::SLASH | sk::EQ | sk::EQ2 | sk::EQ3 | sk::NEQ | sk::NEQ2 
196            | sk::DOT2 | sk::COLON | sk::FAT_ARROW | sk::MINUS2 | sk::LTEQ | sk::GTEQ | sk::PLUSEQ | sk::MINUSEQ | sk::PIPEEQ | sk::AMPEQ
197            | sk::CARETEQ | sk::SLASHEQ | sk::STAREQ | sk::PERCENTEQ | sk::AMP2 | sk::PIPE2 | sk::SHL | sk::SHR
198            | sk::USHR | sk::SHLEQ | sk::SHREQ | sk::USHREQ | sk::AMP2EQ | sk::PIPE2EQ | sk::STAR2EQ | sk::QUESTION2EQ
199            | sk::AT | sk::AWAIT_KW | sk::BREAK_KW | sk::CASE_KW | sk::CATCH_KW | sk::CLASS_KW | sk::CONST_KW | sk::CONTINUE_KW
200            | sk::DEBUGGER_KW | sk::DEFAULT_KW | sk::DELETE_KW | sk::DO_KW | sk::ELSE_KW | sk::ENUM_KW | sk::EXPORT_KW
201            | sk::EXTENDS_KW | sk::FALSE_KW | sk::FINALLY_KW | sk::FOR_KW | sk::FUNCTION_KW | sk::IF_KW | sk::IN_KW | sk::INSTANCEOF_KW
202            | sk::INTERFACE_KW | sk::IMPORT_KW | sk::IMPLEMENTS_KW | sk::NEW_KW | sk::NULL_KW | sk::PACKAGE_KW | sk::PRIVATE_KW
203            | sk::PROTECTED_KW | sk::PUBLIC_KW | sk::RETURN_KW | sk::SUPER_KW | sk::SWITCH_KW | sk::THIS_KW | sk::THROW_KW
204            | sk::TRY_KW | sk::TRUE_KW | sk::TYPEOF_KW | sk::VAR_KW | sk::VOID_KW | sk::WHILE_KW | sk::WITH_KW | sk::YIELD_KW
205            | sk::READONLY_KW | sk::KEYOF_KW | sk::UNIQUE_KW | sk::DECLARE_KW | sk::ABSTRACT_KW | sk::STATIC_KW | sk::ASYNC_KW
206            | sk::TYPE_KW | sk::FROM_KW | sk::AS_KW | sk::REQUIRE_KW | sk::NAMESPACE_KW | sk::ASSERT_KW | sk::MODULE_KW | sk::GLOBAL_KW
207            | sk::INFER_KW | sk::GET_KW | sk::SET_KW | sk::NUMBER | sk::STRING | sk::REGEX | sk::HASH | sk::TEMPLATE_CHUNK
208            | sk::DOLLARCURLY | sk::BACKTICK | sk::ERROR_TOKEN | sk::IDENT | sk::WHITESPACE | sk::COMMENT | sk::SHEBANG
209            | sk::MODULE | sk::ERROR | sk::DECLARATOR
210            | sk::DO_WHILE_STMT | sk::WHILE_STMT | sk::FOR_STMT | sk::FOR_IN_STMT | sk::CONTINUE_STMT | sk::BREAK_STMT
211            | sk::WITH_STMT | sk::SWITCH_STMT | sk::CASE_CLAUSE | sk::DEFAULT_CLAUSE | sk::LABELLED_STMT
212            | sk::THROW_STMT | sk::TRY_STMT | sk::CATCH_CLAUSE | sk::FINALIZER | sk::DEBUGGER_STMT
213            | sk::PARAMETER_LIST | sk::THIS_EXPR | sk::ARRAY_EXPR | sk::OBJECT_EXPR | sk::LITERAL_PROP | sk::GETTER
214            | sk::SETTER | sk::NEW_EXPR | sk::FN_EXPR | sk::BRACKET_EXPR
215            | sk::COND_EXPR | sk::SEQUENCE_EXPR | sk::ARG_LIST
216            | sk::TEMPLATE | sk::TEMPLATE_ELEMENT | sk::SPREAD_ELEMENT | sk::SUPER_CALL | sk::IMPORT_CALL
217            | sk::NEW_TARGET | sk::IMPORT_META | sk::IDENT_PROP | sk::SPREAD_PROP | sk::INITIALIZED_PROP | sk::OBJECT_PATTERN
218            | sk::ARRAY_PATTERN | sk::ASSIGN_PATTERN | sk::REST_PATTERN | sk::KEY_VALUE_PATTERN | sk::COMPUTED_PROPERTY_NAME
219            | sk::FOR_OF_STMT | sk::SINGLE_PATTERN | sk::ARROW_EXPR | sk::YIELD_EXPR | sk::CLASS_DECL | sk::CLASS_EXPR
220            | sk::CLASS_BODY | sk::METHOD | sk::IMPORT_DECL | sk::EXPORT_DECL | sk::EXPORT_NAMED | sk::EXPORT_DEFAULT_DECL
221            | sk::EXPORT_DEFAULT_EXPR | sk::EXPORT_WILDCARD | sk::WILDCARD_IMPORT | sk::NAMED_IMPORTS | sk::SPECIFIER
222            | sk::AWAIT_EXPR | sk::FOR_STMT_TEST | sk::FOR_STMT_UPDATE | sk::FOR_STMT_INIT | sk::PRIVATE_NAME
223            | sk::CLASS_PROP | sk::PRIVATE_PROP | sk::CONSTRUCTOR | sk::CONSTRUCTOR_PARAMETERS| sk::PRIVATE_PROP_ACCESS
224            | sk::IMPORT_STRING_SPECIFIER | sk::EXPR_PATTERN | sk::TS_ANY | sk::TS_UNKNOWN | sk::TS_NUMBER | sk::TS_OBJECT
225            | sk::TS_BOOLEAN | sk::TS_BIGINT | sk::TS_STRING | sk::TS_SYMBOL | sk::TS_VOID | sk::TS_UNDEFINED | sk::TS_NULL
226            | sk::TS_NEVER | sk::TS_THIS | sk::TS_LITERAL | sk::TS_PREDICATE | sk::TS_TUPLE | sk::TS_TUPLE_ELEMENT | sk::TS_PAREN
227            | sk::TS_TYPE_REF | sk::TS_QUALIFIED_PATH | sk::TS_TYPE_NAME | sk::TS_TEMPLATE | sk::TS_TEMPLATE_ELEMENT
228            | sk::TS_MAPPED_TYPE | sk::TS_MAPPED_TYPE_PARAM | sk::TS_MAPPED_TYPE_READONLY | sk::TS_TYPE_QUERY | sk::TS_TYPE_QUERY_EXPR
229            | sk::TS_IMPORT | sk::TS_TYPE_ARGS | sk::TS_ARRAY | sk::TS_INDEXED_ARRAY | sk::TS_TYPE_OPERATOR| sk::TS_INTERSECTION
230            | sk::TS_UNION | sk::TS_TYPE_PARAMS | sk::TS_FN_TYPE | sk::TS_CONSTRUCTOR_TYPE | sk::TS_EXTENDS | sk::TS_CONDITIONAL_TYPE
231            | sk::TS_CONSTRAINT | sk::TS_DEFAULT | sk::TS_TYPE_PARAM | sk::TS_NON_NULL | sk::TS_ASSERTION | sk::TS_CONST_ASSERTION
232            | sk::TS_ENUM | sk::TS_ENUM_MEMBER | sk::TS_TYPE_ALIAS_DECL | sk::TS_NAMESPACE_DECL | sk::TS_MODULE_BLOCK
233            | sk::TS_MODULE_DECL | sk::TS_CONSTRUCTOR_PARAM | sk::TS_CALL_SIGNATURE_DECL | sk::TS_CONSTRUCT_SIGNATURE_DECL
234            | sk::TS_INDEX_SIGNATURE | sk::TS_METHOD_SIGNATURE | sk::TS_PROPERTY_SIGNATURE | sk::TS_INTERFACE_DECL | sk::TS_ACCESSIBILITY
235            | sk::TS_OBJECT_TYPE | sk::TS_EXPR_WITH_TYPE_ARGS | sk::TS_IMPORT_EQUALS_DECL | sk::TS_MODULE_REF | sk::TS_EXTERNAL_MODULE_REF
236            | sk::TS_EXPORT_ASSIGNMENT | sk::TS_NAMESPACE_EXPORT_DECL | sk::TS_DECORATOR | sk::TS_INFER
237            | sk::AMP | sk::PIPE | sk::QUESTIONDOT | sk::PLUS2 | sk::STAR2 | sk::CARET | sk::PERCENT | sk::DOT => {
238                println!("Found ignoring node {:?}", node.kind());
239                at::String{value: "Ignore_node".to_string()}
240            }
241        _ => {
242          println!("Found other node {:?}", node.kind());
243          at::String{value: "Unknown_node".to_string()}
244          }
245    }
246}
247
248/// Javascript parser
249/// #Arguments
250/// `source` - String to parse
251///
252/// # Return
253/// This function return an AlephTree
254pub fn parse(source: String) -> at {
255    let ast = parse_text(&source,0);
256    //println!("AST {:?}", ast);
257
258    let root_node = ast.syntax();
259    translate_ast(root_node)
260}
261
262