LiCode(Alpha26.5.28)
2026-05-28 21:21:46
发布于:香港
本次更新内容:
· 修复变量默认值访问会报错问题
· 修复input会让最后输入的变量输入两次
· variable预留变量从variable*变成std::size_t,用于存储id码
· print和println语法可以输出常量
· 新增ref和reref语法,可以定义引用变量和重新引用
let a=10
ref b=a
relet b=15
print a,' '
let c=10
reref b=c
relet b=20
print a,' '
#输出结果:15 15
· 新增stdin.helpf=open(std::cin.tie(&std::cout))和
/stdin.helpf=close(std::cin.tie(nullptr))
· 新增LiCode关键字,可以获取LiCode版本字面量
· 优化其他语法
源码:
#define _LiCode "Alpha26.5.28"
#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[]={
"LiCode","let","input","print","Null","println",
"stdin.helpf=open","stdin.helpf=close",
"stdout.flush","stdout.buffer=open","stdout.buffer=close",
"relet","ref","reref",
};
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;
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;
//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);
}
std::string trim_all(const std::string& str) noexcept{
std::string result{};
std::string::size_type len=str.size();
for(std::string::size_type i=0;i<len;i++){
if(std::isspace(static_cast<int>(str[i]))) continue;
result.push_back(str[i]);
}
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{
if(str=="input") return variable("","input",KeyWord,0);
if(str=="Null"||str.empty()) return null_v("",0);
if(str=="LiCode") return variable("",_LiCode,String,0);
const std::string::size_type len=str.size();
if(len==1){
char chr=str.front();
if(chr=='.') return variable("","0.000000",Float,0);
if(std::isdigit(static_cast<int>(chr))) return variable("",str,Int,0);
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,0);
}
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,0);
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,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::vector<variable>::size_type index;
while(std::getline(stringin,word,',')){
word=trim(word);
std::string _word=trim_all(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;
while(std::getline(stringin,word,',')){
word=trim(word);
std::string _word=trim_all(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 execln(const std::string& str) noexcept{
std::string line=trim(str);
if(line.empty()||line.front()=='#') return emptyln;
std::string::iterator it=
std::find_if(line.begin(),line.end(),[](char& chr){return !std::isalnum(static_cast<int>(chr));});
if(it==line.end()) return exec_flag(444);
std::string word=trim(line.substr(0,it+1-line.begin()));
std::istringstream stringin(std::string(it,line.end()));
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 return kwordno;
return goodres;
}
int main(){
std::ifstream fin("LiCode.txt");
if(!fin.is_open()){
std::cerr<<"Cannot open 'LiCode.txt!'";
return 404;
}
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展示效果
5小时前 来自 香港
0
















有帮助,赞一个