mush

git clone git://git.lin.moe/mush.git

  1#include "Ast.hpp"
  2#include <memory>
  3#include <string_view>
  4
  5using namespace ast;
  6
  7Position::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}
 19
 20Word::Word(WordType type) : Node{NodeType::word}, type(type) {};
 21
 22std::optional<std::string> Word::toStr()
 23{
 24	std::string buf;
 25
 26	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}
 43
 44bool 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}
 61
 62Word::String::String(const std::string str, bool single_quoted, Range range)
 63    : Word{WordType::string}, str(str), single_quoted(single_quoted),
 64      range(range) {};
 65
 66Word::String::String(const std::string str, bool single_quoted)
 67    : Word{WordType::string}, str(str), single_quoted(single_quoted),
 68      range{} {};
 69
 70Word::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)) {};
 73
 74Word::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}
 80
 81Word::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}
 89
 90Word::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}
 96
 97Word::Arithmetic::Arithmetic(std::unique_ptr<Word> body)
 98    : Word{WordType::arithmetic}, body(std::move(body))
 99{
100}
101
102Program::Program(std::vector<std::unique_ptr<CommandList>> body)
103    : Node{NodeType::program}, body(std::move(body))
104{
105}
106
107CommandList::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}
118
119AndOrList::AndOrList(AndOrListType type)
120    : Node{NodeType::and_or_list}, type{type}
121{
122}
123
124AndOrList::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}
130
131AndOrList::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}
138
139Command::Command(CommandType type) : Node{NodeType::command}, type{type} {}
140
141Command::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}
151
152Command::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}
158
159Command::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}
166
167Command::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}
174
175Command::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}
189
190Command::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}
196
197Command::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}
204
205IORedirect::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}
211
212Assignment::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}
218
219bool ast::isKeyword(std::string_view word) { return keywords.contains(word); }