use aleph_syntax_tree::syntax::AlephTree as at;
use rslint_parser::{parse_text, SyntaxNode};
use rslint_parser::SyntaxKind as sk;
fn is_operator(kind: sk) -> bool {
match kind {
sk::PLUS | sk::MINUS | sk::STAR | sk::SLASH
| sk::EQ | sk::EQ2 | sk::EQ3 | sk::NEQ | sk::NEQ2
| sk::AMP | sk::PIPE | sk::BANG => true,
_ => false
}
}
fn compute_stmt(node_list: Vec<at>) -> at {
let mut res = at::Unit;
for node in node_list {
res = match res {
at::Unit => node,
_ => at::Stmts{expr1: Box::new(res), expr2: Box::new(node)}
}
}
res
}
fn translate_ast(node: SyntaxNode) -> at {
match node.kind() {
sk::EMPTY_STMT => {
at::Unit
}
sk::NAME_REF | sk::NAME => {
let name = node.text();
at::Var{var: name.to_string(), is_pointer: "False".to_string()}
}
sk::LITERAL => {
let value = node.text();
let f = value.to_string().parse::<f64>();
match f {
Ok(_) => {
let i = value.to_string().parse::<u64>();
match i {
Ok(_) => at::Int{value: value.to_string()},
_ => at::Float{value: value.to_string()}
}
},
_ => {
match value.to_string().as_ref() {
"true" | "t" | "True" | "TRUE" => at::Bool{value: "True".to_string()},
"false" | "f" | "False" | "FALSE" => at::Bool{value: "False".to_string()},
_ => at::Var{var: value.to_string(), is_pointer: "False".to_string()}
}
}
}
}
sk::SCRIPT | sk::EXPR_STMT | sk::BLOCK_STMT | sk::GROUPING_EXPR => {
compute_stmt(node.children().map(translate_ast).collect())
}
sk::RETURN_STMT => {
at::Return{value: Box::new(compute_stmt(node.children().map(translate_ast).collect()))}
}
sk::UNARY_EXPR => {
let operator = node
.children_with_tokens()
.find(|child| is_operator(child.kind()))
.map(|token| token.kind())
.expect("Missing operator");
let operands: Vec<at> = node
.children()
.map(translate_ast)
.collect();
match operator {
sk::MINUS => at::Neg{expr: Box::new(operands[0].clone())},
sk::BANG => at::Not{bool_expr: Box::new(operands[0].clone())},
_ => at::String{value : "Unknown".to_string()}
}
}
sk::BIN_EXPR => {
let operator = node
.children_with_tokens()
.find(|child| is_operator(child.kind()))
.map(|token| token.kind())
.expect("Missing operator");
let operands: Vec<at> = node
.children()
.map(translate_ast)
.collect();
match operator {
sk::PLUS => at::Add{number_expr1: Box::new(operands[0].clone()), number_expr2: Box::new(operands[1].clone())},
sk::MINUS => at::Sub{number_expr1: Box::new(operands[0].clone()), number_expr2: Box::new(operands[1].clone())},
sk::STAR => at::Mul{number_expr1: Box::new(operands[0].clone()), number_expr2: Box::new(operands[1].clone())},
sk::SLASH => at::Div{number_expr1: Box::new(operands[0].clone()), number_expr2: Box::new(operands[1].clone())},
sk::AMP => at::And{bool_expr1: Box::new(operands[0].clone()), bool_expr2: Box::new(operands[1].clone())},
sk::PIPE => at::Or{bool_expr1: Box::new(operands[0].clone()), bool_expr2: Box::new(operands[1].clone())},
sk::EQ => at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())},
sk::EQ2 => at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())},
sk::EQ3 => at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())},
sk::NEQ => at::Not{bool_expr: Box::new(at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())})},
sk::NEQ2 => at::Not{bool_expr: Box::new(at::Eq{expr1: Box::new(operands[0].clone()), expr2: Box::new(operands[1].clone())})},
_ => at::String{value : "Unknown".to_string()}
}
}
sk::FN_DECL => {
let name = node
.children()
.find(|child| child.kind() == sk::NAME)
.and_then(|child| Some(child.text()))
.expect("Missing function name")
.to_string();
let parameters: Vec<Box<at>> = node
.children()
.find(|child| child.kind() == sk::PARAMETER_LIST)
.expect("Missing parameter list")
.children()
.map(|param| Box::new(at::Var{var: param.text().to_string(), is_pointer: "False".to_string()}))
.collect();
let body = node
.children()
.find(|child| child.kind() == sk::BLOCK_STMT)
.map(|block| Box::new(translate_ast(block)))
.expect("Missing function body");
at::LetRec{name: name, args: parameters, body: body}
}
sk::CALL_EXPR => {
let callee = node
.children()
.find(|child| child.kind() == sk::DOT_EXPR)
.expect("Missing callee identifier")
.clone();
let parameters: Vec<Box<at>> = node
.children()
.filter(|child| child.kind() == sk::ARG_LIST)
.flat_map(|arg_list| arg_list.children())
.map(|arg| Box::new(translate_ast(arg)))
.collect();
let at::App{object_name, fun, param_list: _} = translate_ast(callee) else { todo!() };
at::App{object_name: object_name, fun: fun, param_list: parameters}
}
sk::DOT_EXPR => {
if let Some(lhs) = node.children().next() {
if let Some(rhs) = node.children().nth(1) {
at::App{object_name: lhs.to_string(), fun: Box::new(translate_ast(rhs)), param_list: Vec::new() }
} else {
at::App{object_name: lhs.to_string(), fun: Box::new(at::Unit), param_list: Vec::new() }
}
} else {
if let Some(rhs) = node.children().nth(1) {
at::App{object_name: "".to_string(), fun: Box::new(translate_ast(rhs)), param_list: Vec::new() }
} else {
at::App{object_name: "".to_string(), fun: Box::new(at::Unit), param_list: Vec::new() }
}
}
}
sk::VAR_DECL => {
if let Some(identifier) = node.children().next() {
at::Var{var: identifier.text().to_string(), is_pointer: "False".to_string()}
} else { todo!() }
}
sk::ASSIGN_EXPR => {
if let Some(lhs) = node.children().next() {
if let Some(rhs) = node.children().nth(1) {
at::Let{var: lhs.text().to_string(), is_pointer: "False".to_string(), value: Box::new(translate_ast(rhs)), expr: Box::new(at::Unit)}
} else { todo!() }
} else { todo!() }
}
sk::IF_STMT => {
let branches: Vec<Box<at>> = node.children()
.filter(|child| child.kind() == sk::BLOCK_STMT)
.map(|arg| Box::new(translate_ast(arg)))
.collect();
if let Some(condition) = node.children().find(|child| child.kind() == sk::CONDITION) {
let mut thn = Box::new(at::Unit);
if let Some(then_ast) = branches.get(0) {
thn = then_ast.clone()
}
let mut els = Box::new(at::Unit);
if let Some(els_ast) = branches.get(1) {
els = els_ast.clone()
}
at::If{condition: Box::new(translate_ast(condition)), then: thn, els: els}
} else { todo!() }
}
sk::CONDITION => {
if let Some(condition) = node.children().next() {
translate_ast(condition)
} else { todo!() }
}
sk::SEMICOLON | sk::COMMA | sk::L_PAREN | sk::R_PAREN | sk::L_CURLY | sk::R_CURLY | sk::BANG
| sk::L_BRACK | sk::R_BRACK | sk::L_ANGLE | sk::R_ANGLE | sk::TILDE | sk::QUESTION | sk::QUESTION2
| sk::PLUS | sk::MINUS | sk::STAR | sk::SLASH | sk::EQ | sk::EQ2 | sk::EQ3 | sk::NEQ | sk::NEQ2
| sk::DOT2 | sk::COLON | sk::FAT_ARROW | sk::MINUS2 | sk::LTEQ | sk::GTEQ | sk::PLUSEQ | sk::MINUSEQ | sk::PIPEEQ | sk::AMPEQ
| sk::CARETEQ | sk::SLASHEQ | sk::STAREQ | sk::PERCENTEQ | sk::AMP2 | sk::PIPE2 | sk::SHL | sk::SHR
| sk::USHR | sk::SHLEQ | sk::SHREQ | sk::USHREQ | sk::AMP2EQ | sk::PIPE2EQ | sk::STAR2EQ | sk::QUESTION2EQ
| sk::AT | sk::AWAIT_KW | sk::BREAK_KW | sk::CASE_KW | sk::CATCH_KW | sk::CLASS_KW | sk::CONST_KW | sk::CONTINUE_KW
| sk::DEBUGGER_KW | sk::DEFAULT_KW | sk::DELETE_KW | sk::DO_KW | sk::ELSE_KW | sk::ENUM_KW | sk::EXPORT_KW
| sk::EXTENDS_KW | sk::FALSE_KW | sk::FINALLY_KW | sk::FOR_KW | sk::FUNCTION_KW | sk::IF_KW | sk::IN_KW | sk::INSTANCEOF_KW
| sk::INTERFACE_KW | sk::IMPORT_KW | sk::IMPLEMENTS_KW | sk::NEW_KW | sk::NULL_KW | sk::PACKAGE_KW | sk::PRIVATE_KW
| sk::PROTECTED_KW | sk::PUBLIC_KW | sk::RETURN_KW | sk::SUPER_KW | sk::SWITCH_KW | sk::THIS_KW | sk::THROW_KW
| sk::TRY_KW | sk::TRUE_KW | sk::TYPEOF_KW | sk::VAR_KW | sk::VOID_KW | sk::WHILE_KW | sk::WITH_KW | sk::YIELD_KW
| sk::READONLY_KW | sk::KEYOF_KW | sk::UNIQUE_KW | sk::DECLARE_KW | sk::ABSTRACT_KW | sk::STATIC_KW | sk::ASYNC_KW
| sk::TYPE_KW | sk::FROM_KW | sk::AS_KW | sk::REQUIRE_KW | sk::NAMESPACE_KW | sk::ASSERT_KW | sk::MODULE_KW | sk::GLOBAL_KW
| sk::INFER_KW | sk::GET_KW | sk::SET_KW | sk::NUMBER | sk::STRING | sk::REGEX | sk::HASH | sk::TEMPLATE_CHUNK
| sk::DOLLARCURLY | sk::BACKTICK | sk::ERROR_TOKEN | sk::IDENT | sk::WHITESPACE | sk::COMMENT | sk::SHEBANG
| sk::MODULE | sk::ERROR | sk::DECLARATOR
| sk::DO_WHILE_STMT | sk::WHILE_STMT | sk::FOR_STMT | sk::FOR_IN_STMT | sk::CONTINUE_STMT | sk::BREAK_STMT
| sk::WITH_STMT | sk::SWITCH_STMT | sk::CASE_CLAUSE | sk::DEFAULT_CLAUSE | sk::LABELLED_STMT
| sk::THROW_STMT | sk::TRY_STMT | sk::CATCH_CLAUSE | sk::FINALIZER | sk::DEBUGGER_STMT
| sk::PARAMETER_LIST | sk::THIS_EXPR | sk::ARRAY_EXPR | sk::OBJECT_EXPR | sk::LITERAL_PROP | sk::GETTER
| sk::SETTER | sk::NEW_EXPR | sk::FN_EXPR | sk::BRACKET_EXPR
| sk::COND_EXPR | sk::SEQUENCE_EXPR | sk::ARG_LIST
| sk::TEMPLATE | sk::TEMPLATE_ELEMENT | sk::SPREAD_ELEMENT | sk::SUPER_CALL | sk::IMPORT_CALL
| sk::NEW_TARGET | sk::IMPORT_META | sk::IDENT_PROP | sk::SPREAD_PROP | sk::INITIALIZED_PROP | sk::OBJECT_PATTERN
| sk::ARRAY_PATTERN | sk::ASSIGN_PATTERN | sk::REST_PATTERN | sk::KEY_VALUE_PATTERN | sk::COMPUTED_PROPERTY_NAME
| sk::FOR_OF_STMT | sk::SINGLE_PATTERN | sk::ARROW_EXPR | sk::YIELD_EXPR | sk::CLASS_DECL | sk::CLASS_EXPR
| sk::CLASS_BODY | sk::METHOD | sk::IMPORT_DECL | sk::EXPORT_DECL | sk::EXPORT_NAMED | sk::EXPORT_DEFAULT_DECL
| sk::EXPORT_DEFAULT_EXPR | sk::EXPORT_WILDCARD | sk::WILDCARD_IMPORT | sk::NAMED_IMPORTS | sk::SPECIFIER
| sk::AWAIT_EXPR | sk::FOR_STMT_TEST | sk::FOR_STMT_UPDATE | sk::FOR_STMT_INIT | sk::PRIVATE_NAME
| sk::CLASS_PROP | sk::PRIVATE_PROP | sk::CONSTRUCTOR | sk::CONSTRUCTOR_PARAMETERS| sk::PRIVATE_PROP_ACCESS
| sk::IMPORT_STRING_SPECIFIER | sk::EXPR_PATTERN | sk::TS_ANY | sk::TS_UNKNOWN | sk::TS_NUMBER | sk::TS_OBJECT
| sk::TS_BOOLEAN | sk::TS_BIGINT | sk::TS_STRING | sk::TS_SYMBOL | sk::TS_VOID | sk::TS_UNDEFINED | sk::TS_NULL
| sk::TS_NEVER | sk::TS_THIS | sk::TS_LITERAL | sk::TS_PREDICATE | sk::TS_TUPLE | sk::TS_TUPLE_ELEMENT | sk::TS_PAREN
| sk::TS_TYPE_REF | sk::TS_QUALIFIED_PATH | sk::TS_TYPE_NAME | sk::TS_TEMPLATE | sk::TS_TEMPLATE_ELEMENT
| sk::TS_MAPPED_TYPE | sk::TS_MAPPED_TYPE_PARAM | sk::TS_MAPPED_TYPE_READONLY | sk::TS_TYPE_QUERY | sk::TS_TYPE_QUERY_EXPR
| sk::TS_IMPORT | sk::TS_TYPE_ARGS | sk::TS_ARRAY | sk::TS_INDEXED_ARRAY | sk::TS_TYPE_OPERATOR| sk::TS_INTERSECTION
| sk::TS_UNION | sk::TS_TYPE_PARAMS | sk::TS_FN_TYPE | sk::TS_CONSTRUCTOR_TYPE | sk::TS_EXTENDS | sk::TS_CONDITIONAL_TYPE
| sk::TS_CONSTRAINT | sk::TS_DEFAULT | sk::TS_TYPE_PARAM | sk::TS_NON_NULL | sk::TS_ASSERTION | sk::TS_CONST_ASSERTION
| sk::TS_ENUM | sk::TS_ENUM_MEMBER | sk::TS_TYPE_ALIAS_DECL | sk::TS_NAMESPACE_DECL | sk::TS_MODULE_BLOCK
| sk::TS_MODULE_DECL | sk::TS_CONSTRUCTOR_PARAM | sk::TS_CALL_SIGNATURE_DECL | sk::TS_CONSTRUCT_SIGNATURE_DECL
| sk::TS_INDEX_SIGNATURE | sk::TS_METHOD_SIGNATURE | sk::TS_PROPERTY_SIGNATURE | sk::TS_INTERFACE_DECL | sk::TS_ACCESSIBILITY
| sk::TS_OBJECT_TYPE | sk::TS_EXPR_WITH_TYPE_ARGS | sk::TS_IMPORT_EQUALS_DECL | sk::TS_MODULE_REF | sk::TS_EXTERNAL_MODULE_REF
| sk::TS_EXPORT_ASSIGNMENT | sk::TS_NAMESPACE_EXPORT_DECL | sk::TS_DECORATOR | sk::TS_INFER
| sk::AMP | sk::PIPE | sk::QUESTIONDOT | sk::PLUS2 | sk::STAR2 | sk::CARET | sk::PERCENT | sk::DOT => {
println!("Found ignoring node {:?}", node.kind());
at::String{value: "Ignore_node".to_string()}
}
_ => {
println!("Found other node {:?}", node.kind());
at::String{value: "Unknown_node".to_string()}
}
}
}
pub fn parse(source: String) -> at {
let ast = parse_text(&source,0);
let root_node = ast.syntax();
translate_ast(root_node)
}