1 // Copyright 2017-2017 the nyan authors, LGPLv3+. See copying.md for legal info.
2 
3 #include "bracket.h"
4 
5 
6 namespace nyan::lexer {
7 
8 
Bracket(token_type ttype,int indent)9 Bracket::Bracket(token_type ttype, int indent)
10 	:
11 	indentation{indent},
12 	type{this->to_type(ttype)},
13 	hanging{true} {}
14 
15 
doesnt_hang(int new_indent)16 void Bracket::doesnt_hang(int new_indent) {
17 	this->hanging = false;
18 	this->indentation = new_indent;
19 }
20 
21 
is_hanging() const22 bool Bracket::is_hanging() const {
23 	return this->hanging;
24 }
25 
26 
matches(token_type type) const27 bool Bracket::matches(token_type type) const {
28 	return type == this->expected_match();
29 }
30 
31 
get_content_indent() const32 int Bracket::get_content_indent() const {
33 	if (this->is_hanging()) {
34 		// hanging brackets store their expected indent level
35 		return this->indentation;
36 	}
37 	else {
38 		// wrapped brackets store their base indent level
39 		return this->indentation + SPACES_PER_INDENT;
40 	}
41 }
42 
43 
closing_indent_ok(int indent) const44 bool Bracket::closing_indent_ok(int indent) const {
45 	if (this->is_hanging()) {
46 		// hanging indent requires the closing bracket to be
47 		// closed after the opening bracket column
48 		return this->indentation <= indent;
49 	}
50 	else {
51 		return this->indentation == indent;
52 	}
53 }
54 
55 
get_closing_indent() const56 std::string Bracket::get_closing_indent() const {
57 	if (this->is_hanging()) {
58 		std::ostringstream builder;
59 		builder << "at least "
60 		        << this->indentation;
61 		return builder.str();
62 	}
63 	else {
64 		return std::to_string(this->indentation);
65 	}
66 }
67 
68 
matching_type_str() const69 const char *Bracket::matching_type_str() const {
70 	return token_type_str(this->expected_match());
71 }
72 
73 
to_type(token_type token)74 bracket_type Bracket::to_type(token_type token) {
75 	switch (token) {
76 	case token_type::LPAREN:
77 	case token_type::RPAREN:
78 		return bracket_type::PAREN;
79 	case token_type::LANGLE:
80 	case token_type::RANGLE:
81 		return bracket_type::ANGLE;
82 	case token_type::LBRACKET:
83 	case token_type::RBRACKET:
84 		return bracket_type::BRACKET;
85 	case token_type::LBRACE:
86 	case token_type::RBRACE:
87 		return bracket_type::BRACE;
88 	default:
89 		throw InternalError{"tried to convert non-bracket token to bracket"};
90 	}
91 }
92 
93 
expected_match() const94 token_type Bracket::expected_match() const {
95 	switch (this->type) {
96 	case bracket_type::PAREN:
97 		return token_type::RPAREN;
98 	case bracket_type::ANGLE:
99 		return token_type::RANGLE;
100 	case bracket_type::BRACKET:
101 		return token_type::RBRACKET;
102 	case bracket_type::BRACE:
103 		return token_type::RBRACE;
104 	default:
105 		throw InternalError{"unknown bracket type"};
106 	}
107 }
108 
109 
110 } // namespace nyan::lexer
111