diff --git a/version1.3/ast.h b/version1.3/ast.h new file mode 100644 index 0000000..688cabb --- /dev/null +++ b/version1.3/ast.h @@ -0,0 +1,189 @@ +#ifndef __NASAL_ABSTRACT_SYNTAX_TREE_RUN_H__ +#define __NASAL_ABSTRACT_SYNTAX_TREE_RUN_H__ + +class abstract_syntax_tree +{ + private: + int ast_node_type; + double var_number; + std::string var_string; + std::string var_name; + std::list children; + public: + abstract_syntax_tree() + { + ast_node_type=0; + var_number=0; + var_string=""; + var_name=""; + children.clear(); + return; + } + abstract_syntax_tree(const abstract_syntax_tree& p) + { + ast_node_type=p.ast_node_type; + var_number=p.var_number; + var_string=p.var_string; + var_name=p.var_name; + children=p.children; + return; + } + abstract_syntax_tree& operator=(const abstract_syntax_tree& p) + { + ast_node_type=p.ast_node_type; + var_number=p.var_number; + var_string=p.var_string; + var_name=p.var_name; + children.clear(); + children=p.children; + return *this; + } + void set_clear() + { + ast_node_type=0; + var_number=0; + var_string=""; + var_name=""; + children.clear(); + return; + } + void print_tree(const int n) + { + std::string str=""; + for(int i=0;iprint_tree(n+1); + } + return; + } + void set_node_type(const int type) + { + ast_node_type=type; + return; + } + void set_var_string(std::string str) + { + var_string=str; + return; + } + void set_var_number(std::string str) + { + if(str=="nil") + { + var_number=0; + return; + } + if((int)str.length()>2 && (str[1]=='x' || str[1]=='o')) + { + if(str[1]=='x') + { + int num=0; + int pw=1; + for(int i=(int)str.length()-1;i>1;--i) + { + if('0'<=str[i] && str[i]<='9') + num+=(str[i]-'0')*pw; + else if('a'<=str[i] && str[i]<='f') + num+=(10+str[i]-'a')*pw; + else if('A'<=str[i] && str[i]<='F') + num+=(10+str[i]-'A')*pw; + pw<<=4; + } + var_number=(double)num; + } + else + { + int num=0; + int pw=1; + for(int i=(int)str.length()-1;i>1;--i) + { + num+=(str[i]-'0')*pw; + pw<<=3; + } + var_number=(double)num; + } + return; + } + int dot_place=-1; + for(int i=0;i<(int)str.length();++i) + if(str[i]=='.') + { + dot_place=i; + break; + } + if(dot_place==-1) + { + var_number=0; + double pw=1; + for(int i=(int)str.length()-1;i>=0;--i) + { + var_number+=(str[i]-'0')*pw; + pw*=10; + } + } + else + { + var_number=0; + double pw=0.1; + for(int i=dot_place+1;i<(int)str.length();++i) + { + var_number+=(str[i]-'0')*pw; + pw/=10; + } + pw=1; + for(int i=dot_place-1;i>=0;--i) + { + var_number+=(str[i]-'0')*pw; + pw*=10; + } + } + return; + } + void set_var_name(std::string& str) + { + var_name=str; + return; + } + void add_child(abstract_syntax_tree p) + { + children.push_back(p); + return; + } + int get_type() + { + return ast_node_type; + } + double get_var_number() + { + return var_number; + } + std::string get_var_string() + { + return var_string; + } + std::string get_var_name() + { + return var_name; + } + std::list& get_children() + { + return children; + } +}; + +#endif diff --git a/version1.3/main.cpp b/version1.3/main.cpp new file mode 100644 index 0000000..4747b8b --- /dev/null +++ b/version1.3/main.cpp @@ -0,0 +1,86 @@ +#include "nasal.h" +int main() +{ + resource_programme_process prog; + nasal_lexer lex; + nasal_parser pas; + nasal_runtime vm; + std::string command; + std::cout<<">> Nasal interpreter by ValKmjolnir"<> Input [help] to find help."<> "; + std::getline(std::cin,command); + if(command=="help") + { + std::cout<<">> Nasal interpreter by ValKmjolnir"<> 1. [ ] |input file name to load the file."<> 2. [cls ] |clear the screen."<> 3. [exit ] |shut down the interpreter."<> 4. [lexer ] |run and show the lexer. (-lexer)"<> 5. [parser] |run parser and see parse stack & parse result(s). (-parser)"<> 6. [ast ] |print the abstract syntax tree."<> 7. [del ] |delete program in memory."<> 8. [run ] |run the programme in stack. (-lexer -parser)"<> 9. [rs ] |check the source program."<>[Delete] Complete."<>[Abstract_syntax_tree] error(s) occurred,stop."<>[Runtime] error(s) occurred,stop."< +#include +#include +#include +#include +#include +#include + +#include "nasal_token_type.h" +#include "ast.h" +#include "nasal_vm.h" +#include "nasal_lexer.h" +#include "nasal_parser.h" + + +#endif diff --git a/version1.3/nasal_lexer.h b/version1.3/nasal_lexer.h new file mode 100644 index 0000000..01bc9fc --- /dev/null +++ b/version1.3/nasal_lexer.h @@ -0,0 +1,543 @@ +#ifndef __NASAL_LEXER_H__ +#define __NASAL_LEXER_H__ + +#include +#include +#include +#include + +#define OPERATOR 1 // operator +#define IDENTIFIER 2 // id +#define NUMBER 3 // number +#define RESERVEWORD 4 // reserve word +#define STRING 5 // string +#define DYNAMIC_ID 6 // id... +#define FAIL -1 //fail +#define SCANEND -2 //complete scanning +#define ERRORFOUND -3 //error occurred + +std::string reserve_word[15]= +{ + "for","foreach","forindex","while", + "var","func","break","continue","return", + "if","else","elsif","nil","and","or" +}; + +int isReserveWord(std::string &p) +{ + for(int i=0;i<15;++i) + if(reserve_word[i]==p) + return i+1; + return FAIL; +} + +bool isLetter(char t) +{ + return (('a'<=t) && (t<='z') || ('A'<=t) && (t<='Z')); +} + +bool isNumber(char t) +{ + return (('0'<=t) && (t<='9')); +} + +bool isHex(char t) +{ + return ((('0'<=t) && (t<='9')) || (('a'<=t) && (t<='f'))); +} + +bool isOct(char t) +{ + return (('0'<=t) && (t<='7')); +} + +class resource_programme_process +{ + private: + char *resource; + public: + resource_programme_process() + { + resource=NULL; + resource=new char[16777216]; + } + ~resource_programme_process() + { + if(resource) + delete []resource; + } + char* use_file() + { + return resource; + } + void input_file(std::string& filename) + { + std::ifstream fin(filename); + if(fin.fail()) + { + std::cout<<">>[Error] Cannot load file: "< lexer; + public: + void scanner(int &syn,const char* source,std::string &__token,int &ptr,int &line) + { + char temp; + temp=source[ptr]; + while(temp==' ' || temp=='\n' || temp=='\t' || temp=='\r' || temp<0 || temp>127) + { + ++ptr; + if(temp=='\n') + ++line; + temp=source[ptr]; + } + __token=""; + if(isLetter(temp) || temp=='_') + { + __token+=temp; + ++ptr; + temp=source[ptr]; + while(isLetter(temp) || isNumber(temp) || temp=='_') + { + __token+=temp; + ++ptr; + temp=source[ptr]; + } + syn=isReserveWord(__token); + if(syn==FAIL) + syn=IDENTIFIER; + else + syn=RESERVEWORD; + if((syn==IDENTIFIER) && source[ptr]=='.' && source[ptr+1]=='.' && source[ptr+2]=='.') + { + __token+="..."; + syn=DYNAMIC_ID; + ptr+=3; + } + } + else if(isNumber(temp)) + { + if((source[ptr]=='0') && (source[ptr+1]=='x')) + { + __token+=source[ptr]; + __token+=source[ptr+1]; + ptr+=2; + temp=source[ptr]; + while(isNumber(temp) || isHex(temp)) + { + __token+=temp; + ++ptr; + temp=source[ptr]; + } + if((int)__token.length()==2) + { + std::cout<<">>[Lexer-warning] lexer: expect a hex-number string after '0x' ."<>[Lexer-warning] lexer: expect a oct-number string after '0o' ."<' || temp=='~') + { + syn=OPERATOR; + __token+=temp; + ++ptr; + temp=source[ptr]; + if(temp=='=') + { + __token+=temp; + ++ptr; + } + } + else if(temp=='\\') + { + syn=OPERATOR; + __token+=temp; + ++ptr; + temp=source[ptr]; + if(temp=='=' || temp=='n' || temp=='t' || temp=='r' || temp=='\\' || temp=='\'' || temp=='\"') + { + __token+=temp; + ++ptr; + } + } + else if(temp=='\"') + { + syn=STRING; + __token+=temp; + ++ptr; + temp=source[ptr]; + while(temp!='\"') + { + if(temp=='\\') + { + __token+=temp; + + ++ptr; + temp=source[ptr]; + __token+=temp; + + ++ptr; + temp=source[ptr]; + } + else + { + __token+=temp; + ++ptr; + temp=source[ptr]; + } + if(temp==0 || temp=='\n') + break; + } + //add the last char \" + if(temp=='\"') + { + __token+=temp; + ++ptr; + } + else + __token+=" __missing_end_of_string"; + } + else if(temp==0) + { + syn=SCANEND; + return; + } + else + { + syn=FAIL; + std::cout<<">>[Error] unexpected error occurred: "<>[Error] cannot identify "<>[Lexer] max size: "<0)//all Syn type is larger than zero + { + temp.line=line; + temp.type=syn; + temp.content=__token; + lexer.push_back(temp); + } + } + std::cout<<">>[Lexer] complete scanning."<::iterator i=lexer.begin();i!=lexer.end();++i) + { + temp=*i; + std::cout<<"line "<::iterator i=lexer.begin();i!=lexer.end();++i) + { + if((*i).type==RESERVEWORD) + { + if((*i).content=="var") + (*i).type=__var; + else if((*i).content=="func") + (*i).type=__func; + else if((*i).content=="return") + (*i).type=__return; + else if((*i).content=="nil") + (*i).type=__number; + else if((*i).content=="continue") + (*i).type=__continue; + else if((*i).content=="break") + (*i).type=__break; + else if((*i).content=="and") + (*i).type=__and_operator; + else if((*i).content=="or") + (*i).type=__or_operator; + else if((*i).content=="for") + (*i).type=__for; + else if((*i).content=="forindex") + (*i).type=__forindex; + else if((*i).content=="foreach") + (*i).type=__foreach; + else if((*i).content=="while") + (*i).type=__while; + else if((*i).content=="if") + (*i).type=__if; + else if((*i).content=="else") + (*i).type=__else; + else if((*i).content=="elsif") + (*i).type=__elsif; + } + else if(((*i).content=="==") || ((*i).content=="!=") || ((*i).content==">") || ((*i).content==">=") || ((*i).content=="<") || ((*i).content=="<=")) + { + if((*i).content=="==") + (*i).type=__cmp_equal; + else if((*i).content=="!=") + (*i).type=__cmp_not_equal; + else if((*i).content==">") + (*i).type=__cmp_more; + else if((*i).content==">=") + (*i).type=__cmp_more_or_equal; + else if((*i).content=="<") + (*i).type=__cmp_less; + else if((*i).content=="<=") + (*i).type=__cmp_less_or_equal; + } + else if(((*i).content==";") || ((*i).content==",") || ((*i).content=="=") || ((*i).content==":") || ((*i).content==".") || ((*i).content=="?") || ((*i).content=="|") || ((*i).content=="&") || ((*i).content=="%") || ((*i).content=="$") || ((*i).content=="`") || ((*i).content=="^") || ((*i).content=="@")) + { + char c=(*i).content[0]; + switch(c) + { + case ';':(*i).type=__semi;break; + case ',':(*i).type=__comma;break; + case '=':(*i).type=__equal;break; + case ':':(*i).type=__colon;break; + case '.':(*i).type=__dot;break; + default:(*i).type=__unknown_operator;break; + } + } + else if(((*i).type==NUMBER) || ((*i).type==STRING) || ((*i).type==IDENTIFIER) || ((*i).type==DYNAMIC_ID)) + { + int t=(*i).type; + switch(t) + { + case NUMBER:(*i).type=__number;break; + case STRING:(*i).type=__string;break; + case IDENTIFIER:(*i).type=__id;break; + case DYNAMIC_ID:(*i).type=__dynamic_id;break; + } + } + else if(((*i).content=="+") || ((*i).content=="-") || ((*i).content=="*") || ((*i).content=="/") || ((*i).content=="~") || ((*i).content=="!")) + { + char c=(*i).content[0]; + switch(c) + { + case '+':(*i).type=__add_operator;break; + case '-':(*i).type=__sub_operator;break; + case '*':(*i).type=__mul_operator;break; + case '/':(*i).type=__div_operator;break; + case '~':(*i).type=__link_operator;break; + case '!':(*i).type=__nor_operator;break; + } + } + else if(((*i).content=="+=") || ((*i).content=="-=") || ((*i).content=="*=") || ((*i).content=="/=") || ((*i).content=="~=")) + { + char c=(*i).content[0]; + switch(c) + { + case '+':(*i).type=__add_equal;break; + case '-':(*i).type=__sub_equal;break; + case '*':(*i).type=__mul_equal;break; + case '/':(*i).type=__div_equal;break; + case '~':(*i).type=__link_equal;break; + } + } + else if(((*i).content=="(") || ((*i).content==")") || ((*i).content=="[") || ((*i).content=="]") || ((*i).content=="{") || ((*i).content=="}")) + { + char c=(*i).content[0]; + switch(c) + { + case '(':(*i).type=__left_curve;break; + case ')':(*i).type=__right_curve;break; + case '[':(*i).type=__left_bracket;break; + case ']':(*i).type=__right_bracket;break; + case '{':(*i).type=__left_brace;break; + case '}':(*i).type=__right_brace;break; + } + } + } + return; + } + std::list& return_list() + { + return lexer; + } +}; + + + + +#endif diff --git a/version1.3/nasal_parser.h b/version1.3/nasal_parser.h new file mode 100644 index 0000000..d40b6f0 --- /dev/null +++ b/version1.3/nasal_parser.h @@ -0,0 +1,1821 @@ +#ifndef __NASAL_PARSER_H__ +#define __NASAL_PARSER_H__ + +class nasal_parser +{ + private: + abstract_syntax_tree root; + std::stack parse; + token this_token; + int error; + int warning; + public: + nasal_parser() + { + error=0; + warning=0; + this_token.type=0; + } + void get_token() + { + if(parse.empty()) + { + this_token.type=0; + return; + } + this_token=parse.top(); + parse.pop(); + return; + } + int get_error_num() + { + return error; + } + abstract_syntax_tree& get_tree() + { + return root; + } + void print_generated_ast() + { + std::cout<<">>[Abstract-syntax-tree]"< temp; + while(!parse.empty()) + { + temp.push(parse.top()); + if(line!=temp.top().line) + { + if(line+1==temp.top().line) + { + line=temp.top().line; + if(line==1) + std::cout<<"line "< "; + parse.pop(); + } + while(!temp.empty()) + { + parse.push(temp.top()); + temp.pop(); + } + std::cout<& lexer) + { + while(!parse.empty()) + parse.pop(); + std::stack temp; + for(std::list::iterator i=lexer.begin();i!=lexer.end();++i) + { + token temp_parse; + temp_parse=*i; + temp.push(temp_parse);//push this into stack + } + if(temp.empty()) + { + std::cout<<">>[Parse] warning: empty lexer list."<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] line "<>[Error] parse stack empty."<>[Parse] complete generation."< + +enum token_type +{ + __stack_end=1, + __equal, // = + __cmp_equal,__cmp_not_equal, // == != + __cmp_less,__cmp_less_or_equal, // < <= + __cmp_more,__cmp_more_or_equal, // > >= + __and_operator,__or_operator,__nor_operator, // and or ! + __add_operator,__sub_operator, // + - + __mul_operator,__div_operator,__link_operator, // * / ~ + __add_equal,__sub_equal, // += -= + __mul_equal,__div_equal,__link_equal, // *= /= ~= + __left_brace,__right_brace, // {} + __left_bracket,__right_bracket, // [] + __left_curve,__right_curve, // () + __semi,__comma,__colon,__dot, // ; , : . + __unknown_operator, + __var,__func,__return, + __if,__elsif,__else, + __continue,__break, + __for,__forindex,__foreach,__while, + //operators & reserve words + + __number,__string,__id,__dynamic_id, + //basic elements + + __root, + __null_type, + __list,__hash, + __hash_member, + __call_function,__list_search,__hash_search, + __normal_statement_block, + __definition,__assignment, + __function,__loop,__ifelse +}; + +void print_token(int type) +{ + std::string context=""; + switch(type) + { + case __stack_end: context="#"; break; + case __equal: context="="; break; + case __cmp_equal: context="==";break; + case __cmp_not_equal: context="!=";break; + case __cmp_less: context="<"; break; + case __cmp_less_or_equal: context="<=";break; + case __cmp_more: context=">"; break; + case __cmp_more_or_equal: context=">=";break; + case __and_operator: context="and";break; + case __or_operator: context="or"; break; + case __nor_operator: context="!"; break; + case __add_operator: context="+"; break; + case __sub_operator: context="-"; break; + case __mul_operator: context="*"; break; + case __div_operator: context="/"; break; + case __link_operator: context="~"; break; + case __add_equal: context="+=";break; + case __sub_equal: context="-=";break; + case __mul_equal: context="*=";break; + case __div_equal: context="/=";break; + case __link_equal: context="~=";break; + case __left_brace: context="{"; break; + case __right_brace: context="}"; break; + case __left_bracket: context="["; break; + case __right_bracket: context="]"; break; + case __left_curve: context="("; break; + case __right_curve: context=")"; break; + case __semi: context=";"; break; + case __comma: context=","; break; + case __colon: context=":"; break; + case __dot: context="."; break; + case __unknown_operator: context="unknown_operator";break; + case __var: context="var"; break; + case __func: context="func";break; + case __continue: context="continye"; break; + case __break: context="break"; break; + case __for: context="for"; break; + case __forindex: context="forindex";break; + case __foreach: context="foreach";break; + case __while: context="while";break; + case __if: context="if";break; + case __elsif: context="elsif";break; + case __else: context="else";break; + case __return: context="return";break; + + case __id: context="id";break; + case __dynamic_id: context="id...";break; + case __number: context="num";break; + case __string: context="str";break; + + case __root: context="root";break; + case __null_type: context="null_type";break; + case __list: context="list";break; + case __hash: context="hash";break; + case __hash_member: context="hash_member";break; + case __call_function: context="call_func";break; + case __list_search: context="call_list";break; + case __hash_search: context="call_hash";break; + case __normal_statement_block:context="block";break; + case __definition: context="definition";break; + case __assignment: context="assignment";break; + case __function: context="function";break; + case __loop: context="loop";break; + case __ifelse: context="if-else";break; + default: context="undefined_token";break; + } + std::cout< var_list; + std::list var_hash; + abstract_syntax_tree function; + public: + var() + { + type=0; + name=""; + number=0; + str=""; + function.set_clear(); + } + var(const var& p) + { + type=p.type; + name=p.name; + number=p.number; + str=p.str; + function=p.function; + } + var& operator=(const var& p) + { + type=p.type; + name=p.name; + number=p.number; + str=p.str; + function=p.function; + return *this; + } + void print_information() + { + std::cout<<"[ type: ";print_token(type);std::cout<<" ]"; + std::cout<<"[ name: "<>[Runtime-error] function type cannot be printed."< p) + { + var_list=p; + return; + } + void append_list(var p) + { + var_list.push_back(p); + return; + } + void set_hash(std::list p) + { + var_hash=p; + return; + } + void append_hash(var p) + { + var_hash.push_back(p); + return; + } + int get_type() + { + return type; + } + std::string get_name() + { + return name; + } + double get_number() + { + return number; + } + std::string get_string() + { + return str; + } + abstract_syntax_tree get_function() + { + return function; + } + std::list get_list() + { + return var_list; + } + std::list get_hash() + { + return var_hash; + } +}; + +class var_scope_manager +{ + private: + std::list> scope_list; + std::list scope_type; + var error_var; + public: + var_scope_manager() + { + scope_list.clear(); + std::string str="__nas_strc_error_ret"; + error_var.set_name(str); + error_var.set_type(__null_type); + return; + } + void set_clear() + { + scope_list.clear(); + scope_type.clear(); + return; + } + var& search_var(std::string str) + { + for(std::list>::iterator i=scope_list.begin();i!=scope_list.end();++i) + for(std::list::iterator j=i->begin();j!=i->end();++j) + if(j->get_name()==str) + return *j; + std::cout<>[Runtime-error] could not find the var '"<>::iterator i=scope_list.begin(); + std::list::iterator t=scope_type.begin(); + // get global scopes + for(;i!=scope_list.end();++i,++t) + { + if(*t!=__function) + { + for(std::list::iterator j=i->begin();j!=i->end();++j) + if(j->get_name()==new_var.get_name()) + { + std::cout<>[Runtime-error] redeclaration of var '"<::iterator j=i->begin();j!=i->end();++j) + if(j->get_name()==new_var.get_name()) + { + std::cout<>[Runtime-error] redeclaration of var '"<push_back(new_var); + } + else + std::cout<>[Runtime-error] empty scope list."< new_list; + scope_list.push_back(new_list); + scope_type.push_back(type); + return; + } + void pop_last_scope() + { + if(!scope_list.empty()) + { + scope_list.pop_back(); + scope_type.pop_back(); + } + else + std::cout<>[Runtime-error] scope poped empty thing."<>[Code] runtime got the ast-root: "<<((void *)&tree)<<"->"<<((void *)&root)<<"."<>[Runtime] process begins."<>[Runtime] process exited after "<>[Runtime] runtime got the ast-root: "<<((void *)&tree)<<"->"<<((void *)&root)<<"."<