From 214b3e4d9e149f7501db3446efc6df1fdca69f38 Mon Sep 17 00:00:00 2001 From: lejulien Date: Tue, 2 Jun 2026 11:47:32 +0200 Subject: [PATCH] Add symbol support --- main.cpp | 86 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/main.cpp b/main.cpp index efb979f..328ea3d 100644 --- a/main.cpp +++ b/main.cpp @@ -96,30 +96,95 @@ static inline std::string strip(const std::string &s) { } using symbolsMap = std::map; +using labelsMap = std::map; + +int find_available_address(const symbolsMap &symbols) { + int address = 16; // Start from 16 for variables + while (true) { + bool found = false; + for (const auto &pair : symbols) { + if (pair.second == address) { + found = true; + break; + } + } + if (!found) return address; + ++address; + } +} int main() { // Load predefined symbols std::ifstream file("./symbols.json"); nlohmann::json symbols_json = nlohmann::json::parse(file); - symbolsMap symbols_map = symbols_json.get(); + symbolsMap symbols_map = {}; + labelsMap labels_map = symbols_json.get(); std::string line; - while (std::getline(std::cin, line)) { + int line_number = 0; + std::vector lines; + while (std::getline(std::cin, line)) { // Store lines for first pass line = trim(line); if (line.empty()) continue; - // skip comments if (line[0] == '#' || (line.size() > 1 && line[0] == '/' && line[1] == '/')) continue; - + lines.push_back(line); + } + auto line_it = lines.begin(); + while (line_it != lines.end()) { // First pass to handle labels + if ((*line_it)[0] == '(' && line_it->back() == ')') { + std::string label = line_it->substr(1, line_it->size() - 2); + labels_map[label] = line_number; + line_it = lines.erase(line_it); // Remove label lines + } else { + ++line_it; + ++line_number; // Only count non-label lines + } + } + for (const std::string &line : lines) { // Second pass to handle variables + if (line[0] == '@') { + if (std::isalpha(line[1]) || line[1] == '_') { + std::string symbol = line.substr(1); + if (labels_map.find(symbol) != labels_map.end()) { + continue; // Skip labels, they are already handled + } + auto it = symbols_map.find(symbol); + if (it == symbols_map.end()) { + int address = find_available_address(symbols_map); + symbols_map[symbol] = address; + } + } + } + } + for (const std::string &line : lines) { // Second pass to generate // A-instruction if (line[0] == '@') { - std::string value = line.substr(1); - if (value.empty()) continue; - try { - int intValue = std::stoi(value); - std::bitset<16> binaryValue(intValue); + // Check if it's a symbol or a number + if (std::isalpha(line[1]) || line[1] == '_') { + std::string symbol = line.substr(1); + int address; + // search labels first + auto labelIt = labels_map.find(symbol); + if (labelIt != labels_map.end()) { + address = labelIt->second; + } else { + // Search variables. + auto it = symbols_map.find(symbol); + if (it != symbols_map.end()) { + address = it->second; + } + } + std::bitset<16> binaryValue(address); std::cout << binaryValue.to_string() << '\n'; - } catch (...) { continue; } + } else { + std::string value = line.substr(1); + if (value.empty()) continue; + try { + int intValue = std::stoi(value); + std::bitset<16> binaryValue(intValue); + std::cout << binaryValue.to_string() << '\n'; + } catch (...) { continue; } + } } else { // C-instruction std::string instruction = "111"; size_t eqPos = line.find('='); @@ -148,6 +213,7 @@ int main() { auto jumpIt = jumpMap.find(jump); instruction += (jumpIt != jumpMap.end()) ? jumpIt->second : jumpMap.at("null"); std::cout << instruction << '\n'; + line_number++; } } return 0;