update
This commit is contained in:
parent
126f995ec3
commit
679fe7a960
@ -1,5 +1,106 @@
|
||||
#pragma once
|
||||
|
||||
#include "Lexer.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace ztl{
|
||||
|
||||
inline void interpreter(const std::vector<Token> &tokens){
|
||||
using ObjectType = std::variant<int64_t>;
|
||||
std::map<std::string, ObjectType> objects;
|
||||
const auto getValueOrLiteral = [&tokens,&objects](size_t i){
|
||||
ObjectType a;
|
||||
if(tokens[i].type==TokenType::Literal){
|
||||
a=atoi(tokens[i].str.data());
|
||||
}else if(tokens[i].type==TokenType::Identifier){
|
||||
if(auto it = objects.find(tokens[i].str);it!=objects.end()){
|
||||
a=(*it).second;
|
||||
}else{
|
||||
throw std::runtime_error(std::format("error in getting value named '{}'",tokens[i].str));
|
||||
}
|
||||
}else{
|
||||
throw std::runtime_error("error in getting expression result");
|
||||
}
|
||||
return a;
|
||||
};
|
||||
const auto getExprAns = [&getValueOrLiteral,&objects,&tokens](size_t i)->std::pair<ObjectType, size_t>{
|
||||
ObjectType a=getValueOrLiteral(i);
|
||||
ObjectType b;
|
||||
if(i+1<tokens.size()&&tokens[i+1].type==TokenType::Operator){
|
||||
if(tokens[i+1].str=="+"){
|
||||
if(i+2<tokens.size()){
|
||||
b=getValueOrLiteral(i+2);
|
||||
}else{
|
||||
throw std::runtime_error(std::format("error getting a op b, b is not found. a named '{}'",tokens[i].str));
|
||||
}
|
||||
}else{
|
||||
throw std::runtime_error(std::format("unknown operator '{}'",tokens[i+1].str));
|
||||
}
|
||||
}else{
|
||||
return {a,1};
|
||||
}
|
||||
ObjectType res;
|
||||
if(std::holds_alternative<int64_t>(a) && tokens[i+1].str=="+" && std::holds_alternative<int64_t>(b)){
|
||||
res = std::get<int64_t>(a) + std::get<int64_t>(b);
|
||||
}else{
|
||||
throw std::runtime_error(std::format("unknown operator '{}' or value type '{}' ,'{}'",tokens[i+1].str,tokens[i].str,tokens[i+2].str));
|
||||
}
|
||||
return {res,3};
|
||||
};
|
||||
for(size_t i=0;i<tokens.size();i++){
|
||||
if(tokens[i].type==TokenType::Keyword){
|
||||
if(tokens[i].str=="int"){
|
||||
if( i+2<tokens.size()
|
||||
&&tokens[i+1].type==TokenType::Identifier
|
||||
&& tokens[i+2].str=="="
|
||||
){
|
||||
std::string valueName = tokens[i+1].str;
|
||||
i+=2;
|
||||
auto res = getExprAns(i+1);
|
||||
objects[valueName] = res.first;
|
||||
i+=res.second;
|
||||
}else{
|
||||
throw std::runtime_error(std::format("error when creatting int value '{}'",tokens[i].str));
|
||||
}
|
||||
|
||||
}else if(tokens[i].str=="print"){
|
||||
if(i+1<tokens.size()&&tokens[i+1].str=="("){
|
||||
i++;
|
||||
}else{
|
||||
throw std::runtime_error("cannot get '(' when printing value");
|
||||
}
|
||||
if(!(i+1<tokens.size()))throw std::runtime_error("cannot get value be printed when printing value");
|
||||
auto [res,addi] = getExprAns(i+1);
|
||||
i+=addi;
|
||||
if(i+1<tokens.size()&&tokens[i+1].str==")"){
|
||||
i++;
|
||||
}else{
|
||||
throw std::runtime_error("cannot get ')' when printing value");
|
||||
}
|
||||
std::visit([](auto &res){
|
||||
std::cout<<res<<'\n';
|
||||
},res);
|
||||
}
|
||||
else{
|
||||
throw std::runtime_error(std::format("interpreter error Cannot find Keyword '{}'",tokens[i].str));
|
||||
}
|
||||
if(i+1<tokens.size()&&tokens[i+1].str==";"){
|
||||
i++;
|
||||
}else{
|
||||
throw std::runtime_error(std::format("cannot get ';' after '{}'",tokens[i].str));
|
||||
}
|
||||
}else{
|
||||
throw std::runtime_error(std::format("interpreter error at '{}'",tokens[i].str));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
#include <vector>
|
||||
|
||||
namespace ztl{
|
||||
|
||||
|
||||
namespace readFileToStrType{
|
||||
struct CannotOpenFile{};
|
||||
using ReturnType = std::variant<
|
||||
@ -31,29 +31,29 @@ namespace ztl{
|
||||
return s;
|
||||
}
|
||||
|
||||
#define FOR_EACH FOR_EACH_V(Keyword)\
|
||||
FOR_EACH_V(Identifier)\
|
||||
FOR_EACH_V(Literal)\
|
||||
FOR_EACH_V(Operator)\
|
||||
FOR_EACH_V(Separator)\
|
||||
FOR_EACH_V(Whitespace)\
|
||||
#define ZTL_FOR_EACH ZTL_FOR_EACH_V(Keyword)\
|
||||
ZTL_FOR_EACH_V(Identifier)\
|
||||
ZTL_FOR_EACH_V(Literal)\
|
||||
ZTL_FOR_EACH_V(Operator)\
|
||||
ZTL_FOR_EACH_V(Separator)\
|
||||
ZTL_FOR_EACH_V(Whitespace)\
|
||||
|
||||
#define FOR_EACH_V(v)v,
|
||||
#define ZTL_FOR_EACH_V(v)v,
|
||||
enum class TokenType{
|
||||
FOR_EACH
|
||||
ZTL_FOR_EACH
|
||||
};
|
||||
#undef FOR_EACH_V
|
||||
#undef ZTL_FOR_EACH_V
|
||||
inline std::string getTokenTypeName(TokenType t){
|
||||
switch (t) {
|
||||
#define FOR_EACH_V(v)case TokenType::v:{return #v;}
|
||||
FOR_EACH
|
||||
#define ZTL_FOR_EACH_V(v)case TokenType::v:{return #v;}
|
||||
ZTL_FOR_EACH
|
||||
default:
|
||||
throw std::runtime_error("unknown TokenType");
|
||||
}
|
||||
throw std::runtime_error("unreachable");
|
||||
}
|
||||
#undef FOR_EACH_V
|
||||
#undef FOR_EACH
|
||||
#undef ZTL_FOR_EACH_V
|
||||
#undef ZTL_FOR_EACH
|
||||
|
||||
struct Token{
|
||||
TokenType type;
|
||||
@ -97,14 +97,14 @@ namespace ztl{
|
||||
}
|
||||
else if(isspace(s[i])){
|
||||
continue;
|
||||
}else if(s[i]=='='){
|
||||
tokens.emplace_back(TokenType::Operator,"=");
|
||||
}else if(s[i]=='='||s[i]=='+'){
|
||||
tokens.emplace_back(TokenType::Operator,std::string()+s[i]);
|
||||
}else if(isdigit(s[i])){
|
||||
size_t begin = i;
|
||||
while(isdigit(s[i])){
|
||||
while(isdigit(s[i+1])){
|
||||
i++;
|
||||
}
|
||||
tokens.emplace_back(TokenType::Literal,s.substr(begin,i-begin));
|
||||
tokens.emplace_back(TokenType::Literal,s.substr(begin,i-begin+1));
|
||||
}
|
||||
else if(s[i]==';'||s[i]=='('||s[i]==')'){
|
||||
tokens.emplace_back(TokenType::Separator,std::string()+s[i]);
|
||||
|
@ -1,14 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "Interpreter.hpp"
|
||||
#include "Lexer.hpp"
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
namespace ztl {
|
||||
template<class ...Ts>
|
||||
struct overloaded : Ts... {using Ts::operator()...;};
|
||||
template<class ...Ts>
|
||||
overloaded (Ts...) -> overloaded<Ts...>;
|
||||
}
|
||||
|
||||
namespace std{
|
||||
template<class T>
|
||||
@ -24,4 +21,25 @@ namespace std{
|
||||
os<<" "<<v[v.size()-1]<<"]";
|
||||
return os;
|
||||
}
|
||||
}
|
||||
namespace ztl {
|
||||
template<class ...Ts>
|
||||
struct overloaded : Ts... {using Ts::operator()...;};
|
||||
template<class ...Ts>
|
||||
overloaded (Ts...) -> overloaded<Ts...>;
|
||||
|
||||
void inline runCodeFromPath(std::string_view v){
|
||||
ztl::Lexer lexer = std::visit(ztl::overloaded{
|
||||
[](std::string &&s){
|
||||
return s;
|
||||
},
|
||||
[&v](const ztl::readFileToStrType::CannotOpenFile &){
|
||||
throw std::runtime_error(std::format("Cannot open file :{}",v));
|
||||
return std::string();
|
||||
}
|
||||
},ztl::readFileToStr(v));
|
||||
|
||||
std::cout<<"Lexer() return vector:\n"<<lexer.tokens<<'\n';
|
||||
ztl::interpreter(lexer.tokens);
|
||||
}
|
||||
}
|
19
src/main.cpp
19
src/main.cpp
@ -1,26 +1,11 @@
|
||||
#include "Lexer.hpp"
|
||||
#include "Tools.hpp"
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <string_view>
|
||||
|
||||
|
||||
int main(int argc,char *argv[]){
|
||||
if(argc<2){
|
||||
throw std::runtime_error("Usage : ztl <filepath>");
|
||||
}
|
||||
ztl::Lexer lexer = std::visit(ztl::overloaded{
|
||||
[](std::string &&s){
|
||||
return s;
|
||||
},
|
||||
[&argv](const ztl::readFileToStrType::CannotOpenFile &){
|
||||
throw std::runtime_error(std::format("Cannot open file :{}",argv[1]));
|
||||
return std::string();
|
||||
}
|
||||
},ztl::readFileToStr(argv[1]));
|
||||
|
||||
std::cout<<"Lexer() return vector:\n"<<lexer.tokens<<'\n';
|
||||
|
||||
ztl::runCodeFromPath(argv[1]);
|
||||
}
|
@ -1,2 +1,5 @@
|
||||
int a =1;
|
||||
print(a);
|
||||
int a =1 +100;
|
||||
print(a);
|
||||
int a = a+5;
|
||||
print(a);
|
||||
print(a+a);
|
@ -1,3 +1,7 @@
|
||||
int main(){
|
||||
|
||||
#include "Tools.hpp"
|
||||
#include <string_view>
|
||||
|
||||
|
||||
int main(int argc,char *argv[]){
|
||||
ztl::runCodeFromPath("/root/dev/cpp/TudorLang/tests/main.ztl");
|
||||
}
|
Loading…
Reference in New Issue
Block a user