LiCode(Alpha26.5.30)
2026-05-30 20:54:15
发布于:香港
本次更新内容:
· 新增sleep(N)语句,可以让程序休眠N毫秒
· 新增clear语句(只能单独存在),可以清屏
· 新增import语句,可以导入文件,不用担心重复导入
· print,input,println需要括号,例如:input(a,b)
· · 优化其他语法
源码:
#define _LiCode "Alpha26.5.30"
#include<algorithm>
#include<cctype>
#include<chrono>
#include<cstdint>
#include<cstdlib>
#include<fstream>
#include<iostream>
#include<limits>
#include<sstream>
#include<string>
#include<thread>
#include<unordered_set>
#include<vector>
#define size_type_max std::numeric_limits<std::vector<variable>::size_type>::max()
static constexpr const char* key_words[]={
"LiCode","let","input","print","Null","println",
"stdin.helpf=open","stdin.helpf=close",
"stdout.flush","stdout.buffer=open","stdout.buffer=close",
"relet","ref","reref",
"sleep","clear","import",
};
static constexpr size_t kw_cnt=sizeof(key_words)/sizeof(const char*);
static std::unordered_set<std::string> imported_files={"LiCode","",};
static bool ostream_need_buffer=true;
void sleep(unsigned long long value) noexcept{
std::chrono::milliseconds ms(value);
std::this_thread::sleep_for(ms);
}
enum ctypes: char{Int,Float,String,Null,Error,KeyWord};
enum exec_flag: char{
emptyln,goodres,
vnameno,valueno,kwordno,fmtnotg,
fnohave
};
exec_flag execln(const std::string&) noexcept;
struct variable{
std::string name{};
std::string data{};
ctypes type=Null;
std::size_t id=0;
variable() noexcept=default;
variable(const std::string& _name,const std::string& _data,ctypes _type,std::size_t _id)
noexcept: name(_name),data(_data),type(_type),id(_id){}
~variable() noexcept=default;
};
#define error_v variable("","",Error,0)
#define null_v(name,id) variable(name,"",Null,id)
static std::vector<variable> memory;
void error(exec_flag exec,std::uint64_t cnt) noexcept{
switch(exec){
case emptyln:
break;
case goodres:
break;
case vnameno:
std::cerr<<"\nLiCode System Error: variable name error";
std::cerr<<"\nError line: "<<cnt;
abort();
case valueno:
std::cerr<<"\nLiCode System Error: variable value error";
std::cerr<<"\nError line: "<<cnt;
abort();
case kwordno:
std::cerr<<"\nLiCode System Error: key word error";
std::cerr<<"\nError line: "<<cnt;
abort();
case fmtnotg:
std::cerr<<"\nLiCode System Error: format error";
std::cerr<<"\nError line: "<<cnt;
abort();
case fnohave:
std::cerr<<"\nLiCode System Error: file error";
std::cerr<<"\nError line: "<<cnt;
abort();
default:
std::cerr<<"\nLiCode System Error: unknown error";
std::cerr<<"\nError line: "<<cnt;
abort();
}
}
std::string trim(const std::string& str) noexcept{
std::string::const_iterator start=str.cbegin();
std::string::const_iterator end=str.cend();
while(start!=end&&std::isspace(static_cast<int>(*start))) start++;
do{end--;}while(std::distance(start,end)>0&&std::isspace(static_cast<int>(*end)));
return std::string(start,end+1);
}
std::string trim_split(const std::string& str) noexcept{
std::string result{};
std::string split_temp{};
std::string::size_type len=str.size();
for(std::string::size_type i=0;i<len;i++){
if(
std::isalnum(static_cast<int>(str[i]))||
std::isspace(static_cast<int>(str[i]))
) split_temp.push_back(str[i]);
else{
result=trim(result);
result.append(trim(split_temp));
result.push_back(str[i]);
split_temp.clear();
}
}
if(!split_temp.empty()){
result=trim(result);
result.append(trim(split_temp));
}
return result;
}
bool vname_check(const std::string& name) noexcept{
if(name.empty()) return false;
std::string::size_type len=name.size();
if(std::isdigit(static_cast<int>(name.front()))) return false;
for(std::string::size_type i=0;i<len;i++){
char chr=name[i];
if(std::isalnum(static_cast<int>(chr))||chr=='_') continue;
return false;
}
for(std::size_t i=0;i<kw_cnt;i++){
if(name==key_words[i]) return false;
}
std::vector<variable>::size_type size=memory.size();
for(std::vector<variable>::size_type i=0;i<size;i++){
if(name==memory[i].name) return false;
}
return true;
}
variable opt_sval(const std::string& str) noexcept{
std::string trim_str=trim(str);
if(trim_str=="input") return variable("","input",KeyWord,0);
if(trim_str=="Null"||str.empty()) return null_v("",0);
if(trim_str=="LiCode") return variable("",_LiCode,String,0);
const std::string::size_type len=trim_str.size();
if(len==1){
char chr=trim_str.front();
if(chr=='.') return variable("","0.000000",Float,0);
if(std::isdigit(static_cast<int>(chr))) return variable("",trim_str,Int,0);
return error_v;
}
if(len>=2){
char front=trim_str.front(),back=trim_str.back();
if((front=='\"'&&back=='\"')||(front=='\''&&back=='\'')){
std::string result{};
for(std::string::size_type i=1;i<len-1;i++){
char chr=trim_str[i];
if(chr=='\''){
if(front=='\'') return error_v;
result.push_back('\'');
}
else if(chr=='\"'){
if(front=='\"') return error_v;
result.push_back('\"');
}
else if(chr=='\\'){
if(i==len-1) return error_v;
switch(trim_str[++i]){
case 'a':
result.push_back('\a');
break;
case 'b':
result.push_back('\b');
break;
case 'f':
result.push_back('\f');
break;
case 'n':
result.push_back('\n');
break;
case 'r':
result.push_back('\r');
break;
case 't':
result.push_back('\t');
break;
case 'v':
result.push_back('\v');
break;
case '\\':
result.push_back('\\');
break;
case '\'':
result.push_back('\'');
break;
case '\"':
result.push_back('\"');
break;
case '0':
result.push_back('\0');
break;
default:
result.push_back(chr);
result.push_back(trim_str[i]);
break;
}
}
else result.push_back(chr);
}
return variable("",result,String,0);
}
else{
std::string::const_iterator cbegin=trim_str.cbegin(),cend=trim_str.cend();
bool isneg=false;
for(;cbegin!=cend;cbegin++){
if(*cbegin=='+') continue;
if(*cbegin=='-') isneg^=true;
else break;
}
if(cbegin==cend) return error_v;
variable result("",isneg?"-":"",Int,0);
std::string::size_type dotpos=trim_str.find('.');
std::string::size_type len;
std::string intpart=std::string(trim(trim_str.substr(cbegin-trim_str.cbegin(),dotpos)));
len=intpart.size();
if(len==0) result.data.push_back('0');
else{
for(std::string::size_type i=0;i<len;i++){
char chr=intpart[i];
if(!std::isdigit(static_cast<int>(chr)))
return error_v;
result.data.push_back(chr);
}
}
if(dotpos!=std::string::npos){
result.type=Float;
result.data.push_back('.');
std::string floatpart=std::string(trim(trim_str.substr(dotpos+1)));
len=floatpart.size();
if(len==0) result.data.append("000000");
for(std::string::size_type i=0;i<6;i++){
char chr=floatpart[i];
if(!std::isdigit(static_cast<int>(chr)))
return error_v;
result.data.push_back(chr);
}
if(len<6){
std::string::size_type pad=6-len;
result.data.append(pad,'0');
}
}
return result;
}
}
return variable();
}
std::vector<variable>::size_type find_v(const std::string& name) noexcept{
std::vector<variable>::iterator it=
std::find_if(memory.begin(),memory.end(),[&name](const variable& var){return var.name==name;});
if(it!=memory.end()) return static_cast<std::vector<variable>::size_type>(std::distance(memory.begin(),it));
else return size_type_max;
}
exec_flag exec_let(std::istringstream& stringin) noexcept{
std::string word;
std::getline(stringin,word);
std::string::size_type eq=word.find('=');
std::string name=trim(word.substr(0,eq));
if(!vname_check(name)) return vnameno;
if(eq!=std::string::npos){
std::string value=trim(word.substr(eq+1));
std::vector<variable>::size_type index=find_v(value);
if(index!=size_type_max){
memory.push_back(variable(name,memory[index].data,memory[index].type,0));
memory.back().id=memory.size()-1;
}
else if(true){
variable opt_value=opt_sval(value);
if(opt_value.type==Error) return valueno;
opt_value.name=name;
memory.push_back(opt_value);
memory.back().id=memory.size()-1;
if(opt_value.type==KeyWord){
if(opt_value.data=="input"){
std::cin>>memory.back().data;
memory.back().type=String;
}
}
}
}
else memory.push_back(null_v(name,memory.size()));
return goodres;
}
exec_flag exec_input(std::istringstream& stringin) noexcept{
std::string word;
std::getline(stringin,word);
word=trim(word);
if(word.empty()||word.front()!='('||word.back()!=')') return fmtnotg;
word=word.substr(1,word.size()-2);
word=trim(word);
if(word.empty()) return goodres;
stringin.str(word);
stringin.clear();
stringin.seekg(0);
std::vector<variable>::size_type index;
while(std::getline(stringin,word,',')){
word=trim(word);
std::string _word=trim_split(word);
if(_word=="stdin.helpf=open") std::cin.tie(&std::cout);
else if(_word=="stdin.helpf=close") std::cin.tie(nullptr);
else{
index=find_v(word);
if(index!=size_type_max){
std::vector<variable>::size_type this_id=memory[index].id;
std::cin>>memory[index].data;
memory[index].type=String;
std::vector<variable>::size_type len=memory.size();
for(std::vector<variable>::size_type i=0;i<len;i++){
if(memory[i].id==this_id)
memory[i]=variable(memory[i].name,memory[index].data,memory[index].type,this_id);
}
}
else return vnameno;
}
}
return goodres;
}
exec_flag exec_print(std::istringstream& stringin) noexcept{
std::string word;
std::getline(stringin,word);
word=trim(word);
if(word.empty()||word.front()!='('||word.back()!=')') return fmtnotg;
word=word.substr(1,word.size()-2);
word=trim(word);
if(word.empty()){
if(ostream_need_buffer) std::cout<<"(nil)";
else std::cerr<<"(nil)";
return goodres;
}
stringin.str(word);
stringin.clear();
stringin.seekg(0);
while(std::getline(stringin,word,',')){
word=trim(word);
std::string _word=trim_split(word);
if(_word=="stdout.flush") std::cout.flush();
else if(_word=="stdout.buffer=open") ostream_need_buffer=true;
else if(_word=="stdout.buffer=close") ostream_need_buffer=false;
else{
std::vector<variable>::size_type index=find_v(word);
if(index!=size_type_max){
if(ostream_need_buffer){
if(memory[index].type==Null) std::cout<<"(nil)";
else std::cout<<memory[index].data;
}
else{
if(memory[index].type==Null) std::cerr<<"(nil)";
else std::cerr<<memory[index].data;
}
}
else if(true){
variable temp=opt_sval(word);
if(temp.type==Error) return valueno;
else if(temp.type==Null) std::cout<<"(nil)";
else std::cout<<temp.data;
}
}
}
return goodres;
}
exec_flag exec_println(std::istringstream& stringin) noexcept{
exec_flag result=exec_print(stringin);
if(result==goodres){
std::cout.put('\n');
return goodres;
}
return result;
}
exec_flag exec_relet(std::istringstream& stringin) noexcept{
std::string word;
std::getline(stringin,word);
std::string::size_type eq=word.find('=');
std::string name=trim(word.substr(0,eq));
std::vector<variable>::size_type index;
index=find_v(name);
if(index==size_type_max) return vnameno;
variable& relet_v=memory[index];
if(eq!=std::string::npos){
std::string value=trim(word.substr(eq+1));
index=find_v(value);
if(index!=size_type_max){
std::vector<variable>::size_type this_id=relet_v.id;
std::vector<variable>::size_type len=memory.size();
for(std::vector<variable>::size_type i=0;i<len;i++){
if(memory[i].id==this_id)
memory[i]=variable(memory[i].name,memory[index].data,memory[index].type,this_id);
}
}
else if(true){
variable opt_value=opt_sval(value);
if(opt_value.type==Error) return valueno;
if(opt_value.type==KeyWord){
if(opt_value.data=="input"){
std::cin>>opt_value.data;
opt_value.type=String;
}
}
std::vector<variable>::size_type this_id=relet_v.id;
opt_value.id=this_id;
std::vector<variable>::size_type len=memory.size();
for(std::vector<variable>::size_type i=0;i<len;i++){
if(memory[i].id==this_id){
opt_value.name=memory[i].name;
memory[i]=opt_value;
}
}
}
}
else relet_v=null_v(name,relet_v.id);
return goodres;
}
exec_flag exec_ref(std::istringstream& stringin) noexcept{
std::string word;
std::getline(stringin,word);
std::string::size_type eq=word.find('=');
std::string name=trim(word.substr(0,eq));
if(!vname_check(name)) return vnameno;
if(eq!=std::string::npos){
std::string value=trim(word.substr(eq+1));
std::vector<variable>::size_type index=find_v(value);
if(index!=size_type_max){
memory.push_back(variable(name,memory[index].data,memory[index].type,0));
memory.back().id=index;
}
else return valueno;
}
else return valueno;
return goodres;
}
exec_flag exec_reref(std::istringstream& stringin) noexcept{
std::string word;
std::getline(stringin,word);
std::string::size_type eq=word.find('=');
std::string name=trim(word.substr(0,eq));
std::vector<variable>::size_type index;
index=find_v(name);
if(index==size_type_max) return vnameno;
variable& relet_v=memory[index];
if(eq!=std::string::npos){
std::string value=trim(word.substr(eq+1));
index=find_v(value);
if(index!=size_type_max)
relet_v=variable(name,memory[index].data,memory[index].type,index);
else if(true){
variable opt_value=opt_sval(value);
if(opt_value.type==Error) return valueno;
opt_value.name=name;
relet_v=variable(name,opt_value.data,opt_value.type,memory.size());
if(opt_value.type==KeyWord){
if(opt_value.data=="input"){
std::cin>>relet_v.data;
relet_v.type=String;
}
}
}
}
else relet_v=null_v(name,relet_v.id);
return goodres;
}
exec_flag exec_sleep(std::istringstream& stringin) noexcept{
std::string word;
std::getline(stringin,word);
word=trim(word);
if(word.empty()||word.front()!='('||word.back()!=')') return fmtnotg;
word=word.substr(1,word.size()-2);
word=trim(word);
if(word.empty()) return valueno;
std::vector<variable>::size_type index=find_v(word);
if(index!=size_type_max){
if(memory[index].type!=Int) return valueno;
if(memory[index].data.front()=='-') return valueno;
try{sleep(std::stoull(memory[index].data));}
catch(...){sleep(std::numeric_limits<unsigned long long>::max());}
}
else if(true){
variable opt_value=opt_sval(word);
if(opt_value.type!=Int) return valueno;
if(opt_value.data.front()=='-') return valueno;
try{sleep(std::stoull(opt_value.data));}
catch(...){sleep(std::numeric_limits<unsigned long long>::max());}
}
else return valueno;
return goodres;
}
exec_flag exec_clear(void) noexcept{
#if defined(_WIN32)||defined(_WIN64)
system("cls");
#elif defined(__linux__)||defined(__APPLE__)
system("clear");
#endif
return goodres;
}
exec_flag exec_import(std::istringstream& stringin) noexcept{
std::string word;
std::getline(stringin,word);
word=trim(word);
const std::string suffix=".txt";
std::string file_path=word;
if(file_path.size()>=suffix.size()&&file_path.substr(file_path.size()-suffix.size())==suffix)
file_path=file_path.substr(0,file_path.size()-suffix.size());
file_path.append(suffix);
if(imported_files.find(file_path)!=imported_files.end()) return goodres;
std::ifstream fin(file_path);
if (!fin.is_open()) return fnohave;
imported_files.insert(file_path);
std::string line;
for(std::size_t cnt=0;std::getline(fin,line);cnt++) error(execln(line),cnt);
if(fin.bad()){
fin.close();
return fnohave;
}
fin.close();
return goodres;
}
exec_flag execln(const std::string& str) noexcept{
std::string line=trim(str);
if(line.empty()||line.front()=='#') return emptyln;
std::string::size_type pos=0;
while(pos<line.size()&&(std::isalnum(static_cast<int>(line[pos])))) pos++;
std::string word=trim(line.substr(0,pos));
std::istringstream stringin(line.substr(pos));
if(word=="let") return exec_let(stringin);
else if(word=="input") return exec_input(stringin);
else if(word=="print") return exec_print(stringin);
else if(word=="println") return exec_println(stringin);
else if(word=="relet") return exec_relet(stringin);
else if(word=="ref") return exec_ref(stringin);
else if(word=="reref") return exec_reref(stringin);
else if(word=="sleep") return exec_sleep(stringin);
else if(word=="clear") return exec_clear();
else if(word=="import") return exec_import(stringin);
else return kwordno;
return goodres;
}
int main(){
std::ifstream fin("LiCode.txt");
if(!fin.is_open()){
std::cerr<<"LiCode System Error: Cannot open 'LiCode.txt'!";
abort();
}
std::string line;
for(std::uint64_t cnt=1;std::getline(fin,line);cnt++) error(execln(line),cnt);
}
提醒一句,要在专案运行,写代码时要在名为LiCode.txt的文件里写
希望大家可以支持一下
如果有Bug,请在评论区留言
全部评论 1
此处输入正文,2千字以内,可点击右上角【去预览】按钮查看markdown展示效果
8小时前 来自 香港
0

















有帮助,赞一个