add stl & more efficient scope
This commit is contained in:
parent
125fc8a9fe
commit
c88620920b
2
lib.nas
2
lib.nas
|
@ -155,3 +155,5 @@ var math=
|
|||
sqrt: func(x) {return __builtin_sqrt(x); },
|
||||
atan2: func(x,y){return __builtin_atan2(x,y);}
|
||||
};
|
||||
|
||||
var D2R=math.pi/180;
|
177
nasal_builtin.h
177
nasal_builtin.h
|
@ -12,58 +12,52 @@
|
|||
|
||||
std::unordered_map<std::string,int> builtin_use_str;
|
||||
// used to find values that builtin function uses
|
||||
#define builtin_find(name) \
|
||||
(\
|
||||
local_scope\
|
||||
->ptr.scop\
|
||||
->get_val\
|
||||
(builtin_use_str[name])\
|
||||
)
|
||||
#define builtin_find(name) (local_scope[builtin_use_str[name]])
|
||||
|
||||
// declaration of builtin functions
|
||||
// to add new builtin function,declare it here and write the definition below
|
||||
|
||||
nasal_val* builtin_print(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_append(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_setsize(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_system(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_input(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_sleep(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_fin(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_fout(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_split(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_rand(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_id(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_int(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_num(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_pop(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_str(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_size(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_xor(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_and(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_or(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_nand(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_not(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_sin(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_cos(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_tan(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_exp(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_ln(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_sqrt(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_atan2(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_time(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_contains(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_delete(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_getkeys(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_import(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_die(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_type(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_substr(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_streq(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_left(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_right(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_cmp(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_chr(nasal_val*,nasal_gc&);
|
||||
nasal_val* builtin_print(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_append(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_setsize(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_system(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_input(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_sleep(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_fin(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_fout(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_split(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_rand(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_id(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_int(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_num(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_pop(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_str(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_size(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_xor(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_and(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_or(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_nand(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_not(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_sin(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_cos(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_tan(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_exp(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_ln(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_sqrt(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_atan2(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_time(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_contains(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_delete(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_getkeys(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_import(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_die(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_type(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_substr(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_streq(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_left(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_right(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_cmp(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
nasal_val* builtin_chr(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
|
||||
void builtin_err(std::string func_name,std::string info)
|
||||
{
|
||||
|
@ -76,7 +70,7 @@ void builtin_err(std::string func_name,std::string info)
|
|||
struct FUNC_TABLE
|
||||
{
|
||||
std::string name;
|
||||
nasal_val* (*func)(nasal_val* x,nasal_gc&);
|
||||
nasal_val* (*func)(std::unordered_map<int,nasal_val*>&,nasal_gc&);
|
||||
} builtin_func[]=
|
||||
{
|
||||
{"__builtin_std_cout", builtin_print },
|
||||
|
@ -123,7 +117,7 @@ struct FUNC_TABLE
|
|||
{"", nullptr }
|
||||
};
|
||||
|
||||
nasal_val* builtin_print(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_print(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
// get arguments
|
||||
nasal_val* vector_val_addr=builtin_find("elements");
|
||||
|
@ -146,7 +140,7 @@ nasal_val* builtin_print(nasal_val* local_scope,nasal_gc& gc)
|
|||
// generate return value
|
||||
return gc.nil_addr;
|
||||
}
|
||||
nasal_val* builtin_append(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_append(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* vec_addr=builtin_find("vector");
|
||||
nasal_val* elem_addr=builtin_find("elements");
|
||||
|
@ -162,7 +156,7 @@ nasal_val* builtin_append(nasal_val* local_scope,nasal_gc& gc)
|
|||
ref_vec.push_back(ref_elems[i]);
|
||||
return gc.nil_addr;
|
||||
}
|
||||
nasal_val* builtin_setsize(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_setsize(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* vec_addr=builtin_find("vector");
|
||||
nasal_val* size_addr=builtin_find("size");
|
||||
|
@ -193,7 +187,7 @@ nasal_val* builtin_setsize(nasal_val* local_scope,nasal_gc& gc)
|
|||
return gc.nil_addr;
|
||||
}
|
||||
|
||||
nasal_val* builtin_system(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_system(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* str_addr=builtin_find("str");
|
||||
if(str_addr->type!=vm_str)
|
||||
|
@ -205,14 +199,14 @@ nasal_val* builtin_system(nasal_val* local_scope,nasal_gc& gc)
|
|||
return gc.nil_addr;
|
||||
}
|
||||
|
||||
nasal_val* builtin_input(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_input(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* ret_addr=gc.gc_alloc(vm_str);
|
||||
std::cin>>*ret_addr->ptr.str;
|
||||
return ret_addr;
|
||||
}
|
||||
|
||||
nasal_val* builtin_sleep(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_sleep(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("duration");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -225,7 +219,7 @@ nasal_val* builtin_sleep(nasal_val* local_scope,nasal_gc& gc)
|
|||
return gc.nil_addr;
|
||||
}
|
||||
|
||||
nasal_val* builtin_fin(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_fin(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("filename");
|
||||
if(val_addr->type!=vm_str)
|
||||
|
@ -251,7 +245,7 @@ nasal_val* builtin_fin(nasal_val* local_scope,nasal_gc& gc)
|
|||
return ret_addr;
|
||||
}
|
||||
|
||||
nasal_val* builtin_fout(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_fout(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("filename");
|
||||
nasal_val* str_addr=builtin_find("str");
|
||||
|
@ -276,7 +270,7 @@ nasal_val* builtin_fout(nasal_val* local_scope,nasal_gc& gc)
|
|||
return gc.nil_addr;
|
||||
}
|
||||
|
||||
nasal_val* builtin_split(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_split(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* delimeter_val_addr=builtin_find("delimeter");
|
||||
nasal_val* string_val_addr=builtin_find("string");
|
||||
|
@ -344,7 +338,7 @@ nasal_val* builtin_split(nasal_val* local_scope,nasal_gc& gc)
|
|||
}
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_rand(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_rand(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("seed");
|
||||
if(val_addr->type!=vm_num && val_addr->type!=vm_nil)
|
||||
|
@ -364,7 +358,7 @@ nasal_val* builtin_rand(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=num;
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_id(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_id(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("thing");
|
||||
nasal_val* ret_addr=gc.gc_alloc(vm_str);
|
||||
|
@ -373,7 +367,7 @@ nasal_val* builtin_id(nasal_val* local_scope,nasal_gc& gc)
|
|||
*ret_addr->ptr.str=buf;
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_int(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_int(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("value");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -386,7 +380,7 @@ nasal_val* builtin_int(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=(double)number;
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_num(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_num(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("value");
|
||||
if(val_addr->type!=vm_str)
|
||||
|
@ -398,7 +392,7 @@ nasal_val* builtin_num(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=val_addr->to_number();
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_pop(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_pop(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("vector");
|
||||
if(val_addr->type!=vm_vec)
|
||||
|
@ -414,7 +408,7 @@ nasal_val* builtin_pop(nasal_val* local_scope,nasal_gc& gc)
|
|||
}
|
||||
return gc.nil_addr;
|
||||
}
|
||||
nasal_val* builtin_str(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_str(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("number");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -426,7 +420,7 @@ nasal_val* builtin_str(nasal_val* local_scope,nasal_gc& gc)
|
|||
*ret_addr->ptr.str=val_addr->to_string();
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_size(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_size(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("object");
|
||||
nasal_val* ret_addr=gc.gc_alloc(vm_num);
|
||||
|
@ -435,14 +429,13 @@ nasal_val* builtin_size(nasal_val* local_scope,nasal_gc& gc)
|
|||
case vm_nil: ret_addr->ptr.num=0; break;
|
||||
case vm_num: ret_addr->ptr.num=val_addr->ptr.num; break;
|
||||
case vm_func: ret_addr->ptr.num=0; break;
|
||||
case vm_scop: ret_addr->ptr.num=val_addr->ptr.scop->elems.size();break;
|
||||
case vm_str: ret_addr->ptr.num=val_addr->ptr.str->length(); break;
|
||||
case vm_vec: ret_addr->ptr.num=val_addr->ptr.vec->elems.size(); break;
|
||||
case vm_hash: ret_addr->ptr.num=val_addr->ptr.hash->elems.size();break;
|
||||
}
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_xor(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_xor(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* a_addr=builtin_find("a");
|
||||
nasal_val* b_addr=builtin_find("b");
|
||||
|
@ -462,7 +455,7 @@ nasal_val* builtin_xor(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=(number_a^number_b);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_and(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_and(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* a_addr=builtin_find("a");
|
||||
nasal_val* b_addr=builtin_find("b");
|
||||
|
@ -482,7 +475,7 @@ nasal_val* builtin_and(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=(number_a&number_b);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_or(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_or(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* a_addr=builtin_find("a");
|
||||
nasal_val* b_addr=builtin_find("b");
|
||||
|
@ -502,7 +495,7 @@ nasal_val* builtin_or(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=(number_a|number_b);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_nand(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_nand(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* a_addr=builtin_find("a");
|
||||
nasal_val* b_addr=builtin_find("b");
|
||||
|
@ -522,7 +515,7 @@ nasal_val* builtin_nand(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=(~(number_a&number_b));
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_not(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_not(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* a_addr=builtin_find("a");
|
||||
if(a_addr->type!=vm_num)
|
||||
|
@ -535,7 +528,7 @@ nasal_val* builtin_not(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=(~number);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_sin(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_sin(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("x");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -547,7 +540,7 @@ nasal_val* builtin_sin(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=sin(val_addr->ptr.num);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_cos(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_cos(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("x");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -559,7 +552,7 @@ nasal_val* builtin_cos(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=cos(val_addr->ptr.num);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_tan(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_tan(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("x");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -571,7 +564,7 @@ nasal_val* builtin_tan(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=tan(val_addr->ptr.num);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_exp(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_exp(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("x");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -583,7 +576,7 @@ nasal_val* builtin_exp(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=exp(val_addr->ptr.num);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_ln(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_ln(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("x");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -595,7 +588,7 @@ nasal_val* builtin_ln(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=(log(val_addr->ptr.num)/log(2.7182818284590452354));
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_sqrt(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_sqrt(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("x");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -607,7 +600,7 @@ nasal_val* builtin_sqrt(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=sqrt(val_addr->ptr.num);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_atan2(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_atan2(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* x_val_addr=builtin_find("x");
|
||||
nasal_val* y_val_addr=builtin_find("y");
|
||||
|
@ -625,7 +618,7 @@ nasal_val* builtin_atan2(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=atan2(y_val_addr->ptr.num,x_val_addr->ptr.num);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_time(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_time(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("begin_time");
|
||||
if(val_addr->type!=vm_num)
|
||||
|
@ -638,7 +631,7 @@ nasal_val* builtin_time(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=time(&begin_time);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_contains(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_contains(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* hash_addr=builtin_find("hash");
|
||||
nasal_val* key_addr=builtin_find("key");
|
||||
|
@ -656,7 +649,7 @@ nasal_val* builtin_contains(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=hash_addr->ptr.hash->check_contain(*key_addr->ptr.str);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_delete(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_delete(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* hash_addr=builtin_find("hash");
|
||||
nasal_val* key_addr=builtin_find("key");
|
||||
|
@ -674,7 +667,7 @@ nasal_val* builtin_delete(nasal_val* local_scope,nasal_gc& gc)
|
|||
hash_addr->ptr.hash->elems.erase(*key_addr->ptr.str);
|
||||
return gc.nil_addr;
|
||||
}
|
||||
nasal_val* builtin_getkeys(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_getkeys(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* hash_addr=builtin_find("hash");
|
||||
if(hash_addr->type!=vm_hash)
|
||||
|
@ -693,14 +686,14 @@ nasal_val* builtin_getkeys(nasal_val* local_scope,nasal_gc& gc)
|
|||
}
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_import(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_import(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
// this function is used in preprocessing.
|
||||
// this function will return nothing when running.
|
||||
builtin_err("import","cannot use import when running");
|
||||
return nullptr;
|
||||
}
|
||||
nasal_val* builtin_die(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_die(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* str_addr=builtin_find("str");
|
||||
if(str_addr->type!=vm_str)
|
||||
|
@ -708,10 +701,10 @@ nasal_val* builtin_die(nasal_val* local_scope,nasal_gc& gc)
|
|||
builtin_err("die","\"str\" must be string");
|
||||
return nullptr;
|
||||
}
|
||||
std::cout<<">> [vm] error: "<<str_addr->ptr.str<<'\n';
|
||||
std::cout<<">> [vm] error: "<<*str_addr->ptr.str<<'\n';
|
||||
return nullptr;
|
||||
}
|
||||
nasal_val* builtin_type(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_type(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* val_addr=builtin_find("object");
|
||||
nasal_val* ret_addr=gc.gc_alloc(vm_str);
|
||||
|
@ -726,7 +719,7 @@ nasal_val* builtin_type(nasal_val* local_scope,nasal_gc& gc)
|
|||
}
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_substr(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_substr(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* str_addr=builtin_find("str");
|
||||
nasal_val* beg_addr=builtin_find("begin");
|
||||
|
@ -760,7 +753,7 @@ nasal_val* builtin_substr(nasal_val* local_scope,nasal_gc& gc)
|
|||
*ret_addr->ptr.str=str.substr(beg,len);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_streq(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_streq(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* a_addr=builtin_find("a");
|
||||
nasal_val* b_addr=builtin_find("b");
|
||||
|
@ -768,7 +761,7 @@ nasal_val* builtin_streq(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=(a_addr->type!=vm_str || b_addr->type!=vm_str)?0:(*a_addr->ptr.str==*b_addr->ptr.str);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_left(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_left(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* str_addr=builtin_find("string");
|
||||
nasal_val* len_addr=builtin_find("length");
|
||||
|
@ -790,7 +783,7 @@ nasal_val* builtin_left(nasal_val* local_scope,nasal_gc& gc)
|
|||
*ret_addr->ptr.str=str.substr(0, len);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_right(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_right(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* str_addr=builtin_find("string");
|
||||
nasal_val* len_addr=builtin_find("length");
|
||||
|
@ -815,7 +808,7 @@ nasal_val* builtin_right(nasal_val* local_scope,nasal_gc& gc)
|
|||
*ret_addr->ptr.str=str.substr(srclen-len, srclen);
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_cmp(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_cmp(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* a_addr=builtin_find("a");
|
||||
nasal_val* b_addr=builtin_find("b");
|
||||
|
@ -833,7 +826,7 @@ nasal_val* builtin_cmp(nasal_val* local_scope,nasal_gc& gc)
|
|||
ret_addr->ptr.num=strcmp(a_addr->ptr.str->data(),b_addr->ptr.str->data());
|
||||
return ret_addr;
|
||||
}
|
||||
nasal_val* builtin_chr(nasal_val* local_scope,nasal_gc& gc)
|
||||
nasal_val* builtin_chr(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
nasal_val* code_addr=builtin_find("code");
|
||||
if(code_addr->type!=vm_num)
|
||||
|
|
|
@ -395,7 +395,7 @@ void nasal_codegen::func_gen(nasal_ast& ast)
|
|||
}
|
||||
}
|
||||
exec_code[newfunc_label].num=exec_code.size()+1;
|
||||
int ptr=exec_code.size();
|
||||
int jmp_ptr=exec_code.size();
|
||||
gen(op_jmp,0);
|
||||
nasal_ast& block=ast.get_children()[1];
|
||||
|
||||
|
@ -407,7 +407,7 @@ void nasal_codegen::func_gen(nasal_ast& ast)
|
|||
nil_gen();
|
||||
gen(op_ret,0);
|
||||
}
|
||||
exec_code[ptr].num=exec_code.size();
|
||||
exec_code[jmp_ptr].num=exec_code.size();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
52
nasal_gc.h
52
nasal_gc.h
|
@ -6,7 +6,6 @@ enum nasal_type
|
|||
vm_nil=0,
|
||||
vm_num,
|
||||
vm_str,
|
||||
vm_scop,
|
||||
vm_func,
|
||||
vm_vec,
|
||||
vm_hash
|
||||
|
@ -48,14 +47,6 @@ struct nasal_func
|
|||
nasal_func();
|
||||
};
|
||||
|
||||
struct nasal_scop
|
||||
{
|
||||
std::unordered_map<int,nasal_val*> elems;
|
||||
|
||||
nasal_val* get_val(int);
|
||||
nasal_val** get_mem(int);
|
||||
};
|
||||
|
||||
struct nasal_val
|
||||
{
|
||||
bool mark;
|
||||
|
@ -67,7 +58,6 @@ struct nasal_val
|
|||
nasal_vec* vec;
|
||||
nasal_hash* hash;
|
||||
nasal_func* func;
|
||||
nasal_scop* scop;
|
||||
}ptr;
|
||||
|
||||
nasal_val();
|
||||
|
@ -232,20 +222,6 @@ nasal_func::nasal_func()
|
|||
return;
|
||||
}
|
||||
|
||||
/*functions of nasal_scop*/
|
||||
nasal_val* nasal_scop::get_val(int key)
|
||||
{
|
||||
if(elems.count(key))
|
||||
return elems[key];
|
||||
return nullptr;
|
||||
}
|
||||
nasal_val** nasal_scop::get_mem(int key)
|
||||
{
|
||||
if(elems.count(key))
|
||||
return &(elems[key]);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*functions of nasal_val*/
|
||||
nasal_val::nasal_val()
|
||||
{
|
||||
|
@ -264,7 +240,6 @@ nasal_val::nasal_val(int val_type)
|
|||
case vm_vec: ptr.vec=new nasal_vec; break;
|
||||
case vm_hash: ptr.hash=new nasal_hash; break;
|
||||
case vm_func: ptr.func=new nasal_func; break;
|
||||
case vm_scop: ptr.scop=new nasal_scop; break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -276,7 +251,6 @@ nasal_val::~nasal_val()
|
|||
case vm_vec: delete ptr.vec; break;
|
||||
case vm_hash: delete ptr.hash; break;
|
||||
case vm_func: delete ptr.func; break;
|
||||
case vm_scop: delete ptr.scop; break;
|
||||
}
|
||||
type=vm_nil;
|
||||
return;
|
||||
|
@ -289,7 +263,6 @@ void nasal_val::clear()
|
|||
case vm_vec: delete ptr.vec; break;
|
||||
case vm_hash: delete ptr.hash; break;
|
||||
case vm_func: delete ptr.func; break;
|
||||
case vm_scop: delete ptr.scop; break;
|
||||
}
|
||||
type=vm_nil;
|
||||
return;
|
||||
|
@ -304,7 +277,6 @@ void nasal_val::set_type(int val_type)
|
|||
case vm_vec: ptr.vec=new nasal_vec; break;
|
||||
case vm_hash: ptr.hash=new nasal_hash; break;
|
||||
case vm_func: ptr.func=new nasal_func; break;
|
||||
case vm_scop: ptr.scop=new nasal_scop; break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -329,14 +301,14 @@ struct nasal_gc
|
|||
nasal_val* zero_addr; // reserved address of nasal_val,type vm_num, 0
|
||||
nasal_val* one_addr; // reserved address of nasal_val,type vm_num, 1
|
||||
nasal_val* nil_addr; // reserved address of nasal_val,type vm_nil
|
||||
nasal_val* global; // global scope address,type vm_scop
|
||||
nasal_val* val_stack[STACK_MAX_DEPTH];
|
||||
nasal_val** stack_top; // stack top
|
||||
std::vector<nasal_val*> num_addrs; // reserved address for const vm_num
|
||||
std::vector<nasal_val*> local; // local scope for function block
|
||||
std::vector<nasal_val*> slice_stack; // slice stack for vec[val,val,val:val]
|
||||
std::vector<nasal_val*> memory; // gc memory
|
||||
std::queue <nasal_val*> free_list; // gc free list
|
||||
std::unordered_map<int,nasal_val*> global;
|
||||
std::vector<std::unordered_map<int,nasal_val*> > local;
|
||||
void mark();
|
||||
void sweep();
|
||||
void gc_init(std::vector<double>&);
|
||||
|
@ -351,14 +323,16 @@ void nasal_gc::mark()
|
|||
zero_addr->mark=true;
|
||||
one_addr->mark=true;
|
||||
nil_addr->mark=true;
|
||||
bfs.push(global);
|
||||
for(auto i=global.begin();i!=global.end();++i)
|
||||
bfs.push(i->second);
|
||||
|
||||
int size=num_addrs.size();
|
||||
for(int i=0;i<size;++i)
|
||||
bfs.push(num_addrs[i]);
|
||||
size=local.size();
|
||||
for(int i=0;i<size;++i)
|
||||
bfs.push(local[i]);
|
||||
for(auto i=local.begin();i!=local.end();++i)
|
||||
for(auto j=i->begin();j!=i->end();++j)
|
||||
bfs.push(j->second);
|
||||
size=slice_stack.size();
|
||||
for(int i=0;i<size;++i)
|
||||
bfs.push(slice_stack[i]);
|
||||
|
@ -395,13 +369,6 @@ void nasal_gc::mark()
|
|||
if(*i && !(*i)->mark)
|
||||
bfs.push(*i);
|
||||
}
|
||||
else if(tmp->type==vm_scop)
|
||||
{
|
||||
std::unordered_map<int,nasal_val*>& scop=tmp->ptr.scop->elems;
|
||||
for(auto i=scop.begin();i!=scop.end();++i)
|
||||
if(!i->second->mark)
|
||||
bfs.push(i->second);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -442,9 +409,6 @@ void nasal_gc::gc_init(std::vector<double>& nums)
|
|||
|
||||
*val_stack=nil_addr; // the first space will not store any values,but gc checks
|
||||
|
||||
global=new nasal_val(vm_scop); // init global symbol table
|
||||
memory.push_back(global);
|
||||
|
||||
num_addrs.clear(); // init constant numbers
|
||||
for(int i=0;i<nums.size();++i)
|
||||
{
|
||||
|
@ -465,7 +429,7 @@ void nasal_gc::gc_clear()
|
|||
memory.clear();
|
||||
while(!free_list.empty())
|
||||
free_list.pop();
|
||||
global=nullptr;
|
||||
global.clear();
|
||||
local.clear();
|
||||
slice_stack.clear();
|
||||
return;
|
||||
|
|
23
nasal_vm.h
23
nasal_vm.h
|
@ -152,12 +152,12 @@ void nasal_vm::opr_nop()
|
|||
}
|
||||
void nasal_vm::opr_loadg()
|
||||
{
|
||||
gc.global->ptr.scop->elems[exec_code[pc].num]=*stack_top--;
|
||||
gc.global[exec_code[pc].num]=*stack_top--;
|
||||
return;
|
||||
}
|
||||
void nasal_vm::opr_loadl()
|
||||
{
|
||||
gc.local.back()->ptr.scop->elems[exec_code[pc].num]=*stack_top--;
|
||||
gc.local.back()[exec_code[pc].num]=*stack_top--;
|
||||
return;
|
||||
}
|
||||
void nasal_vm::opr_pnum()
|
||||
|
@ -204,7 +204,7 @@ void nasal_vm::opr_newf()
|
|||
nasal_val* val=gc.gc_alloc(vm_func);
|
||||
val->ptr.func->entry=exec_code[pc].num;
|
||||
if(!gc.local.empty())
|
||||
val->ptr.func->closure=gc.local.back()->ptr.scop->elems;
|
||||
val->ptr.func->closure=gc.local.back();
|
||||
val->ptr.func->closure[me]=gc.nil_addr;
|
||||
*(++stack_top)=val;
|
||||
return;
|
||||
|
@ -525,12 +525,12 @@ void nasal_vm::opr_feach()
|
|||
}
|
||||
void nasal_vm::opr_callg()
|
||||
{
|
||||
*(++stack_top)=gc.global->ptr.scop->elems[exec_code[pc].num];
|
||||
*(++stack_top)=gc.global[exec_code[pc].num];
|
||||
return;
|
||||
}
|
||||
void nasal_vm::opr_calll()
|
||||
{
|
||||
*(++stack_top)=gc.local.back()->ptr.scop->elems[exec_code[pc].num];
|
||||
*(++stack_top)=gc.local.back()[exec_code[pc].num];
|
||||
return;
|
||||
}
|
||||
void nasal_vm::opr_callv()
|
||||
|
@ -633,14 +633,12 @@ void nasal_vm::opr_callf()
|
|||
return;
|
||||
}
|
||||
// push new local scope
|
||||
nasal_val* closure=gc.gc_alloc(vm_scop);
|
||||
gc.local.push_back(closure);
|
||||
gc.local.push_back(func_addr->ptr.func->closure);
|
||||
// load parameters
|
||||
nasal_func& ref_func=*func_addr->ptr.func;
|
||||
std::vector<int>& ref_para=ref_func.para;
|
||||
std::vector<nasal_val*>& ref_default=ref_func.default_para;
|
||||
std::unordered_map<int,nasal_val*>& ref_closure=closure->ptr.scop->elems;
|
||||
ref_closure=ref_func.closure;
|
||||
std::unordered_map<int,nasal_val*>& ref_closure=gc.local.back();
|
||||
|
||||
if(para_addr->type==vm_vec)
|
||||
{
|
||||
|
@ -677,7 +675,8 @@ void nasal_vm::opr_callf()
|
|||
die("callf: special call cannot use dynamic parameter");
|
||||
return;
|
||||
}
|
||||
for(int i=0;i<ref_para.size();++i)
|
||||
int para_size=ref_para.size();
|
||||
for(int i=0;i<para_size;++i)
|
||||
{
|
||||
std::string& sym=str_table[ref_para[i]];
|
||||
if(ref_hash.count(sym))
|
||||
|
@ -770,12 +769,12 @@ void nasal_vm::opr_slc2()
|
|||
}
|
||||
void nasal_vm::opr_mcallg()
|
||||
{
|
||||
addr_stack.push(&gc.global->ptr.scop->elems[exec_code[pc].num]);
|
||||
addr_stack.push(&gc.global[exec_code[pc].num]);
|
||||
return;
|
||||
}
|
||||
void nasal_vm::opr_mcalll()
|
||||
{
|
||||
addr_stack.push(&gc.local.back()->ptr.scop->elems[exec_code[pc].num]);
|
||||
addr_stack.push(&gc.local.back()[exec_code[pc].num]);
|
||||
return;
|
||||
}
|
||||
void nasal_vm::opr_mcallv()
|
||||
|
|
|
@ -155,3 +155,5 @@ var math=
|
|||
sqrt: func(x) {return __builtin_sqrt(x); },
|
||||
atan2: func(x,y){return __builtin_atan2(x,y);}
|
||||
};
|
||||
|
||||
var D2R=math.pi/180;
|
|
@ -0,0 +1,73 @@
|
|||
# lib list.nas
|
||||
# valkmjolnir 2021/3/31
|
||||
var list=func()
|
||||
{
|
||||
var _={begin:nil,end:nil};
|
||||
return
|
||||
{
|
||||
push_back:func(elem)
|
||||
{
|
||||
var tmp={elem:elem,prev:nil,next:nil};
|
||||
if(_.end!=nil)
|
||||
{
|
||||
_.end.next=tmp;
|
||||
tmp.prev=_.end;
|
||||
_.end=tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
_.begin=tmp;
|
||||
_.end=tmp;
|
||||
}
|
||||
return;
|
||||
},
|
||||
push_front:func(elem)
|
||||
{
|
||||
var tmp={elem:elem,prev:nil,next:nil};
|
||||
if(_.begin!=nil)
|
||||
{
|
||||
_.begin.prev=tmp;
|
||||
tmp.next=_.begin;
|
||||
_.begin=tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
_.begin=tmp;
|
||||
_.end=tmp;
|
||||
}
|
||||
return;
|
||||
},
|
||||
pop_back:func()
|
||||
{
|
||||
if(_.end!=nil)
|
||||
_.end=_.end.prev;
|
||||
if(_.end==nil)
|
||||
_.begin=nil;
|
||||
else
|
||||
_.end.next=nil;
|
||||
return;
|
||||
},
|
||||
pop_front:func()
|
||||
{
|
||||
if(_.begin!=nil)
|
||||
_.begin=_.begin.next;
|
||||
if(_.begin==nil)
|
||||
_.end=nil;
|
||||
else
|
||||
_.begin.prev=nil;
|
||||
return;
|
||||
},
|
||||
front:func()
|
||||
{
|
||||
if(_.begin!=nil)
|
||||
return _.begin.elem;
|
||||
return nil;
|
||||
},
|
||||
back:func()
|
||||
{
|
||||
if(_.end!=nil)
|
||||
return _.end.elem;
|
||||
return nil;
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
# lib sort.nas
|
||||
# valkmjolnir 2021/4/2
|
||||
var sort=func(vec,left,right,cmp=func(a,b){return a<=b;})
|
||||
{
|
||||
if(left>=right) return nil;
|
||||
var L=left;
|
||||
var R=right;
|
||||
var tmp=vec[L];
|
||||
while(left<right)
|
||||
{
|
||||
while(left<right and cmp(tmp,vec[right]))
|
||||
right-=1;
|
||||
while(left<right and cmp(vec[left],tmp))
|
||||
left+=1;
|
||||
if(left!=right)
|
||||
{
|
||||
var t=vec[left];
|
||||
vec[left]=vec[right];
|
||||
vec[right]=t;
|
||||
}
|
||||
}
|
||||
vec[L]=vec[left];
|
||||
vec[left]=tmp;
|
||||
sort(vec,L,left-1,cmp);
|
||||
sort(vec,left+1,R,cmp);
|
||||
return nil;
|
||||
}
|
331
test/ai.nas
331
test/ai.nas
|
@ -1,331 +0,0 @@
|
|||
import("lib.nas");
|
||||
var activate_function=
|
||||
{
|
||||
sigmoid_func:func(x)
|
||||
{
|
||||
return 1.0/(1.0+math.exp(-x));
|
||||
},
|
||||
diffsigmoid_func:func(x)
|
||||
{
|
||||
var t=func(x){return 1.0/(1.0+math.exp(-x));}(x);
|
||||
return t*(1-t);
|
||||
},
|
||||
tanh_func:func(x)
|
||||
{
|
||||
var t1=math.exp(x);
|
||||
var t2=math.exp(-x);
|
||||
return (t1-t2)/(t1+t2);
|
||||
},
|
||||
difftanh_func:func(x)
|
||||
{
|
||||
var t1=math.exp(x);
|
||||
var t2=math.exp(-x);
|
||||
var t=(t1-t2)/(t1+t2);
|
||||
return 1-t*t;
|
||||
},
|
||||
relu_func:func(x)
|
||||
{
|
||||
return x>0? x:0;
|
||||
},
|
||||
diffrelu_func:func(x)
|
||||
{
|
||||
return x>0;
|
||||
},
|
||||
leaky_relu_func:func(k,x)
|
||||
{
|
||||
return x>0? x:k*x;
|
||||
},
|
||||
diffleaky_relu_func:func(k,x)
|
||||
{
|
||||
return x>0? 1:k;
|
||||
}
|
||||
};
|
||||
|
||||
var matrix=
|
||||
{
|
||||
new:func(col,row)
|
||||
{
|
||||
var new_mat=
|
||||
{
|
||||
col:col,
|
||||
row:row,
|
||||
mat:[]
|
||||
};
|
||||
for(var i=0;i<row;i+=1)
|
||||
{
|
||||
append(new_mat.mat,[]);
|
||||
for(var j=0;j<col;j+=1)
|
||||
append(new_mat.mat[i],nil);
|
||||
}
|
||||
return new_mat;
|
||||
},
|
||||
srand:func(x)
|
||||
{
|
||||
rand(x);
|
||||
return nil;
|
||||
},
|
||||
rand_init:func(mat)
|
||||
{
|
||||
for(var i=0;i<mat.row;i+=1)
|
||||
for(var j=0;j<mat.col;j+=1)
|
||||
{
|
||||
if(rand()>0.5)
|
||||
mat.mat[i][j]=-rand();
|
||||
else
|
||||
mat.mat[i][j]=rand();
|
||||
}
|
||||
return;
|
||||
},
|
||||
prt_mat:func(mat)
|
||||
{
|
||||
var prt_s='[\n';
|
||||
foreach(var i;mat.mat)
|
||||
{
|
||||
prt_s~='[';
|
||||
foreach(var j;i)
|
||||
prt_s~=(j~',');
|
||||
prt_s~='],\n';
|
||||
}
|
||||
prt_s~=']\n';
|
||||
print(prt_s);
|
||||
return nil;
|
||||
},
|
||||
mult_mat:func(mat1,mat2)
|
||||
{
|
||||
if(mat1.col!=mat2.row)
|
||||
{
|
||||
die("[error-mult] mat1\'s col does not match mat2\'s row.");
|
||||
return nil;
|
||||
}
|
||||
var new_mat=me.new(mat2.col,mat1.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
{
|
||||
var sum=0;
|
||||
for(var k=0;k<mat1.col;k+=1)
|
||||
sum+=mat1.mat[i][k]*mat2.mat[k][j];
|
||||
new_mat.mat[i][j]=sum;
|
||||
}
|
||||
return new_mat;
|
||||
},
|
||||
add_mat:func(mat1,mat2)
|
||||
{
|
||||
if(mat1.col!=mat2.col or mat1.row!=mat2.row)
|
||||
{
|
||||
die("[error-add] mat1\'s col or row does not match mat2\'s.");
|
||||
return nil;
|
||||
}
|
||||
var new_mat=me.new(mat1.col,mat1.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=mat1.mat[i][j]+mat2.mat[i][j];
|
||||
return new_mat;
|
||||
},
|
||||
sub_mat:func(mat1,mat2)
|
||||
{
|
||||
if(mat1.col!=mat2.col or mat1.row!=mat2.row)
|
||||
{
|
||||
die("[error-sub] mat1\'s col or row does not match mat2\'s.");
|
||||
return nil;
|
||||
}
|
||||
var new_mat=me.new(mat1.col,mat1.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=mat1.mat[i][j]-mat2.mat[i][j];
|
||||
return new_mat;
|
||||
},
|
||||
hadamard:func(mat1,mat2)
|
||||
{
|
||||
if(mat1.col!=mat2.col or mat1.row!=mat2.row)
|
||||
{
|
||||
die("[error-hadamard] mat1\'s col or row does not match mat2\'s.");
|
||||
return nil;
|
||||
}
|
||||
var new_mat=me.new(mat1.col,mat1.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=mat1.mat[i][j]*mat2.mat[i][j];
|
||||
return new_mat;
|
||||
},
|
||||
transpose:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.row,mat.col);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=mat.mat[j][i];
|
||||
return new_mat;
|
||||
},
|
||||
sigmoid:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.sigmoid_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
diffsigmoid:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.diffsigmoid_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
tanh:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.tanh_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
difftanh:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.difftanh_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
relu:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.relu_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
diffrelu:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.diffrelu_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
leaky_relu:func(k,mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.leaky_relu_func(k,mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
diffleaky_relu:func(k,mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.diffleaky_relu_func(k,mat.mat[i][j]);
|
||||
return new_mat;
|
||||
}
|
||||
};
|
||||
|
||||
var bp=
|
||||
{
|
||||
inum:2,
|
||||
hnum:4,
|
||||
onum:1,
|
||||
learning_rate:nil,
|
||||
hidden_layer:nil,
|
||||
hidden_res:nil,
|
||||
output_layer:nil,
|
||||
output_res:nil,
|
||||
result:nil,
|
||||
training_set:[],
|
||||
expect_set:[],
|
||||
init:func()
|
||||
{
|
||||
matrix.srand(time(0));
|
||||
me.hidden_layer=matrix.new(me.hnum,me.inum);
|
||||
matrix.rand_init(me.hidden_layer);
|
||||
me.output_layer=matrix.new(me.onum,me.hnum);
|
||||
matrix.rand_init(me.output_layer);
|
||||
return;
|
||||
},
|
||||
set_learning_rate:func(lr)
|
||||
{
|
||||
me.learning_rate=matrix.new(me.onum,1);
|
||||
for(var i=0;i<me.onum;i+=1)
|
||||
me.learning_rate.mat[i][0]=lr;
|
||||
return;
|
||||
},
|
||||
set_training_set:func()
|
||||
{
|
||||
for(var i=0;i<4;i+=1)
|
||||
append(me.training_set,matrix.new(me.inum,1));
|
||||
me.training_set[0].mat[0][0]=0;
|
||||
me.training_set[0].mat[0][1]=0;
|
||||
me.training_set[1].mat[0][0]=0;
|
||||
me.training_set[1].mat[0][1]=1;
|
||||
me.training_set[2].mat[0][0]=1;
|
||||
me.training_set[2].mat[0][1]=0;
|
||||
me.training_set[3].mat[0][0]=1;
|
||||
me.training_set[3].mat[0][1]=1;
|
||||
return;
|
||||
},
|
||||
set_expect_set:func()
|
||||
{
|
||||
for(var i=0;i<4;i+=1)
|
||||
append(me.expect_set,matrix.new(me.onum,1))
|
||||
me.expect_set[0].mat[0][0]=0;
|
||||
me.expect_set[1].mat[0][0]=1;
|
||||
me.expect_set[2].mat[0][0]=1;
|
||||
me.expect_set[3].mat[0][0]=0;
|
||||
return;
|
||||
},
|
||||
forward:func(i)
|
||||
{
|
||||
var tmp=nil;
|
||||
me.hidden_res=matrix.mult_mat(me.training_set[i],me.hidden_layer);
|
||||
tmp=matrix.sigmoid(me.hidden_res);
|
||||
me.output_res=matrix.mult_mat(tmp,me.output_layer);
|
||||
tmp=matrix.sigmoid(me.output_res);
|
||||
me.result=tmp;
|
||||
return;
|
||||
},
|
||||
backward:func(i)
|
||||
{
|
||||
var output_diff=matrix.sub_mat(me.expect_set[i],me.result);
|
||||
output_diff=matrix.hadamard(output_diff,me.learning_rate);
|
||||
output_diff=matrix.hadamard(output_diff,matrix.diffsigmoid(me.output_res));
|
||||
output_diff=matrix.mult_mat(output_diff,matrix.transpose(me.output_layer));
|
||||
matrix.prt_mat(output_diff);
|
||||
var hidden_diff=matrix.mult_mat();
|
||||
matrix.prt_mat(hidden_diff);
|
||||
|
||||
me.output_layer=matrix.add_mat(me.output_layer,output_diff);
|
||||
var error=0;
|
||||
foreach(var i;me.result.mat[0])
|
||||
error+=i;
|
||||
error*=0.5;
|
||||
return error;
|
||||
},
|
||||
training_process:func()
|
||||
{
|
||||
var cnt=0;
|
||||
var error=1e8;
|
||||
while(error>0.01)
|
||||
{
|
||||
error=0;
|
||||
for(var i=0;i<4;i+=1)
|
||||
{
|
||||
me.forward(i);
|
||||
error+=me.backward(i);
|
||||
}
|
||||
print(error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
var main=func()
|
||||
{
|
||||
bp.init();
|
||||
bp.set_learning_rate(0.1);
|
||||
bp.set_training_set();
|
||||
bp.set_expect_set();
|
||||
bp.training_process();
|
||||
return nil;
|
||||
}
|
||||
|
||||
main();
|
|
@ -1,5 +1,8 @@
|
|||
# Road check and auto pilot(??) by ValKmjolnir
|
||||
|
||||
# Road check and auto pilot by ValKmjolnir
|
||||
var dt=0.01;
|
||||
var intergral=0;
|
||||
var derivative=0;
|
||||
var previous_error=0;
|
||||
var position_change = func(position_val,value){
|
||||
if(position_val+value>180)
|
||||
position_val += value-360;
|
||||
|
@ -10,12 +13,11 @@ var position_change = func(position_val,value){
|
|||
return position_val;
|
||||
}
|
||||
var road_check_func = func(){
|
||||
|
||||
|
||||
var lat = props.getNode("/position/latitude-deg",1).getValue();
|
||||
var lon = props.getNode("/position/longitude-deg",1).getValue();
|
||||
var position_info = geodinfo(lat,lon);
|
||||
var position_names = position_info[1].names;
|
||||
# the friction_factor of freeway runway and road is 1
|
||||
|
||||
if((position_names[0]=="Freeway") or (position_names[0]=="Road"))
|
||||
{
|
||||
|
@ -24,14 +26,14 @@ var road_check_func = func(){
|
|||
var lon_change = 0;
|
||||
var left_range = 0;
|
||||
var right_range = 0;
|
||||
|
||||
|
||||
for(var i=0;i>-0.00005;i-=0.000001)
|
||||
{
|
||||
car_heading = props.getNode("/orientation/heading-deg",1).getValue();
|
||||
lat_change = math.sin(math.pi*car_heading/180);
|
||||
lon_change = -math.cos(math.pi*car_heading/180);
|
||||
lat = props.getNode("/position/latitude-deg",1).getValue()+0.0001*math.cos(math.pi*car_heading/180);
|
||||
lon = props.getNode("/position/longitude-deg",1).getValue()+0.0001*math.sin(math.pi*car_heading/180);
|
||||
lat_change = math.sin(D2R*car_heading);
|
||||
lon_change = -math.cos(D2R*car_heading);
|
||||
lat = props.getNode("/position/latitude-deg",1).getValue()+0.0001*math.cos(D2R*car_heading);
|
||||
lon = props.getNode("/position/longitude-deg",1).getValue()+0.0001*math.sin(D2R*car_heading);
|
||||
var other_position_info = geodinfo(position_change(lat,i*lat_change),position_change(lon,i*lon_change));
|
||||
var other_names = other_position_info[1].names;
|
||||
if((other_names[0]=="Freeway") or (other_names[0]=="Road"))
|
||||
|
@ -42,10 +44,10 @@ var road_check_func = func(){
|
|||
for(var i=0;i<0.00005;i+=0.000001)
|
||||
{
|
||||
car_heading = props.getNode("/orientation/heading-deg",1).getValue();
|
||||
lat_change = math.sin(math.pi*car_heading/180);
|
||||
lon_change = -math.cos(math.pi*car_heading/180);
|
||||
lat = props.getNode("/position/latitude-deg",1).getValue()+0.0001*math.cos(math.pi*car_heading/180);
|
||||
lon = props.getNode("/position/longitude-deg",1).getValue()+0.0001*math.sin(math.pi*car_heading/180);
|
||||
lat_change = math.sin(D2R*car_heading);
|
||||
lon_change = -math.cos(D2R*car_heading);
|
||||
lat = props.getNode("/position/latitude-deg",1).getValue()+0.0001*math.cos(D2R*car_heading);
|
||||
lon = props.getNode("/position/longitude-deg",1).getValue()+0.0001*math.sin(D2R*car_heading);
|
||||
var other_position_info = geodinfo(position_change(lat,i*lat_change),position_change(lon,i*lon_change));
|
||||
var other_names = other_position_info[1].names;
|
||||
if((other_names[0]=="Freeway") or (other_names[0]=="Road"))
|
||||
|
@ -53,25 +55,26 @@ var road_check_func = func(){
|
|||
else
|
||||
break;
|
||||
}
|
||||
#if(left_range>right_range)
|
||||
#{
|
||||
# setprop("/controls/flight/rudder",-(right_range-left_range)*(right_range-left_range)/10000);
|
||||
# print("right ",right_range);
|
||||
#}
|
||||
#else if(left_range<right_range)
|
||||
#{
|
||||
# setprop("/controls/flight/rudder",(right_range-left_range)*(right_range-left_range)/10000);
|
||||
# print("left ",left_range);
|
||||
#}
|
||||
#else
|
||||
# setprop("/controls/flight/rudder",0);
|
||||
props.getNode("/controls/flight/rudder",1).setValue((right_range-left_range)/200);
|
||||
var error=right_range-left_range;
|
||||
intergral+=error*dt;
|
||||
derivative=(error-previous_error)/dt;
|
||||
var (Kp,Ki,Kd)=(1/900,0.05,0.005);
|
||||
# print("change p ",Kp*error*error,' i ',Ki*intergral,' d ',Kd*derivative);
|
||||
if(error<0)
|
||||
props.getNode("/", 1).setValue("/controls/flight/rudder",-Kp*error*error+Ki*intergral+Kd*derivative);
|
||||
else if(error>0)
|
||||
props.getNode("/", 1).setValue("/controls/flight/rudder",Kp*error*error+Ki*intergral+Kd*derivative);
|
||||
else
|
||||
props.getNode("/", 1).setValue("/controls/flight/rudder",0);
|
||||
previous_error=error;
|
||||
}
|
||||
};
|
||||
var road_check_timer = maketimer(0.1,road_check_func);
|
||||
|
||||
var road_check_timer = maketimer(0.01,road_check_func);
|
||||
var toggle_auto_pilot = func(){
|
||||
if(!road_check_timer.isRunning)
|
||||
{
|
||||
intergral=0;
|
||||
road_check_timer.start();
|
||||
props.getNode("/sim/messages/copilot",1).setValue("ze dong sheng teaan see tong yee tse yung. Auto Sheng Teaan System Activated!");
|
||||
}
|
||||
|
@ -80,4 +83,4 @@ var toggle_auto_pilot = func(){
|
|||
road_check_timer.stop();
|
||||
props.getNode("/sim/messages/copilot",1).setValue("ze dong sheng teaan see tong yee guan bee. Auto Sheng Teaan System is off.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
test/bfs.nas
16
test/bfs.nas
|
@ -1,5 +1,5 @@
|
|||
import("lib.nas");
|
||||
import("queue.nas");
|
||||
import("stl/lib.nas");
|
||||
import("stl/queue.nas");
|
||||
|
||||
rand(time(0));
|
||||
|
||||
|
@ -26,13 +26,13 @@ var prt=func()
|
|||
var bfs=func(begin,end)
|
||||
{
|
||||
var move=[[1,0],[0,1],[-1,0],[0,-1]];
|
||||
var queue=new_queue();
|
||||
queue_push(queue,begin);
|
||||
var que=queue();
|
||||
que.push(begin);
|
||||
map[begin[0]][begin[1]]=3;
|
||||
while(!queue_empty(queue))
|
||||
while(!que.empty())
|
||||
{
|
||||
var vertex=queue_front(queue);
|
||||
queue_pop(queue);
|
||||
var vertex=que.front();
|
||||
que.pop();
|
||||
foreach(var i;move)
|
||||
{
|
||||
var x=vertex[0]+i[0];
|
||||
|
@ -44,7 +44,7 @@ var bfs=func(begin,end)
|
|||
}
|
||||
if(0<=x and x<10 and 0<=y and y<10 and map[x][y]==0)
|
||||
{
|
||||
queue_push(queue,[x,y]);
|
||||
que.push([x,y]);
|
||||
map[x][y]=3;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ while(error>0.001)
|
|||
}
|
||||
cnt+=1;
|
||||
show+=1;
|
||||
if(show==250)
|
||||
if(show==300)
|
||||
{
|
||||
show=0;
|
||||
print('epoch ',cnt,':',error,'\r');
|
||||
|
|
|
@ -17,7 +17,11 @@ var student=func(name,age)
|
|||
var s=student('valk',24);
|
||||
s.print_info();
|
||||
println(s.get_age(),' ',s.get_name());
|
||||
s.set_age(18);
|
||||
s.set_age(20);
|
||||
s.set_name('aluo');
|
||||
s.print_info();
|
||||
println(s.get_age(),' ',s.get_name());
|
||||
s.set_age(20);
|
||||
s.set_name('Sidi Liang');
|
||||
s.print_info();
|
||||
println(s.get_age(),' ',s.get_name());
|
2044
test/efb.nas
2044
test/efb.nas
File diff suppressed because it is too large
Load Diff
13
test/fib.nas
13
test/fib.nas
|
@ -5,15 +5,4 @@ var fib=func(x)
|
|||
return fib(x-1)+fib(x-2);
|
||||
}
|
||||
for(var i=0;i<31;i+=1)
|
||||
print(fib(i),'\n');
|
||||
|
||||
var m=[0,1,1,2,3,5,8];
|
||||
setsize(m,32);
|
||||
var fib=func(n)
|
||||
{
|
||||
if(m[n]!=nil) return m[n];
|
||||
var t=fib(n-1)+fib(n-2);
|
||||
m[n]=t;
|
||||
return t;
|
||||
}
|
||||
print(fib(31),'\n');
|
||||
print(fib(i),'\n');
|
7564
test/fmz.nas
7564
test/fmz.nas
File diff suppressed because it is too large
Load Diff
|
@ -1,643 +0,0 @@
|
|||
###############################################################################
|
||||
##
|
||||
## Nasal module for dual control over the multiplayer network.
|
||||
##
|
||||
## Copyright (C) 2007 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
|
||||
## This file is licensed under the GPL license version 2 or later.
|
||||
##
|
||||
###############################################################################
|
||||
## MP properties
|
||||
var lat_mpp = "position/latitude-deg";
|
||||
var lon_mpp = "position/longitude-deg";
|
||||
var alt_mpp = "position/altitude-ft";
|
||||
var heading_mpp = "orientation/true-heading-deg";
|
||||
var pitch_mpp = "orientation/pitch-deg";
|
||||
var roll_mpp = "orientation/roll-deg";
|
||||
|
||||
# Import components from the mp_broadcast module.
|
||||
var Binary = mp_broadcast.Binary;
|
||||
var MessageChannel = mp_broadcast.MessageChannel;
|
||||
|
||||
###############################################################################
|
||||
# Utility classes
|
||||
|
||||
############################################################
|
||||
# Translate a property into another.
|
||||
# Factor and offsets are only used for numeric values.
|
||||
# src - source : property node
|
||||
# dest - destination : property node
|
||||
# factor - : double
|
||||
# offset - : double
|
||||
var Translator = {};
|
||||
Translator.new = func (src = nil, dest = nil, factor = 1, offset = 0) {
|
||||
var obj = { parents : [Translator],
|
||||
src : src,
|
||||
dest : dest,
|
||||
factor : factor,
|
||||
offset : offset };
|
||||
if (obj.src == nil or obj.dest == nil) {
|
||||
print("Translator[");
|
||||
print(" ", debug.string(obj.src));
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
Translator.update = func () {
|
||||
var v = me.src.getValue();
|
||||
if (is_num(v)) {
|
||||
me.dest.setValue(me.factor * v + me.offset);
|
||||
} else {
|
||||
if (typeof(v) == "scalar")
|
||||
me.dest.setValue(v);
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Detects flanks on two insignals encoded in a property.
|
||||
# - positive signal up/down flank
|
||||
# - negative signal up/down flank
|
||||
# n - source : property node
|
||||
# on_positive_flank - action : func (v)
|
||||
# on_negative_flank - action : func (v)
|
||||
var EdgeTrigger = {};
|
||||
EdgeTrigger.new = func (n, on_positive_flank, on_negative_flank) {
|
||||
var obj = { parents : [EdgeTrigger],
|
||||
old : 0,
|
||||
node : n,
|
||||
pos_flank : on_positive_flank,
|
||||
neg_flank : on_negative_flank };
|
||||
if (obj.node == nil) {
|
||||
print("EdgeTrigger[");
|
||||
print(" ", debug.string(obj.node));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
EdgeTrigger.update = func {
|
||||
# NOTE: float MP properties get interpolated.
|
||||
# This detector relies on that steady state is reached between
|
||||
# flanks.
|
||||
var val = me.node.getValue();
|
||||
if (!is_num(val)) return;
|
||||
if (me.old == 1) {
|
||||
if (val < me.old) {
|
||||
me.pos_flank(0);
|
||||
}
|
||||
} elsif (me.old == 0) {
|
||||
if (val > me.old) {
|
||||
me.pos_flank(1);
|
||||
} elsif (val < me.old) {
|
||||
me.neg_flank(1);
|
||||
}
|
||||
} elsif (me.old == -1) {
|
||||
if (val > me.old) {
|
||||
me.neg_flank(0);
|
||||
}
|
||||
}
|
||||
me.old = val;
|
||||
}
|
||||
|
||||
############################################################
|
||||
# StableTrigger: Triggers an action when a MPP property
|
||||
# becomes stable (i.e. doesn't change for
|
||||
# MIN_STABLE seconds).
|
||||
# src - MP prop : property node
|
||||
# action - action to take when the value becomes stable : [func(v)]
|
||||
# An action is triggered when value has stabilized.
|
||||
var StableTrigger = {};
|
||||
StableTrigger.new = func (src, action) {
|
||||
var obj = { parents : [StableTrigger],
|
||||
src : src,
|
||||
action : action,
|
||||
old : 0,
|
||||
stable_since : 0,
|
||||
wait : 0,
|
||||
MIN_STABLE : 0.01 };
|
||||
# Error checking.
|
||||
var bad = (obj.src == nil) or (action = nil);
|
||||
|
||||
if (bad) {
|
||||
print("StableTrigger[");
|
||||
print(" ", debug.string(obj.src));
|
||||
print(" ", debug.string(obj.action));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
StableTrigger.update = func () {
|
||||
var v = me.src.getValue();
|
||||
if (!is_num(v)) return;
|
||||
var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time.
|
||||
|
||||
if ((me.old == v) and
|
||||
((t - me.stable_since) > me.MIN_STABLE) and (me.wait == 1)) {
|
||||
# Trigger action.
|
||||
me.action(v);
|
||||
|
||||
me.wait = 0;
|
||||
} elsif (me.old == v) {
|
||||
# Wait. This is either before the signal is stable or after the action.
|
||||
} else {
|
||||
me.stable_since = t;
|
||||
me.wait = 1;
|
||||
me.old = me.src.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Selects the most recent value of two properties.
|
||||
# src1 - : property node
|
||||
# src2 - : property node
|
||||
# dest - : property node
|
||||
# threshold - : double
|
||||
var MostRecentSelector = {};
|
||||
MostRecentSelector.new = func (src1, src2, dest, threshold) {
|
||||
var obj = { parents : [MostRecentSelector],
|
||||
old1 : 0,
|
||||
old2 : 0,
|
||||
src1 : src1,
|
||||
src2 : src2,
|
||||
dest : dest,
|
||||
thres : threshold };
|
||||
if (obj.src1 == nil or obj.src2 == nil or obj.dest == nil) {
|
||||
print("MostRecentSelector[");
|
||||
print(" ", debug.string(obj.src1));
|
||||
print(" ", debug.string(obj.src2));
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
MostRecentSelector.update = func {
|
||||
var v1 = me.src1.getValue();
|
||||
var v2 = me.src2.getValue();
|
||||
if (!is_num(v1) and !is_num(v2)) return;
|
||||
elsif (!is_num(v1)) me.dest.setValue(v2);
|
||||
elsif (!is_num(v2)) me.dest.setValue(v1);
|
||||
else {
|
||||
if (abs (v2 - me.old2) > me.thres) {
|
||||
me.old2 = v2;
|
||||
me.dest.setValue(me.old2);
|
||||
}
|
||||
if (abs (v1 - me.old1) > me.thres) {
|
||||
me.old1 = v1;
|
||||
me.dest.setValue(me.old1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Adds two input properties.
|
||||
# src1 - : property node
|
||||
# src2 - : property node
|
||||
# dest - : property node
|
||||
var Adder = {};
|
||||
Adder.new = func (src1, src2, dest) {
|
||||
var obj = { parents : [DeltaAccumulator],
|
||||
src1 : src1,
|
||||
src2 : src2,
|
||||
dest : dest };
|
||||
if (obj.src1 == nil or obj.src2 == nil or obj.dest == nil) {
|
||||
print("Adder[");
|
||||
print(" ", debug.string(obj.src1));
|
||||
print(" ", debug.string(obj.src2));
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
Adder.update = func () {
|
||||
var v1 = me.src1.getValue();
|
||||
var v2 = me.src2.getValue();
|
||||
if (!is_num(v1) or !is_num(v2)) return;
|
||||
me.dest.setValue(v1 + v2);
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Adds the delta of src to dest.
|
||||
# src - : property node
|
||||
# dest - : property node
|
||||
var DeltaAdder = {};
|
||||
DeltaAdder.new = func (src, dest) {
|
||||
var obj = { parents : [DeltaAdder],
|
||||
old : 0,
|
||||
src : src,
|
||||
dest : dest };
|
||||
if (obj.src == nil or obj.dest == nil) {
|
||||
print("DeltaAdder[", debug.string(obj.src), ", ",
|
||||
debug.string(obj.dest), "]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
DeltaAdder.update = func () {
|
||||
var v = me.src.getValue();
|
||||
if (!is_num(v)) return;
|
||||
me.dest.setValue((v - me.old) + me.dest.getValue());
|
||||
me.old = v;
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Switch encoder: Encodes upto 32 boolean properties in one
|
||||
# int property.
|
||||
# inputs - list of property nodes
|
||||
# dest - where the bitmask is stored : property node
|
||||
var SwitchEncoder = {};
|
||||
SwitchEncoder.new = func (inputs, dest) {
|
||||
var obj = { parents : [SwitchEncoder],
|
||||
inputs : inputs,
|
||||
dest : dest };
|
||||
# Error checking.
|
||||
var bad = (obj.dest == nil);
|
||||
foreach (var i; inputs) {
|
||||
if (i == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("SwitchEncoder[");
|
||||
foreach (var i; inputs) {
|
||||
print(" ", debug.string(i));
|
||||
}
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
SwitchEncoder.update = func () {
|
||||
var v = 0;
|
||||
var b = 1;
|
||||
forindex (var i; me.inputs) {
|
||||
if (me.inputs[i].getBoolValue()) {
|
||||
v = v + b;
|
||||
}
|
||||
b *= 2;
|
||||
}
|
||||
me.dest.setIntValue(v);
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Switch decoder: Decodes a bitmask in an int property.
|
||||
# src - : property node
|
||||
# actions - list of actions : [func(b)]
|
||||
# Actions are triggered when their input bit change.
|
||||
# Due to interpolation the decoder needs to wait for a
|
||||
# stable input value.
|
||||
var SwitchDecoder = {};
|
||||
SwitchDecoder.new = func (src, actions) {
|
||||
var obj = { parents : [SwitchDecoder],
|
||||
wait : 0,
|
||||
old : 0,
|
||||
old_stable : 0,
|
||||
stable_since : 0,
|
||||
reset : 1,
|
||||
src : src,
|
||||
actions : actions,
|
||||
MIN_STABLE : 0.1 };
|
||||
# Error checking.
|
||||
var bad = (obj.src == nil);
|
||||
foreach (var a; obj.actions) {
|
||||
if (a == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("SwitchDecoder[");
|
||||
print(" ", debug.string(obj.src));
|
||||
foreach (var a; obj.actions) {
|
||||
print(" ", debug.string(a));
|
||||
}
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
SwitchDecoder.update = func () {
|
||||
var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time.
|
||||
var v = me.src.getValue();
|
||||
if (!is_num(v)) return;
|
||||
|
||||
if ((me.old == v) and ((t - me.stable_since) > me.MIN_STABLE) and
|
||||
(me.wait == 1)) {
|
||||
var ov = me.old_stable;
|
||||
# Use this to improve.
|
||||
#<cptf> here's the boring version: var bittest = func(u, b) { while (b) { u = int(u / 2); b -= 1; } u != int(u / 2) * 2; }
|
||||
forindex (var i; me.actions) {
|
||||
var m = math.mod(v, 2);
|
||||
var om = math.mod(ov, 2);
|
||||
if ((m != om or me.reset)) { me.actions[i](m?1:0); }
|
||||
v = (v - m)/2;
|
||||
ov = (ov - om)/2;
|
||||
}
|
||||
me.old_stable = me.src.getValue();
|
||||
me.wait = 0;
|
||||
me.reset = 0;
|
||||
} elsif (me.old == v) {
|
||||
# Wait. This is either before the bitmask is stable or after
|
||||
# it has been processed.
|
||||
} else {
|
||||
me.stable_since = t;
|
||||
me.wait = 1;
|
||||
me.old = me.src.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Time division multiplexing encoder: Transmits a list of
|
||||
# properties over a MP enabled string property.
|
||||
# inputs - input properties : [property node]
|
||||
# dest - MP string prop : property node
|
||||
# Note: TDM can have high latency so it is best used for
|
||||
# non-time critical properties.
|
||||
var TDMEncoder = {};
|
||||
TDMEncoder.new = func (inputs, dest) {
|
||||
var obj = { parents : [TDMEncoder],
|
||||
inputs : inputs,
|
||||
channel : MessageChannel.new(dest,
|
||||
func (msg) {
|
||||
print("This should not happen!");
|
||||
}),
|
||||
MIN_INT : 0.25,
|
||||
last_time : 0,
|
||||
next_item : 0,
|
||||
old : [] };
|
||||
# Error checking.
|
||||
var bad = (dest == nil) or (obj.channel == nil);
|
||||
foreach (var i; inputs) {
|
||||
if (i == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("TDMEncoder[");
|
||||
foreach (var i; inputs) {
|
||||
print(" ", debug.string(i));
|
||||
}
|
||||
print(" ", debug.string(dest));
|
||||
print("]");
|
||||
}
|
||||
|
||||
setsize(obj.old, size(obj.inputs));
|
||||
|
||||
return obj;
|
||||
}
|
||||
TDMEncoder.update = func () {
|
||||
var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time.
|
||||
if (t > me.last_time + me.MIN_INT) {
|
||||
var n = size(me.inputs);
|
||||
while (1) {
|
||||
var v = me.inputs[me.next_item].getValue();
|
||||
|
||||
if ((n <= 0) or (me.old[me.next_item] != v)) {
|
||||
# Set the MP properties to send the next item.
|
||||
me.channel.send(Binary.encodeByte(me.next_item) ~
|
||||
Binary.encodeDouble(v));
|
||||
|
||||
me.old[me.next_item] = v;
|
||||
|
||||
me.last_time = t;
|
||||
me.next_item += 1;
|
||||
if (me.next_item >= size(me.inputs)) { me.next_item = 0; }
|
||||
return;
|
||||
} else {
|
||||
# Search for changed property.
|
||||
n -= 1;
|
||||
me.next_item += 1;
|
||||
if (me.next_item >= size(me.inputs)) { me.next_item = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Time division multiplexing decoder: Receives a list of
|
||||
# properties over a MP enabled string property.
|
||||
# src - MP string prop : property node
|
||||
# actions - list of actions : [func(v)]
|
||||
# An action is triggered when its value is received.
|
||||
# Note: TDM can have high latency so it is best used for
|
||||
# non-time critical properties.
|
||||
var TDMDecoder = {};
|
||||
TDMDecoder.new = func (src, actions) {
|
||||
var obj = { parents : [TDMDecoder],
|
||||
actions : actions };
|
||||
obj.channel = MessageChannel.new(src,
|
||||
func (msg) {
|
||||
obj.process(msg);
|
||||
});
|
||||
|
||||
# Error checking.
|
||||
var bad = (src == nil) or (obj.channel == nil);
|
||||
foreach (var a; actions) {
|
||||
if (a == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("TDMDecoder[");
|
||||
print(" ", debug.string(src));
|
||||
foreach (var a; actions) {
|
||||
print(" ", debug.string(a));
|
||||
}
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
TDMDecoder.process = func (msg) {
|
||||
var v1 = Binary.decodeByte(msg);
|
||||
var v2 = Binary.decodeDouble(substr(msg, 1));
|
||||
# Trigger action.
|
||||
me.actions[v1](v2);
|
||||
}
|
||||
TDMDecoder.update = func {
|
||||
me.channel.update();
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Internal utility functions
|
||||
|
||||
var is_num = func (v) {
|
||||
return num(v) != nil;
|
||||
}
|
||||
|
||||
# fail causes a Nasal runtime error so we get a backtrace.
|
||||
var fail = func {
|
||||
error_detected_in_calling_context();
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# Copilot selection dialog.
|
||||
#
|
||||
# Usage: dual_control_tools.copilot_dialog.show(<copilot type string>);
|
||||
#
|
||||
var COPILOT_DLG = 0;
|
||||
var copilot_dialog = {};
|
||||
############################################################
|
||||
copilot_dialog.init = func (copilot_type, x = nil, y = nil) {
|
||||
me.x = x;
|
||||
me.y = y;
|
||||
me.bg = [0, 0, 0, 0.3]; # background color
|
||||
me.fg = [[1.0, 1.0, 1.0, 1.0]];
|
||||
#
|
||||
# "private"
|
||||
if (contains(aircraft_dual_control, "copilot_view")) {
|
||||
me.title = "Pilot selection";
|
||||
} else {
|
||||
me.title = "Copilot selection";
|
||||
}
|
||||
me.basenode = props.globals.getNode("sim/remote", 1);
|
||||
me.dialog = nil;
|
||||
me.namenode = props.Node.new({"dialog-name" : me.title });
|
||||
me.listeners = [];
|
||||
me.copilot_type = copilot_type;
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.create = func {
|
||||
if (me.dialog != nil)
|
||||
me.close();
|
||||
|
||||
me.dialog = gui.Widget.new();
|
||||
me.dialog.set("name", me.title);
|
||||
if (me.x != nil)
|
||||
me.dialog.set("x", me.x);
|
||||
if (me.y != nil)
|
||||
me.dialog.set("y", me.y);
|
||||
|
||||
me.dialog.set("layout", "vbox");
|
||||
me.dialog.set("default-padding", 0);
|
||||
var titlebar = me.dialog.addChild("group");
|
||||
titlebar.set("layout", "hbox");
|
||||
titlebar.addChild("empty").set("stretch", 1);
|
||||
if (contains(aircraft_dual_control, "copilot_view")) {
|
||||
titlebar.addChild("text").set("label", "Book your flight");
|
||||
} else {
|
||||
titlebar.addChild("text").set("label", "Passengers online");
|
||||
}
|
||||
var w = titlebar.addChild("button");
|
||||
w.set("pref-width", 16);
|
||||
w.set("pref-height", 16);
|
||||
w.set("legend", "");
|
||||
w.set("default", 0);
|
||||
w.set("key", "esc");
|
||||
w.setBinding("nasal", "dual_control_tools.copilot_dialog.destroy(); ");
|
||||
w.setBinding("dialog-close");
|
||||
me.dialog.addChild("hrule");
|
||||
|
||||
var content = me.dialog.addChild("group");
|
||||
content.set("layout", "vbox");
|
||||
content.set("halign", "center");
|
||||
content.set("default-padding", 5);
|
||||
|
||||
# Generate the dialog contents.
|
||||
me.players = me.find_copilot_players();
|
||||
var i = 0;
|
||||
var tmpbase = me.basenode.getNode("dialog", 1);
|
||||
var selected = me.basenode.getNode("pilot-callsign").getValue();
|
||||
foreach (var p; me.players) {
|
||||
var tmp = tmpbase.getNode("b[" ~ i ~ "]", 1);
|
||||
tmp.setBoolValue(streq(selected, p));
|
||||
var w = content.addChild("checkbox");
|
||||
w.node.setValues({"label" : p,
|
||||
"halign" : "left",
|
||||
"property" : tmp.getPath()});
|
||||
w.setBinding
|
||||
("nasal",
|
||||
"dual_control_tools.copilot_dialog.select_action(" ~ i ~ ");");
|
||||
i = i + 1;
|
||||
}
|
||||
me.dialog.addChild("hrule");
|
||||
|
||||
# Display the dialog.
|
||||
fgcommand("dialog-new", me.dialog.prop());
|
||||
fgcommand("dialog-show", me.namenode);
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.close = func {
|
||||
fgcommand("dialog-close", me.namenode);
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.destroy = func {
|
||||
COPILOT_DLG = 0;
|
||||
me.close();
|
||||
foreach(var l; me.listeners)
|
||||
removelistener(l);
|
||||
delete(gui.dialog, "\"" ~ me.title ~ "\"");
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.show = func (copilot_type) {
|
||||
# print("Showing MPCopilots dialog!");
|
||||
if (!COPILOT_DLG) {
|
||||
COPILOT_DLG = int(getprop("/sim/time/elapsed-sec"));
|
||||
me.init(copilot_type);
|
||||
me.create();
|
||||
me._update_(COPILOT_DLG);
|
||||
}
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog._redraw_ = func {
|
||||
if (me.dialog != nil) {
|
||||
me.close();
|
||||
me.create();
|
||||
}
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog._update_ = func (id) {
|
||||
if (COPILOT_DLG != id) return;
|
||||
me._redraw_();
|
||||
settimer(func { me._update_(id); }, 4.1);
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.select_action = func (n) {
|
||||
var selected = me.basenode.getNode("pilot-callsign").getValue();
|
||||
var bs = me.basenode.getNode("dialog").getChildren();
|
||||
# Assumption: There are two true b:s or none. The one not matching selected
|
||||
# is the new selection.
|
||||
var i = 0;
|
||||
me.basenode.getNode("pilot-callsign").setValue("");
|
||||
foreach (var b; bs) {
|
||||
if (!b.getValue() and (i == n)) {
|
||||
b.setValue(1);
|
||||
me.basenode.getNode("pilot-callsign").setValue(me.players[i]);
|
||||
} else {
|
||||
b.setValue(0);
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
dual_control.main.reset();
|
||||
me._redraw_();
|
||||
}
|
||||
############################################################
|
||||
# Return a list containing all nearby copilot players of the right type.
|
||||
copilot_dialog.find_copilot_players = func {
|
||||
var mpplayers =
|
||||
props.globals.getNode("ai/models").getChildren("multiplayer");
|
||||
|
||||
var res = [];
|
||||
foreach (var pilot; mpplayers) {
|
||||
if ((pilot.getNode("valid") != nil) and
|
||||
(pilot.getNode("valid").getValue()) and
|
||||
(pilot.getNode("sim/model/path") != nil)) {
|
||||
var type = pilot.getNode("sim/model/path").getValue();
|
||||
|
||||
if (type == me.copilot_type) {
|
||||
append(res, pilot.getNode("callsign").getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
# debug.dump(res);
|
||||
return res;
|
||||
}
|
||||
###############################################################################
|
162
test/neo4j.nas
162
test/neo4j.nas
|
@ -1,162 +0,0 @@
|
|||
import("lib.nas");
|
||||
|
||||
rand(time(0));
|
||||
var chartable='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
var node=func(type)
|
||||
{
|
||||
var s="";
|
||||
for(var i=0;i<10;i+=1)
|
||||
s~=chr(chartable[rand()*62]);
|
||||
return {name:s,type:type,next:[]};
|
||||
}
|
||||
var film_node=[];
|
||||
for(var i=0;i<1000;i+=1)
|
||||
append(film_node,node("film"));
|
||||
var director_node=[];
|
||||
for(var i=0;i<200;i+=1)
|
||||
append(director_node,node("direct"));
|
||||
var actor_node=[];
|
||||
for(var i=0;i<400;i+=1)
|
||||
append(actor_node,node("actor"));
|
||||
var writer_node=[];
|
||||
for(var i=0;i<100;i+=1)
|
||||
append(writer_node,node("writer"));
|
||||
var type_node=[];
|
||||
for(var i=0;i<40;i+=1)
|
||||
append(type_node,node("type"));
|
||||
var lang_node=[];
|
||||
for(var i=0;i<120;i+=1)
|
||||
append(lang_node,node("lang"));
|
||||
var country_node=[];
|
||||
for(var i=0;i<120;i+=1)
|
||||
append(country_node,node("country"));
|
||||
|
||||
func()
|
||||
{
|
||||
var director_size=size(director_node);
|
||||
var actor_size=size(actor_node);
|
||||
var writer_size=size(writer_node);
|
||||
var type_size=size(type_node);
|
||||
var lang_size=size(lang_node);
|
||||
var country_size=size(country_node);
|
||||
|
||||
foreach(var film;film_node)
|
||||
{
|
||||
var director_link=int(1+rand()*2);
|
||||
var actor_link=int(1+rand()*20);
|
||||
var writer_link=int(1+rand()*2);
|
||||
var type_link=int(1+rand()*5);
|
||||
var lang_link=int(1+rand()*4);
|
||||
var country_link=int(1+rand()*4);
|
||||
for(var i=0;i<director_link;i+=1)
|
||||
{
|
||||
var director=director_node[rand()*director_size];
|
||||
append(film.next,director);
|
||||
append(director.next,film);
|
||||
}
|
||||
for(var i=0;i<actor_link;i+=1)
|
||||
{
|
||||
var actor=actor_node[rand()*actor_size];
|
||||
append(film.next,actor);
|
||||
append(actor.next,film);
|
||||
}
|
||||
for(var i=0;i<writer_link;i+=1)
|
||||
{
|
||||
var writer=writer_node[rand()*writer_size];
|
||||
append(film.next,writer);
|
||||
append(writer.next,film);
|
||||
}
|
||||
for(var i=0;i<type_link;i+=1)
|
||||
{
|
||||
var _type=type_node[rand()*type_size];
|
||||
append(film.next,_type);
|
||||
append(_type.next,film);
|
||||
}
|
||||
for(var i=0;i<lang_link;i+=1)
|
||||
{
|
||||
var lang=lang_node[rand()*lang_size];
|
||||
append(film.next,lang);
|
||||
append(lang.next,film);
|
||||
}
|
||||
for(var i=0;i<country_link;i+=1)
|
||||
{
|
||||
var country=country_node[rand()*country_size];
|
||||
append(film.next,country);
|
||||
append(country.next,film);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}();
|
||||
|
||||
|
||||
var film_list=[];
|
||||
var count_list=[];
|
||||
for(var i=0;i<10;i+=1)
|
||||
{
|
||||
append(film_list,film_node[i]);
|
||||
append(count_list,1);
|
||||
}
|
||||
|
||||
var sort_list=func(begin,end)
|
||||
{
|
||||
for(var i=begin;i<end;i+=1)
|
||||
{
|
||||
var index=i;
|
||||
for(var j=i+1;j<end;j+=1)
|
||||
if(count_list[index]<count_list[j])
|
||||
index=j;
|
||||
if(index!=i)
|
||||
{
|
||||
var tmp=film_list[i];
|
||||
film_list[i]=film_list[index];
|
||||
film_list[index]=tmp;
|
||||
tmp=count_list[i];
|
||||
count_list[i]=count_list[index];
|
||||
count_list[index]=tmp;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var get_next=func(index)
|
||||
{
|
||||
var label_list=film_list[index].next;
|
||||
film_list=[];
|
||||
count_list=[];
|
||||
foreach(var label;label_list)
|
||||
foreach(var film;label.next)
|
||||
{
|
||||
var has=0;
|
||||
for(var i=0;i<size(film_list);i+=1)
|
||||
if(film_list[i].name==film.name)
|
||||
{
|
||||
has=1;
|
||||
count_list[i]+=1;
|
||||
break;
|
||||
}
|
||||
if(has==0)
|
||||
{
|
||||
append(film_list,film);
|
||||
append(count_list,1);
|
||||
}
|
||||
}
|
||||
sort_list(0,size(film_list));
|
||||
return;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
var list_size=size(film_list);
|
||||
list_size=list_size>10?10:list_size;
|
||||
for(var i=1;i<list_size;i+=1)
|
||||
println('| ',i,'\t:',film_list[i].name,'\t',count_list[i]);
|
||||
var choose=input();
|
||||
if(choose=="exit")
|
||||
break;
|
||||
if(num(choose)==0 or num(choose)>=list_size)
|
||||
die("choose a correct index");
|
||||
get_next(num(choose));
|
||||
}
|
||||
|
||||
foreach(var film;film_node)
|
||||
setsize(film.next,0);
|
|
@ -1,210 +0,0 @@
|
|||
var smartScreen = canvas.new({
|
||||
"name": "smartScreen", # The name is optional but allow for easier identification
|
||||
"size": [2048, 2048], # Size of the underlying texture (should be a power of 2, required) [Resolution]
|
||||
"view": [768, 768], # Virtual resolution (Defines the coordinate system of the canvas [Dimensions]
|
||||
# which will be stretched the size of the texture, required)
|
||||
"mipmapping": 1 # Enable mipmapping (optional)
|
||||
});
|
||||
|
||||
smartScreen.addPlacement({"node": "screen", "texture": "screen.jpeg"});
|
||||
var group = smartScreen.createGroup();
|
||||
|
||||
# Create a text element and set some values
|
||||
var text = group.createChild("text", "optional-id-for element")
|
||||
.setTranslation(10, 20) # The origin is in the top left corner
|
||||
.setAlignment("left-center") # All values from osgText are supported (see $FG_ROOT/Docs/README.osgtext)
|
||||
.setFont("LiberationFonts/LiberationSans-Regular.ttf") # Fonts are loaded either from $AIRCRAFT_DIR/Fonts or $FG_ROOT/Fonts
|
||||
.setFontSize(14, 1.2) # Set fontsize and optionally character aspect ratio
|
||||
.setColor(1,0,0) # Text color
|
||||
.setText("This is a text element");
|
||||
text.hide();
|
||||
text.setText("SELF TEST NORMAL").show();
|
||||
|
||||
|
||||
|
||||
var ui_root = smartScreen.createGroup();
|
||||
var vbox = canvas.VBoxLayout.new();
|
||||
smartScreen.setLayout(vbox);
|
||||
|
||||
|
||||
var button_onl = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}).setText("Online OSM").listen("clicked", func showOnlineMap());
|
||||
var button_offl = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}).setText("Offline OSM").listen("clicked", func showOfflineMap());
|
||||
button_onl.setSizeHint([32, 128]);
|
||||
button_offl.setSizeHint([32, 128]);
|
||||
|
||||
var label = canvas.gui.widgets.Label.new(ui_root, canvas.style, {});
|
||||
|
||||
var button_box = canvas.HBoxLayout.new();
|
||||
button_box.addItem(button_onl);
|
||||
button_box.addItem(button_offl);
|
||||
button_box.addItem(label);
|
||||
button_box.addStretch(1);
|
||||
|
||||
vbox.addItem(button_box);
|
||||
vbox.addStretch(1);
|
||||
|
||||
|
||||
var showOnlineMap = func(){
|
||||
TestMap.show();
|
||||
g.hide();
|
||||
label.setText("Online Mode");
|
||||
}
|
||||
|
||||
|
||||
var showOfflineMap = func(){
|
||||
TestMap.hide();
|
||||
g.show();
|
||||
label.setText("Offline Mode");
|
||||
}
|
||||
|
||||
|
||||
# Online Map using MapStructure
|
||||
var TestMap = smartScreen.createGroup().createChild("map");
|
||||
TestMap.setTranslation(smartScreen.get("view[0]")/2,smartScreen.get("view[1]")/2);
|
||||
|
||||
|
||||
var ctrl_ns = canvas.Map.Controller.get("Aircraft position");
|
||||
var source = ctrl_ns.SOURCES["map-dialog"];
|
||||
if (source == nil) {
|
||||
# TODO: amend
|
||||
var source = ctrl_ns.SOURCES["map-dialog"] = {
|
||||
getPosition: func subvec(geo.aircraft_position().latlon(), 0, 2),# ? ? ?
|
||||
getAltitude: func getprop('/position/altitude-ft'),
|
||||
getHeading: func {
|
||||
if (me.aircraft_heading)
|
||||
getprop('/orientation/heading-deg');
|
||||
else
|
||||
0;
|
||||
},
|
||||
aircraft_heading: 1,
|
||||
};
|
||||
}
|
||||
setlistener("/sim/gui/dialogs/map-canvas/aircraft-heading-up", func(n){source.aircraft_heading = n.getBoolValue();}, 1);
|
||||
TestMap.setController("Aircraft position", "map-dialog");
|
||||
TestMap.setRange(1);
|
||||
|
||||
var r = func(name,vis=1,zindex=nil){return caller(0)[0];};
|
||||
# TODO: we'll need some z-indexing here, right now it's just random
|
||||
|
||||
foreach(var type; [r('APS')] ){
|
||||
TestMap.addLayer(factory: canvas.SymbolLayer, type_arg: type.name, visible: type.vis, priority: 2);
|
||||
}
|
||||
|
||||
foreach(var type; [ r('OSM')]) {
|
||||
TestMap.addLayer(factory: canvas.OverlayLayer,
|
||||
type_arg: type.name,
|
||||
visible: type.vis,
|
||||
priority: 1);
|
||||
}
|
||||
|
||||
|
||||
TestMap.hide();
|
||||
|
||||
# Offline map
|
||||
|
||||
var g = smartScreen.createGroup();
|
||||
var zoom = 15;
|
||||
var type = "intl";
|
||||
var tile_size = 256;
|
||||
|
||||
|
||||
var changeZoom = func(d)
|
||||
{
|
||||
zoom = math.max(2, math.min(19, zoom + d));
|
||||
updateTiles();
|
||||
}
|
||||
|
||||
# http://polymaps.org/docs/
|
||||
# https://github.com/simplegeo/polymaps
|
||||
# https://github.com/Leaflet/Leaflet
|
||||
|
||||
var maps_base = getprop("/sim/fg-home") ~ '/cache/maps';
|
||||
|
||||
var makePath =
|
||||
string.compileTemplate(maps_base ~ '/osm-{type}/{z}/{x}/{y}.jpg');
|
||||
var num_tiles = [4, 4];
|
||||
|
||||
var center_tile_offset = [(num_tiles[0]-1)/2, (num_tiles[1]-1)/ 2];
|
||||
|
||||
# simple aircraft icon at current position/center of the map
|
||||
g.createChild("path")
|
||||
.moveTo( tile_size*center_tile_offset[0]-10, tile_size*center_tile_offset[1])
|
||||
.horiz(20)
|
||||
.move(-10,-10)
|
||||
.vert(20)
|
||||
.set("stroke", "red")
|
||||
.set("stroke-width", 2)
|
||||
.set("z-index", 1);
|
||||
|
||||
# initialize the map by setting up
|
||||
# a grid of raster images
|
||||
|
||||
var tiles = setsize([], num_tiles[0]);
|
||||
for(var x=0; x<num_tiles[0]; x+=1)
|
||||
{
|
||||
tiles[x] = setsize([], num_tiles[1]);
|
||||
for(var y=0; y<num_tiles[1]; y+=1)
|
||||
tiles[x][y] = g.createChild("image", "map-tile");
|
||||
}
|
||||
|
||||
var last_tile = [-1,-1];
|
||||
var last_type = type;
|
||||
|
||||
# this is the callback that will be regularly called by the timer
|
||||
# to update the map
|
||||
var updateTiles = func()
|
||||
{
|
||||
# get current position
|
||||
var lat = getprop('/position/latitude-deg');
|
||||
var lon = getprop('/position/longitude-deg');
|
||||
|
||||
var n = math.pow(2, zoom);
|
||||
var offset = [n*((lon+180)/360)-center_tile_offset[0], (1-math.ln(math.tan(lat*math.pi/180)+1/math.cos(lat*math.pi/180))/math.pi)/2*n-center_tile_offset[1]];
|
||||
var tile_index = [int(offset[0]), int(offset[1])];
|
||||
|
||||
var ox = tile_index[0] - offset[0];
|
||||
var oy = tile_index[1] - offset[1];
|
||||
|
||||
for(var x = 0; x < num_tiles[0]; x += 1)
|
||||
for(var y = 0; y < num_tiles[1]; y += 1)
|
||||
tiles[x][y].setTranslation(int((ox + x) * tile_size + 0.5), int((oy + y) * tile_size + 0.5));
|
||||
|
||||
if( tile_index[0] != last_tile[0]
|
||||
or tile_index[1] != last_tile[1]
|
||||
or type != last_type )
|
||||
{
|
||||
for(var x = 0; x < num_tiles[0]; x += 1)
|
||||
for(var y = 0; y < num_tiles[1]; y += 1)
|
||||
{
|
||||
var pos = {
|
||||
z: zoom,
|
||||
x: int(offset[0] + x),
|
||||
y: int(offset[1] + y),
|
||||
type: type
|
||||
};
|
||||
|
||||
(func {
|
||||
var img_path = makePath(pos);
|
||||
var tile = tiles[x][y];
|
||||
print('loading ' ~ img_path);
|
||||
tile.set("src", img_path);
|
||||
})();
|
||||
# lambda
|
||||
}
|
||||
|
||||
last_tile = tile_index;
|
||||
last_type = type;
|
||||
}
|
||||
};
|
||||
|
||||
# set up a timer that will invoke updateTiles at 2-second intervals
|
||||
var update_timer = maketimer(2, updateTiles);
|
||||
# actually start the timer
|
||||
update_timer.start();
|
||||
|
||||
# set up default zoom level
|
||||
changeZoom(0);
|
||||
|
||||
#g.hide();
|
||||
|
||||
|
Loading…
Reference in New Issue