Add notes

This commit is contained in:
Valk Richard Li 2019-11-14 19:29:43 +08:00 committed by GitHub
parent 763af6e7aa
commit c421f726fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 177 additions and 78 deletions

View File

@ -4,8 +4,9 @@
int exit_type=0;
std::stack<var> ret_stack;// for function ret use
std::list<var> parameter;// for function call use
std::stack<var> ret_stack; // for function ret use
std::list<var> parameter; // for function call use
var abstract_syntax_tree::calculation()
{
@ -30,12 +31,23 @@ var abstract_syntax_tree::calculation()
}
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;
}
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;
}
else if(this->type==__function)
@ -477,31 +489,6 @@ var abstract_syntax_tree::call_identifier()
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* addr=&error_var;
@ -697,6 +684,8 @@ void abstract_syntax_tree::run_root()
}
end_time=time(NULL);
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 \'";
print_exit_type(exit_type);
std::cout<<"\'."<<std::endl;

View File

@ -201,8 +201,6 @@ class abstract_syntax_tree
var calculation();
bool condition_check();
var call_identifier();
var array_generation();
var hash_generation();
var* get_var_addr();
var assignment();
void run_root();

View File

@ -1,6 +1,16 @@
#ifndef __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 <cstdlib>
#include <cstring>
@ -10,13 +20,34 @@
#include <stack>
#include <ctime>
#include "balloon_type.h"
#include "abstract_syntax_tree.h"
#include "balloon_var.h"
#include "balloon_lexer.h"
#include "balloon_parse.h"
#include "balloon_scope.h"
#include "abstract_syntax_tree.cpp"
void alert_sound()
{
printf("\a");
return;
}
#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

View File

@ -1,12 +1,17 @@
#ifndef __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]=
{
"for","foreach","forindex","while",
"var","func","break","continue","return",
"if","else","elsif","nil","and","or"
};
int is_reserve_word(std::string str)
{
for(int i=0;i<15;++i)
@ -14,6 +19,10 @@ int is_reserve_word(std::string str)
return __reserve_word;
return __token_identifier;
}
/*
check if the generated string can be put to number
*/
bool check_number(std::string str)
{
if(str.length()==1)
@ -63,7 +72,12 @@ bool check_number(std::string str)
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
{
private:
@ -108,6 +122,8 @@ class resource_file
{
if(32<=*i && *i<128 || *i=='\n')
std::cout<<*i;
else if(*i=='\t')
std::cout<<" ";
if(*i=='\n')
{
++line;
@ -125,7 +141,15 @@ struct token
int type;
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
{
private:

View File

@ -81,26 +81,58 @@ class balloon_parse
root.run_root();
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 choose();
abstract_syntax_tree loop();
abstract_syntax_tree definition();
abstract_syntax_tree assignment();
abstract_syntax_tree block();
abstract_syntax_tree array_generate();
abstract_syntax_tree hash_generate();
abstract_syntax_tree func_generate();
abstract_syntax_tree check_number();
abstract_syntax_tree check_string();
abstract_syntax_tree check_unary();
abstract_syntax_tree block();
abstract_syntax_tree func_generate();
abstract_syntax_tree scalar();
abstract_syntax_tree call_identifier();
abstract_syntax_tree check_unary();
abstract_syntax_tree calculation();
abstract_syntax_tree calculation_or();
abstract_syntax_tree calculation_and();
abstract_syntax_tree calculation_cmp();
abstract_syntax_tree calculation_additive();
abstract_syntax_tree calculation_multive();
abstract_syntax_tree scalar();
void check_semi();
void parse_main();
};
@ -489,7 +521,7 @@ abstract_syntax_tree balloon_parse::block()
{
abstract_syntax_tree new_node;
abstract_syntax_tree temp;
new_node.set_type(__block);
new_node.set_type(__normal_block);
get_token();
if(this_token.type!=__left_brace)
{

View File

@ -6,6 +6,14 @@ class balloon_scope
private:
std::list<var> global;
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:
void set_clear()
{

View File

@ -51,7 +51,7 @@ enum parse_type
//basic elements
__null_node,
__block,
__normal_block,
__array,
__hash,
__root,
@ -65,6 +65,7 @@ enum parse_type
__call_hash,
__call_function
};
void print_detail_token(int type)
{
std::string context="";
@ -119,7 +120,7 @@ void print_detail_token(int type)
case __string: context="str";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 __hash: context="hash";break;
case __root: context="root";break;
@ -138,6 +139,34 @@ void print_detail_token(int type)
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
{
__process_exited_successfully,

View File

@ -1,33 +1,6 @@
#ifndef __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
{
private:

View File

@ -29,9 +29,9 @@ int main()
else if(command=="cls")
{
system("cls");
//windows system("cls");
//linux system("clear");
//macOS system("clear");
// Windows system("cls");
// Linux system("clear");
// MacOS system("clear");
}
else if(command=="rs")
prog.print_file();
@ -59,7 +59,10 @@ int main()
pas.parse_main();
}
else
{
alert_sound();
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
}
}
else if(command=="ast")
{
@ -72,10 +75,16 @@ int main()
if(!pas.get_error())
pas.print_generated_tree();
else
{
alert_sound();
std::cout<<">>[Parse] error(s) found,stop."<<std::endl;
}
}
else
{
alert_sound();
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
}
}
else if(command=="run")
{
@ -88,10 +97,16 @@ int main()
if(!pas.get_error())
pas.run_tree();
else
{
alert_sound();
std::cout<<">>[Parse] error(s) found,stop."<<std::endl;
}
}
else
{
alert_sound();
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
}
}
else
prog.input_file(command);