use aleph_syntax_tree::syntax::AlephTree as at; grammar; pub Stmts = { Let, ";" => stmts, ";" => at::Stmts{expr1: Box::new(stmts), expr2: Box::new(e)} } Elems: Vec> = { => vec![Box::new(e)], "," => { el.push(Box::new(e)); el } } Let = { Expr, "=" => match left { at::Get{array_name, elem} => at::Put{array_name: array_name, elem: elem, value: Box::new(right), insert: "false".to_string()}, at::Put{array_name, elem, value: _value, insert} => at::Put{array_name: array_name, elem: elem, value: Box::new(right), insert: insert}, _ => at::Let{var: left.to_string_value(), is_pointer: "false".to_string(), value: Box::new(right), expr: Box::new(at::Unit)}, }, ":" "=" => at::Let{var: left.to_string_value(), is_pointer: "true".to_string(), value: Box::new(right), expr: Box::new(at::Unit)}, } Expr = { #[precedence(level="0")] Term, #[precedence(level="4")] "(" ";" ";" ")" "?" "*" "{" "}" => at::While{init_expr: Box::new(init), condition: Box::new(condition), loop_expr: Box::new(then), post_expr: Box::new(post)}, #[precedence(level="4")] #[assoc(side="left")] "-" => at::Sub{number_expr1:Box::new(left), number_expr2:Box::new(right)}, #[precedence(level="4")] #[assoc(side="left")] "+" => at::Add{number_expr1:Box::new(left), number_expr2:Box::new(right)}, #[precedence(level="4")] "?" "{" "}" => at::If{condition: Box::new(condition), then: Box::new(then), els: Box::new(at::Unit)}, #[precedence(level="4")] "?" "{" "}" ":" "{" "}" => at::If{condition: Box::new(condition), then: Box::new(then), els: Box::new(els)}, #[precedence(level="4")] "?" "*" "{" "}" => at::While{init_expr: Box::new(at::Unit), condition: Box::new(condition), loop_expr: Box::new(then), post_expr: Box::new(at::Unit)}, #[precedence(level="3")] "return" => at::Return{value: Box::new(e)}, #[precedence(level="2")] #[assoc(side="left")] "|" => at::Or{bool_expr1:Box::new(left), bool_expr2:Box::new(right)}, #[precedence(level="1")] #[assoc(side="left")] "*" => at::Mul{number_expr1:Box::new(left), number_expr2:Box::new(right)}, #[precedence(level="1")] #[assoc(side="left")] "/" => at::Div{number_expr1:Box::new(left), number_expr2:Box::new(right)}, #[precedence(level="1")] #[assoc(side="left")] "&" => at::And{bool_expr1:Box::new(left), bool_expr2:Box::new(right)}, #[precedence(level="1")] #[assoc(side="left")] "==" => at::Eq{expr1: Box::new(left), expr2: Box::new(right)}, #[precedence(level="1")] #[assoc(side="left")] "<=" => at::LE{expr1: Box::new(left), expr2: Box::new(right)}, #[precedence(level="1")] #[assoc(side="left")] "<" => at::Not{bool_expr: Box::new(at::LE{expr1: Box::new(right), expr2: Box::new(left)})}, #[precedence(level="1")] #[assoc(side="left")] ">=" => at::LE{expr1: Box::new(right), expr2: Box::new(left)}, #[precedence(level="1")] #[assoc(side="left")] ">" => at::Not{bool_expr: Box::new(at::LE{expr1: Box::new(left), expr2: Box::new(right)})}, #[precedence(level="1")] #[assoc(side="left")] "in" => at::In{expr1: Box::new(left), expr2: Box::new(right)}, "import" => at::Iprt{name: import.to_string_value()}, "class" "{" "}" => at::Clss{name: name.to_string_value(), attribute_list: Vec::new(), body: Box::new(body)}, "(" ")" => at::App{object_name: "".to_string(), fun: Box::new(name), param_list: Vec::new()}, "(" ")" => at::App{object_name: "".to_string(), fun: Box::new(name), param_list: elems}, "." "(" ")" => at::App{object_name: cname.to_string_value(), fun: Box::new(name), param_list: Vec::new()}, "." "(" ")" => at::App{object_name: cname.to_string_value(), fun: Box::new(name), param_list: elems}, "fun" "(" ")" "=" "{" "}" => at::LetRec{name: name.to_string_value(), args: Vec::new(), body: Box::new(body)}, "fun" "(" ")" "=" "{" "}" => at::LetRec{name: name.to_string_value(), args: elems, body: Box::new(body)}, "[" "/" "]" => at::Remove{array_name: name.to_string_value(), elem: Box::new(key), is_value: "false".to_string()}, "match" "with" => at::Match{expr: Box::new(e), case_list: match_list}, => at::Assert{condition: Box::new(condition), message: Box::new(message)}, } Term = { Num, String, Ident, Comment, CommentLine, "(" ")" => e, "-" => at::Neg{expr:Box::new(right)}, "!" => at::Not{bool_expr: Box::new(right)}, "[" "]" => match key { (k,true) => at::Put{array_name: name.to_string_value(), elem: Box::new(k), value: Box::new(at::Unit), insert: "true".to_string()}, (k,_) => match k { at::Neg{expr} => at::Remove{array_name: name.to_string_value(), elem: expr, is_value: "true".to_string()}, _ => at::Get{array_name: name.to_string_value(), elem: Box::new(k)}, }, }, "[" "]" => at::Array{elems: el}, "[" "]" => at::Array{elems: Vec::new()}, "|" "|" => at::Length{var: ident.to_string_value()}, } Num: at = r"[0-9]+(\.[0-9]+){0,1}" => match <>.to_string() { f if f.contains(".") => at::Float{value: f}, i => at::Int{value: i} }; Ident: at = r"[a-z](\d|[A-Za-z]|_)*" => match <> { "true" | "false" => at::Bool{value: <>.to_string()}, _ => at::Ident{value: <>.to_string()}, }; String: at = r#""[^\"]*""# => at::String{value: <>.to_string()}; Comment : at = r#"/\*([^\*/]*)\*/"# => at::CommentMulti{value: <>.to_string()}; CommentLine : at = r#"//([^\n]*)\n"# => at::Comment{value: <>.to_string()}; LeftAdd:(at, bool) = { => (left, false), "+" => (left, true), } MatchLine = { Ident, ":" "-" ">" ":" => at::MatchLine{condition: Box::new(left), case_expr: Box::new(right)}, } MatchList: Vec> = { => vec![Box::new(<>)], => { el.push(Box::new(e)); el } }