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,请在下方留言。文章来源:https://www.toymoban.com/news/detail-690224.html
最后说一句:不喜勿喷!文章来源地址https://www.toymoban.com/news/detail-690224.html
到了这里,关于使用C++编写自己的编程语言CASM的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!