使用C++编写自己的编程语言CASM

CASM帮助文档:

0.注释:用于在代码中添加注释。注释不会被执行,只是对代码的解释说明。 
    ;注释内容 
1.FUNC:通过这个指令,你可以定义一个可以被跳转的代码区块。
    FUNC [NAME]     
    *结束标记:另一个函数或文件结束 
2.TYPE:这个指令用于标明要保存的数据的类型。 
    TYPE [INT(高精整数) | STR(字符串) | BOOL(布尔值) | DOUBLE(双精度浮点数) | FLOAT(浮点数) | CHAR(字符)] 
3.PUSH:这个指令用于将数据推入栈顶。 
    PUSH [DATA] 
4.OUT:用于将栈顶的数据输出。
    OUT 
5.ENDL:用于输出一个换行符。 
    ENDL 
6.PUSHCOMMENT:将一个分号字符";"推入字符栈的栈顶。 
    PUSHCOMMENT 
7.POP:从栈中移除栈顶元素。 
    POP 
8.ADD:取出栈顶的元素,与下一个栈顶元素相加,并将结果推回栈顶。对于布尔类型,加法表示逻辑“或”操作。 
    ADD 
9.SUB:取出栈顶的元素,与下一个栈顶元素相减,并将结果推回栈顶。对于布尔类型,减法表示逻辑“异或”操作。对于字符串类型,减法会导致错误。 
    SUB 
10.MUL:取出栈顶的元素,与下一个栈顶元素相乘,并将结果推回栈顶。对于布尔类型,乘法表示逻辑“与”操作。对于字符串类型,乘法会导致错误。 
    MUL 
11.DIV:取出栈顶的元素,与下一个栈顶元素相除,并将结果推回栈顶。字符串、布尔类型或字符类型无法进行除法操作。 
    DIV 
12.MOD: 取出栈顶的元素,与下一个栈顶元素进行取模运算,并将结果推回栈顶。仅适用于整数类型。 
    MOD 
13.IN:从输入中读取一个变量的值,并将其推入栈顶。 
    IN 
14.VAR:声明一个变量。 
    VAR [NAME] 
15.GETVAR:查找名为 [VARNAME] 的变量,然后将其值赋给栈顶元素,并弹栈。 
    GETVAR [VARNAME] 
16.PUSHVAR:将变量推入栈顶。 
    PUSHVAR [VARNAME] 
17.IFE:比较栈顶元素与次栈顶元素是否相等,如果相等,将真值推入布尔栈。 
    IFE 
18.IFB:比较栈顶元素与次栈顶元素,判断是否栈顶元素较大,如果是,将真值推入布尔栈。 
    IFB 
19.IFS:比较栈顶元素与次栈顶元素,判断是否次栈顶元素较大,如果是,将真值推入布尔栈。
    IFS 
20.GOTO:跳转到指定的代码块。 
    GOTO [NAME] 
21.IF: 如果布尔栈的栈顶为真,跳转到指定标签。如果标签是 "RET",函数将退出。
     IF [NAME] 
22.EXIT:退出整个程序。 
    EXIT 
23.RAND: 将一个指定范围内的随机整数推入整数栈。 
    RAND [NUM1] [NUM2]    
     *从 NUM1 开始,到 NUM1+NUM2 结束 
24.CLEAR: 清空栈中的所有数据。 
    CLEAR 
25.NOT:对布尔栈顶进行“非”运算。 
    NOT

CASM解释器讲解视频:

我独自开发了一种编程语言:CASM

CASM解释器源代码(剪贴板有问题,总是粘贴成一行,哪位大佬帮帮我……):

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <map>
#include <queue>
#include <stack>
#include <cstdlib>
#include <list>
#include "hint.hpp"
using namespace std;

map<string, list<string>> codes;
map<string, HyperInt> intVar;
map<string, string> stringVar;
map<string, bool> boolVar;
map<string, double> doubleVar;
map<string, float> floatVar;
map<string, unsigned char> charVar;
stack<HyperInt> intData;
stack<string> stringData;
stack<bool> boolData;
stack<double> doubleData;
stack<float> floatData;
stack<unsigned char> charData;
int nowType;//0:int,1:string,2:bool,3:double,4:float,5:char

struct Lines {
    string op;
    string params[25];

    Lines() {
        op = "";
        memset(params, 0, sizeof(params));
        strData = "";
    }
    int len = -1;
    string strData;
    /* ABOUT LEN:
     *  -1: AN EMPTY LINE;
     *  0:OPERATOR ONLY;
     *  N:OPERATOR WITH N PARAMETERS.
     */
};

Lines analysisLine(const string &line);

void knifeCode();

void runCode(const string &name);

void setType(const string &type) {
    if (type == "INT") {
        nowType = 0;
    } else if (type == "STR") {
        nowType = 1;
    } else if (type == "BOOL") {
        nowType = 2;
    } else if (type == "DOUBLE") {
        nowType = 3;
    } else if (type == "FLOAT") {
        nowType = 4;
    } else if (type == "CHAR") {
        nowType = 5;
    } else {
        cout << "ERR:UnKnow Type.";
        exit(1);
    }
}

void push(Lines &line) {
    try {
        if (nowType == 0) {
            HyperInt data = 0;
            for (char i: line.params[0]) {
                data = data * 10;
                data = data + i - '0';
            }
            intData.push(data);

        } else if (nowType == 1) {
            stringData.push(line.strData);
        } else if (nowType == 2) {
            boolData.push(line.params[0] != "FALSE");
        } else if (nowType == 3) {
            doubleData.push(stod(line.params[0]));//stod:string to double
        } else if (nowType == 4) {
            floatData.push(stof(line.params[0]));//stof:string to float
        } else {
            charData.push(line.params[0][0]);
        }
    } catch (exception &e) {
        cout << "ERROR: Type error.";
        exit(1);
    }
}

void out() {
    if (nowType == 0) {
        cout << intData.top();
        intData.pop();
    } else if (nowType == 1) {
        cout << stringData.top();
        stringData.pop();
    } else if (nowType == 2) {
        cout << boolData.top();
        boolData.pop();
    } else if (nowType == 3) {
        cout << doubleData.top();
        doubleData.pop();
    } else if (nowType == 4) {
        cout << floatData.top();
        floatData.pop();
    } else {
        cout << charData.top();
        charData.pop();
    }
}

void endLine() {
    cout << endl;
}

void pushComment() {
    charData.push(';');
}

void pop() {
    if (nowType == 0) {
        intData.pop();
    } else if (nowType == 1) {
        stringData.pop();
    } else if (nowType == 2) {
        boolData.pop();
    } else if (nowType == 3) {
        doubleData.pop();
    } else if (nowType == 4) {
        floatData.pop();
    } else {
        charData.pop();
    }
}

void add() {
    if (nowType == 0) {
        HyperInt a = intData.top();
        intData.pop();
        HyperInt b = intData.top();
        intData.pop();
        intData.push(a + b);
    } else if (nowType == 1) {
        string a = stringData.top();
        stringData.pop();
        string b = stringData.top();
        stringData.pop();
        stringData.push(a + b);
    } else if (nowType == 2) {
        bool a = boolData.top();
        boolData.pop();
        bool b = boolData.top();
        boolData.pop();
        boolData.push(a || b);
    } else if (nowType == 3) {
        double a = doubleData.top();
        doubleData.pop();
        double b = doubleData.top();
        doubleData.pop();
        doubleData.push(a + b);
    } else if (nowType == 4) {
        float a = floatData.top();
        floatData.pop();
        float b = floatData.top();
        floatData.pop();
        floatData.push(a + b);
    } else {
        int a = (int) charData.top();
        charData.pop();
        int b = (int) charData.top();
        charData.pop();
        charData.push((char) (a + b));
    }

}

void sub() {
    if (nowType == 0) {
        HyperInt a = intData.top();
        intData.pop();
        HyperInt b = intData.top();
        intData.pop();
        intData.push(a - b);
    } else if (nowType == 1) {
        cout << "TypeError.";
        exit(1);
    } else if (nowType == 2) {
        bool a = boolData.top();
        boolData.pop();
        bool b = boolData.top();
        boolData.pop();
        boolData.push(a ^ b);
    } else if (nowType == 3) {
        double a = doubleData.top();
        doubleData.pop();
        double b = doubleData.top();
        doubleData.pop();
        doubleData.push(a - b);
    } else if (nowType == 4) {
        float a = floatData.top();
        floatData.pop();
        float b = floatData.top();
        floatData.pop();
        floatData.push(a - b);
    } else {
        int a = (int) charData.top();
        charData.pop();
        int b = (int) charData.top();
        charData.pop();
        charData.push((char) (a - b));
    }
}

void mul() {
    if (nowType == 0) {
        HyperInt a = intData.top();
        intData.pop();
        HyperInt b = intData.top();
        intData.pop();
        intData.push(a * b);
    } else if (nowType == 1) {
        cout << "TypeError.";
        exit(1);
    } else if (nowType == 2) {
        bool a = boolData.top();
        boolData.pop();
        bool b = boolData.top();
        boolData.pop();
        boolData.push(a && b);
    } else if (nowType == 3) {
        double a = doubleData.top();
        doubleData.pop();
        double b = doubleData.top();
        doubleData.pop();
        doubleData.push(a * b);
    } else if (nowType == 4) {
        float a = floatData.top();
        floatData.pop();
        float b = floatData.top();
        floatData.pop();
        floatData.push(a * b);
    } else {
        int a = (int) charData.top();
        charData.pop();
        int b = (int) charData.top();
        charData.pop();
        charData.push((char) (a * b));
    }
}

void div() {
    if (nowType == 0) {
        HyperInt a = intData.top();
        intData.pop();
        HyperInt b = intData.top();
        intData.pop();
        intData.push(a / b);
    } else if (nowType == 3) {
        double a = doubleData.top();
        doubleData.pop();
        double b = doubleData.top();
        doubleData.pop();
        doubleData.push(a / b);
    } else if (nowType == 4) {
        float a = floatData.top();
        floatData.pop();
        float b = floatData.top();
        floatData.pop();
        floatData.push(a / b);
    } else {
        cout << "TypeError.";
        exit(1);
    }
}

void mod() {
    if (nowType == 0) {
        HyperInt a = intData.top();
        intData.pop();
        HyperInt b = intData.top();
        intData.pop();
        intData.push(a % b);
    } else {
        cout << "TypeError.";
        exit(1);
    }
}

void casmIn() {
    if (nowType == 0) {
        HyperInt a;
        cin >> a;
        intData.push(a);
    } else if (nowType == 1) {
        string a;
        stringData.push(a);
    } else if (nowType == 2) {
        bool a;
        cin >> a;
        boolData.push(a);
    } else if (nowType == 3) {
        double a;
        cin >> a;
        doubleData.push(a);
    } else if (nowType == 4) {
        float a;
        cin >> a;
        floatData.push(a);
    } else {
        char a;
        cin >> a;
        charData.push(a);
    }
}

void var(const string &varName) {
    if (nowType == 0) {
        intVar[varName] = 0;
    } else if (nowType == 1) {
        stringVar[varName] = "";
    } else if (nowType == 2) {
        boolVar[varName] = false;
    } else if (nowType == 3) {
        doubleVar[varName] = 0;
    } else if (nowType == 4) {
        floatVar[varName] = 0;
    } else {
        charVar[varName] = '\0';
    }
}

void getvar(const string &varName) {
    if (nowType == 0) {
        intVar[varName] = intData.top();
        intData.pop();
    } else if (nowType == 1) {
        stringVar[varName] = stringData.top();
        stringData.pop();
    } else if (nowType == 2) {
        boolVar[varName] = boolData.top();
        boolData.pop();
    } else if (nowType == 3) {
        doubleVar[varName] = doubleData.top();
        doubleData.pop();
    } else if (nowType == 4) {
        floatVar[varName] = floatData.top();
        floatData.pop();
    } else {
        charVar[varName] = charData.top();
        charData.pop();
    }
}

void pushVar(const string &varName) {
    if (nowType == 0) {
        intData.push(intVar[varName]);
    } else if (nowType == 1) {
        stringData.push(stringVar[varName]);
    } else if (nowType == 2) {
        boolData.push(boolVar[varName]);
    } else if (nowType == 3) {
        doubleData.push(doubleVar[varName]);
    } else if (nowType == 4) {
        floatData.push(floatVar[varName]);
    } else {
        charData.push(charVar[varName]);
    }
}

void ifEqual() {
    if (nowType == 0) {
        HyperInt a = intData.top();
        intData.pop();
        HyperInt b = intData.top();
        intData.pop();
        boolData.push(a == b);
    } else if (nowType == 1) {
        string a = stringData.top();
        stringData.pop();
        string b = stringData.top();
        stringData.pop();
        boolData.push(a == b);
    } else if (nowType == 2) {
        bool a = boolData.top();
        boolData.pop();
        bool b = boolData.top();
        boolData.pop();
        boolData.push(a == b);
    } else if (nowType == 3) {
        double a = doubleData.top();
        doubleData.pop();
        double b = doubleData.top();
        doubleData.pop();
        boolData.push(a == b);
    } else if (nowType == 4) {
        float a = floatData.top();
        floatData.pop();
        float b = floatData.top();
        floatData.pop();
        boolData.push(a == b);
    } else {
        unsigned char a = charData.top();
        charData.pop();
        unsigned char b = charData.top();
        charData.pop();
        boolData.push(a == b);
    }
}

void ifBig() {
    if (nowType == 0) {
        HyperInt a = intData.top();
        intData.pop();
        HyperInt b = intData.top();
        intData.pop();
        boolData.push(a > b);
    } else if (nowType == 1) {
        string a = stringData.top();
        stringData.pop();
        string b = stringData.top();
        stringData.pop();
        boolData.push(a > b);
    } else if (nowType == 2) {
        bool a = boolData.top();
        boolData.pop();
        bool b = boolData.top();
        boolData.pop();
        boolData.push(a > b);
    } else if (nowType == 3) {
        double a = doubleData.top();
        doubleData.pop();
        double b = doubleData.top();
        doubleData.pop();
        boolData.push(a > b);
    } else if (nowType == 4) {
        float a = floatData.top();
        floatData.pop();
        float b = floatData.top();
        floatData.pop();
        boolData.push(a > b);
    } else {
        unsigned char a = charData.top();
        charData.pop();
        unsigned char b = charData.top();
        charData.pop();
        boolData.push(a > b);
    }
}

void ifSmall() {
    if (nowType == 0) {
        HyperInt a = intData.top();
        intData.pop();
        HyperInt b = intData.top();
        intData.pop();
        boolData.push(a < b);
    } else if (nowType == 1) {
        string a = stringData.top();
        stringData.pop();
        string b = stringData.top();
        stringData.pop();
        boolData.push(a < b);
    } else if (nowType == 2) {
        bool a = boolData.top();
        boolData.pop();
        bool b = boolData.top();
        boolData.pop();
        boolData.push(a < b);
    } else if (nowType == 3) {
        double a = doubleData.top();
        doubleData.pop();
        double b = doubleData.top();
        doubleData.pop();
        boolData.push(a < b);
    } else if (nowType == 4) {
        float a = floatData.top();
        floatData.pop();
        float b = floatData.top();
        floatData.pop();
        boolData.push(a < b);
    } else {
        unsigned char a = charData.top();
        charData.pop();
        unsigned char b = charData.top();
        charData.pop();
        boolData.push(a < b);
    }
}

char casmIf(const string &code) {
    if (code == "RET") {
        return 'b';
    }
    if(boolData.top()){
        boolData.pop();
        runCode(code);
    }
    return '\0';
}

void casmRand(const string& num1,const string& num2){
    long long int data1 = 0;
    for (char i: num1) {
        data1 = data1 * 10;
        data1 = data1 + i - '0';
    }
    long long int data2 = 0;
    for (char i: num2) {
        data2 = data2 * 10;
        data2 = data2 + i - '0';
    }
    intData.push((HyperInt)rand() % data2 + data1);
}

void clear() {
    if (nowType == 0) {
        while(!intData.empty()) {
            intData.pop();
        }
    } else if (nowType == 1) {
        while(!stringData.empty()) {
            stringData.pop();
        }
    } else if (nowType == 2) {
        while(!boolData.empty()) {
            boolData.pop();
        }
    } else if (nowType == 3) {
        while(!doubleData.empty()) {
            doubleData.pop();
        }
    } else if (nowType == 4) {
        while(!floatData.empty()) {
            floatData.pop();
        }
    } else {
        while(!charData.empty()) {
            charData.pop();
        }
    }
}
void casmNot(){
    bool x=!boolData.top();
    boolData.pop();
    boolData.push(x);
}
int main(int argc, char* argv[]) {
    srand(time(nullptr));
    if(argc == 1){
        cout << "Please input the file name" << endl;
        return 0;
    }
    const char* name = argv[1];
    freopen(name, "r", stdin);
    knifeCode();
    fclose(stdin);
    freopen("CON", "r", stdin);
    cin.clear();
    setType("INT");
    runCode("MAIN");
    return 0;
}
char upper(const char& i){
    char x = i;
    if('a'<=i&&i<='z') x-=32;
    return x;
}
Lines analysisLine(const string &line) {
    /* EACH LINE IN CASM(EXCEPT COMMENT) HAS ONLY A OPERATOR AND MANY
         * PARAMETER. THE ONLY THINGS THAT IT NEEDS TO DO IS RECORD THEM
         * AND RUN THEM.
         */
    Lines res;
    bool flag = false;
    for (char i: line) {
        if (i == ' ') {
            if (res.len == -1 && (!flag)) continue;
            res.len++;
            if (res.len != 0)
                res.strData += i;
            continue;
        } else {
            if (res.len == -1) flag = true;
        }
        if (i == ';') break;
        if (res.len == -1) res.op += upper(i);
        else res.params[res.len] += i, res.strData += i;
    }
    res.len++; /* NO SPACE FOLLOWS LAST ARG */
    return res;
}

void knifeCode() {
    string code;
    string name;
    while (getline(cin, code, '\n')) {
        Lines l = analysisLine(code);
        if (l.op == "FUNC") {
            name = l.params[0];
            list<string> lines;
            codes.insert(pair<string, list<string>>(name, lines));
        } else {
            codes[name].push_back(code);
        }
    }
}

void runCode(const string &name) {
    for (auto &nowLine: codes[name]) {
        Lines line = analysisLine(nowLine);
        if (line.op == "TYPE") {
            setType(line.params[0]);
        } else if (line.op == "PUSH") {
            push(line);
        } else if (line.op == "EXIT") {
            exit(0);
        } else if (line.op == "OUT") {
            out();
        } else if (line.op == "ENDL") {
            endLine();
        } else if (line.op == "PUSHCOMMENT") {
            pushComment();
        } else if (line.op == "POP") {
            pop();
        } else if (line.op == "ADD") {
            add();
        } else if (line.op == "SUB") {
            sub();
        } else if (line.op == "MUL") {
            mul();
        } else if (line.op == "DIV") {
            div();
        } else if (line.op == "IN") {
            casmIn();
        } else if (line.op == "MOD") {
            mod();
        } else if (line.op == "VAR") {
            var(line.params[0]);
        } else if (line.op == "GETVAR") {
            getvar(line.params[0]);
        } else if (line.op == "PUSHVAR") {
            pushVar(line.params[0]);
        } else if (line.op == "IFE") {
            ifEqual();
        } else if (line.op == "IFB") {
            ifBig();
        } else if (line.op == "IFS") {
            ifSmall();
        } else if (line.op == "GOTO") {
            runCode(line.params[0]);
        } else if(line.op == "IF"){
            if(casmIf(line.params[0])=='b')break;
        } else if (line.op =="RAND"){
            casmRand(line.params[0], line.params[1]);
        } else if (line.op == "CLEAR"){
            clear();
        } else if (line.op == "NOT"){
            casmNot();
        }
    }
}
其中的“hint.hpp”为GitHub上开源的高精度库,非常好用,链接:github.com/With-Sky/HyperInt 作者:WS_TSKY https://www.bilibili.com/read/cv18911017/

本文目的仅为发布源代码,如果真有人向学习CASM,请在下方留言。

最后说一句:不喜勿喷!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值