自制编程语言(一、基本的编译器)

news2024/10/19 14:02:37

此教程实现一个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()

 

 

看来很成功 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2218528.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如在下载自己的需要的rmp包呢

下载地址&#xff1a;https://pkgs.org/和https://rpmfind.net/linux/rpm2html/search.php 根基自己的需要进行下载使用。

IRMV Lab新作:Mamba Diffusion模型实现高精度2D手部轨迹预测

作者主页&#xff1a; https://bit-mjy.github.io/ https://xieyuanli-chen.com/ 论文标题&#xff1a; MADiff: Motion-Aware Mamba Diffusion Models for Hand Trajectory Prediction on Egocentric Videos 1. 背景与挑战 在具身人工智能&#xff08;Embodied AI&#xff0…

NAT机制

目录 1、NAT机制的定义 2、NAT机制的工作原理 1、NAT机制的定义 如今IP地址的分配已经不够使用&#xff0c;为了解决这一问题&#xff0c;NAT机制起到了很关键的作用。 NAT机制&#xff08;网络地址转换&#xff09;&#xff0c;本质上&#xff0c;让一个IP地址代表一批设备…

【SpringBoot】14 缓存(cache)

Gitee仓库 https://gitee.com/Lin_DH/system 介绍 Spring 框架支持透明地向应用程序添加缓存对缓存进行管理&#xff0c;其管理缓存的核心是将缓存应用于操作数据的方法&#xff08;包括增删查改等&#xff09;&#xff0c;从而减少操作数据的执行次数&#xff08;主要是查询…

录微课专用提词器,不会被录进视频中的提词器,还能显示PPT中备注的内容

不坑提词器&#xff0c;全称&#xff1a;不坑隐形提词器。是一款能够在截图、录屏、直播过程中隐藏界面的提词器软件。 系统要求&#xff1a;Win10 1024 以上&#xff08;特别提醒&#xff1a;Win7状态下不可隐身&#xff09; ⏬下载 提词器默认放在不坑盒子的安装目录下&…

基于springboot家乡特色推荐系统

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 系统展示 【2024最新】基于JavaSpringBootVueMySQL的&#xff0c;前后端分离。 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;…

【YOLOv11】制作使用YOLOv11的docker环境

目录 一 安装docker 1 安装依赖 2 添加docker官网 GPG 密钥、设置stable 仓库 3 安装 4 使用 二 环境制作 ① 拉基础镜像 ② 起容器 ③ 安装Anaconda3 ④ 安装YOLO11 ⑤ /root/.bashrc ⑥ 退出容器 ⑦ 保存镜像 ⑧ 镜像的使用 一 安装docker ubuntu:20.04 1 安装…

与双指针的亲密接触:快与慢的浪漫交错

公主请阅 1.合并两个有序数组1.1 题目说明示例 1示例 2示例 3 1.2 题目分析 1.3代码部分1.4 代码解析 2.移动零2.1题目说明示例 1示例 2 2.2题目分析2.3代码部分2.4代码解析 1.合并两个有序数组 题目传送门 1.1 题目说明 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums…

25计软新增考研院校!或可捡漏上岸!

C哥专业提供——计软考研院校选择分析专业课备考指南规划 新增的计算机与软件工程考研院校为考研同学带来了多方面的机遇&#xff0c;这些机遇不仅体现在过国家线后可能面临的更低竞争压力&#xff0c;还包括更多元化的教育选择和更广阔的就业前景&#xff1a; 一、降低竞争压…

周报5<仅供自己学习>

文章目录 一、NeRF代码1.齐次化位姿坐标2.理解rays_d和rays_o3.min_line_dist的函数问题1&#xff1a;该函数的作用问题2&#xff1a;为何要计算ray_d的外积①形成投影矩阵&#xff08;1&#xff09;投影矩阵&#xff08;2&#xff09;投影矩阵的性质&#xff08;3&#xff09;…

网络编程基础-IO模型深入理解

一、IO的基本概念 什么是IO&#xff1f; I/O就是计算机内存与外部设备之间拷贝数据的过程 什么是网络IO&#xff1f; 网络IO是指在计算机网络环境中进行的输入和输出操作&#xff0c;涉及数据在网络设备之间的传输。 网络IO操作可以是发送请求、接收响应、下载文件、传输数…

adb devices没找到安卓设备的解决办法

要想让设备让adb识别到&#xff0c;要开启设备的开发者模式&#xff0c;并且开启USB调试功能&#xff1a; 然后重新运行&#xff1a;就找到了

Linux零基础教程学习(黑马)

1.初识Linux 1.2远程连接Linux系统 图形化、命令行 对于操作系统的使用&#xff0c;有2种使用形式&#xff1a; 图形化页面使用操作系统 以命令的形式使用操作系统 不论是Windows还是Linux亦或是MacOS系统&#xff0c;都是支持这两种使用形式。 图形化&#xff1a;使用操作…

前端页面使用google地图api实现导航功能,开发国外网站免费简单好用

开发国外软件的时候&#xff0c;想使用goole map实现导航等功能&#xff0c;可以使用google的api来做&#xff0c;官方文档地址&#xff1a;https://developers.google.com/maps/documentation/urls/get-started?hlzh-cn &#xff0c;比如&#xff1a; 支持的请求的操作&…

基于MATLAB/octave的容积卡尔曼滤波(CKF)【带逐行注释】

介绍 CKF的三维滤波程序例程 产品概述 我们的 MATLAB 数据处理工具是专为科研人员、工程师和数据分析师设计的高效解决方案。该工具提供了一系列强大的功能&#xff0c;能够快速处理和分析大规模数据集&#xff0c;适用于各种科学和工程应用&#xff0c;包括信号处理、图像分…

Redis Search系列 - 第四讲 支持中文

目录 一、支持中文二、自定义中文词典2.1 Redis Search设置FRISOINI参数2.2 friso.ini文件相关配置1&#xff09;自定义friso UTF-8字典2&#xff09;修改friso.ini配置文件 三、实测中文分词效果 一、支持中文 Redis Stack 从版本 0.99.0 开始支持中文文档的添加和分词。中文…

什么是大数据分析:定义、优缺点、应用、机遇和风险

大数据分析的概念已经成为我们社会不可或缺的一部分。众多公司和机构已经开发了大数据应用程序&#xff0c;取得了不同程度的成功。社交媒体平台和传感器等技术正在以前所未有的速度生成数据&#xff0c;就像一条装配线。如今&#xff0c;几乎所有东西都是物联网的一部分&#…

C#教程笔记

C#开发的程序依附.NET平台 编译器->IL中间语言->CLR->机器指令 .NET CORE平台 跨平台 .cs后缀名 快捷键 CtrlKD格式化CtrlL或CtrlX删除一行CtrlY反撤销cwTab快速生成命令行输出Ctrl空格或CtrlJ获取提示///方法注释CtrlMO代码全部折叠CtrlML代码全部展开 上升沿0变1 安…

硬件产品经理的开店冒险之旅(下篇)

缘起&#xff1a;自己为何想要去寻找职业第二曲线 承接上篇的内容&#xff0c;一名工作13年的普通硬件产品经理将尝试探索第二职业曲线。根本原因不是出于什么高大上的人生追求或者什么职业理想主义&#xff0c;就是限于目前的整体就业形式到了40岁的IT从业人员基本不可能在岗…

Spring Boot技术栈在电影评论网站中的应用

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…