This commit is contained in:
Valk Richard Li 2020-10-23 17:10:02 +08:00
parent e8341c7b06
commit 9958431b58
5 changed files with 61 additions and 145 deletions

View File

@ -1,20 +1,18 @@
#include "nasal.h" #include "nasal.h"
nasal_resource resource;
nasal_lexer lexer; nasal_lexer lexer;
nasal_parse parse; nasal_parse parse;
nasal_import preprocessor; nasal_import preprocessor;
nasal_codegen code_generator; nasal_codegen code_generator;
std::string command;
std::string inputfile="null"; std::string inputfile="null";
nasal_runtime runtime; nasal_runtime runtime;
void help() void help()
{ {
std::cout<<">> [\"file\"] input a file name.\n"; std::cout<<">> [\"file\"] input a file name.\n";
std::cout<<">> [help ] show help.\n";
std::cout<<">> [clear ] clear the screen.\n"; std::cout<<">> [clear ] clear the screen.\n";
std::cout<<">> [del ] clear the input filename.\n"; std::cout<<">> [del ] clear the input filename.\n";
std::cout<<">> [rs ] print source code.\n";
std::cout<<">> [lex ] use lexer to turn code into tokens.\n"; std::cout<<">> [lex ] use lexer to turn code into tokens.\n";
std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n"; std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n";
std::cout<<">> [run ] run abstract syntax tree.\n"; std::cout<<">> [run ] run abstract syntax tree.\n";
@ -37,7 +35,6 @@ void logo()
void del_func() void del_func()
{ {
resource.clear();
lexer.clear(); lexer.clear();
parse.clear(); parse.clear();
inputfile="null"; inputfile="null";
@ -53,12 +50,8 @@ void die(std::string stage,std::string filename)
void lex_func() void lex_func()
{ {
if(!resource.input_file(inputfile)) lexer.openfile(inputfile);
{ lexer.scanner();
die("resource",inputfile);
return;
}
lexer.scanner(resource.get_file());
if(lexer.get_error()) if(lexer.get_error())
{ {
die("lexer",inputfile); die("lexer",inputfile);
@ -70,12 +63,8 @@ void lex_func()
void ast_print() void ast_print()
{ {
if(!resource.input_file(inputfile)) lexer.openfile(inputfile);
{ lexer.scanner();
die("resource",inputfile);
return;
}
lexer.scanner(resource.get_file());
if(lexer.get_error()) if(lexer.get_error())
{ {
die("lexer",inputfile); die("lexer",inputfile);
@ -93,12 +82,8 @@ void ast_print()
} }
void runtime_start() void runtime_start()
{ {
if(!resource.input_file(inputfile)) lexer.openfile(inputfile);
{ lexer.scanner();
die("resource",inputfile);
return;
}
lexer.scanner(resource.get_file());
if(lexer.get_error()) if(lexer.get_error())
{ {
die("lexer",inputfile); die("lexer",inputfile);
@ -124,12 +109,8 @@ void runtime_start()
void codegen_start() void codegen_start()
{ {
if(!resource.input_file(inputfile)) lexer.openfile(inputfile);
{ lexer.scanner();
die("resource",inputfile);
return;
}
lexer.scanner(resource.get_file());
if(lexer.get_error()) if(lexer.get_error())
{ {
die("lexer",inputfile); die("lexer",inputfile);
@ -173,6 +154,7 @@ void execution_start()
int main() int main()
{ {
std::string command;
#ifdef _WIN32 #ifdef _WIN32
// use chcp 65001 to use unicode io // use chcp 65001 to use unicode io
system("chcp 65001"); system("chcp 65001");
@ -213,11 +195,6 @@ int main()
} }
else if(command=="del") else if(command=="del")
del_func(); del_func();
else if(command=="rs")
{
if(resource.input_file(inputfile))
resource.print_file();
}
else if(command=="lex") else if(command=="lex")
lex_func(); lex_func();
else if(command=="ast") else if(command=="ast")
@ -233,16 +210,7 @@ int main()
else if(command=="exit") else if(command=="exit")
break; break;
else else
{
inputfile=command; inputfile=command;
std::ifstream fin(command);
if(fin.fail())
{
std::cout<<">> [file] cannot open file \""<<command<<"\".\n";
inputfile="null";
}
fin.close();
}
} }
return 0; return 0;
} }

View File

@ -11,8 +11,7 @@
#include <cstdlib> #include <cstdlib>
#include <ctime> #include <ctime>
#include <cmath> #include <cmath>
/* if thread is used, don't forget to add -std=c++11 or higher standard before executing */ #include <thread>
// #include <thread>
#include <list> #include <list>
#include <stack> #include <stack>
#include <queue> #include <queue>
@ -21,7 +20,6 @@
#include "nasal_enum.h" #include "nasal_enum.h"
#include "nasal_misc.h" #include "nasal_misc.h"
#include "nasal_resource.h"
#include "nasal_lexer.h" #include "nasal_lexer.h"
#include "nasal_ast.h" #include "nasal_ast.h"
#include "nasal_parse.h" #include "nasal_parse.h"

View File

@ -4,7 +4,6 @@
class nasal_import class nasal_import
{ {
private: private:
nasal_resource import_src;
nasal_lexer import_lex; nasal_lexer import_lex;
nasal_parse import_par; nasal_parse import_par;
nasal_ast import_ast; nasal_ast import_ast;
@ -26,7 +25,6 @@ public:
nasal_import::nasal_import() nasal_import::nasal_import()
{ {
import_src.clear();
import_lex.clear(); import_lex.clear();
import_par.clear(); import_par.clear();
import_ast.clear(); import_ast.clear();
@ -43,7 +41,6 @@ void nasal_import::die(std::string filename,std::string error_stage)
void nasal_import::init() void nasal_import::init()
{ {
import_src.clear();
import_lex.clear(); import_lex.clear();
import_par.clear(); import_par.clear();
return; return;
@ -112,12 +109,8 @@ nasal_ast nasal_import::file_import(nasal_ast& node)
return tmp; return tmp;
// start importing... // start importing...
if(!import_src.input_file(filename)) import_lex.openfile(filename);
{ import_lex.scanner();
this->die(filename,"resource");
return tmp;
}
import_lex.scanner(import_src.get_file());
if(import_lex.get_error()) if(import_lex.get_error())
{ {
this->die(filename,"lexer"); this->die(filename,"lexer");

View File

@ -81,14 +81,19 @@ class nasal_lexer
{ {
private: private:
int error; int error;
int res_size;
int line;
int ptr;
std::vector<char> res;
std::vector<token> token_list; std::vector<token> token_list;
std::string identifier_gen(std::vector<char>&,int&,int&); std::string identifier_gen();
void generate_number_error(int,std::string); void generate_number_error(int,std::string);
std::string number_gen(std::vector<char>&,int&,int&); std::string number_gen();
std::string string_gen(std::vector<char>&,int&,int&); std::string string_gen();
public: public:
void clear(); void clear();
void scanner(std::vector<char>&); void openfile(std::string);
void scanner();
void print_token(); void print_token();
int get_error(); int get_error();
std::vector<token>& get_token_list(); std::vector<token>& get_token_list();
@ -96,13 +101,41 @@ public:
void nasal_lexer::clear() void nasal_lexer::clear()
{ {
error=0;
res_size=0;
line=0;
ptr=0;
res.clear();
token_list.clear(); token_list.clear();
return; return;
} }
std::string nasal_lexer::identifier_gen(std::vector<char>& res,int& ptr,int& line) void nasal_lexer::openfile(std::string filename)
{
error=0;
res.clear();
std::ifstream fin(filename,std::ios::binary);
if(fin.fail())
{
++error;
std::cout<<">> [lexer] cannot open file \""<<filename<<"\".\n";
fin.close();
return;
}
while(!fin.eof())
{
char c=fin.get();
if(fin.eof())
break;
res.push_back(c);
}
fin.close();
res_size=res.size();
return;
}
std::string nasal_lexer::identifier_gen()
{ {
int res_size=res.size();
std::string token_str=""; std::string token_str="";
while(ptr<res_size && IS_IDENTIFIER_BODY(res[ptr])) while(ptr<res_size && IS_IDENTIFIER_BODY(res[ptr]))
token_str+=res[ptr++]; token_str+=res[ptr++];
@ -116,9 +149,8 @@ void nasal_lexer::generate_number_error(int line,std::string token_str)
std::cout<<">> [lexer] line "<<line<<": \""<<token_str<<"\" is not a correct number.\n"; std::cout<<">> [lexer] line "<<line<<": \""<<token_str<<"\" is not a correct number.\n";
return; return;
} }
std::string nasal_lexer::number_gen(std::vector<char>& res,int& ptr,int& line) std::string nasal_lexer::number_gen()
{ {
int res_size=res.size();
bool scientific_notation=false;// numbers like 1e8 are scientific_notation bool scientific_notation=false;// numbers like 1e8 are scientific_notation
std::string token_str=""; std::string token_str="";
// generate hex number // generate hex number
@ -203,9 +235,8 @@ std::string nasal_lexer::number_gen(std::vector<char>& res,int& ptr,int& line)
return token_str; return token_str;
} }
std::string nasal_lexer::string_gen(std::vector<char>& res,int& ptr,int& line) std::string nasal_lexer::string_gen()
{ {
int res_size=res.size();
std::string token_str=""; std::string token_str="";
char str_begin=res[ptr++]; char str_begin=res[ptr++];
if(ptr>=res_size) return token_str; if(ptr>=res_size) return token_str;
@ -246,11 +277,12 @@ std::string nasal_lexer::string_gen(std::vector<char>& res,int& ptr,int& line)
return token_str; return token_str;
} }
void nasal_lexer::scanner(std::vector<char>& res) void nasal_lexer::scanner()
{ {
error=0;
token_list.clear(); token_list.clear();
int line=1,ptr=0,res_size=res.size(); line=1;
ptr=0;
std::string token_str; std::string token_str;
while(ptr<res_size) while(ptr<res_size)
{ {
@ -263,7 +295,7 @@ void nasal_lexer::scanner(std::vector<char>& res)
if(ptr>=res_size) break; if(ptr>=res_size) break;
if(IS_IDENTIFIER_HEAD(res[ptr])) if(IS_IDENTIFIER_HEAD(res[ptr]))
{ {
token_str=identifier_gen(res,ptr,line); token_str=identifier_gen();
token new_token; token new_token;
new_token.line=line; new_token.line=line;
new_token.str=token_str; new_token.str=token_str;
@ -280,7 +312,7 @@ void nasal_lexer::scanner(std::vector<char>& res)
} }
else if(IS_DIGIT(res[ptr])) else if(IS_DIGIT(res[ptr]))
{ {
token_str=number_gen(res,ptr,line); token_str=number_gen();
token new_token; token new_token;
new_token.line=line; new_token.line=line;
new_token.str=token_str; new_token.str=token_str;
@ -289,7 +321,7 @@ void nasal_lexer::scanner(std::vector<char>& res)
} }
else if(IS_STRING_HEAD(res[ptr])) else if(IS_STRING_HEAD(res[ptr]))
{ {
token_str=string_gen(res,ptr,line); token_str=string_gen();
token new_token; token new_token;
new_token.line=line; new_token.line=line;
new_token.type=tok_string; new_token.type=tok_string;

View File

@ -1,75 +0,0 @@
#ifndef __NASAL_RESOURCE_H__
#define __NASAL_RESOURCE_H__
class nasal_resource
{
private:
std::vector<char> res;
public:
bool input_file(std::string);
void clear();
void print_file();
std::vector<char>& get_file();
};
bool nasal_resource::input_file(std::string filename)
{
res.clear();
std::ifstream fin(filename,std::ios::binary);
if(fin.fail())
{
std::cout<<">> [resource] cannot open file \""<<filename<<"\".\n";
fin.close();
return false;
}
while(!fin.eof())
{
char c=fin.get();
if(fin.eof())
break;
res.push_back(c);
}
fin.close();
return true;
}
void nasal_resource::clear()
{
res.clear();
return;
}
void nasal_resource::print_file()
{
int size=res.size(),line=1;
std::cout<<line<<"\t";
std::string unicode_str="";
for(int i=0;i<size;++i)
{
if(res[i]>=0 && unicode_str.length())
{
std::cout<<unicode_str;
unicode_str="";
}
if(32<=res[i])
std::cout<<res[i];
else if(res[i]<0)
unicode_str+=res[i];
else
std::cout<<" ";
if(res[i]=='\n')
{
++line;
std::cout<<std::endl<<line<<"\t";
}
}
std::cout<<(unicode_str.length()?unicode_str:"")<<'\n';
return;
}
std::vector<char>& nasal_resource::get_file()
{
return res;
}
#endif