1#include "Ast.hpp"2#include <memory>3#include <string_view>45using namespace ast;67Position::Position() : offset(0), line(1), column(1) {};8void Position::addCol()9{10 offset++;11 column++;12}13void Position::addLine()14{15 offset++;16 column = 0;17 line++;18}1920Word::Word(WordType type) : Node{NodeType::word}, type(type) {};2122std::optional<std::string> Word::toStr()23{24 std::string buf;2526 switch (type) {27 case WordType::string:28 return static_cast<String *>(this)->str;29 case WordType::list:30 for (auto &&w : static_cast<List *>(this)->children) {31 auto str = w->toStr();32 if (str.has_value()) {33 buf += str.value();34 } else {35 return {};36 }37 }38 return buf;39 default:40 return {};41 }42}4344bool Word::isQuoted()45{46 switch (type) {47 case WordType::string:48 return static_cast<String *>(this)->single_quoted;49 case WordType::list:50 if (static_cast<List *>(this)->double_quoted)51 return true;52 for (auto &&i : static_cast<List *>(this)->children) {53 if (i->isQuoted())54 return true;55 }56 return false;57 default:58 return false;59 }60}6162Word::String::String(const std::string str, bool single_quoted, Range range)63 : Word{WordType::string}, str(str), single_quoted(single_quoted),64 range(range) {};6566Word::String::String(const std::string str, bool single_quoted)67 : Word{WordType::string}, str(str), single_quoted(single_quoted),68 range{} {};6970Word::Parameter::Parameter(std::string name, Word::ParameterOp op,71 std::unique_ptr<Word> args)72 : Word{WordType::parameter}, name(name), op(op), args(std::move(args)) {};7374Word::List::List(std::vector<std::unique_ptr<Word>> &&children,75 bool double_quoted)76 : Word{WordType::list}, children(std::move(children)),77 double_quoted(double_quoted)78{79}8081Word::Command::Command(std::unique_ptr<Program> program, bool back_quoted)82 : Word{WordType::command}, program(std::move(program)),83 back_quoted(back_quoted), range{}84{85}86Command::SimpleCommand::SimpleCommand() : Command{CommandType::simple_command}87{88}8990Word::Command::Command(std::unique_ptr<Program> program, bool back_quoted,91 Range range)92 : Word{WordType::command}, program(std::move(program)),93 back_quoted(back_quoted), range(range)94{95}9697Word::Arithmetic::Arithmetic(std::unique_ptr<Word> body)98 : Word{WordType::arithmetic}, body(std::move(body))99{100}101102Program::Program(std::vector<std::unique_ptr<CommandList>> body)103 : Node{NodeType::program}, body(std::move(body))104{105}106107CommandList::CommandList(std::unique_ptr<AndOrList> and_or, bool ampersand)108 : Node{NodeType::command_list}, and_or_list{std::move(and_or)},109 ampersand(ampersand)110{111}112CommandList::CommandList(std::unique_ptr<AndOrList> and_or, bool ampersand,113 ast::Position sep_pos)114 : Node{NodeType::command_list}, and_or_list{std::move(and_or)},115 ampersand(ampersand), separator_pos{sep_pos}116{117}118119AndOrList::AndOrList(AndOrListType type)120 : Node{NodeType::and_or_list}, type{type}121{122}123124AndOrList::Pipeline::Pipeline(std::vector<std::unique_ptr<Command>> cmds,125 bool bang, Position bangPos)126 : AndOrList{AndOrListType::pipeline}, commands{std::move(cmds)}, bang{bang},127 bangPos{bangPos}128{129}130131AndOrList::BinOp::BinOp(AndOrList::BinOpType type,132 std::unique_ptr<AndOrList> left,133 std::unique_ptr<AndOrList> right, Range opRange)134 : AndOrList{AndOrListType::bin_op}, type{type}, left{std::move(left)},135 right{std::move(right)}, opRange{opRange}136{137}138139Command::Command(CommandType type) : Node{NodeType::command}, type{type} {}140141Command::BraceGroup::BraceGroup(std::vector<std::unique_ptr<CommandList>> body)142 : Command{CommandType::brace_group}, body{std::move(body)}143{144}145Command::BraceGroup::BraceGroup(std::vector<std::unique_ptr<CommandList>> body,146 Position lbrace_pos, Position rbrace_pos)147 : Command{CommandType::brace_group}, body{std::move(body)},148 lbrace_pos{lbrace_pos}, rbrace_pos{rbrace_pos}149{150}151152Command::SubShell::SubShell(std::vector<std::unique_ptr<CommandList>> body,153 Position lparen_pos, Position rparen_pos)154 : Command{CommandType::subshell}, body{std::move(body)},155 lparen_pos{lparen_pos}, rparen_pos{rparen_pos}156{157}158159Command::IfClause::IfClause(std::vector<std::unique_ptr<CommandList>> cond,160 std::vector<std::unique_ptr<CommandList>> body,161 std::unique_ptr<Command> else_part)162 : Command{CommandType::if_clause}, condition{std::move(cond)},163 body{std::move(body)}, else_part{std::move(else_part)}164{165}166167Command::ForClause::ForClause(168 bool in, std::vector<std::unique_ptr<ast::Word>> wordList,169 std::vector<std::unique_ptr<ast::CommandList>> body)170 : Command{CommandType::for_clause}, in{in}, wordList{std::move(wordList)},171 body{std::move(body)}172{173}174175Command::LoopClause::LoopClause(176 LoopClauseType type, std::vector<std::unique_ptr<CommandList>> condition,177 std::vector<std::unique_ptr<CommandList>> body)178 : Command{CommandType::loop_clause}, type{type},179 condition{std::move(condition)}, body{std::move(body)}180{181}182Command::CaseClause::CaseClause(183 std::unique_ptr<Word> word,184 std::vector<std::unique_ptr<struct CaseItem>> items)185 : Command{CommandType::case_clase}, word{std::move(word)},186 items{std::move(items)}187{188}189190Command::FunctionDefine::FunctionDefine(std::string name,191 std::unique_ptr<ast::Command> command)192 : Command{CommandType::function_define}, name{name},193 command{std::move(command)}, io_redirects{}194{195}196197Command::FunctionDefine::FunctionDefine(198 std::string name, std::unique_ptr<ast::Command> command,199 std::vector<std::shared_ptr<ast::IORedirect>> io_redirects)200 : Command{CommandType::function_define}, name{name},201 command{std::move(command)}, io_redirects{io_redirects}202{203}204205IORedirect::IORedirect(int io_num, IORedirectOp op, std::unique_ptr<Word> name,206 ast::Position ionum_pos, ast::Range op_range)207 : io_number{io_num}, op{op}, name{std::move(name)}, here_document{},208 io_number_pos{ionum_pos}, op_range{op_range}209{210}211212Assignment::Assignment(std::string name, std::unique_ptr<Word> value,213 ast::Range name_range, ast::Position equal_pos)214 : name{name}, value{std::move(value)}, name_range{name_range},215 equal_pos{equal_pos}216{217}218219bool ast::isKeyword(std::string_view word) { return keywords.contains(word); }