update
This commit is contained in:
parent
c0f58cc2b1
commit
a723b878f0
|
@ -69,7 +69,6 @@ var io=
|
||||||
|
|
||||||
var print=func(dyn...)
|
var print=func(dyn...)
|
||||||
{
|
{
|
||||||
forindex(var i;dyn)
|
nasal_call_inline_c_std_puts(dyn);
|
||||||
nasal_call_inline_c_std_puts(dyn[i]);
|
|
||||||
return nil;
|
return nil;
|
||||||
};
|
};
|
|
@ -1,24 +1,26 @@
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
|
|
||||||
// source code will be put in resource
|
// source code will be put in resource
|
||||||
resource_file resource;
|
resource_file resource;
|
||||||
// source code will be generated to tokens in lexer
|
// source code will be generated to tokens in lexer
|
||||||
nasal_lexer lexer;
|
nasal_lexer lexer;
|
||||||
// token list will be checked in parser and output the abstract syntax tree
|
// token list will be checked in parser and output the abstract syntax tree
|
||||||
nasal_parse parser;
|
nasal_parse parser;
|
||||||
// libroot stores the ast of lib file
|
// libroot stores the ast of lib file
|
||||||
abstract_syntax_tree libroot;
|
abstract_syntax_tree libroot;
|
||||||
// root stores the ast of source code
|
// root stores the ast of source code
|
||||||
abstract_syntax_tree root;
|
abstract_syntax_tree root;
|
||||||
// executable_ast generates libroot and root together
|
// executable_ast generates libroot and root together
|
||||||
|
// this ast will be sent into nasal runtime
|
||||||
abstract_syntax_tree executable_ast;
|
abstract_syntax_tree executable_ast;
|
||||||
|
// main process is running here
|
||||||
nasal_runtime runtime;
|
nasal_runtime runtime;
|
||||||
|
|
||||||
|
// command is used in main()
|
||||||
std::string command;
|
std::string command;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
// this curve looks really cool
|
||||||
std::cout<<" __ _ "<<std::endl;
|
std::cout<<" __ _ "<<std::endl;
|
||||||
std::cout<<" /\\ \\ \\__ _ ___ __ _| | "<<std::endl;
|
std::cout<<" /\\ \\ \\__ _ ___ __ _| | "<<std::endl;
|
||||||
std::cout<<" / \\/ / _` / __|/ _` | | "<<std::endl;
|
std::cout<<" / \\/ / _` / __|/ _` | | "<<std::endl;
|
||||||
|
@ -54,9 +56,9 @@ int main()
|
||||||
std::cout<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
std::cout<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
||||||
std::cout<<">> [run ] run code."<<std::endl;
|
std::cout<<">> [run ] run code."<<std::endl;
|
||||||
std::cout<<">> [logo ] print logo of nasal ."<<std::endl;
|
std::cout<<">> [logo ] print logo of nasal ."<<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;
|
||||||
}
|
}
|
||||||
|
// clear the window
|
||||||
else if(command=="cls")
|
else if(command=="cls")
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -69,6 +71,7 @@ int main()
|
||||||
system("clear");
|
system("clear");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
// del all the source codes and asts
|
||||||
else if(command=="del")
|
else if(command=="del")
|
||||||
{
|
{
|
||||||
resource.delete_all_source();
|
resource.delete_all_source();
|
||||||
|
@ -78,6 +81,7 @@ int main()
|
||||||
executable_ast.set_clear();
|
executable_ast.set_clear();
|
||||||
std::cout<<">> [Delete] complete."<<std::endl;
|
std::cout<<">> [Delete] complete."<<std::endl;
|
||||||
}
|
}
|
||||||
|
// add lib
|
||||||
else if(command=="lib")
|
else if(command=="lib")
|
||||||
{
|
{
|
||||||
libroot.set_clear();
|
libroot.set_clear();
|
||||||
|
@ -102,10 +106,10 @@ int main()
|
||||||
lexer.delete_all_tokens();
|
lexer.delete_all_tokens();
|
||||||
parser.delete_all_elements();
|
parser.delete_all_elements();
|
||||||
}
|
}
|
||||||
|
// print source codes
|
||||||
else if(command=="rs")
|
else if(command=="rs")
|
||||||
{
|
|
||||||
resource.print_resource();
|
resource.print_resource();
|
||||||
}
|
// print detail token after scanning source codes
|
||||||
else if(command=="lex")
|
else if(command=="lex")
|
||||||
{
|
{
|
||||||
lexer.scanner(resource.get_source());
|
lexer.scanner(resource.get_source());
|
||||||
|
@ -115,6 +119,7 @@ int main()
|
||||||
else
|
else
|
||||||
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
||||||
}
|
}
|
||||||
|
// print the parse result of source codes
|
||||||
else if(command=="par")
|
else if(command=="par")
|
||||||
{
|
{
|
||||||
lexer.scanner(resource.get_source());
|
lexer.scanner(resource.get_source());
|
||||||
|
@ -128,6 +133,7 @@ int main()
|
||||||
else
|
else
|
||||||
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
||||||
}
|
}
|
||||||
|
// print the ast of source codes
|
||||||
else if(command=="ast")
|
else if(command=="ast")
|
||||||
{
|
{
|
||||||
lexer.scanner(resource.get_source());
|
lexer.scanner(resource.get_source());
|
||||||
|
@ -144,6 +150,7 @@ int main()
|
||||||
else
|
else
|
||||||
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
||||||
}
|
}
|
||||||
|
// running process begins here
|
||||||
else if(command=="run")
|
else if(command=="run")
|
||||||
{
|
{
|
||||||
lexer.scanner(resource.get_source());
|
lexer.scanner(resource.get_source());
|
||||||
|
@ -166,6 +173,7 @@ int main()
|
||||||
else
|
else
|
||||||
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
||||||
}
|
}
|
||||||
|
// do you wanna see it again?
|
||||||
else if(command=="logo")
|
else if(command=="logo")
|
||||||
{
|
{
|
||||||
std::cout<<" __ _ "<<std::endl;
|
std::cout<<" __ _ "<<std::endl;
|
||||||
|
@ -174,16 +182,7 @@ int main()
|
||||||
std::cout<<" / /\\ / (_| \\__ \\ (_| | | "<<std::endl;
|
std::cout<<" / /\\ / (_| \\__ \\ (_| | | "<<std::endl;
|
||||||
std::cout<<" \\_\\ \\/ \\__,_|___/\\__,_|_|"<<std::endl;
|
std::cout<<" \\_\\ \\/ \\__,_|___/\\__,_|_|"<<std::endl;
|
||||||
}
|
}
|
||||||
else if(command=="info")
|
// exit interpreter
|
||||||
{
|
|
||||||
lexer.scanner(resource.get_source());
|
|
||||||
lexer.print_token_list();
|
|
||||||
lexer.generate_detail_token();
|
|
||||||
parser.get_token_list(lexer.get_detail_token_list());
|
|
||||||
parser.print_detail_token();
|
|
||||||
parser.main_generate();
|
|
||||||
parser.get_root().print_tree();
|
|
||||||
}
|
|
||||||
else if(command=="exit")
|
else if(command=="exit")
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
|
|
|
@ -6,18 +6,80 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
//#include <thread>
|
// if thread is used, don't forget to add -std=c++11 or higher standard before executing
|
||||||
|
// #include <thread>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
/*
|
||||||
|
nasal_misc.h:
|
||||||
|
including some functions that change number to string or change string to number
|
||||||
|
including a function that check if a string is a numerable string
|
||||||
|
including a function that print the hex format number of an integer
|
||||||
|
*/
|
||||||
#include "nasal_misc.h"
|
#include "nasal_misc.h"
|
||||||
|
/*
|
||||||
|
nasal_enum.h
|
||||||
|
including enums of: lexer token type,parse generated type,scalar type
|
||||||
|
lexer token type is used by nasal_lexer
|
||||||
|
parse generated type is used both by nasal_parse and abstract_syntax_tree
|
||||||
|
parse generated type is also used when lexer is generating detailed tokens which are used in nasal_parse
|
||||||
|
scalar type is used in nasal_runtime and nasal_gc
|
||||||
|
*/
|
||||||
#include "nasal_enum.h"
|
#include "nasal_enum.h"
|
||||||
|
/*
|
||||||
|
nasal_ast.h
|
||||||
|
including a class named abstract_syntax_tree
|
||||||
|
this class is frequently used in nasal_parse nasal_runtime
|
||||||
|
*/
|
||||||
#include "nasal_ast.h"
|
#include "nasal_ast.h"
|
||||||
|
/*
|
||||||
|
nasal_lexer.h
|
||||||
|
including a class named resource_file
|
||||||
|
including a class named nasal_lexer
|
||||||
|
including a string[] named lib_filename, by this way resource_file can load lib files
|
||||||
|
including a string[] named reserve_word, it is used in lexer,when generating an identifier,nasal_lexer will check if it is a reserve word
|
||||||
|
including a struct named token, this struct is often used in nasal_lexer
|
||||||
|
including a function named is_reserve_word, checking if an identifier is a reserve word
|
||||||
|
*/
|
||||||
#include "nasal_lexer.h"
|
#include "nasal_lexer.h"
|
||||||
|
/*
|
||||||
|
nasal_parse.h
|
||||||
|
including a class named nasal_parse
|
||||||
|
nasal_parse uses tokens generated by lexer and generats them into abstract syntax tree
|
||||||
|
this class has a special enum named parse_error_type
|
||||||
|
if parse errors occur,this enum will be into use
|
||||||
|
*/
|
||||||
#include "nasal_parse.h"
|
#include "nasal_parse.h"
|
||||||
|
/*
|
||||||
|
nasal_gc.h(garbage collector and memory manager of nasal_runtime)
|
||||||
|
including basic classed named: nasal_number, nasal_string, nasal_vector, nasal_hash, nasal_function
|
||||||
|
including important class named gc_manager
|
||||||
|
including struct named gc_unit, it is the smallest memory unit.used in gc_manager
|
||||||
|
nasal_gc is an object of class gc_manager,and nasal_runtime uses this object as it's memory manager
|
||||||
|
*/
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
|
/*
|
||||||
|
nasal_runtime.h
|
||||||
|
including a class named nasal_runtime
|
||||||
|
including a string[] named inline_func_name
|
||||||
|
function that mentioned in inline_func_name is special functions that were written by cpp,so they can be ca;;ed directly
|
||||||
|
|
||||||
|
if you want to add new built-in functions:
|
||||||
|
add it's name into inline_func_name
|
||||||
|
change the number of nas_lib_func_num
|
||||||
|
write it's function in nasal_runtime::inline_function
|
||||||
|
and don't forget to warp it up with a function that written by nasal
|
||||||
|
|
||||||
|
for example: print(dyn...)
|
||||||
|
var print=func(dyn...)
|
||||||
|
{
|
||||||
|
nasal_call_inline_c_std_puts(dyn);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
*/
|
||||||
#include "nasal_runtime.h"
|
#include "nasal_runtime.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -356,7 +356,7 @@ void nasal_vector::set_clear()
|
||||||
}
|
}
|
||||||
void nasal_vector::vec_push(int addr)
|
void nasal_vector::vec_push(int addr)
|
||||||
{
|
{
|
||||||
nasal_gc.reference_add(addr);
|
nas_array.push_back(addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int* nasal_vector::get_elem_addr(int addr)
|
int* nasal_vector::get_elem_addr(int addr)
|
||||||
|
|
|
@ -374,7 +374,16 @@ class nasal_lexer
|
||||||
if(*ptr=='\\')
|
if(*ptr=='\\')
|
||||||
{
|
{
|
||||||
++ptr;
|
++ptr;
|
||||||
token_str+=*ptr;
|
switch(*ptr)
|
||||||
|
{
|
||||||
|
case '\\':token_str.pop_back();token_str.push_back('\\');break;
|
||||||
|
case 'r': token_str.pop_back();token_str.push_back('\r');break;
|
||||||
|
case 't': token_str.pop_back();token_str.push_back('\t');break;
|
||||||
|
case 'n': token_str.pop_back();token_str.push_back('\n');break;
|
||||||
|
case '\'':token_str.pop_back();token_str.push_back('\'');break;
|
||||||
|
case '\"':token_str.pop_back();token_str.push_back('\"');break;
|
||||||
|
default: token_str.push_back(*ptr);break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++ptr;
|
++ptr;
|
||||||
if(ptr==res.end())
|
if(ptr==res.end())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef __NASAL_RUNTIME_H__
|
#ifndef __NASAL_RUNTIME_H__
|
||||||
#define __NASAL_RUNTIME_H__
|
#define __NASAL_RUNTIME_H__
|
||||||
#define nas_lib_func_num 29
|
#define nas_lib_func_num 30
|
||||||
std::string inline_func_name[nas_lib_func_num]=
|
std::string inline_func_name[nas_lib_func_num]=
|
||||||
{
|
{
|
||||||
//base.nas
|
//base.nas
|
||||||
|
@ -27,6 +27,8 @@ std::string inline_func_name[nas_lib_func_num]=
|
||||||
"nasal_call_built_in_sbitcalc",
|
"nasal_call_built_in_sbitcalc",
|
||||||
"nasal_call_built_in_setbit",
|
"nasal_call_built_in_setbit",
|
||||||
"nasal_call_built_in_null_string_gen",
|
"nasal_call_built_in_null_string_gen",
|
||||||
|
//io.nas
|
||||||
|
"nasal_call_inline_c_std_puts",
|
||||||
//math.nas
|
//math.nas
|
||||||
"nasal_call_inline_sin",
|
"nasal_call_inline_sin",
|
||||||
"nasal_call_inline_cos",
|
"nasal_call_inline_cos",
|
||||||
|
@ -34,7 +36,8 @@ std::string inline_func_name[nas_lib_func_num]=
|
||||||
"nasal_call_inline_pow",
|
"nasal_call_inline_pow",
|
||||||
"nasal_call_inline_cpp_math_ln",
|
"nasal_call_inline_cpp_math_ln",
|
||||||
"nasal_call_inline_cpp_math_sqrt",
|
"nasal_call_inline_cpp_math_sqrt",
|
||||||
"nasal_call_inline_cpp_atan2"
|
"nasal_call_inline_cpp_atan2",
|
||||||
|
//
|
||||||
};
|
};
|
||||||
|
|
||||||
class nasal_runtime
|
class nasal_runtime
|
||||||
|
@ -50,9 +53,9 @@ class nasal_runtime
|
||||||
// enum of state type used by loop/conditional
|
// enum of state type used by loop/conditional
|
||||||
enum state_stack_member_type
|
enum state_stack_member_type
|
||||||
{
|
{
|
||||||
__state_error,
|
__state_error = 0,
|
||||||
__state_no_operation,
|
__state_no_operation,
|
||||||
__state_continue=1,
|
__state_continue,
|
||||||
__state_break,
|
__state_break,
|
||||||
__state_return,
|
__state_return,
|
||||||
};
|
};
|
||||||
|
@ -102,8 +105,8 @@ class nasal_runtime
|
||||||
int loop_expr (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
int loop_expr (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||||
int conditional (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
int conditional (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||||
int block_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
int block_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||||
int func_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&,abstract_syntax_tree&,abstract_syntax_tree&,int);// checked
|
int func_proc (std::list<std::map<std::string,int> >&,std::list<std::map<std::string,int> >&,abstract_syntax_tree&,abstract_syntax_tree&,abstract_syntax_tree&,int);// checked
|
||||||
int inline_function (std::list<std::map<std::string,int> >&,abstract_syntax_tree&,int);
|
int inline_function (std::list<std::map<std::string,int> >&,std::string);
|
||||||
public:
|
public:
|
||||||
nasal_runtime()
|
nasal_runtime()
|
||||||
{
|
{
|
||||||
|
@ -419,6 +422,8 @@ int nasal_runtime::vector_generation(std::list<std::map<std::string,int> >& loca
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(nasal_gc.get_scalar(data_addr).get_type()==scalar_number)
|
||||||
|
place_num=nasal_gc.get_scalar(data_addr).get_number().get_number();
|
||||||
if(place_num>2147483647 || place_num<-2147483648)
|
if(place_num>2147483647 || place_num<-2147483648)
|
||||||
{
|
{
|
||||||
error_interrupt(__normal_call_vector_too_large_value,call_node->get_children().front().get_node_line());
|
error_interrupt(__normal_call_vector_too_large_value,call_node->get_children().front().get_node_line());
|
||||||
|
@ -481,6 +486,7 @@ int nasal_runtime::vector_generation(std::list<std::map<std::string,int> >& loca
|
||||||
}
|
}
|
||||||
int tmp_addr=addr;
|
int tmp_addr=addr;
|
||||||
addr=func_proc(
|
addr=func_proc(
|
||||||
|
local_scope,
|
||||||
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||||
|
@ -748,6 +754,8 @@ int nasal_runtime::hash_generation(std::list<std::map<std::string,int> >& local_
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(nasal_gc.get_scalar(data_addr).get_type()==scalar_number)
|
||||||
|
place_num=nasal_gc.get_scalar(data_addr).get_number().get_number();
|
||||||
if(place_num>2147483647 || place_num<-2147483648)
|
if(place_num>2147483647 || place_num<-2147483648)
|
||||||
{
|
{
|
||||||
error_interrupt(__normal_call_vector_too_large_value,call_node->get_children().front().get_node_line());
|
error_interrupt(__normal_call_vector_too_large_value,call_node->get_children().front().get_node_line());
|
||||||
|
@ -810,6 +818,7 @@ int nasal_runtime::hash_generation(std::list<std::map<std::string,int> >& local_
|
||||||
}
|
}
|
||||||
int tmp_addr=addr;
|
int tmp_addr=addr;
|
||||||
addr=func_proc(
|
addr=func_proc(
|
||||||
|
local_scope,
|
||||||
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||||
|
@ -1036,6 +1045,8 @@ int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& lo
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(nasal_gc.get_scalar(data_addr).get_type()==scalar_number)
|
||||||
|
place_num=nasal_gc.get_scalar(data_addr).get_number().get_number();
|
||||||
if(place_num>2147483647 || place_num<-2147483648)
|
if(place_num>2147483647 || place_num<-2147483648)
|
||||||
{
|
{
|
||||||
error_interrupt(__normal_call_vector_too_large_value,call_node->get_children().front().get_node_line());
|
error_interrupt(__normal_call_vector_too_large_value,call_node->get_children().front().get_node_line());
|
||||||
|
@ -1098,6 +1109,7 @@ int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& lo
|
||||||
}
|
}
|
||||||
int tmp_addr=addr;
|
int tmp_addr=addr;
|
||||||
addr=func_proc(
|
addr=func_proc(
|
||||||
|
local_scope,
|
||||||
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||||
|
@ -1141,7 +1153,13 @@ int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scop
|
||||||
{
|
{
|
||||||
// calculation will return a value that points to a new area in memory
|
// calculation will return a value that points to a new area in memory
|
||||||
int node_type=node.get_node_type();
|
int node_type=node.get_node_type();
|
||||||
if(node_type==__number)
|
if(node_type==__nil)
|
||||||
|
{
|
||||||
|
int ret=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(ret).set_type(scalar_nil);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else if(node_type==__number)
|
||||||
return number_generation(node);
|
return number_generation(node);
|
||||||
else if(node_type==__string)
|
else if(node_type==__string)
|
||||||
return string_generation(node);
|
return string_generation(node);
|
||||||
|
@ -1846,6 +1864,7 @@ int nasal_runtime::assignment(std::list<std::map<std::string,int> >& local_scope
|
||||||
if(!assigned_addr)
|
if(!assigned_addr)
|
||||||
return -1;
|
return -1;
|
||||||
int assigned_value_addr=*assigned_addr;
|
int assigned_value_addr=*assigned_addr;
|
||||||
|
nasal_gc.reference_add(*assigned_addr);
|
||||||
for(std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();iter!=node.get_children().end();++iter)
|
for(std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();iter!=node.get_children().end();++iter)
|
||||||
{
|
{
|
||||||
// call vector/special call hash/subvec
|
// call vector/special call hash/subvec
|
||||||
|
@ -2011,10 +2030,10 @@ int nasal_runtime::assignment(std::list<std::map<std::string,int> >& local_scope
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// normal vector/hash calling
|
// normal vector/hash calling
|
||||||
int data_addr=calculation(local_scope,iter->get_children().front());
|
int tmp_data_addr=calculation(local_scope,iter->get_children().front());
|
||||||
if(data_addr<0)
|
if(tmp_data_addr<0)
|
||||||
return -1;
|
return -1;
|
||||||
if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_number && nasal_gc.get_scalar(data_addr).get_type()!=scalar_string)
|
if(nasal_gc.get_scalar(tmp_data_addr).get_type()!=scalar_number && nasal_gc.get_scalar(tmp_data_addr).get_type()!=scalar_string)
|
||||||
{
|
{
|
||||||
error_interrupt(__error_value_type_when_calling_vector,iter->get_children().front().get_node_line());
|
error_interrupt(__error_value_type_when_calling_vector,iter->get_children().front().get_node_line());
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2022,16 +2041,18 @@ int nasal_runtime::assignment(std::list<std::map<std::string,int> >& local_scope
|
||||||
if(called_type==scalar_vector)
|
if(called_type==scalar_vector)
|
||||||
{
|
{
|
||||||
double place_num=0;
|
double place_num=0;
|
||||||
if(nasal_gc.get_scalar(data_addr).get_type()==scalar_string)
|
if(nasal_gc.get_scalar(tmp_data_addr).get_type()==scalar_string)
|
||||||
{
|
{
|
||||||
if(check_numerable_string(nasal_gc.get_scalar(data_addr).get_string().get_string()))
|
if(check_numerable_string(nasal_gc.get_scalar(tmp_data_addr).get_string().get_string()))
|
||||||
place_num=(int)trans_string_to_number(nasal_gc.get_scalar(data_addr).get_string().get_string());
|
place_num=(int)trans_string_to_number(nasal_gc.get_scalar(tmp_data_addr).get_string().get_string());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_interrupt(__not_numerable_str,iter->get_children().front().get_node_line());
|
error_interrupt(__not_numerable_str,iter->get_children().front().get_node_line());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(nasal_gc.get_scalar(tmp_data_addr).get_type()==scalar_number)
|
||||||
|
place_num=nasal_gc.get_scalar(tmp_data_addr).get_number().get_number();
|
||||||
if(place_num>2147483647 || place_num<-2147483648)
|
if(place_num>2147483647 || place_num<-2147483648)
|
||||||
{
|
{
|
||||||
error_interrupt(__normal_call_vector_too_large_value,iter->get_children().front().get_node_line());
|
error_interrupt(__normal_call_vector_too_large_value,iter->get_children().front().get_node_line());
|
||||||
|
@ -2050,7 +2071,7 @@ int nasal_runtime::assignment(std::list<std::map<std::string,int> >& local_scope
|
||||||
}
|
}
|
||||||
else if(called_type==scalar_hash)
|
else if(called_type==scalar_hash)
|
||||||
{
|
{
|
||||||
if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_string)
|
if(nasal_gc.get_scalar(tmp_data_addr).get_type()!=scalar_string)
|
||||||
{
|
{
|
||||||
error_interrupt(__error_value_type_when_calling_hash,iter->get_children().front().get_node_line());
|
error_interrupt(__error_value_type_when_calling_hash,iter->get_children().front().get_node_line());
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2066,7 +2087,7 @@ int nasal_runtime::assignment(std::list<std::map<std::string,int> >& local_scope
|
||||||
nasal_gc.reference_add(assigned_value_addr);
|
nasal_gc.reference_add(assigned_value_addr);
|
||||||
nasal_gc.reference_delete(tmp_addr);
|
nasal_gc.reference_delete(tmp_addr);
|
||||||
}
|
}
|
||||||
nasal_gc.reference_delete(data_addr);
|
nasal_gc.reference_delete(tmp_data_addr);
|
||||||
}
|
}
|
||||||
}// end call vector
|
}// end call vector
|
||||||
// call hash identifier.identifier
|
// call hash identifier.identifier
|
||||||
|
@ -2122,9 +2143,7 @@ int nasal_runtime::assignment(std::list<std::map<std::string,int> >& local_scope
|
||||||
nasal_gc.reference_add(data_addr);
|
nasal_gc.reference_add(data_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nasal_gc.reference_delete(assigned_value_addr);
|
|
||||||
// data_addr is only a parameter here,and it's refcnt has not been changed when using it here
|
// data_addr is only a parameter here,and it's refcnt has not been changed when using it here
|
||||||
nasal_gc.reference_add(*assigned_addr);
|
|
||||||
return *assigned_addr;
|
return *assigned_addr;
|
||||||
}
|
}
|
||||||
int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||||
|
@ -2138,9 +2157,16 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
addr=(*iter)[tmp_id_name];
|
addr=(*iter)[tmp_id_name];
|
||||||
if(addr<0)
|
if(addr<0)
|
||||||
{
|
{
|
||||||
|
// inline function call only needs local_scope and function name
|
||||||
|
// because all the inline functions are wraped in functions that can be searched in global scope
|
||||||
for(int i=0;i<nas_lib_func_num;++i)
|
for(int i=0;i<nas_lib_func_num;++i)
|
||||||
if(inline_func_name[i]==tmp_id_name)
|
if(inline_func_name[i]==tmp_id_name)
|
||||||
addr=inline_function(local_scope,node,-1);
|
{
|
||||||
|
addr=inline_function(local_scope,tmp_id_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(addr>=0)
|
||||||
|
return addr;
|
||||||
}
|
}
|
||||||
if(addr<0)
|
if(addr<0)
|
||||||
{
|
{
|
||||||
|
@ -2148,6 +2174,9 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int last_hash_addr=-1;
|
int last_hash_addr=-1;
|
||||||
|
// after calculation or assignment/definition,reference counter of this address will -1
|
||||||
|
// to avoid nasal_gc collecting this address,reference counter+1 here
|
||||||
|
nasal_gc.reference_add(addr);
|
||||||
for(std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();iter!=node.get_children().end();++iter)
|
for(std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();iter!=node.get_children().end();++iter)
|
||||||
{
|
{
|
||||||
if(nasal_gc.get_scalar(addr).get_type()==scalar_hash)
|
if(nasal_gc.get_scalar(addr).get_type()==scalar_hash)
|
||||||
|
@ -2335,6 +2364,8 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(nasal_gc.get_scalar(data_addr).get_type()==scalar_number)
|
||||||
|
place_num=nasal_gc.get_scalar(data_addr).get_number().get_number();
|
||||||
if(place_num>2147483647 || place_num<-2147483648)
|
if(place_num>2147483647 || place_num<-2147483648)
|
||||||
{
|
{
|
||||||
error_interrupt(__normal_call_vector_too_large_value,iter->get_children().front().get_node_line());
|
error_interrupt(__normal_call_vector_too_large_value,iter->get_children().front().get_node_line());
|
||||||
|
@ -2395,6 +2426,7 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
}
|
}
|
||||||
int tmp_addr=addr;
|
int tmp_addr=addr;
|
||||||
addr=func_proc(
|
addr=func_proc(
|
||||||
|
local_scope,
|
||||||
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||||
|
@ -2404,9 +2436,6 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// after calculation or assignment/definition,reference counter of this address will -1
|
|
||||||
// to avoid nasal_gc collecting this address,reference counter+1 here
|
|
||||||
nasal_gc.reference_add(addr);
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
void nasal_runtime::definition(std::list<std::map<std::string,int> >&local_scope,std::map<std::string,int>& now_scope,abstract_syntax_tree& node)
|
void nasal_runtime::definition(std::list<std::map<std::string,int> >&local_scope,std::map<std::string,int>& now_scope,abstract_syntax_tree& node)
|
||||||
|
@ -2841,7 +2870,8 @@ int nasal_runtime::block_proc(std::list<std::map<std::string,int> >& local_scope
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
int nasal_runtime::func_proc(
|
int nasal_runtime::func_proc(
|
||||||
std::list<std::map<std::string,int> >& local_scope,// running scope,often gets the scope that has been recorded in nasal function
|
std::list<std::map<std::string,int> >& local_scope,// running scope,often gets the scope that calls it
|
||||||
|
std::list<std::map<std::string,int> >& function_scope,// running scope,often gets the scope that has been recorded in nasal function
|
||||||
abstract_syntax_tree& parameter_list, // parameter list format of nasal function
|
abstract_syntax_tree& parameter_list, // parameter list format of nasal function
|
||||||
abstract_syntax_tree& func_root, // main runnning block of nasal function
|
abstract_syntax_tree& func_root, // main runnning block of nasal function
|
||||||
abstract_syntax_tree& input_parameters, // input parameters when calling this nasal function
|
abstract_syntax_tree& input_parameters, // input parameters when calling this nasal function
|
||||||
|
@ -2851,6 +2881,12 @@ int nasal_runtime::func_proc(
|
||||||
function_returned_addr=-1;
|
function_returned_addr=-1;
|
||||||
std::map<std::string,int> new_scope;
|
std::map<std::string,int> new_scope;
|
||||||
local_scope.push_back(new_scope);
|
local_scope.push_back(new_scope);
|
||||||
|
for(std::list<std::map<std::string,int> >::iterator i=function_scope.begin();i!=function_scope.end();++i)
|
||||||
|
for(std::map<std::string,int>::iterator j=i->begin();j!=i->end();++j)
|
||||||
|
{
|
||||||
|
local_scope.back()[j->first]=j->second;
|
||||||
|
nasal_gc.reference_delete(j->second);
|
||||||
|
}
|
||||||
if(called_hash_addr>=0)
|
if(called_hash_addr>=0)
|
||||||
local_scope.back()["me"]=called_hash_addr;
|
local_scope.back()["me"]=called_hash_addr;
|
||||||
// loading parameters
|
// loading parameters
|
||||||
|
@ -3016,11 +3052,48 @@ int nasal_runtime::func_proc(
|
||||||
else if(state==__state_no_operation)
|
else if(state==__state_no_operation)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
if(state!=__state_return)
|
||||||
|
{
|
||||||
|
function_returned_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(function_returned_addr).set_type(scalar_nil);
|
||||||
|
}
|
||||||
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i)
|
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i)
|
||||||
nasal_gc.reference_delete(i->second);
|
nasal_gc.reference_delete(i->second);
|
||||||
local_scope.pop_back();
|
local_scope.pop_back();
|
||||||
return function_returned_addr;
|
return function_returned_addr;
|
||||||
}
|
}
|
||||||
|
int nasal_runtime::inline_function(std::list<std::map<std::string,int> >& local_scope,std::string func_name)
|
||||||
|
{
|
||||||
|
int ret_addr=-1;
|
||||||
|
if(func_name=="nasal_call_inline_c_std_puts")
|
||||||
|
{
|
||||||
|
int vector_addr=-1;
|
||||||
|
for(std::list<std::map<std::string,int> >::iterator i=local_scope.begin();i!=local_scope.end();++i)
|
||||||
|
if(i->find("dyn")!=i->end())
|
||||||
|
vector_addr=(*i)["dyn"];
|
||||||
|
if(vector_addr<0)
|
||||||
|
return -1;
|
||||||
|
for(int i=0;i<nasal_gc.get_scalar(vector_addr).get_vector().get_size();++i)
|
||||||
|
{
|
||||||
|
int data_addr=nasal_gc.get_scalar(vector_addr).get_vector().get_elem(i);
|
||||||
|
if(data_addr<0)
|
||||||
|
return -1;
|
||||||
|
switch(nasal_gc.get_scalar(data_addr).get_type())
|
||||||
|
{
|
||||||
|
case scalar_nil:break;
|
||||||
|
case scalar_number:std::cout<<nasal_gc.get_scalar(data_addr).get_number().get_number();break;
|
||||||
|
case scalar_string:std::cout<<nasal_gc.get_scalar(data_addr).get_string().get_string();break;
|
||||||
|
case scalar_vector:std::cout<<"[...]";break;
|
||||||
|
case scalar_hash: std::cout<<"{...}";break;
|
||||||
|
case scalar_function:std::cout<<"func(...){...}";break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout<<std::endl;
|
||||||
|
ret_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(ret_addr).set_type(scalar_nil);
|
||||||
|
}
|
||||||
|
return ret_addr;
|
||||||
|
}
|
||||||
|
|
||||||
void nasal_runtime::main_proc(abstract_syntax_tree& root)
|
void nasal_runtime::main_proc(abstract_syntax_tree& root)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue