此教程实现一个simple语言
这是一个编译型语言,编译成nasm
simple.h
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <unordered_set>
#include <set>
void clearFileContent(const std::string& filePath) {
std::ofstream file(filePath, std::ofstream::out | std::ofstream::trunc);
if (!file) {
std::cerr << "无法打开文件进行清空操作:" << filePath << std::endl;
}
file.close();
}
void copyFileContent(const std::string& sourceFilePath, const std::string& destinationFilePath) {
std::ifstream sourceFile(sourceFilePath);
if (!sourceFile) {
std::cerr << "无法打开源文件:" << sourceFilePath << std::endl;
return;
}
std::ofstream destinationFile(destinationFilePath, std::ios_base::app);
if (!destinationFile) {
std::cerr << "无法打开目标文件:" << destinationFilePath << std::endl;
return;
}
std::string line;
while (std::getline(sourceFile, line)) {
destinationFile << line << std::endl;
}
sourceFile.close();
destinationFile.close();
}
void convertToAsm(const std::string& inputFilePath, const std::string& outputFilePath, std::unordered_set<std::string>& processedFiles) {
std::ifstream inputFile(inputFilePath);
if (!inputFile) {
std::cerr << "无法打开输入文件:" << inputFilePath << std::endl;
return;
}
std::ofstream outputFile(outputFilePath, std::ios_base::app);
if (!outputFile) {
std::cerr << "无法创建输出文件:" << outputFilePath << std::endl;
return;
}
std::string line;
bool inBlockComment = false;
bool inNasmBlock = false;
std::string nasmContent;
while (std::getline(inputFile, line)) {
std::string trimmedLine = line;
while (!trimmedLine.empty() && (trimmedLine[0] == ' ' || trimmedLine[0] == '\t')) {
trimmedLine.erase(0, 1);
}
if (trimmedLine.empty()) continue;
if (trimmedLine.find("//") == 0) continue;
if (trimmedLine.find("/*")!= std::string::npos) {
inBlockComment = true;
}
if (inBlockComment) {
if (trimmedLine.find("*/")!= std::string::npos) {
inBlockComment = false;
}
continue;
}
if (line.find("main()")!= std::string::npos) {
outputFile << "main:\n push rbp\n mov rbp, rsp\n";
} else if (line.find("print(")!= std::string::npos) {
std::string content = line.substr(line.find("(") + 1, line.find(")") - line.find("(") - 1);
outputFile << " sub rsp, 20h\n";
outputFile << " mov rcx, " << content << "\n";
outputFile << " call printf\n";
outputFile << " add rsp, 20h\n";
} else if (line.find("return")!= std::string::npos) {
std::string content = line.substr(line.find("return") + 6, line.find("\n") - line.find("return") - 6);
outputFile << " mov eax," << content << "\n";
outputFile << " pop rbp\n ret\n";
} else if (line.find("str ")!= std::string::npos) {
size_t spacePos = line.find(" ");
size_t equalPos = line.find("=");
if (spacePos == std::string::npos || equalPos == std::string::npos) {
std::cerr << "错误的字符串定义格式:" << line << std::endl;
continue;
}
std::string content1 = line.substr(spacePos + 1, equalPos - spacePos - 1);
std::string content2 = line.substr(equalPos + 1);
outputFile << "jmp " << content1 << "_end\n" << content1 << " db " << content2 << ",0\n" << content1 << "_end:\n";
} else if (line.find("#NASM")!= std::string::npos) {
size_t endPos = line.find("}#NASM_END");
if (endPos == std::string::npos) {
std::cerr << "未找到 #NASM_END :" << line << std::endl;
continue;
}
std::string content = line.substr(line.find("#NASM{") + 6, endPos - line.find("#NASM{") - 6);
outputFile << content << std::endl;
} else if (line.find("int ")!= std::string::npos) {
size_t spacePos = line.find(" ");
size_t equalPos = line.find("=");
if (spacePos == std::string::npos || equalPos == std::string::npos) {
std::cerr << "错误的整数定义格式:" << line << std::endl;
continue;
}
std::string content1 = line.substr(spacePos + 1, equalPos - spacePos - 1);
std::string content2 = line.substr(equalPos + 1);
outputFile << "jmp " << content1 << "_end\n" << content1 << " db " << content2 << "\n" << content1 << "_end:\n";
} else if (line.find("input(")!= std::string::npos) {
std::string content = line.substr(line.find("(") + 1, line.find(")") - line.find("(") - 1);
outputFile << " " << content << "1 resb 50\n";
outputFile << " sub rsp, 20h\n";
outputFile << " lea rdx, [" << content << "1]\n";
outputFile << " lea rcx, [aS]\n";
outputFile << " call scanf\n";
outputFile << " add rsp, 20h\n";
outputFile << " " << content << " db " << content << "1,0\n";
} else if (line.find("system(")!= std::string::npos) {
std::string content = line.substr(line.find("(") + 1, line.find(")") - line.find("(") - 1);
outputFile << " sub rsp, 20h\n";
outputFile << " lea rcx, [" << content << "]\n";
outputFile << " call system\n";
outputFile << " add rsp, 20h\n";
} else if (line.find("#include")!= std::string::npos) {
size_t startQuote = line.find('"');
size_t endQuote = line.rfind('"');
if (startQuote!= std::string::npos && endQuote!= std::string::npos && startQuote < endQuote) {
std::string includeFileName = line.substr(startQuote + 1, endQuote - startQuote - 1);
if (processedFiles.find(includeFileName) == processedFiles.end()) {
processedFiles.insert(includeFileName);
copyFileContent(includeFileName, outputFilePath);
}
}
} else if (line.find("MessageBoxA(")!= std::string::npos) {
size_t start = line.find("(");
size_t mid = line.find(",");
size_t end = line.find(")");
std::string content1 = line.substr(start + 1, mid - start - 1);
std::string content2 = line.substr(mid + 1, end - mid - 1);
outputFile << " sub rsp, 20h\n mov r9d, 0\n lea r8, [" << content1 << "]\n";
outputFile << " lea rdx, [" << content2 << "]\n" << " mov rcx, 0\n mov rax, [__imp_MessageBoxA]\n call rax\n add rsp, 20h\n";
} else if (line.find("if(")!= std::string::npos) {
size_t startOpenParen = line.find("(");
size_t endOpenParen = line.find(")");
std::string condition = line.substr(startOpenParen + 1, endOpenParen - startOpenParen - 1);
size_t comparisonOpPos = 0;
if ((comparisonOpPos = condition.find("=="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " je " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find("<="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jle " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find(">="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jge " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find("<"))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 1);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jl " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find(">"))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 1);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jg " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find("!="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " pop rax\n";
outputFile << " jne " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else {
std::cerr << "错误的 if 条件格式:" << line << std::endl;
continue;
}
} else if (line.find("func")!= std::string::npos) {
size_t start = line.find("(");
size_t func = line.find("func");
std::string content1 = line.substr(func + 1, start - func - 1);
outputFile << content1 << ":\n push rbp\n mov rbp, rsp\n";
} else if (line.find("use")!= std::string::npos) {
size_t start = line.find("()");
size_t func = line.find("use");
std::string content1 = line.substr(func + 1, start - func - 1);
outputFile << "call" << content1 << "\n";
} else if (line.find("while(")!= std::string::npos) {
size_t startOpenParen = line.find("(");
size_t endOpenParen = line.find(")");
std::string condition = line.substr(startOpenParen + 1, endOpenParen - startOpenParen - 1);
size_t comparisonOpPos = 0;
if ((comparisonOpPos = condition.find("=="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " je " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find("<="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jle " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find(">="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jge " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find("<"))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 1);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jl " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find(">"))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 1);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jg " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else if ((comparisonOpPos = condition.find("!="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
std::string labelTrue = "__if_true_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__if_end_" + std::to_string(outputFile.tellp());
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " pop rax\n";
outputFile << " jne " << labelTrue << "\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelTrue << ":\n";
// Process the code inside the if block.
while (std::getline(inputFile, line) &&!line.find("}")) {
convertToAsm(line, outputFilePath, processedFiles);
}
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelEnd << ":\n";
} else {
std::cerr << "错误的 if 条件格式:" << line << std::endl;
continue;
}
} else if (line.find("while(")!= std::string::npos) {
size_t startOpenParen = line.find("(");
size_t endOpenParen = line.find(")");
std::string condition = line.substr(startOpenParen + 1, endOpenParen - startOpenParen - 1);
size_t comparisonOpPos = 0;
std::string labelStart = "__while_start_" + std::to_string(outputFile.tellp());
std::string labelEnd = "__while_end_" + std::to_string(outputFile.tellp());
outputFile << labelStart << ":\n";
if ((comparisonOpPos = condition.find("=="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " je " << labelStart << "_true\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelStart << "_true:\n";
bool inWhileBlock = true;
std::ifstream inputFile;
if (outputFile.is_open()) {
inputFile.open(outputFilePath);
}
std::streampos startPos = inputFile.tellg();
while (inWhileBlock) {
std::string nextLine;
if (std::getline(inputFile, nextLine)) {
if (nextLine.find("}")!= std::string::npos) {
inWhileBlock = false;
} else {
convertToAsm(nextLine, outputFilePath, processedFiles);
}
} else {
inWhileBlock = false;
}
}
inputFile.clear();
inputFile.seekg(startPos);
outputFile << " jmp " << labelStart << "\n";
outputFile << labelEnd << ":\n";
if (inputFile.is_open()) {
inputFile.close();
}
} else if ((comparisonOpPos = condition.find("<="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jle " << labelStart << "_true\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelStart << "_true:\n";
bool inWhileBlock = true;
std::ifstream inputFile;
if (outputFile.is_open()) {
inputFile.open(outputFilePath);
}
std::streampos startPos = inputFile.tellg();
while (inWhileBlock) {
std::string nextLine;
if (std::getline(inputFile, nextLine)) {
if (nextLine.find("}")!= std::string::npos) {
inWhileBlock = false;
} else {
convertToAsm(nextLine, outputFilePath, processedFiles);
}
} else {
inWhileBlock = false;
}
}
inputFile.clear();
inputFile.seekg(startPos);
outputFile << " jmp " << labelStart << "\n";
outputFile << labelEnd << ":\n";
if (inputFile.is_open()) {
inputFile.close();
}
} else if ((comparisonOpPos = condition.find(">="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jge " << labelStart << "_true\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelStart << "_true:\n";
bool inWhileBlock = true;
std::ifstream inputFile;
if (outputFile.is_open()) {
inputFile.open(outputFilePath);
}
std::streampos startPos = inputFile.tellg();
while (inWhileBlock) {
std::string nextLine;
if (std::getline(inputFile, nextLine)) {
if (nextLine.find("}")!= std::string::npos) {
inWhileBlock = false;
} else {
convertToAsm(nextLine, outputFilePath, processedFiles);
}
} else {
inWhileBlock = false;
}
}
inputFile.clear();
inputFile.seekg(startPos);
outputFile << " jmp " << labelStart << "\n";
outputFile << labelEnd << ":\n";
if (inputFile.is_open()) {
inputFile.close();
}
} else if ((comparisonOpPos = condition.find("<"))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 1);
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jl " << labelStart << "_true\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelStart << "_true:\n";
bool inWhileBlock = true;
std::ifstream inputFile;
if (outputFile.is_open()) {
inputFile.open(outputFilePath);
}
std::streampos startPos = inputFile.tellg();
while (inWhileBlock) {
std::string nextLine;
if (std::getline(inputFile, nextLine)) {
if (nextLine.find("}")!= std::string::npos) {
inWhileBlock = false;
} else {
convertToAsm(nextLine, outputFilePath, processedFiles);
}
} else {
inWhileBlock = false;
}
}
inputFile.clear();
inputFile.seekg(startPos);
outputFile << " jmp " << labelStart << "\n";
outputFile << labelEnd << ":\n";
if (inputFile.is_open()) {
inputFile.close();
}
} else if ((comparisonOpPos = condition.find(">"))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 1);
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " push rax\n";
outputFile << " jg " << labelStart << "_true\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelStart << "_true:\n";
bool inWhileBlock = true;
std::ifstream inputFile;
if (outputFile.is_open()) {
inputFile.open(outputFilePath);
}
std::streampos startPos = inputFile.tellg();
while (inWhileBlock) {
std::string nextLine;
if (std::getline(inputFile, nextLine)) {
if (nextLine.find("}")!= std::string::npos) {
inWhileBlock = false;
} else {
convertToAsm(nextLine, outputFilePath, processedFiles);
}
} else {
inWhileBlock = false;
}
}
inputFile.clear();
inputFile.seekg(startPos);
outputFile << " jmp " << labelStart << "\n";
outputFile << labelEnd << ":\n";
if (inputFile.is_open()) {
inputFile.close();
}
} else if ((comparisonOpPos = condition.find("!="))!= std::string::npos) {
std::string leftOperand = condition.substr(0, comparisonOpPos);
std::string rightOperand = condition.substr(comparisonOpPos + 2);
outputFile << " push rax\n";
outputFile << " mov rax, " << leftOperand << "\n";
outputFile << " cmp rax, " << rightOperand << "\n";
outputFile << " pop rax\n";
outputFile << " jne " << labelStart << "_true\n";
outputFile << " jmp " << labelEnd << "\n";
outputFile << labelStart << "_true:\n";
bool inWhileBlock = true;
std::ifstream inputFile;
if (outputFile.is_open()) {
inputFile.open(outputFilePath);
}
std::streampos startPos = inputFile.tellg();
while (inWhileBlock) {
std::string nextLine;
if (std::getline(inputFile, nextLine)) {
if (nextLine.find("}")!= std::string::npos) {
inWhileBlock = false;
} else {
convertToAsm(nextLine, outputFilePath, processedFiles);
}
} else {
inWhileBlock = false;
}
}
inputFile.clear();
inputFile.seekg(startPos);
outputFile << " jmp " << labelStart << "\n";
outputFile << labelEnd << ":\n";
if (inputFile.is_open()) {
inputFile.close();
}
} else {
std::cerr << "错误的 while 条件格式:" << line << std::endl;
}
}
}
inputFile.close();
outputFile.close();
}
simple.cpp
#include "simple.h"
int main(int argc, char* argv[]) {
if (argc!= 3) {
std::cerr << "用法:程序名 输入文件路径 输出文件路径" << std::endl;
system("pause");
return 1;
}
std::unordered_set<std::string> processedFiles;
clearFileContent(argv[2]);
convertToAsm(argv[1], argv[2], processedFiles);
return 0;
}
编译:
g++ simple.cpp -o simple -std=c++11
.\simple input.si a.asm
nasm -f win64 -o a.obj a.asm
gcc a.obj -o a.exe
input.si
#include"simpleio.si"
main(){
str title="title"
str text="hello",0x0A
str cmd="pause"
int i=0
MessageBoxA(title,text)
print(text)
system(cmd)
return 0
}
simpleio.si
global main
extern printf
extern scanf
extern system
extern __imp_MessageBoxA
SECTION .data
aS db '%s',0
SECTION .text
自己写一个高亮代码编辑器
import tkinter as tk
from tkinter import filedialog, messagebox
class CodeEditor(tk.Tk):
def __init__(self):
super().__init__()
self.title('高亮代码编辑器')
self.geometry('600x400')
# 创建用于显示行号的Canvas组件
self.lineno = tk.Canvas(self, width=40, bg='light grey')
self.lineno.pack(side=tk.LEFT, fill=tk.Y)
# 创建垂直滚动条
self.vsb = tk.Scrollbar(self, orient="vertical")
self.vsb.pack(side=tk.RIGHT, fill=tk.Y)
self.text_editor = tk.Text(self, bg='black', fg='white', insertbackground='white')
self.text_editor.pack(fill=tk.BOTH, expand=True)
# 绑定 <<Modified>> 事件到 text_editor_change 方法
self.text_editor.bind("<<Modified>>", self.text_editor_change)
self.create_menu()
# 初始化keywords字典
self.keywords = {
'赋值': '#00ffff',
'加': '#00ffff',
'减': '#00ffff',
'调用': '#00ffff',
'定义': '#00ffff',
';': '#aaaaaa',
'“': '#00ff00',
'”': '#00ff00',
'主函数': '#ff0000',
'返回': '#ff0000',
'声明': '#aa00ff',
'全局': '#aa00ff',
'代码段': '#aa00ff',
'0': '#ffff00',
'1': '#ffff00',
'2': '#ffff00',
'3': '#ffff00',
'4': '#ffff00',
'5': '#ffff00',
'6': '#ffff00',
'7': '#ffff00',
'8': '#ffff00',
'9': '#ffff00',
'0x': '#ffff00',
'栈顶': '#848400',
'rax': '#848400',
'rbx': '#848400',
'rcx': '#848400',
'rdx': '#848400'
}
self.highlight_keywords()
# 更新行号
self.update_line_numbers()
# 配置滚动条
self.vsb['command'] = self.on_vsb_move
def on_text_yview(self, *args):
# 更新行号
self.update_line_numbers()
# 调用垂直滚动条的set方法
self.vsb.set(*args)
def create_menu(self):
menu_bar = tk.Menu(self)
self.config(menu=menu_bar)
file_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label='文件', menu=file_menu)
file_menu.add_command(label='打开', command=self.open_file)
file_menu.add_command(label='保存', command=self.save_file)
mode_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label='模式', menu=mode_menu)
mode_menu.add_command(label='CASM', command=self.CASM)
mode_menu.add_command(label='NASM', command=self.NASM)
mode_menu.add_command(label='simple', command=self.simple)
other_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label='其他', menu=other_menu)
other_menu.add_command(label='关于', command=self.about)
other_menu.add_command(label='...', command=self.nothing)
def open_file(self):
filepath = filedialog.askopenfilename()
if filepath:
with open(filepath, 'r') as file:
content = file.read()
self.text_editor.delete(1.0, tk.END)
self.text_editor.insert(1.0, content)
# 调用 text_editor_change 以高亮显示新内容
self.text_editor_change(None)
def save_file(self):
filepath = filedialog.asksaveasfilename(defaultextension='.txt')
if filepath:
content = self.text_editor.get(1.0, tk.END)
with open(filepath, 'w') as file:
file.write(content)
def highlight_keywords(self):
for keyword, color in self.keywords.items():
self.text_editor.tag_config(keyword, foreground=color)
start = '1.0'
while True:
pos = self.text_editor.search(keyword, start, stopindex=tk.END)
if not pos: break
end = f'{pos}+{len(keyword)}c'
self.text_editor.tag_add(keyword, pos, end)
start = end
def text_editor_change(self, event):
self.text_editor.edit_modified(False) # 清除已修改标记
self.highlight_keywords() # 重新高亮显示关键词
self.update_line_numbers() # 更新行号
def update_line_numbers(self):
# Clear existing line numbers
self.lineno.delete("all")
# Get the total number of lines in the text editor
line_count = int(self.text_editor.index('end-1c').split('.')[0])
# Redraw the line numbers based on the actual position of each line in the text editor
for i in range(1, line_count + 1):
# Get the top-left and bottom-right coordinates of the line in the text editor
bbox = self.text_editor.bbox(f"{i}.0")
if bbox:
# The third element of bbox represents the Y-coordinate of the top-left corner of the line
y = bbox[1]
# Draw the line number at the appropriate position in the canvas
self.lineno.create_text(2, y, anchor="nw", text=str(i), fill="dark blue")
def on_vsb_move(self, first, last):
try:
first_float = float(first)
self.text_editor.yview_moveto(first_float)
except ValueError:
pass
def nothing(self):
pass
def about(self):
messagebox.showinfo("关于", "作者:林泓翰")
def NASM(self):
global keywords
self.keywords = {
'mov': '#00ffff',
'add': '#00ffff',
'sub': '#00ffff',
'call': '#00ffff',
'db': '#00ffff',
';': '#aaaaaa',
'"': '#00ff00',
'main': '#ff0000',
'ret': '#ff0000',
'extern': '#aa00ff',
'global': '#aa00ff',
'SECTION .test': '#aa00ff',
'0': '#ffff00',
'1': '#ffff00',
'2': '#ffff00',
'3': '#ffff00',
'4': '#ffff00',
'5': '#ffff00',
'6': '#ffff00',
'7': '#ffff00',
'8': '#ffff00',
'9': '#ffff00',
'0x': '#ffff00',
'rsp': '#848400',
'rax': '#848400',
'rbx': '#848400',
'rcx': '#848400',
'rdx': '#848400'
}
def simple(self):
global keywords
self.keywords = {
'print': '#00ffff',
'input': '#00ffff',
'int': '#00ffff',
'str': '#00ffff',
'MessageBoxA': '#00ffff',
'/*': '#aaaaaa',
'//': '#aaaaaa',
'"': '#00ff00',
'main': '#ff0000',
'return': '#ff0000',
'0': '#ffff00',
'1': '#ffff00',
'2': '#ffff00',
'3': '#ffff00',
'4': '#ffff00',
'5': '#ffff00',
'6': '#ffff00',
'7': '#ffff00',
'8': '#ffff00',
'9': '#ffff00',
'0x': '#ffff00',
'#NASM_END': '#848400',
'#NASM': '#848400',
'#include': '#848400',
'{': '#848400',
'}': '#848400'
}
def CASM(self):
global keywords
self.keywords = {
'赋值': '#00ffff',
'加': '#00ffff',
'减': '#00ffff',
'调用': '#00ffff',
'定义': '#00ffff',
';': '#aaaaaa',
'“': '#00ff00',
'”': '#00ff00',
'主函数': '#ff0000',
'返回': '#ff0000',
'声明': '#aa00ff',
'全局': '#aa00ff',
'代码段': '#aa00ff',
'0': '#ffff00',
'1': '#ffff00',
'2': '#ffff00',
'3': '#ffff00',
'4': '#ffff00',
'5': '#ffff00',
'6': '#ffff00',
'7': '#ffff00',
'8': '#ffff00',
'9': '#ffff00',
'0x': '#ffff00',
'栈顶': '#848400',
'rax': '#848400',
'rbx': '#848400',
'rcx': '#848400',
'rdx': '#848400'
}
if __name__ == '__main__':
app = CodeEditor()
app.mainloop()
看来很成功