Add notes
This commit is contained in:
parent
763af6e7aa
commit
c421f726fa
|
@ -4,8 +4,9 @@
|
||||||
|
|
||||||
|
|
||||||
int exit_type=0;
|
int exit_type=0;
|
||||||
std::stack<var> ret_stack;// for function ret use
|
std::stack<var> ret_stack; // for function ret use
|
||||||
std::list<var> parameter;// for function call use
|
std::list<var> parameter; // for function call use
|
||||||
|
|
||||||
|
|
||||||
var abstract_syntax_tree::calculation()
|
var abstract_syntax_tree::calculation()
|
||||||
{
|
{
|
||||||
|
@ -30,12 +31,23 @@ var abstract_syntax_tree::calculation()
|
||||||
}
|
}
|
||||||
else if(this->type==__array)
|
else if(this->type==__array)
|
||||||
{
|
{
|
||||||
temp=this->array_generation();
|
temp.set_type(__var_array);
|
||||||
|
if(!children.empty())
|
||||||
|
for(std::list<abstract_syntax_tree>::iterator i=children.begin();i!=children.end();++i)
|
||||||
|
temp.append_array(i->calculation());
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
else if(this->type==__hash)
|
else if(this->type==__hash)
|
||||||
{
|
{
|
||||||
temp=this->hash_generation();
|
temp.set_type(__var_hash);
|
||||||
|
if(!children.empty())
|
||||||
|
for(std::list<abstract_syntax_tree>::iterator i=children.begin();i!=children.end();++i)
|
||||||
|
{
|
||||||
|
var t;
|
||||||
|
t=i->children.front().calculation();
|
||||||
|
t.set_name(i->name);
|
||||||
|
temp.append_hash(t);
|
||||||
|
}
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
else if(this->type==__function)
|
else if(this->type==__function)
|
||||||
|
@ -477,31 +489,6 @@ var abstract_syntax_tree::call_identifier()
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
var abstract_syntax_tree::array_generation()
|
|
||||||
{
|
|
||||||
var new_var;
|
|
||||||
new_var.set_type(__var_array);
|
|
||||||
if(!children.empty())
|
|
||||||
for(std::list<abstract_syntax_tree>::iterator i=children.begin();i!=children.end();++i)
|
|
||||||
new_var.append_array(i->calculation());
|
|
||||||
return new_var;
|
|
||||||
}
|
|
||||||
|
|
||||||
var abstract_syntax_tree::hash_generation()
|
|
||||||
{
|
|
||||||
var new_var;
|
|
||||||
new_var.set_type(__var_hash);
|
|
||||||
if(!children.empty())
|
|
||||||
for(std::list<abstract_syntax_tree>::iterator i=children.begin();i!=children.end();++i)
|
|
||||||
{
|
|
||||||
var temp;
|
|
||||||
temp=i->children.front().calculation();
|
|
||||||
temp.set_name(i->name);
|
|
||||||
new_var.append_hash(temp);
|
|
||||||
}
|
|
||||||
return new_var;
|
|
||||||
}
|
|
||||||
|
|
||||||
var* abstract_syntax_tree::get_var_addr()
|
var* abstract_syntax_tree::get_var_addr()
|
||||||
{
|
{
|
||||||
var* addr=&error_var;
|
var* addr=&error_var;
|
||||||
|
@ -697,6 +684,8 @@ void abstract_syntax_tree::run_root()
|
||||||
}
|
}
|
||||||
end_time=time(NULL);
|
end_time=time(NULL);
|
||||||
std::cout<<"------------------------------------------------------------------------------"<<std::endl;
|
std::cout<<"------------------------------------------------------------------------------"<<std::endl;
|
||||||
|
if(exit_type!=__process_exited_successfully)
|
||||||
|
alert_sound();
|
||||||
std::cout<<">>[Runtime] process exited after "<<end_time-beg_time<<" sec(s) with returned state \'";
|
std::cout<<">>[Runtime] process exited after "<<end_time-beg_time<<" sec(s) with returned state \'";
|
||||||
print_exit_type(exit_type);
|
print_exit_type(exit_type);
|
||||||
std::cout<<"\'."<<std::endl;
|
std::cout<<"\'."<<std::endl;
|
||||||
|
|
|
@ -201,8 +201,6 @@ class abstract_syntax_tree
|
||||||
var calculation();
|
var calculation();
|
||||||
bool condition_check();
|
bool condition_check();
|
||||||
var call_identifier();
|
var call_identifier();
|
||||||
var array_generation();
|
|
||||||
var hash_generation();
|
|
||||||
var* get_var_addr();
|
var* get_var_addr();
|
||||||
var assignment();
|
var assignment();
|
||||||
void run_root();
|
void run_root();
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
#ifndef __BALLOON_H__
|
#ifndef __BALLOON_H__
|
||||||
#define __BALLOON_H__
|
#define __BALLOON_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
Balloon language made by ValKmjolnir
|
||||||
|
place: NUAA QQ: 896693328 e-mail: 896693328@qq.com
|
||||||
|
Balloon is a real subset of Nasal language
|
||||||
|
Nasal language is created for FlightGear
|
||||||
|
Nasal language seems like ECMAscript
|
||||||
|
So you may find some similarities between nas & js
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -10,13 +20,34 @@
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
#include "balloon_type.h"
|
void alert_sound()
|
||||||
#include "abstract_syntax_tree.h"
|
{
|
||||||
#include "balloon_var.h"
|
printf("\a");
|
||||||
#include "balloon_lexer.h"
|
return;
|
||||||
#include "balloon_parse.h"
|
}
|
||||||
#include "balloon_scope.h"
|
|
||||||
|
|
||||||
#include "abstract_syntax_tree.cpp"
|
|
||||||
|
|
||||||
|
#include "balloon_type.h" // place some enums
|
||||||
|
#include "abstract_syntax_tree.h" // ast
|
||||||
|
#include "balloon_var.h" // var
|
||||||
|
/* global varia in balloon_var.h :
|
||||||
|
var error_var; // give an error_var to get
|
||||||
|
*/
|
||||||
|
#include "balloon_lexer.h" // lexer
|
||||||
|
/* global varia in balloon_lexer.h :
|
||||||
|
struct token; // used to get token from resource codes
|
||||||
|
std::string reserve_word[15]; // place many reserve words
|
||||||
|
int is_reserve_word(std::string str); // check the string is a reserve word or not and return the number of reserve word
|
||||||
|
bool check_number(std::string str); // check the string can be processed to number or not
|
||||||
|
*/
|
||||||
|
#include "balloon_parse.h" // parser
|
||||||
|
#include "balloon_scope.h" // place to store vars
|
||||||
|
/* global varia in balloon_scope.h :
|
||||||
|
balloon_scope scope; // make a place to vars
|
||||||
|
*/
|
||||||
|
#include "abstract_syntax_tree.cpp" // runtime
|
||||||
|
/* global varia in abstract_syntax_tree.cpp :
|
||||||
|
int exit_type; // record the state of runtime
|
||||||
|
std::stack<var> ret_stack; // for function ret use
|
||||||
|
std::list<var> parameter; // for function call use
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
#ifndef __BALLOON_LEXER_H__
|
#ifndef __BALLOON_LEXER_H__
|
||||||
#define __BALLOON_LEXER_H__
|
#define __BALLOON_LEXER_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
reserve words are those below
|
||||||
|
and they are also the reserve words of nasal
|
||||||
|
*/
|
||||||
std::string reserve_word[15]=
|
std::string reserve_word[15]=
|
||||||
{
|
{
|
||||||
"for","foreach","forindex","while",
|
"for","foreach","forindex","while",
|
||||||
"var","func","break","continue","return",
|
"var","func","break","continue","return",
|
||||||
"if","else","elsif","nil","and","or"
|
"if","else","elsif","nil","and","or"
|
||||||
};
|
};
|
||||||
|
|
||||||
int is_reserve_word(std::string str)
|
int is_reserve_word(std::string str)
|
||||||
{
|
{
|
||||||
for(int i=0;i<15;++i)
|
for(int i=0;i<15;++i)
|
||||||
|
@ -14,6 +19,10 @@ int is_reserve_word(std::string str)
|
||||||
return __reserve_word;
|
return __reserve_word;
|
||||||
return __token_identifier;
|
return __token_identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
check if the generated string can be put to number
|
||||||
|
*/
|
||||||
bool check_number(std::string str)
|
bool check_number(std::string str)
|
||||||
{
|
{
|
||||||
if(str.length()==1)
|
if(str.length()==1)
|
||||||
|
@ -63,7 +72,12 @@ bool check_number(std::string str)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
use std::list<char> to store resource codes
|
||||||
|
and if you continue adding files
|
||||||
|
the codes will be added behind files that have
|
||||||
|
been added in before
|
||||||
|
*/
|
||||||
class resource_file
|
class resource_file
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -108,6 +122,8 @@ class resource_file
|
||||||
{
|
{
|
||||||
if(32<=*i && *i<128 || *i=='\n')
|
if(32<=*i && *i<128 || *i=='\n')
|
||||||
std::cout<<*i;
|
std::cout<<*i;
|
||||||
|
else if(*i=='\t')
|
||||||
|
std::cout<<" ";
|
||||||
if(*i=='\n')
|
if(*i=='\n')
|
||||||
{
|
{
|
||||||
++line;
|
++line;
|
||||||
|
@ -125,7 +141,15 @@ struct token
|
||||||
int type;
|
int type;
|
||||||
std::string str;
|
std::string str;
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
|
lexer can recognize:
|
||||||
|
number: 100(int) 0.001(double) 0xdeadbeef(hex) 0o1701(oct)
|
||||||
|
string: "str" 'str'
|
||||||
|
identifier
|
||||||
|
reserve word
|
||||||
|
normal identifier: ID and id is different
|
||||||
|
operator
|
||||||
|
*/
|
||||||
class balloon_lexer
|
class balloon_lexer
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -81,26 +81,58 @@ class balloon_parse
|
||||||
root.run_root();
|
root.run_root();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
ret: return expression
|
||||||
|
choose: if-else expression
|
||||||
|
loop: while/for/forindex/foreach expression
|
||||||
|
definition
|
||||||
|
assignment
|
||||||
|
block: set of expressions
|
||||||
|
generate:
|
||||||
|
array
|
||||||
|
hash
|
||||||
|
number
|
||||||
|
string
|
||||||
|
function
|
||||||
|
block
|
||||||
|
scalar:
|
||||||
|
calculation:
|
||||||
|
calculation_or:
|
||||||
|
calculation_and:
|
||||||
|
calculation_cmp:
|
||||||
|
calculation_additive:
|
||||||
|
calculation_multive:
|
||||||
|
call_identifier
|
||||||
|
unary expression
|
||||||
|
->generate
|
||||||
|
semi: check if the statements is ended with semi
|
||||||
|
parse_main: main process
|
||||||
|
*/
|
||||||
abstract_syntax_tree ret();
|
abstract_syntax_tree ret();
|
||||||
abstract_syntax_tree choose();
|
abstract_syntax_tree choose();
|
||||||
abstract_syntax_tree loop();
|
abstract_syntax_tree loop();
|
||||||
abstract_syntax_tree definition();
|
abstract_syntax_tree definition();
|
||||||
abstract_syntax_tree assignment();
|
abstract_syntax_tree assignment();
|
||||||
|
abstract_syntax_tree block();
|
||||||
|
|
||||||
abstract_syntax_tree array_generate();
|
abstract_syntax_tree array_generate();
|
||||||
abstract_syntax_tree hash_generate();
|
abstract_syntax_tree hash_generate();
|
||||||
|
abstract_syntax_tree func_generate();
|
||||||
abstract_syntax_tree check_number();
|
abstract_syntax_tree check_number();
|
||||||
abstract_syntax_tree check_string();
|
abstract_syntax_tree check_string();
|
||||||
abstract_syntax_tree check_unary();
|
|
||||||
abstract_syntax_tree block();
|
abstract_syntax_tree scalar();
|
||||||
abstract_syntax_tree func_generate();
|
|
||||||
abstract_syntax_tree call_identifier();
|
abstract_syntax_tree call_identifier();
|
||||||
|
abstract_syntax_tree check_unary();
|
||||||
|
|
||||||
abstract_syntax_tree calculation();
|
abstract_syntax_tree calculation();
|
||||||
abstract_syntax_tree calculation_or();
|
abstract_syntax_tree calculation_or();
|
||||||
abstract_syntax_tree calculation_and();
|
abstract_syntax_tree calculation_and();
|
||||||
abstract_syntax_tree calculation_cmp();
|
abstract_syntax_tree calculation_cmp();
|
||||||
abstract_syntax_tree calculation_additive();
|
abstract_syntax_tree calculation_additive();
|
||||||
abstract_syntax_tree calculation_multive();
|
abstract_syntax_tree calculation_multive();
|
||||||
abstract_syntax_tree scalar();
|
|
||||||
void check_semi();
|
void check_semi();
|
||||||
void parse_main();
|
void parse_main();
|
||||||
};
|
};
|
||||||
|
@ -489,7 +521,7 @@ abstract_syntax_tree balloon_parse::block()
|
||||||
{
|
{
|
||||||
abstract_syntax_tree new_node;
|
abstract_syntax_tree new_node;
|
||||||
abstract_syntax_tree temp;
|
abstract_syntax_tree temp;
|
||||||
new_node.set_type(__block);
|
new_node.set_type(__normal_block);
|
||||||
get_token();
|
get_token();
|
||||||
if(this_token.type!=__left_brace)
|
if(this_token.type!=__left_brace)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,14 @@ class balloon_scope
|
||||||
private:
|
private:
|
||||||
std::list<var> global;
|
std::list<var> global;
|
||||||
std::list<std::list<std::list<var> > > scope_list;
|
std::list<std::list<std::list<var> > > scope_list;
|
||||||
|
/*
|
||||||
|
example:
|
||||||
|
std::list<var> global // global scope
|
||||||
|
std::list<std::list<std::list<var> > > // total scope
|
||||||
|
-> std::list<std::list<var> > // block scope
|
||||||
|
->std::list<var> // local scope
|
||||||
|
-> var -> var -> var -> var
|
||||||
|
*/
|
||||||
public:
|
public:
|
||||||
void set_clear()
|
void set_clear()
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ enum parse_type
|
||||||
//basic elements
|
//basic elements
|
||||||
|
|
||||||
__null_node,
|
__null_node,
|
||||||
__block,
|
__normal_block,
|
||||||
__array,
|
__array,
|
||||||
__hash,
|
__hash,
|
||||||
__root,
|
__root,
|
||||||
|
@ -65,6 +65,7 @@ enum parse_type
|
||||||
__call_hash,
|
__call_hash,
|
||||||
__call_function
|
__call_function
|
||||||
};
|
};
|
||||||
|
|
||||||
void print_detail_token(int type)
|
void print_detail_token(int type)
|
||||||
{
|
{
|
||||||
std::string context="";
|
std::string context="";
|
||||||
|
@ -119,7 +120,7 @@ void print_detail_token(int type)
|
||||||
case __string: context="str";break;
|
case __string: context="str";break;
|
||||||
|
|
||||||
case __null_node: context="null node";break;
|
case __null_node: context="null node";break;
|
||||||
case __block: context="block";break;
|
case __normal_block: context="block";break;
|
||||||
case __array: context="array";break;
|
case __array: context="array";break;
|
||||||
case __hash: context="hash";break;
|
case __hash: context="hash";break;
|
||||||
case __root: context="root";break;
|
case __root: context="root";break;
|
||||||
|
@ -138,6 +139,34 @@ void print_detail_token(int type)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum var_type
|
||||||
|
{
|
||||||
|
__null_type,
|
||||||
|
__var_number,
|
||||||
|
__var_string,
|
||||||
|
__var_array,
|
||||||
|
__var_hash,
|
||||||
|
__var_function
|
||||||
|
};
|
||||||
|
|
||||||
|
void print_scalar(int type)
|
||||||
|
{
|
||||||
|
std::string str="";
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case __null_type: str="null";break;
|
||||||
|
case __var_number: str="number";break;
|
||||||
|
case __var_string: str="string";break;
|
||||||
|
case __var_array: str="array";break;
|
||||||
|
case __var_hash: str="hash";break;
|
||||||
|
case __var_function:str="function";break;
|
||||||
|
default: str="unknown";break;
|
||||||
|
}
|
||||||
|
std::cout<<str;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum runtime_error_type
|
enum runtime_error_type
|
||||||
{
|
{
|
||||||
__process_exited_successfully,
|
__process_exited_successfully,
|
||||||
|
|
|
@ -1,33 +1,6 @@
|
||||||
#ifndef __BALLOON_VAR_H__
|
#ifndef __BALLOON_VAR_H__
|
||||||
#define __BALLOON_VAR_H__
|
#define __BALLOON_VAR_H__
|
||||||
|
|
||||||
enum var_type
|
|
||||||
{
|
|
||||||
__null_type,
|
|
||||||
__var_number,
|
|
||||||
__var_string,
|
|
||||||
__var_array,
|
|
||||||
__var_hash,
|
|
||||||
__var_function
|
|
||||||
};
|
|
||||||
|
|
||||||
void print_scalar(int type)
|
|
||||||
{
|
|
||||||
std::string str="";
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case __null_type: str="null";break;
|
|
||||||
case __var_number: str="number";break;
|
|
||||||
case __var_string: str="string";break;
|
|
||||||
case __var_array: str="array";break;
|
|
||||||
case __var_hash: str="hash";break;
|
|
||||||
case __var_function:str="function";break;
|
|
||||||
default: str="unknown";break;
|
|
||||||
}
|
|
||||||
std::cout<<str;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
class var
|
class var
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -29,9 +29,9 @@ int main()
|
||||||
else if(command=="cls")
|
else if(command=="cls")
|
||||||
{
|
{
|
||||||
system("cls");
|
system("cls");
|
||||||
//windows system("cls");
|
// Windows system("cls");
|
||||||
//linux system("clear");
|
// Linux system("clear");
|
||||||
//macOS system("clear");
|
// MacOS system("clear");
|
||||||
}
|
}
|
||||||
else if(command=="rs")
|
else if(command=="rs")
|
||||||
prog.print_file();
|
prog.print_file();
|
||||||
|
@ -59,7 +59,10 @@ int main()
|
||||||
pas.parse_main();
|
pas.parse_main();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
alert_sound();
|
||||||
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
|
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(command=="ast")
|
else if(command=="ast")
|
||||||
{
|
{
|
||||||
|
@ -72,10 +75,16 @@ int main()
|
||||||
if(!pas.get_error())
|
if(!pas.get_error())
|
||||||
pas.print_generated_tree();
|
pas.print_generated_tree();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
alert_sound();
|
||||||
std::cout<<">>[Parse] error(s) found,stop."<<std::endl;
|
std::cout<<">>[Parse] error(s) found,stop."<<std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
alert_sound();
|
||||||
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
|
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(command=="run")
|
else if(command=="run")
|
||||||
{
|
{
|
||||||
|
@ -88,10 +97,16 @@ int main()
|
||||||
if(!pas.get_error())
|
if(!pas.get_error())
|
||||||
pas.run_tree();
|
pas.run_tree();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
alert_sound();
|
||||||
std::cout<<">>[Parse] error(s) found,stop."<<std::endl;
|
std::cout<<">>[Parse] error(s) found,stop."<<std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
alert_sound();
|
||||||
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
|
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
prog.input_file(command);
|
prog.input_file(command);
|
||||||
|
|
Loading…
Reference in New Issue