aboutsummaryrefslogtreecommitdiff
path: root/asm/preprocesser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'asm/preprocesser.cpp')
-rw-r--r--asm/preprocesser.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/asm/preprocesser.cpp b/asm/preprocesser.cpp
index 31cf6a7..dd7067a 100644
--- a/asm/preprocesser.cpp
+++ b/asm/preprocesser.cpp
@@ -63,6 +63,87 @@ preprocess_use_blocks(vector<token_t *> tokens)
return VAL(new_tokens);
}
+struct const_t
+{
+ size_t start, end;
+};
+
+pair<vector<token_t *>, pp_err_t>
+preprocess_const_blocks(vector<token_t *> &tokens)
+{
+ std::unordered_map<string_view, const_t> blocks;
+ for (size_t i = 0; i < tokens.size(); ++i)
+ {
+ token_t *t = tokens[i];
+ if (t->type == token_type_t::PP_CONST)
+ {
+ string_view capture;
+ if (t->content == "" && (i == tokens.size() - 1 ||
+ tokens[i + 1]->type != token_type_t::SYMBOL))
+ return ERR(pp_err_t{pp_err_type_t::EXPECTED_NAME});
+ else if (t->content != "")
+ capture = t->content;
+ else
+ capture = tokens[++i]->content;
+
+ // Check for brackets
+ auto start = capture.find('(');
+ auto end = capture.find(')');
+ if (start == string::npos || end == string::npos)
+ return ERR(pp_err_t{pp_err_type_t::EXPECTED_NAME});
+
+ ++i;
+ size_t block_start = i, block_end = 0;
+ for (; i < tokens.size() && tokens[i]->type != token_type_t::PP_END; ++i)
+ continue;
+
+ if (i == tokens.size())
+ return ERR(pp_err_t{pp_err_type_t::EXPECTED_END});
+
+ block_end = i - 1;
+
+ blocks[capture.substr(start + 1, end - 1)] =
+ const_t{block_start, block_end};
+ }
+ }
+
+ vector<token_t *> new_tokens;
+ if (blocks.size() == 0)
+ {
+ // Just construct a new vector and carry on
+ for (token_t *token : tokens)
+ new_tokens.push_back(new token_t{*token});
+ }
+ else
+ {
+ for (size_t i = 0; i < tokens.size(); ++i)
+ {
+ token_t *token = tokens[i];
+ // Skip the tokens that construct the const
+ if (token->type == token_type_t::PP_CONST)
+ for (; i < tokens.size() && tokens[i]->type != token_type_t::PP_END;
+ ++i)
+ continue;
+ else if (token->type == token_type_t::PP_REFERENCE)
+ {
+ auto it = blocks.find(token->content);
+ if (it == blocks.end())
+ {
+ new_tokens.clear();
+ return ERR(pp_err_t(pp_err_type_t::UNKNOWN_NAME, token));
+ }
+
+ const_t block = it->second;
+ for (size_t i = block.start; i < block.end; ++i)
+ new_tokens.push_back(new token_t{*tokens[i]});
+ }
+ else
+ new_tokens.push_back(new token_t{*token});
+ }
+ }
+
+ return VAL(new_tokens);
+}
std::ostream &operator<<(std::ostream &os, pp_err_t &err)
{