update
This commit is contained in:
parent
19fdb25242
commit
a03d8a440d
|
@ -5,8 +5,7 @@ nasal_lexer lexer;
|
||||||
nasal_parse parser;
|
nasal_parse parser;
|
||||||
abstract_syntax_tree libroot;
|
abstract_syntax_tree libroot;
|
||||||
abstract_syntax_tree root;
|
abstract_syntax_tree root;
|
||||||
|
abstract_syntax_tree linker;
|
||||||
nasal_symbol_table symtable;
|
|
||||||
|
|
||||||
std::string command;
|
std::string command;
|
||||||
|
|
||||||
|
@ -40,7 +39,6 @@ int main()
|
||||||
std::cout<<">> [lex ] turn code into tokens."<<std::endl;
|
std::cout<<">> [lex ] turn code into tokens."<<std::endl;
|
||||||
std::cout<<">> [par ] turn tokens into abstract syntax tree."<<std::endl;
|
std::cout<<">> [par ] turn tokens into abstract syntax tree."<<std::endl;
|
||||||
std::cout<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
std::cout<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
||||||
std::cout<<">> [sym ] generate symbol table and print the information of it."<<std::endl;
|
|
||||||
std::cout<<">> [run ] run code."<<std::endl;
|
std::cout<<">> [run ] run code."<<std::endl;
|
||||||
std::cout<<">> [info ] print lexer,parser and ast on screen."<<std::endl;
|
std::cout<<">> [info ] print lexer,parser and ast on screen."<<std::endl;
|
||||||
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
||||||
|
@ -62,8 +60,8 @@ int main()
|
||||||
resource.delete_all_source();
|
resource.delete_all_source();
|
||||||
lexer.delete_all_tokens();
|
lexer.delete_all_tokens();
|
||||||
parser.delete_all_elements();
|
parser.delete_all_elements();
|
||||||
symtable.set_scope_clear();
|
|
||||||
root.set_clear();
|
root.set_clear();
|
||||||
|
linker.set_clear();
|
||||||
std::cout<<">> [Delete] complete."<<std::endl;
|
std::cout<<">> [Delete] complete."<<std::endl;
|
||||||
}
|
}
|
||||||
else if(command=="lib")
|
else if(command=="lib")
|
||||||
|
@ -82,14 +80,13 @@ int main()
|
||||||
std::cout<<">> [Lib] loaded."<<std::endl;
|
std::cout<<">> [Lib] loaded."<<std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout<<">> [Lib-error] lib files have parse error(s),stop."<<std::endl;
|
std::cout<<">> [Lib] lib files have parse error(s),stop."<<std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout<<">> [Lib-error] lib files have lexer error(s),stop."<<std::endl;
|
std::cout<<">> [Lib] lib files have lexer error(s),stop."<<std::endl;
|
||||||
resource.delete_all_source();
|
resource.delete_all_source();
|
||||||
lexer.delete_all_tokens();
|
lexer.delete_all_tokens();
|
||||||
parser.delete_all_elements();
|
parser.delete_all_elements();
|
||||||
symtable.set_scope_clear();
|
|
||||||
}
|
}
|
||||||
else if(command=="rs")
|
else if(command=="rs")
|
||||||
{
|
{
|
||||||
|
@ -126,33 +123,7 @@ int main()
|
||||||
parser.get_token_list(lexer.get_detail_token_list());
|
parser.get_token_list(lexer.get_detail_token_list());
|
||||||
parser.main_generate();
|
parser.main_generate();
|
||||||
if(!parser.get_error())
|
if(!parser.get_error())
|
||||||
{
|
|
||||||
symtable.set_scope_clear();
|
|
||||||
symtable.symbol_table_main_generate(parser.get_root());
|
|
||||||
parser.get_root().print_tree();
|
parser.get_root().print_tree();
|
||||||
}
|
|
||||||
else
|
|
||||||
std::cout<<">> [Parse] error occurred,stop."<<std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
|
||||||
}
|
|
||||||
else if(command=="sym")
|
|
||||||
{
|
|
||||||
lexer.scanner(resource.get_source());
|
|
||||||
lexer.generate_detail_token();
|
|
||||||
if(!lexer.get_error())
|
|
||||||
{
|
|
||||||
parser.get_token_list(lexer.get_detail_token_list());
|
|
||||||
parser.main_generate();
|
|
||||||
if(!parser.get_error())
|
|
||||||
{
|
|
||||||
symtable.set_scope_clear();
|
|
||||||
symtable.symbol_table_main_generate(parser.get_root());
|
|
||||||
symtable.print_symbol_table();
|
|
||||||
if(symtable.get_error())
|
|
||||||
std::cout<<">> [Symbol] error occurred,stop."<<std::endl;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
std::cout<<">> [Parse] error occurred,stop."<<std::endl;
|
std::cout<<">> [Parse] error occurred,stop."<<std::endl;
|
||||||
}
|
}
|
||||||
|
@ -169,12 +140,11 @@ int main()
|
||||||
parser.main_generate();
|
parser.main_generate();
|
||||||
if(!parser.get_error())
|
if(!parser.get_error())
|
||||||
{
|
{
|
||||||
symtable.set_scope_clear();
|
linker.set_clear();
|
||||||
symtable.symbol_table_main_generate(parser.get_root());
|
linker=libroot;
|
||||||
if(!symtable.get_error())
|
linker.merge_children(parser.get_root());
|
||||||
root=parser.get_root();// run code
|
root=linker;
|
||||||
else
|
root.print_tree();
|
||||||
std::cout<<">> [Symbol] error occurred,stop."<<std::endl;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout<<">> [Parse] error occurred,stop."<<std::endl;
|
std::cout<<">> [Parse] error occurred,stop."<<std::endl;
|
||||||
|
|
|
@ -9,12 +9,17 @@
|
||||||
//#include <thread>
|
//#include <thread>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "numeral_misc.h"
|
#include "nasal_misc.h"
|
||||||
#include "nasal_enum.h"
|
#include "nasal_enum.h"
|
||||||
#include "abstract_syntax_tree.h"
|
#include "nasal_ast.h"
|
||||||
#include "nasal_lexer.h"
|
#include "nasal_lexer.h"
|
||||||
#include "nasal_parse.h"
|
#include "nasal_parse.h"
|
||||||
#include "nasal_symbol_table.h"
|
#include "nasal_scalar.h"
|
||||||
|
#include "nasal_gc.h"
|
||||||
|
#include "nasal_sym.h"
|
||||||
|
#include "nasal_runtime.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -0,0 +1,223 @@
|
||||||
|
#ifndef __NASAL_AST_H__
|
||||||
|
#define __NASAL_AST_H__
|
||||||
|
|
||||||
|
class abstract_syntax_tree
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// basic elements
|
||||||
|
int line;
|
||||||
|
int node_type;
|
||||||
|
std::list<abstract_syntax_tree> children;
|
||||||
|
|
||||||
|
// is this node is a number|string|identifier node
|
||||||
|
// then the three elements below is of great use
|
||||||
|
// var_name is set for __id
|
||||||
|
double var_number;
|
||||||
|
std::string var_string;
|
||||||
|
std::string var_name;
|
||||||
|
public:
|
||||||
|
/* basic */
|
||||||
|
abstract_syntax_tree();
|
||||||
|
abstract_syntax_tree(const abstract_syntax_tree&);
|
||||||
|
~abstract_syntax_tree();
|
||||||
|
abstract_syntax_tree& operator=(const abstract_syntax_tree&);
|
||||||
|
|
||||||
|
/* main functions */
|
||||||
|
// print
|
||||||
|
void print_tree();
|
||||||
|
void print_tree_block(const int);
|
||||||
|
|
||||||
|
// set
|
||||||
|
void set_clear();
|
||||||
|
void set_node_line(const int);
|
||||||
|
void set_node_type(const int);
|
||||||
|
void set_var_number(std::string);
|
||||||
|
void set_var_string(std::string);
|
||||||
|
void set_var_name(std::string);
|
||||||
|
void add_children(abstract_syntax_tree);
|
||||||
|
|
||||||
|
// get
|
||||||
|
int get_node_line();
|
||||||
|
int get_node_type();
|
||||||
|
double get_var_number();
|
||||||
|
std::string get_var_string();
|
||||||
|
std::string get_var_name();
|
||||||
|
std::list<abstract_syntax_tree>& get_children();
|
||||||
|
|
||||||
|
// merge
|
||||||
|
void merge_children(abstract_syntax_tree&);
|
||||||
|
};
|
||||||
|
|
||||||
|
abstract_syntax_tree::abstract_syntax_tree()
|
||||||
|
{
|
||||||
|
node_type=__null_type;
|
||||||
|
line=0;
|
||||||
|
var_number=0;
|
||||||
|
var_string="";
|
||||||
|
var_name="";
|
||||||
|
children.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract_syntax_tree::abstract_syntax_tree(const abstract_syntax_tree& tmp)
|
||||||
|
{
|
||||||
|
node_type=tmp.node_type;
|
||||||
|
line=tmp.line;
|
||||||
|
var_number=tmp.var_number;
|
||||||
|
var_string=tmp.var_string;
|
||||||
|
var_name=tmp.var_name;
|
||||||
|
children=tmp.children;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract_syntax_tree::~abstract_syntax_tree()
|
||||||
|
{
|
||||||
|
node_type=__null_type;
|
||||||
|
line=0;
|
||||||
|
var_number=0;
|
||||||
|
var_string.clear();
|
||||||
|
var_name.clear();
|
||||||
|
children.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract_syntax_tree& abstract_syntax_tree::operator=(const abstract_syntax_tree& tmp)
|
||||||
|
{
|
||||||
|
node_type=tmp.node_type;
|
||||||
|
line=tmp.line;
|
||||||
|
var_number=tmp.var_number;
|
||||||
|
var_string=tmp.var_string;
|
||||||
|
var_name=tmp.var_name;
|
||||||
|
children.clear();
|
||||||
|
children=tmp.children;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::print_tree()
|
||||||
|
{
|
||||||
|
std::cout<<">> [Abstract-syntax-tree] get tree root: "<<(this)<<""<<std::endl;
|
||||||
|
print_tree_block(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::print_tree_block(const int n)
|
||||||
|
{
|
||||||
|
std::string __str="";
|
||||||
|
for(int i=0;i<n;++i)
|
||||||
|
__str+="| ";
|
||||||
|
std::cout<<__str;
|
||||||
|
print_parse_token(node_type);
|
||||||
|
switch(node_type)
|
||||||
|
{
|
||||||
|
case __number: std::cout<<": "<<var_number;break;
|
||||||
|
case __string: std::cout<<": "<<var_string;break;
|
||||||
|
case __id:
|
||||||
|
case __dynamic_id:
|
||||||
|
case __call_hash: std::cout<<": "<<var_name;break;
|
||||||
|
case __call_vector:
|
||||||
|
case __call_function: break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
std::cout<<std::endl;
|
||||||
|
if(!children.empty())
|
||||||
|
{
|
||||||
|
for(std::list<abstract_syntax_tree>::iterator i=children.begin();i!=children.end();++i)
|
||||||
|
i->print_tree_block(n+1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::set_clear()
|
||||||
|
{
|
||||||
|
node_type=__null_type;
|
||||||
|
line=0;
|
||||||
|
var_number=0;
|
||||||
|
var_string="";
|
||||||
|
var_name="";
|
||||||
|
children.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::set_node_type(const int __node_type)
|
||||||
|
{
|
||||||
|
node_type=__node_type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::set_node_line(const int __line)
|
||||||
|
{
|
||||||
|
if(__line>=0)
|
||||||
|
line=__line;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout<<">> [Abstract-syntax-tree-warning] incorrect line under 0: "<<__line<<"."<<std::endl;
|
||||||
|
line=0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::set_var_string(std::string __str)
|
||||||
|
{
|
||||||
|
var_string=__str;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::set_var_number(std::string __str)
|
||||||
|
{
|
||||||
|
var_number=trans_string_to_number(__str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::set_var_name(std::string __str)
|
||||||
|
{
|
||||||
|
var_name=__str;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::add_children(abstract_syntax_tree p)
|
||||||
|
{
|
||||||
|
// use abstract_syntax_tree instead of abstract_syntax_tree&
|
||||||
|
// because when this function get a 'p' from returned value of
|
||||||
|
// another function,this may result in s SIGSEGV.
|
||||||
|
children.push_back(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int abstract_syntax_tree::get_node_type()
|
||||||
|
{
|
||||||
|
return node_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int abstract_syntax_tree::get_node_line()
|
||||||
|
{
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
double abstract_syntax_tree::get_var_number()
|
||||||
|
{
|
||||||
|
return var_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string abstract_syntax_tree::get_var_string()
|
||||||
|
{
|
||||||
|
return var_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string abstract_syntax_tree::get_var_name()
|
||||||
|
{
|
||||||
|
return var_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<abstract_syntax_tree>& abstract_syntax_tree::get_children()
|
||||||
|
{
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstract_syntax_tree::merge_children(abstract_syntax_tree& tmp)
|
||||||
|
{
|
||||||
|
for(std::list<abstract_syntax_tree>::iterator i=tmp.children.begin();i!=tmp.children.end();++i)
|
||||||
|
this->children.push_back(*i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,143 @@
|
||||||
|
#ifndef __NASAL_GC_H__
|
||||||
|
#define __NASAL_GC_H__
|
||||||
|
|
||||||
|
struct gc_unit
|
||||||
|
{
|
||||||
|
// collected: If gc collected this item,it'll be set to true.Otherwise it is false.
|
||||||
|
// elem: Item that this unit stores
|
||||||
|
// refcnt: Reference counter
|
||||||
|
bool collected;
|
||||||
|
nasal_scalar elem;
|
||||||
|
int refcnt;
|
||||||
|
gc_unit()
|
||||||
|
{
|
||||||
|
collected=true;
|
||||||
|
//elem=0;
|
||||||
|
refcnt=0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gc_unit(const gc_unit& tmp)
|
||||||
|
{
|
||||||
|
collected=tmp.collected;
|
||||||
|
//elem=tmp.elem;
|
||||||
|
refcnt=tmp.refcnt;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class gc_manager
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// free_space list is used to store space that is not in use.
|
||||||
|
std::list<int> free_space;
|
||||||
|
std::vector<gc_unit> memory;
|
||||||
|
public:
|
||||||
|
gc_manager()
|
||||||
|
{
|
||||||
|
memory.clear();
|
||||||
|
free_space.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
~gc_manager()
|
||||||
|
{
|
||||||
|
memory.clear();
|
||||||
|
free_space.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void gc_init()
|
||||||
|
{
|
||||||
|
// this function must be called in class nasal_runtime
|
||||||
|
// before running any codes
|
||||||
|
std::vector<gc_unit> tmp_vec;
|
||||||
|
memory.clear();
|
||||||
|
memory.swap(tmp_vec);
|
||||||
|
// clear the memory capacity by using tmp_vec.~vector<gc_unit>()
|
||||||
|
free_space.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void gc_scanner()
|
||||||
|
{
|
||||||
|
int memory_size=memory.size();
|
||||||
|
for(int i=0;i<memory_size;++i)
|
||||||
|
if((memory[i].refcnt<=0) && (!memory[i].collected))
|
||||||
|
{
|
||||||
|
memory[i].collected=true;
|
||||||
|
free_space.push_back(i);
|
||||||
|
std::cout<<">> [Gc] collected ";
|
||||||
|
prt_hex(i);
|
||||||
|
std::cout<<"."<<std::endl;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int gc_alloc()
|
||||||
|
{
|
||||||
|
if(free_space.empty())
|
||||||
|
{
|
||||||
|
gc_unit new_unit;
|
||||||
|
memory.push_back(new_unit);
|
||||||
|
free_space.push_back(memory.size()-1);
|
||||||
|
}
|
||||||
|
int alloc_plc=free_space.front();
|
||||||
|
free_space.pop_front();
|
||||||
|
memory[alloc_plc].collected=false;
|
||||||
|
memory[alloc_plc].refcnt=1;
|
||||||
|
return alloc_plc;
|
||||||
|
}
|
||||||
|
bool place_check(const int place)
|
||||||
|
{
|
||||||
|
// check if this place is in memory
|
||||||
|
// and this place is uncollected
|
||||||
|
return (place<memory.size()) && (!memory[place].collected);
|
||||||
|
}
|
||||||
|
void reference_add(const int place)
|
||||||
|
{
|
||||||
|
if(place<memory.size())
|
||||||
|
++memory[place].refcnt;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout<<">> [Gc] fatal error: unexpected memory place ";
|
||||||
|
prt_hex(place);
|
||||||
|
std::cout<<" ."<<std::endl;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void reference_delete(const int place)
|
||||||
|
{
|
||||||
|
if(place<memory.size())
|
||||||
|
--memory[place].refcnt;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout<<">> [Gc] fatal error: unexpected memory place ";
|
||||||
|
prt_hex(place);
|
||||||
|
std::cout<<" ."<<std::endl;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void info_print()
|
||||||
|
{
|
||||||
|
std::cout<<">> [Gc] memory size:"<<memory.size()*sizeof(gc_unit)<<" byte."<<std::endl;
|
||||||
|
std::cout<<">> [Gc] memory capacity:"<<memory.capacity()*sizeof(gc_unit)<<" byte."<<std::endl;
|
||||||
|
std::cout<<">> [Gc] memory usage: "<<std::endl;
|
||||||
|
int cnt=0;
|
||||||
|
for(int i=0;i<memory.size();++i)
|
||||||
|
if(!memory[i].collected)
|
||||||
|
{
|
||||||
|
prt_hex(i);
|
||||||
|
std::cout<<"["<<memory[i].refcnt<<"]";
|
||||||
|
// cnt is used to check if it is the right time to output in the next line
|
||||||
|
++cnt;
|
||||||
|
if(!(cnt%8))
|
||||||
|
std::cout<<std::endl;
|
||||||
|
else
|
||||||
|
std::cout<<" ";
|
||||||
|
}
|
||||||
|
if(cnt%8)
|
||||||
|
std::cout<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gc_manager nasal_gc;
|
||||||
|
// this object is used in "nasal_sym.h" and "nasal_runtime.h"
|
||||||
|
// because there must be only one gc when running a program
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,168 @@
|
||||||
|
#ifndef __NASAL_MISC_H__
|
||||||
|
#define __NASAL_MISC_H__
|
||||||
|
|
||||||
|
bool check_numerable_string(std::string str)
|
||||||
|
{
|
||||||
|
if(str.length()>1 && str[0]=='-')
|
||||||
|
{
|
||||||
|
// in lexer this statements are useless
|
||||||
|
// because lexer judge a number that begins with 0~9 (or 0x for hex & 0o for oct)
|
||||||
|
std::string temp="";
|
||||||
|
int str_len=str.length();
|
||||||
|
for(int i=1;i<str_len;++i)
|
||||||
|
temp+=str[i];
|
||||||
|
str=temp;
|
||||||
|
}
|
||||||
|
if(str.length()==1 && '0'<=str[0] && str[0]<='9')
|
||||||
|
return true;
|
||||||
|
else if(str.length()>2 && str[0]=='0' && str[1]=='x')
|
||||||
|
{
|
||||||
|
int str_len=str.length();
|
||||||
|
for(int i=2;i<str_len;++i)
|
||||||
|
if(!(('0'<=str[i] && str[i]<='9') || ('a'<=str[i] && str[i]<='f') || ('A'<=str[i] && str[i]<='F')))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(str.length()>2 && str[0]=='0' && str[1]=='o')
|
||||||
|
{
|
||||||
|
int str_len=str.length();
|
||||||
|
for(int i=2;i<str_len;++i)
|
||||||
|
if(!('0'<=str[i] && str[i]<='7'))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int str_len=str.length();
|
||||||
|
int float_dot_cnt=0;
|
||||||
|
for(int i=0;i<str_len;++i)
|
||||||
|
{
|
||||||
|
if(str[i]=='.')
|
||||||
|
++float_dot_cnt;
|
||||||
|
else if(!('0'<=str[i] && str[i]<='9'))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if((float_dot_cnt>1) || (str[0]=='.') || (!float_dot_cnt && str[0]=='0'))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double trans_string_to_number(std::string str)
|
||||||
|
{
|
||||||
|
bool is_negative=false;
|
||||||
|
if(str.length()>1 && str[0]=='-')
|
||||||
|
{
|
||||||
|
// in parse this statements are useless
|
||||||
|
// because lexer recognizes a number that begins with a '0'~'9' char
|
||||||
|
std::string temp="";
|
||||||
|
int str_len=str.length();
|
||||||
|
for(int i=1;i<str_len;++i)
|
||||||
|
temp+=str[i];
|
||||||
|
str=temp;
|
||||||
|
is_negative=true;
|
||||||
|
}
|
||||||
|
double trans_str_number=0;
|
||||||
|
if(str.length()==1)
|
||||||
|
trans_str_number=(double)(str[0]-'0');
|
||||||
|
else if(str[0]=='0' && str[1]=='x')
|
||||||
|
{
|
||||||
|
long long int hex_number=0,bit_pow=1;
|
||||||
|
for(int i=str.length()-1;i>1;--i)
|
||||||
|
{
|
||||||
|
if('0'<=str[i] && str[i]<='9')
|
||||||
|
hex_number+=bit_pow*(str[i]-'0');
|
||||||
|
else if('a'<=str[i] && str[i]<='f')
|
||||||
|
hex_number+=bit_pow*(10+str[i]-'a');
|
||||||
|
else
|
||||||
|
hex_number+=bit_pow*(10+str[i]-'A');
|
||||||
|
bit_pow<<=4;
|
||||||
|
}
|
||||||
|
trans_str_number=(double)hex_number;
|
||||||
|
}
|
||||||
|
else if(str[0]=='0' && str[1]=='o')
|
||||||
|
{
|
||||||
|
long long int oct_number=0,bit_pow=1;
|
||||||
|
for(int i=str.length()-1;i>1;--i)
|
||||||
|
{
|
||||||
|
oct_number+=bit_pow*(str[i]-'0');
|
||||||
|
bit_pow<<=3;
|
||||||
|
}
|
||||||
|
trans_str_number=(double)oct_number;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int float_dot_place=str.length();
|
||||||
|
int str_len=str.length();
|
||||||
|
double pow;
|
||||||
|
for(int i=0;i<str_len;++i)
|
||||||
|
if(str[i]=='.')
|
||||||
|
{
|
||||||
|
float_dot_place=i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pow=0.1;
|
||||||
|
for(int i=float_dot_place+1;i<str_len;++i)
|
||||||
|
{
|
||||||
|
trans_str_number+=pow*(double(str[i]-'0'));
|
||||||
|
pow/=10;
|
||||||
|
}
|
||||||
|
pow=1;
|
||||||
|
for(int i=float_dot_place-1;i>=0;--i)
|
||||||
|
{
|
||||||
|
trans_str_number+=pow*(double(str[i]-'0'));
|
||||||
|
pow*=10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(is_negative)
|
||||||
|
trans_str_number*=-1;
|
||||||
|
return trans_str_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string trans_number_to_string(double number)
|
||||||
|
{
|
||||||
|
std::string trans_num_string="";
|
||||||
|
if(number<0)
|
||||||
|
{
|
||||||
|
trans_num_string+='-';
|
||||||
|
number*=-1;
|
||||||
|
}
|
||||||
|
double integer_bit=1;
|
||||||
|
while(number>=integer_bit)
|
||||||
|
integer_bit*=10;
|
||||||
|
integer_bit/=10;
|
||||||
|
while(integer_bit!=0.1)
|
||||||
|
{
|
||||||
|
trans_num_string+=(char)('0'+(int(number/integer_bit)));
|
||||||
|
number-=(double)(int(number/integer_bit))*integer_bit;
|
||||||
|
integer_bit/=10;
|
||||||
|
}
|
||||||
|
if(number!=0)
|
||||||
|
trans_num_string+='.';
|
||||||
|
while(number!=0)
|
||||||
|
{
|
||||||
|
trans_num_string+=(char)('0'+int(number*10));
|
||||||
|
number*=10;
|
||||||
|
number-=(double)(int(number));
|
||||||
|
}
|
||||||
|
return trans_num_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prt_hex(const int ptr)
|
||||||
|
{
|
||||||
|
// transform int to hex and print it (std::cout)
|
||||||
|
char hex[9];
|
||||||
|
hex[8]=0;
|
||||||
|
int tmp_plc=ptr;
|
||||||
|
for(int j=7;j>=0;--j)
|
||||||
|
{
|
||||||
|
int tmp=(tmp_plc & 0x0000000f);
|
||||||
|
hex[j]=tmp<10? (char)('0'+tmp):(char)('a'+tmp-10);
|
||||||
|
tmp_plc>>=4;
|
||||||
|
}
|
||||||
|
std::cout<<"0x"<<hex;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef __NASAL_RUNTIME_H__
|
||||||
|
#define __NASAL_RUNTIME_H__
|
||||||
|
|
||||||
|
class nasal_runtime
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
sym_hash_map global;
|
||||||
|
public:
|
||||||
|
nasal_runtime()
|
||||||
|
{
|
||||||
|
global.set_clear();
|
||||||
|
nasal_gc.gc_init();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
~nasal_runtime()
|
||||||
|
{
|
||||||
|
global.set_clear();
|
||||||
|
nasal_gc.gc_init();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void before_running_init()
|
||||||
|
{
|
||||||
|
global.set_clear();
|
||||||
|
nasal_gc.gc_init();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void main_proc(abstract_syntax_tree& root)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,14 +1,35 @@
|
||||||
#ifndef __NASAL_SCALAR_H__
|
#ifndef __NASAL_SCALAR_H__
|
||||||
#define __NASAL_SCALAR_H__
|
#define __NASAL_SCALAR_H__
|
||||||
|
|
||||||
|
class nasal_function
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::map<std::string,int> local_scope;
|
||||||
|
abstract_syntax_tree function_root;
|
||||||
|
public:
|
||||||
|
nasal_function()
|
||||||
|
{
|
||||||
|
local_scope.clear();
|
||||||
|
function_root.set_clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
~nasal_function()
|
||||||
|
{
|
||||||
|
local_scope.clear();
|
||||||
|
function_root.set_clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class nasal_scalar
|
class nasal_scalar
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int type;
|
int type;
|
||||||
std::string var_string;
|
std::string var_string;
|
||||||
double var_number;
|
double var_number;
|
||||||
std::vector<nasal_scalar> var_array;
|
std::vector<int> var_array;
|
||||||
std::map<std::string,nasal_scalar> var_hash;
|
std::map<std::string,int> var_hash;
|
||||||
|
nasal_function var_func;
|
||||||
public:
|
public:
|
||||||
nasal_scalar()
|
nasal_scalar()
|
||||||
{
|
{
|
||||||
|
@ -62,6 +83,19 @@ class nasal_scalar
|
||||||
var_string=tmp_str;
|
var_string=tmp_str;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
void vector_add_new_member(const int addr)
|
||||||
|
{
|
||||||
|
var_array.push_back(addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void hash_add_new_member(const std::string member_name,const int addr)
|
||||||
|
{
|
||||||
|
if(var_hash.find(member_name)!=var_hash.end())
|
||||||
|
std::cout<<">> [Runtime] "<<member_name<<" exists."<<std::endl;
|
||||||
|
else
|
||||||
|
var_hash[member_name]=addr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
int get_type() {return type;}
|
int get_type() {return type;}
|
||||||
double get_number() {return var_number;}
|
double get_number() {return var_number;}
|
||||||
std::string get_string(){return var_string;}
|
std::string get_string(){return var_string;}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
#ifndef __NASAL_SYM_H__
|
||||||
|
#define __NASAL_SYM_H__
|
||||||
|
|
||||||
|
// all symbol_map use a same gc system named nasal_gc
|
||||||
|
// see detail of nasal_gc in "nasal_gc.h"
|
||||||
|
class sym_hash_map
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::map<std::string,int> sym_map;
|
||||||
|
public:
|
||||||
|
sym_hash_map()
|
||||||
|
{
|
||||||
|
sym_map.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sym_hash_map(const sym_hash_map& tmp)
|
||||||
|
{
|
||||||
|
sym_map=tmp.sym_map;
|
||||||
|
for(std::map<std::string,int>::iterator i=sym_map.begin();i!=sym_map.end();++i)
|
||||||
|
nasal_gc.reference_add(i->second);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
~sym_hash_map()
|
||||||
|
{
|
||||||
|
for(std::map<std::string,int>::iterator i=sym_map.begin();i!=sym_map.end();++i)
|
||||||
|
nasal_gc.reference_delete(i->second);
|
||||||
|
sym_map.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void set_clear()
|
||||||
|
{
|
||||||
|
sym_map.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void add_new_symbol(std::string __sym_name)
|
||||||
|
{
|
||||||
|
if(sym_map.find(__sym_name)==sym_map.end())
|
||||||
|
sym_map[__sym_name]=nasal_gc.gc_alloc();
|
||||||
|
else
|
||||||
|
std::cout<<">> [Runtime] "<<__sym_name<<" exists."<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int get_symbol_addr(std::string __sym_name)
|
||||||
|
{
|
||||||
|
if(sym_map.find(__sym_name)!=sym_map.end())
|
||||||
|
return sym_map[__sym_name];
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue