update
This commit is contained in:
parent
e8341c7b06
commit
9958431b58
52
main.cpp
52
main.cpp
|
@ -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;
|
||||||
}
|
}
|
4
nasal.h
4
nasal.h
|
@ -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"
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
Loading…
Reference in New Issue