This commit is contained in:
parent
ffc243d528
commit
8793c64f1c
286
src/Parser.cpp
286
src/Parser.cpp
|
@ -25,6 +25,7 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include "Parser.h"
|
||||
|
||||
void Parser::parse() {
|
||||
|
@ -61,162 +62,167 @@ void Parser::parse() {
|
|||
Declaration currentDeclaration;
|
||||
|
||||
while (true) {
|
||||
c = getByte();
|
||||
if (c == '\n' || c == '\0' || (!isComment && (c == ' ' || c == '\t' || c == ',' || c == ';'))) {
|
||||
//End token
|
||||
try{
|
||||
c = getByte();
|
||||
if (c == '\n' || c == '\0' || (!isComment && (c == ' ' || c == '\t' || c == ',' || c == ';'))) {
|
||||
//End token
|
||||
|
||||
//TODO: identify Token
|
||||
if (!currentValue.empty()) {
|
||||
bool foundToken = false;
|
||||
for (auto &t : states[currentStateIndex]) {
|
||||
switch (t.first) {
|
||||
case Token::Type::Label:
|
||||
if (isLabel(currentValue)) {
|
||||
if (!currentFunction.label.empty()) {
|
||||
functions.emplace_back(std::move(currentFunction));
|
||||
currentFunction = Function();
|
||||
}
|
||||
currentFunction.label = currentValue.substr(0, currentValue.size() - 1);
|
||||
//TODO: identify Token
|
||||
if (!currentValue.empty()) {
|
||||
bool foundToken = false;
|
||||
for (auto &t : states[currentStateIndex]) {
|
||||
switch (t.first) {
|
||||
case Token::Type::Label:
|
||||
if (isLabel(currentValue)) {
|
||||
if (!currentFunction.label.empty()) {
|
||||
functions.emplace_back(std::move(currentFunction));
|
||||
currentFunction = Function();
|
||||
}
|
||||
currentFunction.label = currentValue.substr(0, currentValue.size() - 1);
|
||||
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::LocalLabel:
|
||||
if (isLocalLabel(currentValue)) {
|
||||
currentDeclaration.label = currentValue.substr(0, currentValue.size() - 1);
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::Operator:
|
||||
if (isOperator(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(Token(t.first, currentValue));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::RegisterLocation:
|
||||
if (isRegisterLocation(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue.substr(1, std::string::npos),
|
||||
std::stoi(currentValue.substr(1, std::string::npos), nullptr, 0)));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::CodeLabel:
|
||||
if (isCodeLabel(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue.substr(1, std::string::npos)));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::CodeLocation:
|
||||
if (isCodeLocation(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue.substr(1, std::string::npos),
|
||||
std::stoi(currentValue.substr(1, std::string::npos), nullptr, 0)));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::Immediate:
|
||||
if (isImmediate(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue, std::stoi(currentValue, nullptr, 0)));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::Offset:
|
||||
if (isOffset(currentValue) && !currentDeclaration.tokens.empty()) {
|
||||
auto& prevValue = currentDeclaration.tokens.at(currentDeclaration.tokens.size() - 1);
|
||||
if(prevValue.getType() == Token::Type::Immediate || prevValue.getType() == Token::Type::CodeLabel || prevValue.getType() == Token::Type::CodeLocation || prevValue.getType() == Token::Type::RegisterLocation){
|
||||
prevValue.valueImmediate += std::stoi(currentValue, nullptr, 0);
|
||||
}else{
|
||||
throw std::runtime_error("Cannot apply Offset to value not numeric");
|
||||
foundToken = true;
|
||||
}
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::Directive:
|
||||
if (isDirective(currentValue) && currentValue == ".constant") {
|
||||
if (!currentFunction.label.empty()) {
|
||||
functions.emplace_back(std::move(currentFunction));
|
||||
currentFunction = Function();
|
||||
break;
|
||||
case Token::Type::LocalLabel:
|
||||
if (isLocalLabel(currentValue)) {
|
||||
currentDeclaration.label = currentValue.substr(0, currentValue.size() - 1);
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::Operator:
|
||||
if (isOperator(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(Token(t.first, currentValue));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::RegisterLocation:
|
||||
if (isRegisterLocation(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue.substr(1, std::string::npos),
|
||||
std::stoul(currentValue.substr(1, std::string::npos), nullptr, 0)));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::CodeLabel:
|
||||
if (isCodeLabel(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue.substr(1, std::string::npos)));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::CodeLocation:
|
||||
if (isCodeLocation(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue.substr(1, std::string::npos),
|
||||
std::stoul(currentValue.substr(1, std::string::npos), nullptr, 0)));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::Immediate:
|
||||
if (isImmediate(currentValue)) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue, std::stoul(currentValue, nullptr, 0)));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::Offset:
|
||||
if (isOffset(currentValue) && !currentDeclaration.tokens.empty()) {
|
||||
auto& prevValue = currentDeclaration.tokens.at(currentDeclaration.tokens.size() - 1);
|
||||
if(prevValue.getType() == Token::Type::Immediate || prevValue.getType() == Token::Type::CodeLabel || prevValue.getType() == Token::Type::CodeLocation || prevValue.getType() == Token::Type::RegisterLocation){
|
||||
prevValue.valueImmediate += std::stoi(currentValue, nullptr, 0);
|
||||
}else{
|
||||
throw std::runtime_error("Cannot apply Offset to value not numeric");
|
||||
}
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::Directive:
|
||||
if (isDirective(currentValue) && currentValue == ".constant") {
|
||||
if (!currentFunction.label.empty()) {
|
||||
functions.emplace_back(std::move(currentFunction));
|
||||
currentFunction = Function();
|
||||
}
|
||||
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue));
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
case Token::Type::BareValue:
|
||||
if (isAlphaNumeric(currentValue)) {
|
||||
if (currentDeclaration.tokens.size() == 1 &&
|
||||
currentDeclaration.tokens.at(0).getType() == Token::Type::Directive) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue));
|
||||
} else {
|
||||
if (variables.find(currentValue) != variables.end()) {
|
||||
for (auto &token : variables[currentValue]) {
|
||||
currentDeclaration.tokens.emplace_back(token);
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("Unknown variable " + currentValue);
|
||||
}
|
||||
foundToken = true;
|
||||
}
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case Token::Type::BareValue:
|
||||
if (isAlphaNumeric(currentValue)) {
|
||||
if (currentDeclaration.tokens.size() == 1 &&
|
||||
currentDeclaration.tokens.at(0).getType() == Token::Type::Directive) {
|
||||
currentDeclaration.tokens.emplace_back(
|
||||
Token(t.first, currentValue));
|
||||
} else {
|
||||
if (variables.find(currentValue) != variables.end()) {
|
||||
for (auto &token : variables[currentValue]) {
|
||||
currentDeclaration.tokens.emplace_back(token);
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("Unknown variable " + currentValue);
|
||||
}
|
||||
}
|
||||
foundToken = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (foundToken) {
|
||||
currentValue.clear();
|
||||
currentStateIndex = t.second;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (foundToken) {
|
||||
currentValue.clear();
|
||||
currentStateIndex = t.second;
|
||||
if (!foundToken) {
|
||||
//TODO: ERROR
|
||||
throw std::runtime_error("Could not find new Token state");
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\n' || c == '\0') {
|
||||
isComment = false;
|
||||
if (resetStateIndex < currentStateIndex) {
|
||||
currentStateIndex = resetStateIndex;
|
||||
}
|
||||
|
||||
if (!currentDeclaration.tokens.empty()) {
|
||||
if (currentDeclaration.tokens.size() >= 3 &&
|
||||
currentDeclaration.tokens.at(0).getType() == Token::Type::Directive) {
|
||||
if (currentDeclaration.tokens.at(0).getTextValue() == ".constant") {
|
||||
std::vector<Token> tokens;
|
||||
for (auto it = currentDeclaration.tokens.begin() + 2;
|
||||
it < currentDeclaration.tokens.end(); ++it) {
|
||||
tokens.push_back(*it);
|
||||
}
|
||||
variables[currentDeclaration.tokens.at(1).getTextValue()] = tokens;
|
||||
}
|
||||
currentDeclaration = Declaration();
|
||||
currentStateIndex = 0;
|
||||
} else {
|
||||
currentFunction.declarations.emplace_back(std::move(currentDeclaration));
|
||||
currentDeclaration = Declaration();
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\0') {
|
||||
functions.emplace_back(std::move(currentFunction));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!foundToken) {
|
||||
//TODO: ERROR
|
||||
throw std::runtime_error("Could not find new Token state");
|
||||
if (c == ';') {
|
||||
isComment = true;
|
||||
}
|
||||
} else if (!isComment) {
|
||||
currentValue += c;
|
||||
}
|
||||
|
||||
if (c == '\n' || c == '\0') {
|
||||
isComment = false;
|
||||
if (resetStateIndex < currentStateIndex) {
|
||||
currentStateIndex = resetStateIndex;
|
||||
}
|
||||
|
||||
if (!currentDeclaration.tokens.empty()) {
|
||||
if (currentDeclaration.tokens.size() >= 3 &&
|
||||
currentDeclaration.tokens.at(0).getType() == Token::Type::Directive) {
|
||||
if (currentDeclaration.tokens.at(0).getTextValue() == ".constant") {
|
||||
std::vector<Token> tokens;
|
||||
for (auto it = currentDeclaration.tokens.begin() + 2;
|
||||
it < currentDeclaration.tokens.end(); ++it) {
|
||||
tokens.push_back(*it);
|
||||
}
|
||||
variables[currentDeclaration.tokens.at(1).getTextValue()] = tokens;
|
||||
}
|
||||
currentDeclaration = Declaration();
|
||||
currentStateIndex = 0;
|
||||
} else {
|
||||
currentFunction.declarations.emplace_back(std::move(currentDeclaration));
|
||||
currentDeclaration = Declaration();
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\0') {
|
||||
functions.emplace_back(std::move(currentFunction));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c == ';') {
|
||||
isComment = true;
|
||||
}
|
||||
} else if (!isComment) {
|
||||
currentValue += c;
|
||||
}catch (const std::exception& e){
|
||||
std::cerr << "Exception: " << e.what() << " on " << currentFunction.label << "\n";
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,8 +173,8 @@ namespace Instruction {
|
|||
segments.push_back(segment);
|
||||
}
|
||||
|
||||
uint8_t offset1 = segments.size() > 1 ? std::stoi(segments.at(1).substr(0, 1), nullptr, 10) : 0;
|
||||
uint8_t offset2 = (segments.size() > 1 && segments.at(1).size() > 1) ? std::stoi(
|
||||
uint8_t offset1 = segments.size() > 1 ? std::stoul(segments.at(1).substr(0, 1), nullptr, 10) : 0;
|
||||
uint8_t offset2 = (segments.size() > 1 && segments.at(1).size() > 1) ? std::stoul(
|
||||
segments.at(1).substr(1, 1), nullptr, 10) : 0;
|
||||
|
||||
return Instruction::parseOperatorResult{
|
||||
|
|
Loading…
Reference in a new issue