CLGO语言发布
C、C++、Java、js都是别人发明的语言,感觉不是很合自己的胃口。于是自己创造语法规则,构造了一门脚本语言。CLGO语言问世了,有很深的LOGO语言的影子,个别关键词只是同名,但这绝对是门独立的语言与其他语言的工作原理完全不一样。另外这些关键词随着加载的库的不同可以发挥不同的作用,如果加载了正则库,那他就是类似gawk的正则脚本,加载了gdi他就是一门绘图脚本语言,加载了文件流库,那就是文本处理语言类似sed,加载了其他库就具有其他的功能,加载了按键模拟那就是类似ahk的脚本语言。初版默认只加载绘图库,也是为了压缩包能控制在25KB以下。
文件下载
脚本演示
脚本示例
/*
@echo OFF&CLS&COLOR 0F&MODE CON COLS=100 LINES=30&CLGO "%~F0"&PAUSE>NUL&EXIT /B
COPYRIGHT@2017~2019 BY HAPPY
*/
TO MAIN
$PENX=-36 $PENY=126 $PENS=2 $PENW=2 $PENA=180 $HEADING=12
//MEMUSE
REPEAT 12
[
$PENC=$RANDOM%15+1
REPEAT 75
[
FD 100
BK 100
RT 2
]
FD 250
]
//MEMSEE
//MEMOUT
CLGO SCRIPT
_____________________________________________________________________________
CLGO SCRIPT控制台绘图脚本语言,具有类似C语言的函数定义、函数调用、递归、循环、
逻辑判断等语法功能。在内存中解释运行,速度迅猛。同时,CLGO语言具有非常简单的
语法结构、关键词、非常适合快速上手。简短的语句就能绘出美妙的画面。
_____________________________________________________________________________
命令:
-----------------------------------------------------------------------------
关键词(不区分大小写) 中文释义 用法说明
-----------------------------------------------------------------------------
___________________________________全局变量__________________________________
PENX 横坐标
PENY 纵坐标
PENW 笔宽 取值0-255
PENC 笔色 取值0-15
PENB 笔背景色 取值0-15
PENS 笔光滑度 取值0-6
PENA 笔透明度 取值0-255
HEADING 笔头角度 取值0-360
RANDOM 随机数 取值随机
YEAR、MONTH、DAY、HOUR、MINUTE、SECOND 时间变量
TP0 - TP9 用户变量 供用户使用的全局变量
___________________________________绘图命令___________________________________
FD 前进 FD 100 //前进100步
BK 后退 BK 100 //后退100步
LT 左转 LT 90 //左转 90度
RT 右转 RT 90 //右转 90度
PU 抬笔 PU //抬笔
PD 落笔 PD //落笔
PE 笔擦 PE //笔擦
HOME 回家 笔归位至中央、笔头朝上
CLEAN 清图 清除绘图区
___________________________________语句命令___________________________________
IF~ELIF 如果~再则 条件指令
REPEAT 重复 RP 4[循环体]
WHILE 当 WHILE 条件[循环体]
FOR 循环 FOR 变量 初值 终值[循环体]步长
___________________________________语句词语___________________________________
NOT 逻辑否
AND 逻辑与
OR 逻辑或
___________________________________扩展命令___________________________________
PAUSE 暂停 请按任意键继续
WAIT 等待 WAIT 3000 //等待3秒
STOP 停止 停止子过程
EXIT 退出 退出整个脚本
FILL 颜色填充 用颜色填充笔所在的封闭区域
ECHO 显示字符 ECHO 你好
EVAL 计算表达式值 EVAL sin(pi/6)+cos(pi/3)
READ 获取按键
OVAL 画椭圆 OVAL 100 50//画横向半径为100,纵向半径为50的椭圆
RECT 画矩形 RECT 100 50//画横向长度为100,纵向长度为50的矩形
ROTE 旋转 ROTE 30 //画布旋转30度
MEMUSE 启用内存画布
MEMSEE 查看内存画布
MEMOUT 抛弃内存画布
-----------------------------------------------------------------------------
释符:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
行注释// 行内容
段注释/*
段内容
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
数学类关键词(必须小写):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
常数类
pi 3.1415926535897932
e 2.7182818284590452
通用类
round 四舍五入
floor 整取
abs 绝对值
ceil向上舍入
deg 角度转弧度
exp e的次幂
sqrt开方
fac 阶乘
lg 常用对数,以10为底
ln 自然对数
+ 加
- 减
* 乘
/ 除
% 取余数
^ 次方
! 阶乘
三角函数类
sin、cos、tan
arcsin、arccos、arctan
双曲函数类
sinh、cosh、tanh
arcsinh、arccosh、arctanh
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
十六色系:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{0,0,0,RGB(0,0,0)}, //黑色
{0,0,255,RGB(0,0,255)}, //蓝色
{0,255,0,RGB(0,255,0)}, //绿色
{0,255,255,RGB(0,255,255)}, //青色
{255,0,0,RGB(255,0,0)}, //红色
{238,130,238,RGB(238,130,238)}, //紫兰
{165, 42, 42,RGB(165, 42, 42)}, //棕色
{211,211,211,RGB(211,211,211)}, //浅灰
{169,169,169,RGB(169,169,169)}, //深灰
{173,216,230,RGB(173,216,230)}, //淡蓝
{144,238,144,RGB(144,238,144)}, //浅绿
{224,255,255,RGB(224,255,255)}, //淡青
{248, 29, 56,RGB(248, 29, 56)}, //亮红
{255,0,255,RGB(255,0,255)}, //洋紫
{255,255,0,RGB(255,255,0)}, //黄色
{255,255,255,RGB(255,255,255)}//白色
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
英译:
-----------------------------------------------------------------------------
COPYRIGHT@2016~2018 BY HAPPY, CLGO SCRIPT, VERSION 1.0
CLGO.EXE
USAGE: CLGO
-----------------------------------------------------------------------------
2017-01-10
核心代码
/*
CLGO SCRIPT, COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.0
CLGO.EXE
LINK: -lline -L./ -lgdi32 -lgdiplus
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include<stdbool.h>
#include<windows.h>
#include <wincon.h>
#include <io.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include <unistd.h>
#include <gdiplus\gdiplus.h>
/***************定义宏变量***************/
//堆栈尺寸
#define STACK_SIZE 1024
//循环体最大层数
#define LOOP_LEVELS 64
//变量名最大长度
#define MAX_WORDS_SIZE 64
//定义变量值最大长度
#define MAX_VALUE_SIZE 16
//绘图系关键词数
#define KEY_SIZE 20
//循环系关键词数
#define CYC_SIZE 5
//逻辑系关键词
#define LGC_SIZE 3
//全局变量解释数
#define GLOBAL_SIZE 25
/***************全局类变量***************/
//主窗句柄
HWNDhCMD;
HWNDhWND2;
HWNDhWND3;
//主窗区域
RECTwinRECT={0};
LPRECT lrRECT;
//画布句柄
HDC hDC;
HDC hDC1;
HDC hDC2;
HDC hDC3;
//内存变量
char* tRAM;
//缓存容器
charcacheTain={0};
//画线可见,可见即PD,不可见即PU
BOOLpenMODE=TRUE;
//启用内存背景
BOOLmemMODE=FALSE;
/***************关键词类目***************/
//运算符栈
char STACK1={0};
//逆波兰栈
char STACK2={0};
//浮点数栈
double STACK3={0};
//数学函数关键词
static const char* MATH_WORDS[]={"e", "pi", "sqrt", "lg", "ln", "sin", "cos", "tan", "arcsin", "arccos", "arctan", "deg", "abs", "round", "floor", "ceil", "exp", "sinh", "cosh", "tanh", "arcsinh", "arccosh", "arctanh", NULL};
//绘图系关键词
static const char* KEY_WORDS[]={"FD", "BK", "LT", "RT", "PU", "PD", "PE", "CLEAN", "ECHO", "HOME", "STOP", "EXIT", "FILL", "PAUSE", "WAIT", "ROTE", "MEMUSE", "MEMSEE", "MEMOUT", "EVAL"};
static const charKEY_LLENS[]={ 2, 2, 2, 2, 2, 2, 2, 5, 4, 4, 4, 4, 4, 5, 4, 4, 6, 6, 6, 4};
//循环系关键词
static const char* CYC_WORDS[]={"IF", "REPEAT", "WHILE", "FOR", "ELIF"};
static const charCYC_LLENS[]={ 2, 6, 5, 3, 4};
//逻辑系关键词
static const char* LGC_WORDS[]={"NOT", "AND", "OR"};
static const charLGC_LLENS[]={ 3, 3, 2};
//定义解释器全局变量
static const char* GLOBAL_WORDS[]={"$PENX", "$PENY", "$HEADING", "$PENB", "$PENW", "$PENC", "$PENS", "$PENA", "$RANDOM", "$YEAR", "$MONTH", "$DAY", "$HOUR", "$MINUTE", "$SECOND", "$TP0", "$TP1", "$TP2", "$TP3", "$TP4", "$TP5", "$TP6", "$TP7", "$TP8", "$TP9"};
static const charGLOBAL_LLENS[]={ 5, 5, 8, 5, 5, 5, 5, 5, 7, 5, 6, 4, 5, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
doubleGLOBAL_VALUE[]={ 0, 0, 0, 0, 1, 15, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/***************申明函数类***************/
HWND WINAPI GetConsoleWindow();
float EvalLine(const char* exp, int PRO_NUM, char** WORDS, char** VALUE, const char* endstring);
/***************RGB 结构体***************/
typedef struct{
BYTE R;
BYTE G;
BYTE B;
COLORREF VALUE;
}STRGB;
//十六色系数组
STRGB LOGO_RGB={
{0,0,0,RGB(0,0,0)}, //黑色
{0,0,255,RGB(0,0,255)}, //蓝色
{0,255,0,RGB(0,255,0)}, //绿色
{0,255,255,RGB(0,255,255)}, //青色
{255,0,0,RGB(255,0,0)}, //红色
{238,130,238,RGB(238,130,238)}, //紫兰
{165, 42, 42,RGB(165, 42, 42)}, //棕色
{211,211,211,RGB(211,211,211)}, //浅灰
{169,169,169,RGB(169,169,169)}, //深灰
{173,216,230,RGB(173,216,230)}, //淡蓝
{144,238,144,RGB(144,238,144)}, //浅绿
{224,255,255,RGB(224,255,255)}, //淡青
{248, 29, 56,RGB(248, 29, 56)}, //亮红
{255,0,255,RGB(255,0,255)}, //洋紫
{255,255,0,RGB(255,255,0)}, //黄色
{255,255,255,RGB(255,255,255)}//白色
};
/***************计算函数群***************/
//阶乘函数
long long fact(long long n)
{
return (n<2) ?1 :n*(fact(n-1));
}
//逆波兰核心
double RevPolishCore(const char* expression)
{
STACK3=0;
char *op=(char*)expression, *S1=STACK1, *S2=STACK2, **key, *cp, *kp;
double *S3=STACK3, di, ni;
//生成逆波兰
while(*op!='\0'){
switch(*op){
case ' ' :
case '\t':
case '\r':
case '\n':
//过滤空字符
op++;
continue;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
//识别数学函数关键词
key=(char**)MATH_WORDS;
while(*key !=NULL){
cp=op, kp=*key;
//比对关键词字母
while(*cp==*kp && *kp!='\0'){
cp++, kp++;
}
//验证关键词结尾
if((*cp<'a'||*cp>'z') && (*kp=='\0')){
op=cp;
break;
}
key++;
}
//构建伪双目
if(*key !=NULL){
*(S2++)='.';
*(S2++)=' ';
//伪双目入栈
while('A'<=(*S1) && (*S1)<='Z'){
*(S2++)=*(S1--);
}
*(++S1)=key-(char**)MATH_WORDS+65;
continue;
}else{
//无法识别的数学函数
fputs("Unrecognized math function\n", stderr);
exit(1);
}
break;
case '(':
*(++S1)=*op;
if(*(op+1)=='-' || *(op+1)=='+'){
*(S2++)='0', *(S2++)=' ';
}
break;
case ')':
while(*S1!='(')
{
*(S2++)=*(S1--);
}
//舍弃'('
S1--;
break;
case '+':
case '-':
while(S1!=STACK1 && *S1!='(')
{
*(S2++)=*(S1--);
}
*(++S1)=*op;
break;
case '^':
//指数符
while('A'<=(*S1) && (*S1)<='Z')
{
*(S2++)=*(S1--);
}
*(++S1)=*op;
break;
case '!':
//阶乘符
*(S2++)=*op;
break;
case '%':
case '*':
case '/':
while(('A'<=(*S1) && (*S1)<='Z') ||*S1=='%' ||*S1=='*' ||*S1=='/' ||*S1=='^'){
*(S2++)=*(S1--);
}
*(++S1)=*op;
break;
default :
if((*op<'0' || *op>'9') && (*op!='.')){
//无法识别的运算符
fputs("Unrecognized operator\n", stderr);
exit(1);
}
//浮点数入栈
while(('0'<=*op && *op<='9') ||*op=='.'){
*(S2++)=*(op++);
}
op--;
*(S2++)=' ';
break;
}
op++;
}
//收尾逆波兰
while(S1 !=STACK1){*(S2++)=*(S1--);}
*S2=' ';
//计算逆波兰
op=STACK2;
while(*op!=' '){
switch(*op){
case 'A':
*S3=2.7182818284590452;
break;
case 'B':
*S3=3.1415926535897932;
break;
case 'C':
if(*S3 <0){
//负数没有平方根
fputs("Negative numbers have no square root\n", stderr);
exit(1);
}
*(S3-1)=sqrt(*S3);
S3--;
break;
case 'D':
if(*S3 <0){
//负数没有对数
fputs("Negative numbers are not logarithmic\n", stderr);
exit(1);
}
*(S3-1)=log10(*S3);
S3--;
break;
case 'E':
if(*S3 <0){
//负数没有自然对数
fputs("Negative numbers have no natural logarithms\n", stderr);
exit(1);
}
*(S3-1)=log(*S3);
S3--;
break;
case 'F':
*(S3-1)=sin(*S3);
S3--;
break;
case 'G':
*(S3-1)=cos(*S3);
S3--;
break;
case 'H':
if(*S3==3.1415926535897932/2){
//π/2没有正切值
fputs("The pi/2 has no tangent\n", stderr);
exit(1);
}
*(S3-1)=tan(*S3);
S3--;
break;
case 'I':
*(S3-1)=asin(*S3);
S3--;
break;
case 'J':
*(S3-1)=acos(*S3);
S3--;
break;
case 'K':
*(S3-1)=atan(*S3);
S3--;
break;
case 'L':
*(S3-1)=(*S3)*3.1415926535897932/180.0;
S3--;
break;
case 'M':
*(S3-1)=(*S3<0)?(-(*S3)):(*S3);
S3--;
break;
case 'N':
*(S3-1)=round(*S3);
S3--;
break;
case 'O':
*(S3-1)=floor(*S3);
S3--;
break;
case 'P':
*(S3-1)=ceil(*S3);
S3--;
break;
case 'Q':
*(S3-1)=exp(*S3);
S3--;
break;
case 'R':
*(S3-1)=sinh(*S3);
S3--;
break;
case 'S':
*(S3-1)=cosh(*S3);
S3--;
break;
case 'T':
*(S3-1)=tanh(*S3);
S3--;
break;
case 'U':
*(S3-1)=asinh(*S3);
S3--;
break;
case 'V':
*(S3-1)=acosh(*S3);
S3--;
break;
case 'W':
*(S3-1)=atanh(*S3);
S3--;
break;
case '+':
*(S3-1)+=*S3;
S3--;
break;
case '-':
*(S3-1)-=*S3;
S3--;
break;
case '*':
*(S3-1)*=*S3;
S3--;
break;
case '%':
case '/':
if(*S3 !=0){
if(*op=='%'){
//取余数
*(S3-1)=(int)*(S3-1) % (int)*S3;
}else{
*(S3-1)/=*S3;
}
}else{
//除数不能为零
fputs("Divisor is zero error\n", stderr);
exit(1);
}
S3--;
break;
case '^':
if(*(S3-1)==0 && *S3<0){
//除数不能为零
fputs("Function pow's divisor is zero error\n", stderr);
exit(1);
}
*(S3-1)=pow(*(S3-1), *S3);
S3--;
break;
case '!':
if(*S3 <0){
//负数没有阶乘
fputs("Negative numbers have no factorial\n", stderr);
exit(1);
}
*S3=fact((long long)(*S3));
break;
default :
//字符串转浮点
di=0, ni=1;
while('0'<=*op && *op<='9'){
di=10*di+(*op)-'0';
op++;
}
if(*op=='.'){
op++;
while('0'<=*op && *op<='9'){
di=10*di+(*op)-'0';
op++, ni*=10;
}
}
*(++S3)=di/ni;
break;
}
op++;
}
//返回计算结果
return *S3;
}
/***************辅助函数群***************/
//获取时间
inline int getTIME(int i)
{
time_t timep;
struct tm *p;
time(&timep);
p=localtime(&timep);
switch(i){
case9:
return p->tm_year+1900;
case 10:
return p->tm_mon+1;
case 11:
return p->tm_mday;
case 12:
return p->tm_hour;
case 13:
return p->tm_min;
case 14:
return p->tm_sec;
default:
return -1;
}
return -1;
}
//测空字符
inline BOOL isEND(const char c,const char* endstring)
{
if(c=='\0'){return TRUE;}
while(*endstring!='\0'){
if(c==*(endstring++)){
return TRUE;
}
}
return FALSE;
}
//过滤行TAB缩进或前空格
char* passNULL(char* Str)
{
if(Str!=NULL){
while(*Str=='\t' ||*Str==' '){Str++;}
}
return Str;
}
//识别关键字
BOOL isKEY(char* Line, char* key, const char* endstring)
{
char *op=Line, *kp=key;
while(*kp!='\0'){
if((('a'<= *op && *op<='z')?*op-32:*op) != (('a'<= *kp && *kp<='z')?*kp-32:*kp)){break;}
op++;kp++;
}
if(
*kp=='\0' &&
isEND(*op, endstring)
){
return TRUE;
}
return FALSE;
}
//切分变量名
int ARGS(char* Str, char** WORDS, int PRO_NUM, int LineNUM, char* Line)
{
if(PRO_NUM==0){return 0;}
//过滤回车符
Str='\0';
inti=0;
char* lp=Str;
char* tp;
strtok(lp, " ");
while(i<PRO_NUM){
WORDS=(char*)calloc(MAX_WORDS_SIZE, sizeof(char));
if((tp=strtok(NULL, " "))==NULL){break;}
strcpy(WORDS, tp);
}
if(i==0){WORDS=(char*)calloc(MAX_WORDS_SIZE, sizeof(char)); return 1;}
if(i<PRO_NUM){fprintf(stdout, "[%d]:Missing Parameter %s\n", LineNUM, Line);exit(1);}
return i;
}
//切分参数
int ARGP(char* Str, char** WORDS, int PRO_NUM, char** PRO_WORDS, char** PRO_VALUE)
{
int i=-1;
char* tp;
strtok(Str, " ");
while((tp=strtok(NULL, " "))!=NULL && *tp!='\r'){
WORDS[++i]=(char*)calloc(MAX_VALUE_SIZE, sizeof(char));
itoa(EvalLine(tp, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n"), WORDS, 10);
}
if(i==-1){WORDS[++i]=(char*)calloc(MAX_VALUE_SIZE, sizeof(char));}
return i+1;
}
//关键词解析函数
int Identify_KeyWords(char* Line, int SENSITIVE_NUM, char** WORDS, const char* endstring)
{
int i, SN;
for(SN=0; SN<SENSITIVE_NUM; SN++){
char *op=Line, *kp=WORDS;
while(*kp!='\0'){
if(
(('a'<= *op && *op<='z')?*op-32:*op) != (('a'<= *kp && *kp<='z')?*kp-32:*kp)
){
break;
}
op++;kp++;
}
if(
*kp=='\0' &&
isEND(*op, endstring)
){
return SN;
}
}
return -1;
}
//计算含变量表达式函数
float EvalLine(const char* exp, int PRO_NUM, char** WORDS, char** VALUE, const char* endstring)
{
char* op=cacheTain;
char* cp=(char*)exp;
char* Line_Cache=op;
int i=-1;
while(!isEND(*cp, " \t\r\n\0")){
if(!isEND(*cp, ":$ \t\r\n\0")){
*(op++)=*(cp++);
continue;
}
if((*cp==':') && (i=Identify_KeyWords(cp, PRO_NUM, WORDS, endstring))!=-1){
char* tmp=VALUE;
*op++='(';
while(*tmp!='\0'){*(op++)=*(tmp++);}
*op++=')';
cp+=strlen(WORDS);
}else if((*cp==') && (i=Identify_KeyWords(cp, GLOBAL_SIZE, (char**)GLOBAL_WORDS, endstring))!=-1){
//准备临时容器
char* tmp=(char*)calloc(16, sizeof(char));
//解析变量名
switch(i){
case 8:
itoa(rand(), tmp, 10);
break;
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
itoa(getTIME(i), tmp, 10);
break;
default:
_gcvt(GLOBAL_VALUE, 10, tmp);
break;
}
*op++='(';
while(*tmp!='\0'){*(op++)=*(tmp++);}
*op++=')';
free(tmp);
cp+=GLOBAL_LLENS;
}
}
*op='\0' ;
return (float)RevPolishCore(Line_Cache);
}
//赋值函数
BOOL AssignMent(const char* exp, int PRO_NUM, char** WORDS, char** VALUE, const char* endstring)
{
char *gp=(char*)exp, *cp=gp;
while(!isEND(*cp, "=")){
cp++;
}
cp++;
int i=-1;
if(gp==':'){
if(gp==':'){return TRUE;}
i=Identify_KeyWords(gp, PRO_NUM, WORDS, " \t=");
itoa(EvalLine(cp, PRO_NUM, WORDS, VALUE, endstring), VALUE, 10);
}else if(gp=='){
i=Identify_KeyWords(gp, GLOBAL_SIZE, (char**)GLOBAL_WORDS, " \t=");
GLOBAL_VALUE=EvalLine(cp, PRO_NUM, WORDS, VALUE, endstring);
switch(i){
case 3:
GLOBAL_VALUE=(GLOBAL_VALUE>=0) ?(int)GLOBAL_VALUE%16 :16+(int)GLOBAL_VALUE%16;
STRGB* bgRGB=&LOGO_RGB[(int)GLOBAL_VALUE];
//创建画刷
HBRUSH m_brush=CreateSolidBrush(bgRGB->VALUE);
//填充背景
FillRect(hDC1, lrRECT, m_brush);
//删除画刷
DeleteObject(m_brush);
break;
break;
case 4:
if(GLOBAL_VALUE<0){GLOBAL_VALUE=-GLOBAL_VALUE;}
break;
case 5:
GLOBAL_VALUE=(GLOBAL_VALUE>=0) ?(int)GLOBAL_VALUE%16 :360+(int)GLOBAL_VALUE%16;
break;
case 6:
GLOBAL_VALUE=(GLOBAL_VALUE>=0) ?(int)GLOBAL_VALUE%6 :(0-(int)GLOBAL_VALUE)%6;
break;
case 7:
GLOBAL_VALUE=(GLOBAL_VALUE>=0) ?(int)GLOBAL_VALUE%255 :(0-(int)GLOBAL_VALUE)%255;
break;
default:
break;
}
}
return TRUE;
}
//批量赋值
BOOL MoreAssignMent(const char* Line, int PRO_NUM, char** WORDS, char** VALUE, const char* endstring)
{
char *gp=(char*)Line;
while(isEND(*gp, ":$")){
AssignMent(gp, PRO_NUM, WORDS, VALUE, endstring);
gp++;
while(!isEND(*gp, " \t\0")){
gp++;
}
while(!isEND(*gp, ":$\0")){gp++;}
if(*gp=='\0'){return TRUE;}
}
return TRUE;
}
//测FOR循环
inline BOOL isForTrue(const char* Line, int PRO_NUM, char** WORDS, char** VALUE, int CYC)
{
if(CYC ==0){return TRUE;}
int i=-1;
if((i=Identify_KeyWords(strtok((char*)Line, " "), PRO_NUM, WORDS, " \t")) !=-1){
int staNUM=EvalLine(strtok(NULL, " "), PRO_NUM, WORDS, VALUE, "()+-*%/ \t\r\n");
int endNUM=EvalLine(strtok(NULL, " "), PRO_NUM, WORDS, VALUE, "()+-*%/ \t\r\n");
int var =atoi(VALUE);
if(staNUM-endNUM<0){return (var<=endNUM)?TRUE:FALSE;}
return (var>=endNUM)?TRUE:FALSE;
}
return FALSE;
}
//真值条件判断
BOOL JudgMent(const char* exp, int PRO_NUM, char** WORDS, char** VALUE, const char* endstring)
{
char* op=cacheTain;
char* cp=(char*)exp;
//过滤行TAB缩进或空格
while(*cp=='\t'|| *cp==' '){cp++;}
if(isEND(*cp, "\r\n\0")){
return TRUE;
}
char* Line_Cache=op;
int i=-1, flag=0;
while(!isEND(*cp, " \t\r\n\0")){
if (*cp=='>'){
flag+=4;
*(op++)='-';
*(op++)='(';
cp++;
continue;
}else if(*cp=='<'){
flag+=2;
*(op++)='-';
*(op++)='(';
cp++;
continue;
}else if(*cp=='='){
flag+=1;
if(flag==1){
*(op++)='-';
*(op++)='(';
}
cp++;
continue;
}else if(*cp!=':'&& *cp!='){
*(op++)=*(cp++);
continue;
}
if((*cp==':') && (i=Identify_KeyWords(cp, PRO_NUM, WORDS, endstring))!=-1){
char* tmp=VALUE;
*op++='(';
while(*tmp!='\0'){*(op++)=*(tmp++);}
*op++=')';
cp+=strlen(WORDS);
}else if((*cp==') && (i=Identify_KeyWords(cp, PRO_NUM, WORDS, endstring))!=-1){
char* tmp=(char*)calloc(16, sizeof(char));
if(i==8){
itoa(rand(), tmp, 10);
}else if(9<=i && i<=14){
itoa(getTIME(i), tmp, 10);
}else{
_gcvt(GLOBAL_VALUE, 10, tmp);
}
*op++='(';
while(*tmp!='\0'){*(op++)=*(tmp++);}
*op++=')';
cp+=GLOBAL_LLENS;
}else{
return FALSE;
}
}
*(op++)=')';
*op='\0' ;
int m=(int)RevPolishCore(Line_Cache);
if(
(m >0 && (flag==4||flag==5 )) ||
(m <0 && (flag==2||flag==3 )) ||
(m==0 && (flag==1||flag==3||flag==5||flag==0))
){
return TRUE;
}
return FALSE;
}
//批量真值判断
BOOL MoreJudgMent(const char* Line, int PRO_NUM, char** WORDS, char** VALUE, const char* endstring)
{
char *gp=(char*)Line;
int li=Identify_KeyWords(gp, LGC_SIZE, (char**)LGC_WORDS, " \t");
if(li !=-1){gp+=LGC_LLENS;}
do{
while(isEND(*gp, " \t")){
gp++;
}
if(JudgMent(gp, PRO_NUM, WORDS, VALUE, endstring)){
switch(li){
case 0:
return FALSE;
case 1:
break;
case 2:
return TRUE;
default:
return TRUE;
}
}else{
switch(li){
case 0:
break;
case 1:
return FALSE;
case 2:
break;
default:
return FALSE;
}
}
while(!isEND(*gp, " \t\0")){gp++;}
if(*gp=='\0'){return TRUE;}
while( isEND(*gp, " \t\r\n")){gp++;}
}while(*gp !='\0');
}
/***************绘图函数群***************/
//隐藏光标
BOOL SizeCursor(int size)
{
CONSOLE_CURSOR_INFO cursor_info = {(DWORD)((size==0)?25:size), (size==0)?FALSE:TRUE};
return SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
//平滑画线函数,C++连接库
void drawSMOOTHLINE(HDC hDC, int penWith, int mode, BYTE alpha, STRGB* penRGB, float x1, float y1, float x2, float y2);
//封闭区域填充函数,C++连接库
void fillAREA(HDC hDC, BYTE alpha, STRGB* penRGB, float fill_X, float fill_Y);
//快速画线函数
BOOL drawLINE(HDC hDC, int d)
{
float x1=GLOBAL_VALUE, y1=GLOBAL_VALUE;
GLOBAL_VALUE+=d * sin(GLOBAL_VALUE*0.017453292519943);
GLOBAL_VALUE+=d * cos(GLOBAL_VALUE*0.017453292519943);
//当为PU抬笔时,不做绘图
if(!penMODE){
return FALSE;
}
STRGB* penRGB=&LOGO_RGB[(int)GLOBAL_VALUE];
drawSMOOTHLINE(hDC, (int)GLOBAL_VALUE, (int)GLOBAL_VALUE, (int)GLOBAL_VALUE, penRGB, lrRECT->right/2+x1, lrRECT->bottom/2-y1, lrRECT->right/2+GLOBAL_VALUE, lrRECT->bottom/2-GLOBAL_VALUE);
return TRUE;
}
//退步函数,实现BK
void backWARD(int d)
{
GLOBAL_VALUE-=d * sin(GLOBAL_VALUE*0.017453292519943);
GLOBAL_VALUE-=d * cos(GLOBAL_VALUE*0.017453292519943);
}
//图形旋转
int RotateDC(HDC hDC, int angle)
{
if(angle==0){return 1;}
XFORM Matrix;
double rad =-angle * 0.017453292519943;
Matrix.eM11 = (float)cos(rad);
Matrix.eM12 = (float)sin(rad);
Matrix.eM21 =-(float)sin(rad);
Matrix.eM22 = (float)cos(rad);
Matrix.eDx= (float)(GLOBAL_VALUE-cos(rad)*GLOBAL_VALUE+sin(rad)*GLOBAL_VALUE);
Matrix.eDy= (float)(GLOBAL_VALUE-cos(rad)*GLOBAL_VALUE-sin(rad)*GLOBAL_VALUE);
SetGraphicsMode(hDC, GM_ADVANCED);
SetWorldTransform(hDC, &Matrix);
return 0;
}
/***************解析函数群***************/
//脚本解析函数
int FileScript(char* prossName, int PRO_NUM, char** PRO_VALUE)
{
//初始参数,其中KLevel为当前循环层号;
int i=0, j=0, KLevel=0, SN=-1, Line_LEN=0, fcolor=-1, BASE_VAR_NUM=PRO_NUM;
char* prepos=NULL;
//定义过程变量存储容器,即定义 :A型变量,后接 ::A型变量
char** PRO_WORDS=(char**)calloc(LOOP_LEVELS, sizeof(char*));
//初始化开关参数,SFLAG==1开始;
char* SFLAG=(char*)calloc(8, sizeof(char));
SFLAG=-1;
//初始化循环参量数组
int* FORI_CYCL=(int*)calloc(LOOP_LEVELS, sizeof(int));
int* FORI_LNUM=(int*)calloc(LOOP_LEVELS, sizeof(int));
char** FORI_FTEL=(char**)calloc(LOOP_LEVELS, sizeof(char*));
char** FORI_FEND=(char**)calloc(LOOP_LEVELS, sizeof(char*));
BOOL*FORI_IFOT=(BOOL *)calloc(LOOP_LEVELS, sizeof(BOOL ));
//分配行容器
char* LCache=(char*)calloc(1025, sizeof(char));
//辅助行指针
char* Line;
//辅助流指针
char* tmpfp=tRAM;
while(*tmpfp !='\0'){
//记录位置
char* prepos=tmpfp;
//指针置换
Line=LCache;
while(*tmpfp !='\n' && *tmpfp !='\0'){
*(Line++)=*(tmpfp++);
}
if(*tmpfp =='\n'){*(Line++)=*(tmpfp++);}
*Line='\0';
//指针回首
Line=LCache;
//行计数器
i++;
//过滤行TAB缩进或前空格
while(*Line=='\t'|| *Line==' '){Line++;}
//过滤空行或行注释
if(
(Line=='\r') ||
(Line=='\n') ||
(Line=='/' && Line=='/')
){
continue;
}
//过滤段间注释
if(
(Line=='/' &&Line=='*')
){
SFLAG=0;
continue;
}else if(
(Line=='*' &&Line=='/')
){
SFLAG=1;
continue;
}
//识别子过程名
if(
(isEND(Line, " \t\r\n\0") )&&
(Line=='T' || Line=='t')&&
(Line=='O' || Line=='o')
){
Line+=2;
//过滤TO后TAB缩进,或TO后空格
while(*Line=='\t'|| *Line==' '){Line++;}
if(isKEY(Line, prossName, " \t\r\n\0")){
SFLAG=1;
ARGS(Line, PRO_WORDS, PRO_NUM, i, Line);
}else{
SFLAG=0;
}
continue;
}
//开始开关未打开,或遇到空行
if(
SFLAG==0 ||
isEND(Line, "\r\n[")
){continue;}
//IF...ELIF连带性分析
if(
(FORI_IFOT ) &&
(Line!='E'&&Line!='e') &&
(Line!='L'&&Line!='l') &&
(Line!='I'&&Line!='i') &&
(Line!='F'&&Line!='f')
){
FORI_IFOT=FALSE;
}
//解析循环结束标签,循环加速
if(Line==']'){
if(KLevel>SFLAG){
if(FORI_CYCL <0){
int tpadd=EvalLine(Line+1, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n");
if(tpadd==0){tpadd=1;}
itoa(atoi(PRO_VALUE])+tpadd, PRO_VALUE], 10);
}
if(FORI_FEND==NULL){FORI_FEND=tmpfp;}
tmpfp=FORI_FTEL;
i=FORI_LNUM-1;
}else{
FORI_FTEL=NULL;
FORI_FEND=NULL;
FORI_CYCL=0;
SFLAG=0;
}
KLevel--;
continue;
}else{
int ki =Identify_KeyWords(Line, CYC_SIZE, (char**)CYC_WORDS, " \t\r\n\0");
if( ki!=-1){
Line=passNULL(Line+CYC_LLENS);
KLevel++;
//解析循环
if(
ki==0 && FORI_CYCL<1 && MoreJudgMent(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*/><= \t\r\n") ||
ki==1 && FORI_CYCL<EvalLine(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n" ) ||
ki==2 && MoreJudgMent(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*/><= \t\r\n") ||
ki==3 && isForTrue(Line, PRO_NUM, PRO_WORDS, PRO_VALUE,FORI_CYCL) ||
ki==4 && (FORI_IFOT) && FORI_CYCL<1 && MoreJudgMent(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*/><= \t\r\n")
){
if( FORI_FTEL==NULL ){
FORI_FTEL=prepos;
FORI_LNUM=i+1;
if(ki==3){
char *tp1, *tp2;
//提取瞬时变量名
if((tp1=strtok(Line, " "))==NULL){fprintf(stdout, "[%d]:Missing Parameter %s\n", i, Line);exit(1);}
PRO_WORDS=(char*)calloc(MAX_WORDS_SIZE, sizeof(char));
strcpy(PRO_WORDS, tp1);
//提取始步
if((tp2=strtok(NULL, " "))==NULL){fprintf(stdout, "[%d]:Missing Parameter %s\n", i, Line);exit(1);}
PRO_VALUE=(char*)calloc(MAX_VALUE_SIZE, sizeof(char));
itoa(EvalLine(tp2, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n"), PRO_VALUE, 10);
FORI_CYCL =0-PRO_NUM;
PRO_NUM++;
}
if(ki==0 || ki==4){
FORI_IFOT=FALSE;
}
}
if(ki !=3){FORI_CYCL++;}
}else{
if((ki==0||ki==4) && FORI_CYCL==0){
FORI_IFOT=TRUE;
}
if(FORI_FEND !=NULL){
if(FORI_CYCL <0){
free(PRO_WORDS);
free(PRO_VALUE);
PRO_NUM-=1;
}
tmpfp=FORI_FEND;
i=FORI_LNUM-1;
FORI_FTEL=NULL;
FORI_FEND=NULL;
FORI_CYCL=0;
KLevel--;
}else{
SFLAG=KLevel;
}
}
continue;
}
}
//语句块循环开关
if(SFLAG!=0){continue;}
//变量赋值
if(Line==':'||Line=='){
MoreAssignMent(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n");
continue;
}
//调用子过程
if(Line=='.'){
//定义过程传参容器
char** PAR_VALUE=(char**)calloc(LOOP_LEVELS, sizeof(char*));
int PAR_NUM=ARGP(Line, PAR_VALUE, PRO_NUM, PRO_WORDS, PRO_VALUE);
FileScript(Line+1, PAR_NUM, PAR_VALUE);
free(PAR_VALUE);
continue;
}
//过滤回车符
if((Line_LEN=strlen(Line))==2){
continue;
}else{
Line='\0';
}
//解析命令行
if((SN=Identify_KeyWords(Line, KEY_SIZE, (char**)KEY_WORDS, " \t\r\n\0")) !=-1){
Line=passNULL(Line+KEY_LLENS);
}else{
printf("[%d]:EEEOR LINE \"%s\"\n", i, Line);
exit(1);
}
switch(SN)
{
case0:
//FD
drawLINE(hDC, EvalLine(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n"));
break;
case1:
//BK
backWARD(EvalLine(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n"));
break;
case2:
//LT
GLOBAL_VALUE-=EvalLine(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n");
break;
case3:
//RT
GLOBAL_VALUE+=EvalLine(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n");
break;
case4:
//PU
penMODE=FALSE;
break;
case5:
//PD
if(SFLAG !=-1){
GLOBAL_VALUE=SFLAG;
SFLAG =-1;
}
penMODE=TRUE;
break;
case6:
//PE
if(SFLAG ==-1){
SFLAG=GLOBAL_VALUE;
GLOBAL_VALUE=GLOBAL_VALUE;
}
break;
case7:
//CLEAN
InvalidateRect(hCMD,NULL,FALSE);
break;
case8:
//ECHO, 输出字符串
printf("%s\n", Line);
break;
case9:
//HOME
GLOBAL_VALUE=GLOBAL_VALUE=GLOBAL_VALUE=0;
break;
case 10:
//STOP
return 0;
case 11:
//EXIT
exit(0);
case 12:
//FILL
if((fcolor=EvalLine(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n")) !=-1){
fillAREA(hDC,(BYTE)((int)GLOBAL_VALUE&0xFF), &LOGO_RGB,lrRECT->right/2+GLOBAL_VALUE,lrRECT->bottom/2-GLOBAL_VALUE);
}
break;
case 13:
//PAUSE
getch();
break;
case 14:
//WAIT
Sleep(EvalLine(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n"));
break;
case 15:
//ROTE
//将内存画布拷屏到CMD窗口
//BitBlt(hDC,0,0,WINDOW_WIDTH,WINDOW_HEIGHT, hDC1,0,0,SRCCOPY);
RotateDC(hDC, EvalLine(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n"));
break;
case 16:
//MEMUSE,开辟内存画布
if(!memMODE){
BitBlt(hDC3,0,0,lrRECT->right,lrRECT->bottom, hDC1,0,0,SRCCOPY);
memMODE=TRUE;
}
BitBlt(hDC2,0,0,lrRECT->right,lrRECT->bottom, hDC3,0,0,SRCCOPY);
hDC=hDC2;
break;
case 17:
//MEMSEE,展示内存画布
BitBlt(hDC1,0,0,lrRECT->right,lrRECT->bottom, hDC2,0,0,SRCCOPY);
BitBlt(hDC2,0,0,lrRECT->right,lrRECT->bottom, hDC3,0,0,SRCCOPY);
break;
case 18:
//MEMOUT,丢弃内存画布
memMODE=FALSE;
hDC=hDC1;
break;
case 19:
//EVAL,表达式计算输出
printf("%.12g\n", EvalLine(Line, PRO_NUM, PRO_WORDS, PRO_VALUE, "()+-*%/ \t\r\n"));
break;
default:
printf("[%d]:EEEOR LINE 。\n", i);
exit(1);
break;
}
}
free(PRO_WORDS);
free(SFLAG);
free(FORI_CYCL);
free(FORI_LNUM);
free(FORI_FTEL);
free(FORI_FEND);
free(FORI_IFOT);
free(LCache);
return 0;
}
/*************MAIN主函数入口*************/
int main(int argc, char** argv)
{
if(argc==2){
//隐藏光标
SizeCursor(0);
//初始化变量
int fsize=0;
//初始化随机种子
srand((unsigned)time(NULL));
//读文件流
FILE* fp;
if( (fp=fopen(argv, "rb"))==NULL ){
fputs("Failed to read file.", stdout);
return 2;
}
//测量尺寸
fseek(fp, 0, SEEK_END);
fsize=ftell(fp);
//超过1M的脚本,拒绝执行
if(fsize > 1*1024*1024){
fputs("File size is too large, out of memory.", stdout);
return 1;
//小于10字节的,拒绝执行
}else if(fsize < 10){
fputs("File size is too small,in of memory.", stdout);
return 1;
}
//指针复原
fseek(fp, 0, SEEK_SET);
//读入内存
tRAM=(char*)calloc(fsize+3, sizeof(char));
tRAM='\r', tRAM='\n', tRAM='\0';
fread(tRAM, fsize, 1, fp);
//释放文件
fclose(fp);
//获取CMD窗口句柄
hCMD=GetConsoleWindow();
//获取CMD窗口大小
lrRECT=&winRECT;
GetClientRect(hCMD, lrRECT);
//CMD画布
hDC1=GetDC(hCMD);
HBITMAP hBitmap1=CreateCompatibleBitmap(hDC1, lrRECT->right, lrRECT->bottom);
SelectObject(hDC1, hBitmap1);
//内存画布
hWND2=NULL;
hDC2=CreateCompatibleDC(GetDC(hWND2));
HBITMAP hBitmap2=CreateCompatibleBitmap(hDC1, lrRECT->right, lrRECT->bottom);
SelectObject(hDC2, hBitmap2);
//辅助画布
hWND3=NULL;
hDC3=CreateCompatibleDC(GetDC(hWND3));
HBITMAP hBitmap3=CreateCompatibleBitmap(hDC1, lrRECT->right, lrRECT->bottom);
SelectObject(hDC3, hBitmap3);
//运行脚本
char** PAR_VALUE=(char**)calloc(LOOP_LEVELS, sizeof(char*));
//主DC选择CMD画布
hDC=hDC1;
//寻找主函数入口点
FileScript("MAIN", 1, PAR_VALUE);
//释放DC
ReleaseDC(NULL, hDC3);
ReleaseDC(NULL, hDC2);
ReleaseDC(hCMD, hDC1);
DeleteDC(hDC3);
DeleteDC(hDC2);
DeleteDC(hDC1);
DeleteObject(hBitmap3);
DeleteObject(hBitmap2);
DeleteObject(hBitmap1);
//释放内存
free(PAR_VALUE);
free(tRAM);
return 0;
}
//异常则抛出使用说明
fputs("COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.0\nUSAGE: CLGO \n", stdout);
return 1;
}
页:
[1]