LiCode(Alpha26.5.27)
2026-05-27 21:20:12
发布于:香港
本次更新内容:
· 优化let语法,可以赋值变量
#不会报错
let a=10
let b=a
· 新增relet语法,可以重新定义变量
#不会报错
let a=10
relet a=20
· variable结构体新增预留变量,目前没有发现Bug
· 优化部分代码
struct variable{
std::string name{};
std::string data{};
ctypes type=Null;
variable* point=nullptr; //新增预留变量
variable() noexcept=default;
variable(const std::string& _name,const std::string& _data,ctypes _type,variable* _point)
noexcept: name(_name),data(_data),type(_type),point(_point){}
~variable() noexcept=default;
};
源码:
#define _LiCode "Alpha26.5.27"
#include<algorithm>
#include<cctype>
#include<cstdint>
#include<fstream>
#include<iostream>
#include<limits>
#include<sstream>
#include<string>
#include<vector>
#define size_type_max std::numeric_limits<std::vector<variable>::size_type>::max()
static constexpr const char* key_words[]={
"let","input","print","Null","println",
"stdout.flush","stdout.buffer=open","stdout.buffer=close",
"relet",
};
static constexpr size_t kw_cnt=sizeof(key_words)/sizeof(const char*);
bool ostream_need_buffer=true;
enum ctypes: char{Int,Float,String,Null,Error,KeyWord};
enum exec_flag: char{emptyln,goodres,vnameno,valueno,kwordno};
struct variable{
std::string name{};
std::string data{};
ctypes type=Null;
variable* point=nullptr;
variable() noexcept=default;
variable(const std::string& _name,const std::string& _data,ctypes _type,variable* _point)
noexcept: name(_name),data(_data),type(_type),point(_point){}
~variable() noexcept=default;
};
#define error_v variable("","",Error,nullptr)
#define null_v variable("","",Null,nullptr)
static std::vector<variable> memory;
//static std::vector<variable> temps(16,variable{{},{},Null});
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);
}
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{
if(str=="input") return variable("","input",KeyWord,nullptr);
if(str=="Null"||str.empty()) return null_v;
const std::string::size_type len=str.size();
if(len==1){
char chr=str.front();
if(chr=='.') return variable("","0.000000",Float,nullptr);
if(std::isdigit(static_cast<int>(chr))) return variable("",str,Int,nullptr);
return error_v;
}
if(len>=2){
char front=str.front(),back=str.back();
if((front=='\"'&&back=='\"')||(front=='\''&&back=='\'')){
std::string result{};
for(std::string::size_type i=1;i<len-1;i++){
char chr=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(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(str[i]);
break;
}
}
else result.push_back(chr);
}
return variable("",result,String,nullptr);
}
else{
std::string::const_iterator cbegin=str.cbegin(),cend=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,nullptr);
std::string::size_type dotpos=str.find('.');
std::string::size_type len;
std::string intpart=std::string(trim(str.substr(cbegin-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(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,nullptr));
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);
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);
return goodres;
}
exec_flag exec_input(std::istringstream& stringin) noexcept{
std::string word;
std::vector<variable>::size_type index=find_v(word);
while(std::getline(stringin,word,',')){
index=find_v(word);
if(index!=size_type_max){
std::cin>>memory.back().data;
memory[index].type=String;
}
else return vnameno;
}
if(!word.empty()){
index=find_v(word);
if(index!=size_type_max){
std::cin>>memory.back().data;
memory[index].type=String;
}
else return vnameno;
}
return goodres;
}
exec_flag exec_print(std::istringstream& stringin) noexcept{
std::string word;
while(std::getline(stringin,word,',')){
word=trim(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) std::cout<<memory[index].data;
else std::cerr<<memory[index].data;
}
else if(true){
variable temp=opt_sval(word);
if(temp.type==Error) return valueno;
else if(temp.type==KeyWord){
if(temp.data=="input"){
std::cin>>temp.data;
std::cout<<temp.data;
}
}
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').flush();
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)
relet_v=variable(name,memory[index].data,memory[index].type,relet_v.point);
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,relet_v.point);
if(opt_value.type==KeyWord){
if(opt_value.data=="input"){
std::cin>>relet_v.data;
relet_v.type=String;
}
}
}
}
else relet_v=null_v;
return goodres;
}
exec_flag execln(const std::string& str) noexcept{
std::string line=trim(str);
if(line.empty()||line.front()=='#') return emptyln;
std::istringstream stringin(line);
std::string word;
stringin>>word;
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 return kwordno;
return goodres;
}
int main(){
std::ifstream fin("LiCode.txt");
if(!fin.is_open()){
std::cerr<<"Cannot open 'LiCode.txt!'";
return 404;
}
memory.push_back(null_v);
std::string line;
for(std::uint64_t cnt=1;std::getline(fin,line);cnt++){
exec_flag exec_result=execln(line);
switch(exec_result){
case emptyln:
continue;
case goodres:
continue;
case vnameno:
std::cerr<<"\nLiCode System Error: variable name is not good";
std::cerr<<"\nError line: "<<cnt;
return vnameno;
case valueno:
std::cerr<<"\nLiCode System Error: variable value is not good";
std::cerr<<"\nError line: "<<cnt;
return valueno;
case kwordno:
std::cerr<<"\nLiCode System Error: key word cannot find it";
std::cerr<<"\nError line: "<<cnt;
return kwordno;
default:
std::cerr<<"\nLiCode System Error: unknown error";
std::cerr<<"\nError line: "<<cnt;
return 444;
}
}
fin.close();
}
希望大家可以支持一下
如果有Bug,请在评论区留言
全部评论 1
此处输入正文,2千字以内,可点击右上角【去预览】按钮查看markdown展示效果
昨天 来自 香港
0
















有帮助,赞一个