add stl & more efficient scope

This commit is contained in:
Valk Richard Li 2021-04-02 22:19:29 +08:00
parent 125fc8a9fe
commit c88620920b
21 changed files with 256 additions and 11154 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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()

View File

@ -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;

73
stl/list.nas Normal file
View File

@ -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;
},
};
}

27
stl/sort.nas Normal file
View File

@ -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;
}

View File

@ -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();

View File

@ -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.");
}
}
}

View File

@ -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;
}
}

View File

@ -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');

View File

@ -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());

File diff suppressed because it is too large Load Diff

View File

@ -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');

File diff suppressed because it is too large Load Diff

View File

@ -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;
}
###############################################################################

View File

@ -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);

View File

@ -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();