⚡ move lvalue check from parse to codegen
This commit is contained in:
parent
9196d7815f
commit
54969681fc
15
README.md
15
README.md
|
@ -593,16 +593,19 @@ Luckily, we have developed some useful native-functions to help you add modules
|
||||||
After 2021/12/3, there are some new functions added to `lib.nas`:
|
After 2021/12/3, there are some new functions added to `lib.nas`:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var dylib=
|
var dylib={
|
||||||
{
|
dlopen: func(libname){
|
||||||
dlopen: func(libname){return __dlopen;},
|
...
|
||||||
dlsym: func(lib,sym){return __dlsym; },
|
},
|
||||||
dlclose: func(lib){return __dlclose; },
|
dlclose: func(lib){return __dlclose; },
|
||||||
dlcall: func(funcptr,args...){return __dlcall;}
|
dlcall: func(ptr,args...){return __dlcallv},
|
||||||
|
limitcall: func(arg_size=0){
|
||||||
|
...
|
||||||
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Aha, as you could see, these functions are used to load dynamic libraries into the nasal runtime and execute.
|
As you could see, these functions are used to load dynamic libraries into the nasal runtime and execute.
|
||||||
Let's see how they work.
|
Let's see how they work.
|
||||||
|
|
||||||
First, write a cpp file that you want to generate the dynamic lib, take the `fib.cpp` as the example(example codes are in `./module`):
|
First, write a cpp file that you want to generate the dynamic lib, take the `fib.cpp` as the example(example codes are in `./module`):
|
||||||
|
|
|
@ -569,16 +569,19 @@ import("./dirname/dirname/filename.nas");
|
||||||
在2021/12/3更新后,我们给`lib.nas`添加了下面的这一批函数:
|
在2021/12/3更新后,我们给`lib.nas`添加了下面的这一批函数:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var dylib=
|
var dylib={
|
||||||
{
|
dlopen: func(libname){
|
||||||
dlopen: func(libname){return __dlopen;},
|
...
|
||||||
dlsym: func(lib,sym){return __dlsym; },
|
},
|
||||||
dlclose: func(lib){return __dlclose; },
|
dlclose: func(lib){return __dlclose; },
|
||||||
dlcall: func(funcptr,args...){return __dlcall;}
|
dlcall: func(ptr,args...){return __dlcallv},
|
||||||
|
limitcall: func(arg_size=0){
|
||||||
|
...
|
||||||
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
看名字就大概能猜出来,这些函数就是用来加载动态库的,这样nasal解释器可以根据用户需求灵活加载动态库来执行。让我们看看这些函数该如何使用。
|
这些函数是用来加载动态库的,这样nasal解释器可以根据用户需求灵活加载动态库来执行。让我们看看这些函数该如何使用。
|
||||||
|
|
||||||
首先,用C++写个项目,并且编译成动态库。我们就拿`fib.cpp`作为例子来说明(样例代码可以在`./module`中找到):
|
首先,用C++写个项目,并且编译成动态库。我们就拿`fib.cpp`作为例子来说明(样例代码可以在`./module`中找到):
|
||||||
|
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -99,7 +99,7 @@ void execute(const string& file,const std::vector<string>& argv,const u32 cmd)
|
||||||
if(cmd&VM_OPT)
|
if(cmd&VM_OPT)
|
||||||
optimize(parse.tree());
|
optimize(parse.tree());
|
||||||
if(cmd&VM_AST)
|
if(cmd&VM_AST)
|
||||||
parse.print();
|
parse.tree().dump();
|
||||||
|
|
||||||
// code generator gets parser's ast and linker's import file list to generate code
|
// code generator gets parser's ast and linker's import file list to generate code
|
||||||
gen.compile(parse,ld).chkerr();
|
gen.compile(parse,ld).chkerr();
|
||||||
|
|
91
nasal_ast.h
91
nasal_ast.h
|
@ -3,8 +3,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
enum ast_node:u32
|
enum ast_node:u32{
|
||||||
{
|
|
||||||
ast_null=0, // null node
|
ast_null=0, // null node
|
||||||
ast_root, // mark the root node of ast
|
ast_root, // mark the root node of ast
|
||||||
ast_block, // expression block
|
ast_block, // expression block
|
||||||
|
@ -22,7 +21,7 @@ enum ast_node:u32
|
||||||
ast_callv, // id[index]
|
ast_callv, // id[index]
|
||||||
ast_callf, // id()
|
ast_callf, // id()
|
||||||
ast_subvec, // id[index:index]
|
ast_subvec, // id[index:index]
|
||||||
ast_args, // mark a sub-tree of function parameters
|
ast_params, // mark a sub-tree of function parameters
|
||||||
ast_default, // default parameter
|
ast_default, // default parameter
|
||||||
ast_dynamic, // dynamic parameter
|
ast_dynamic, // dynamic parameter
|
||||||
ast_and, // and keyword
|
ast_and, // and keyword
|
||||||
|
@ -65,23 +64,65 @@ enum ast_node:u32
|
||||||
ast_ret // return keyword, only used in function block
|
ast_ret // return keyword, only used in function block
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* ast_name[]=
|
const char* ast_name[]={
|
||||||
{
|
"NullNode",
|
||||||
"null", "root", "block", "file",
|
"AbstractSyntaxTreeRoot",
|
||||||
"nil", "num", "str", "id",
|
"CodeBlock",
|
||||||
"func", "hash", "vec", "pair",
|
"FileIndex",
|
||||||
"call", "callh", "callv", "callf",
|
"LiteralNil",
|
||||||
"subvec", "args", "default", "dynamic",
|
"LiteralNumber",
|
||||||
"and", "or", "=", "+=",
|
"LiteralString",
|
||||||
"-=", "*=", "/=", "~=",
|
"Identifier",
|
||||||
"==", "!=", "<", "<=",
|
"Function",
|
||||||
">", ">=", "+", "-",
|
"HashMap",
|
||||||
"*", "/", "~", "neg",
|
"Vector",
|
||||||
"!", "trino", "for", "forindex",
|
"HashMapPair",
|
||||||
"foreach", "while", "iter", "cond",
|
"IdentifierCallExpression",
|
||||||
"if", "elsif", "else", "ltuple",
|
"HashMapCallExpression",
|
||||||
"tuple", "def", "massign", "continue",
|
"VectorCallExpression",
|
||||||
"break", "return"
|
"FunctionCallExpression",
|
||||||
|
"SubVector",
|
||||||
|
"ParameterList",
|
||||||
|
"DefaultParameter",
|
||||||
|
"DynamicParameter",
|
||||||
|
"AndExpression",
|
||||||
|
"OrExpression",
|
||||||
|
"EqualExpression",
|
||||||
|
"AddEqualExpression",
|
||||||
|
"SubEqualExpression",
|
||||||
|
"MultEqualExpression",
|
||||||
|
"DivEqualExpression",
|
||||||
|
"LinkEqualExpression",
|
||||||
|
"CompareEqualExpression",
|
||||||
|
"NotEqualExpression",
|
||||||
|
"LessExpression",
|
||||||
|
"LessOrEqualExpression",
|
||||||
|
"GreatExpression",
|
||||||
|
"GreatOrEqualExpression",
|
||||||
|
"AddExpression",
|
||||||
|
"SubExpression",
|
||||||
|
"MultExpression",
|
||||||
|
"DivExpression",
|
||||||
|
"LinkExpression",
|
||||||
|
"NegativeExpression",
|
||||||
|
"NotExpression",
|
||||||
|
"TrinocularExpression",
|
||||||
|
"ForLoop",
|
||||||
|
"ForindexLoop",
|
||||||
|
"ForeachLoop",
|
||||||
|
"WhileLoop",
|
||||||
|
"Iterator",
|
||||||
|
"ConditionExpression",
|
||||||
|
"IfExpression",
|
||||||
|
"ElsifExpression",
|
||||||
|
"ElseExpression",
|
||||||
|
"LeftTuple",
|
||||||
|
"Tuple",
|
||||||
|
"Definition",
|
||||||
|
"MultipleAssignment",
|
||||||
|
"ContinueExpression",
|
||||||
|
"BreakExpression",
|
||||||
|
"ReturnExpression"
|
||||||
};
|
};
|
||||||
|
|
||||||
class ast
|
class ast
|
||||||
|
@ -98,8 +139,8 @@ public:
|
||||||
nd_line(l),nd_col(c),nd_type(t),nd_num(0){}
|
nd_line(l),nd_col(c),nd_type(t),nd_num(0){}
|
||||||
ast(const ast&);
|
ast(const ast&);
|
||||||
ast(ast&&);
|
ast(ast&&);
|
||||||
void print_tree();
|
void dump() const;
|
||||||
void print(u32,bool,std::vector<string>&);
|
void print(u32,bool,std::vector<string>&) const;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
ast& operator=(const ast&);
|
ast& operator=(const ast&);
|
||||||
|
@ -174,13 +215,13 @@ void ast::clear()
|
||||||
nd_child.clear();
|
nd_child.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ast::print_tree()
|
void ast::dump() const
|
||||||
{
|
{
|
||||||
std::vector<string> tmp;
|
std::vector<string> tmp;
|
||||||
print(0,false,tmp);
|
print(0,false,tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ast::print(u32 depth,bool last,std::vector<string>& indent)
|
void ast::print(u32 depth,bool last,std::vector<string>& indent) const
|
||||||
{
|
{
|
||||||
for(auto& i:indent)
|
for(auto& i:indent)
|
||||||
std::cout<<i;
|
std::cout<<i;
|
||||||
|
@ -191,7 +232,7 @@ void ast::print(u32 depth,bool last,std::vector<string>& indent)
|
||||||
std::cout<<":"<<rawstr(nd_str);
|
std::cout<<":"<<rawstr(nd_str);
|
||||||
else if(nd_type==ast_num || nd_type==ast_file)
|
else if(nd_type==ast_num || nd_type==ast_file)
|
||||||
std::cout<<":"<<nd_num;
|
std::cout<<":"<<nd_num;
|
||||||
std::cout<<"\n";
|
std::cout<<" -> "<<nd_line<<":"<<nd_col<<"\n";
|
||||||
if(last && depth)
|
if(last && depth)
|
||||||
indent.back()=" ";
|
indent.back()=" ";
|
||||||
else if(!last && depth)
|
else if(!last && depth)
|
||||||
|
|
|
@ -220,6 +220,8 @@ private:
|
||||||
// func end stack, reserved for code print
|
// func end stack, reserved for code print
|
||||||
std::stack<u32> fbstk;
|
std::stack<u32> fbstk;
|
||||||
std::stack<u32> festk;
|
std::stack<u32> festk;
|
||||||
|
|
||||||
|
bool check_memory_reachable(const ast&);
|
||||||
|
|
||||||
void die(const string&,const u32,const u32,const u32);
|
void die(const string&,const u32,const u32,const u32);
|
||||||
void regist_num(const f64);
|
void regist_num(const f64);
|
||||||
|
@ -272,6 +274,25 @@ public:
|
||||||
const std::vector<opcode>& codes() const {return code;}
|
const std::vector<opcode>& codes() const {return code;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool codegen::check_memory_reachable(const ast& node)
|
||||||
|
{
|
||||||
|
if(node.type()==ast_call){
|
||||||
|
const ast& tmp=node.child().back();
|
||||||
|
if(tmp.type()==ast_callf){
|
||||||
|
die("bad left-value",tmp.line(),tmp.col(),1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(tmp.type()==ast_callv && (tmp.size()==0 || tmp.size()>1 || tmp[0].type()==ast_subvec)){
|
||||||
|
die("bad left-value",tmp.line(),tmp.col(),1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else if(node.type()!=ast_id){
|
||||||
|
die("bad left-value",node.line(),node.col(),1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void codegen::die(const string& info,const u32 line,const u32 col,const u32 len=1)
|
void codegen::die(const string& info,const u32 line,const u32 col,const u32 len=1)
|
||||||
{
|
{
|
||||||
err.load(file[fileindex]);
|
err.load(file[fileindex]);
|
||||||
|
@ -592,6 +613,9 @@ void codegen::call_func(const ast& node)
|
||||||
*/
|
*/
|
||||||
void codegen::mcall(const ast& node)
|
void codegen::mcall(const ast& node)
|
||||||
{
|
{
|
||||||
|
if(!check_memory_reachable(node)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(node.type()==ast_id)
|
if(node.type()==ast_id)
|
||||||
{
|
{
|
||||||
mcall_id(node);
|
mcall_id(node);
|
||||||
|
|
|
@ -99,9 +99,9 @@ public:
|
||||||
res.push_back(line);
|
res.push_back(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const string& operator[](usize n){return res[n];}
|
const string& operator[](usize n) const {return res[n];}
|
||||||
const string& name(){return file;}
|
const string& name() const {return file;}
|
||||||
usize size(){return res.size();}
|
usize size() const {return res.size();}
|
||||||
};
|
};
|
||||||
|
|
||||||
class error:public flstream
|
class error:public flstream
|
||||||
|
|
|
@ -107,7 +107,6 @@ private:
|
||||||
bool check_func_end(const ast&);
|
bool check_func_end(const ast&);
|
||||||
bool check_special_call();
|
bool check_special_call();
|
||||||
bool need_semi_check(const ast&);
|
bool need_semi_check(const ast&);
|
||||||
void check_memory_reachable(const ast&);
|
|
||||||
ast null();
|
ast null();
|
||||||
ast nil();
|
ast nil();
|
||||||
ast num();
|
ast num();
|
||||||
|
@ -117,7 +116,7 @@ private:
|
||||||
ast hash();
|
ast hash();
|
||||||
ast pair();
|
ast pair();
|
||||||
ast func();
|
ast func();
|
||||||
ast args();
|
ast params();
|
||||||
ast lcurve_expr();
|
ast lcurve_expr();
|
||||||
ast expr();
|
ast expr();
|
||||||
ast exprs();
|
ast exprs();
|
||||||
|
@ -138,7 +137,7 @@ private:
|
||||||
ast incurve_def();
|
ast incurve_def();
|
||||||
ast outcurve_def();
|
ast outcurve_def();
|
||||||
ast multi_id();
|
ast multi_id();
|
||||||
ast multi_scalar(bool);
|
ast multi_scalar();
|
||||||
ast multi_assgin();
|
ast multi_assgin();
|
||||||
ast loop();
|
ast loop();
|
||||||
ast while_loop();
|
ast while_loop();
|
||||||
|
@ -154,7 +153,6 @@ public:
|
||||||
ptr(0),in_func(0),in_loop(0),
|
ptr(0),in_func(0),in_loop(0),
|
||||||
toks(nullptr),root(0,0,ast_root),
|
toks(nullptr),root(0,0,ast_root),
|
||||||
err(e){}
|
err(e){}
|
||||||
void print(){root.print_tree();}
|
|
||||||
const error& compile(const lexer&);
|
const error& compile(const lexer&);
|
||||||
ast& tree(){return root;}
|
ast& tree(){return root;}
|
||||||
const ast& tree() const {return root;}
|
const ast& tree() const {return root;}
|
||||||
|
@ -183,7 +181,6 @@ void parse::die(u32 line,u32 col,u32 len,string info,bool prev=false)
|
||||||
col-=2;
|
col-=2;
|
||||||
len+=2;
|
len+=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// used to report lack of ',' ';'
|
// used to report lack of ',' ';'
|
||||||
if(prev && ptr){
|
if(prev && ptr){
|
||||||
line=toks[ptr-1].line;
|
line=toks[ptr-1].line;
|
||||||
|
@ -191,7 +188,6 @@ void parse::die(u32 line,u32 col,u32 len,string info,bool prev=false)
|
||||||
len=toks[ptr-1].str.length();
|
len=toks[ptr-1].str.length();
|
||||||
len+=toks[ptr-1].type==tok_str?2:0;
|
len+=toks[ptr-1].type==tok_str?2:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
err.err("parse",line,col,lookahead(tok_eof)?1:len,info);
|
err.err("parse",line,col,lookahead(tok_eof)?1:len,info);
|
||||||
}
|
}
|
||||||
void parse::match(u32 type,const char* info)
|
void parse::match(u32 type,const char* info)
|
||||||
|
@ -305,20 +301,6 @@ bool parse::need_semi_check(const ast& node)
|
||||||
}
|
}
|
||||||
return !check_func_end(node);
|
return !check_func_end(node);
|
||||||
}
|
}
|
||||||
void parse::check_memory_reachable(const ast& node)
|
|
||||||
{
|
|
||||||
if(node.type()==ast_call){
|
|
||||||
const ast& tmp=node.child().back();
|
|
||||||
if(tmp.type()==ast_callf){
|
|
||||||
die(tmp.line(),tmp.col(),1,"bad left-value");
|
|
||||||
}
|
|
||||||
if(tmp.type()==ast_callv && (tmp.size()==0 || tmp.size()>1 || tmp[0].type()==ast_subvec)){
|
|
||||||
die(tmp.line(),tmp.col(),1,"bad left-value");
|
|
||||||
}
|
|
||||||
}else if(node.type()!=ast_id){
|
|
||||||
die(node.line(),node.col(),1,"bad left-value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast parse::null()
|
ast parse::null()
|
||||||
{
|
{
|
||||||
return {toks[ptr].line,toks[ptr].col,ast_null};
|
return {toks[ptr].line,toks[ptr].col,ast_null};
|
||||||
|
@ -411,7 +393,7 @@ ast parse::func()
|
||||||
ast node(toks[ptr].line,toks[ptr].col,ast_func);
|
ast node(toks[ptr].line,toks[ptr].col,ast_func);
|
||||||
match(tok_func);
|
match(tok_func);
|
||||||
if(lookahead(tok_lcurve)){
|
if(lookahead(tok_lcurve)){
|
||||||
node.add(args());
|
node.add(params());
|
||||||
}else{
|
}else{
|
||||||
node.add(null());
|
node.add(null());
|
||||||
}
|
}
|
||||||
|
@ -419,9 +401,9 @@ ast parse::func()
|
||||||
--in_func;
|
--in_func;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
ast parse::args()
|
ast parse::params()
|
||||||
{
|
{
|
||||||
ast node(toks[ptr].line,toks[ptr].col,ast_args);
|
ast node(toks[ptr].line,toks[ptr].col,ast_params);
|
||||||
match(tok_lcurve);
|
match(tok_lcurve);
|
||||||
while(!lookahead(tok_rcurve)){
|
while(!lookahead(tok_rcurve)){
|
||||||
ast tmp=id();
|
ast tmp=id();
|
||||||
|
@ -534,7 +516,6 @@ ast parse::calc()
|
||||||
tmp.add(calc());
|
tmp.add(calc());
|
||||||
node=std::move(tmp);
|
node=std::move(tmp);
|
||||||
}else if(tok_eq<=toks[ptr].type && toks[ptr].type<=tok_lnkeq){
|
}else if(tok_eq<=toks[ptr].type && toks[ptr].type<=tok_lnkeq){
|
||||||
check_memory_reachable(node);
|
|
||||||
// tok_eq~tok_lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26
|
// tok_eq~tok_lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26
|
||||||
ast tmp(toks[ptr].line,toks[ptr].col,toks[ptr].type-tok_eq+ast_equal);
|
ast tmp(toks[ptr].line,toks[ptr].col,toks[ptr].type-tok_eq+ast_equal);
|
||||||
tmp.add(std::move(node));
|
tmp.add(std::move(node));
|
||||||
|
@ -764,7 +745,7 @@ ast parse::definition()
|
||||||
}
|
}
|
||||||
match(tok_eq);
|
match(tok_eq);
|
||||||
if(lookahead(tok_lcurve)){
|
if(lookahead(tok_lcurve)){
|
||||||
node.add(check_tuple()?multi_scalar(false):calc());
|
node.add(check_tuple()?multi_scalar():calc());
|
||||||
}else{
|
}else{
|
||||||
node.add(calc());
|
node.add(calc());
|
||||||
}
|
}
|
||||||
|
@ -804,7 +785,7 @@ ast parse::multi_id()
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
ast parse::multi_scalar(bool check_call_memory)
|
ast parse::multi_scalar()
|
||||||
{
|
{
|
||||||
// if check_call_memory is true,we will check if value called here can reach a memory space
|
// if check_call_memory is true,we will check if value called here can reach a memory space
|
||||||
const u32 panic_set[]={
|
const u32 panic_set[]={
|
||||||
|
@ -817,9 +798,6 @@ ast parse::multi_scalar(bool check_call_memory)
|
||||||
match(tok_lcurve);
|
match(tok_lcurve);
|
||||||
while(!lookahead(tok_rcurve)){
|
while(!lookahead(tok_rcurve)){
|
||||||
node.add(calc());
|
node.add(calc());
|
||||||
if(check_call_memory){
|
|
||||||
check_memory_reachable(node.child().back());
|
|
||||||
}
|
|
||||||
if(lookahead(tok_comma)){
|
if(lookahead(tok_comma)){
|
||||||
match(tok_comma);
|
match(tok_comma);
|
||||||
}else if(lookahead(tok_eof)){
|
}else if(lookahead(tok_eof)){
|
||||||
|
@ -834,14 +812,14 @@ ast parse::multi_scalar(bool check_call_memory)
|
||||||
ast parse::multi_assgin()
|
ast parse::multi_assgin()
|
||||||
{
|
{
|
||||||
ast node(toks[ptr].line,toks[ptr].col,ast_multi_assign);
|
ast node(toks[ptr].line,toks[ptr].col,ast_multi_assign);
|
||||||
node.add(multi_scalar(true));
|
node.add(multi_scalar());
|
||||||
match(tok_eq);
|
match(tok_eq);
|
||||||
if(lookahead(tok_eof)){
|
if(lookahead(tok_eof)){
|
||||||
die(thisline,thiscol,thislen,"expected value list");
|
die(thisline,thiscol,thislen,"expected value list");
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
if(lookahead(tok_lcurve)){
|
if(lookahead(tok_lcurve)){
|
||||||
node.add(check_tuple()?multi_scalar(false):calc());
|
node.add(check_tuple()?multi_scalar():calc());
|
||||||
}else{
|
}else{
|
||||||
node.add(calc());
|
node.add(calc());
|
||||||
}
|
}
|
||||||
|
@ -948,7 +926,6 @@ ast parse::iter_gen()
|
||||||
while(is_call(toks[ptr].type)){
|
while(is_call(toks[ptr].type)){
|
||||||
node.add(call_scalar());
|
node.add(call_scalar());
|
||||||
}
|
}
|
||||||
check_memory_reachable(node);
|
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
16
stl/lib.nas
16
stl/lib.nas
|
@ -456,14 +456,14 @@ var dylib={
|
||||||
# get dlcall function with limited parameter list
|
# get dlcall function with limited parameter list
|
||||||
limitcall: func(arg_size=0){
|
limitcall: func(arg_size=0){
|
||||||
if(arg_size==0){return func(ptr){return __dlcall};}
|
if(arg_size==0){return func(ptr){return __dlcall};}
|
||||||
else if(arg_size==1){return func(ptr,_0){return __dlcall};}
|
elsif(arg_size==1){return func(ptr,_0){return __dlcall};}
|
||||||
else if(arg_size==2){return func(ptr,_0,_1){return __dlcall};}
|
elsif(arg_size==2){return func(ptr,_0,_1){return __dlcall};}
|
||||||
else if(arg_size==3){return func(ptr,_0,_1,_2){return __dlcall};}
|
elsif(arg_size==3){return func(ptr,_0,_1,_2){return __dlcall};}
|
||||||
else if(arg_size==4){return func(ptr,_0,_1,_2,_3){return __dlcall};}
|
elsif(arg_size==4){return func(ptr,_0,_1,_2,_3){return __dlcall};}
|
||||||
else if(arg_size==5){return func(ptr,_0,_1,_2,_3,_4){return __dlcall};}
|
elsif(arg_size==5){return func(ptr,_0,_1,_2,_3,_4){return __dlcall};}
|
||||||
else if(arg_size==6){return func(ptr,_0,_1,_2,_3,_4,_5){return __dlcall};}
|
elsif(arg_size==6){return func(ptr,_0,_1,_2,_3,_4,_5){return __dlcall};}
|
||||||
else if(arg_size==7){return func(ptr,_0,_1,_2,_3,_4,_5,_6){return __dlcall};}
|
elsif(arg_size==7){return func(ptr,_0,_1,_2,_3,_4,_5,_6){return __dlcall};}
|
||||||
else if(arg_size==8){return func(ptr,_0,_1,_2,_3,_4,_5,_6,_7){return __dlcall};}
|
elsif(arg_size==8){return func(ptr,_0,_1,_2,_3,_4,_5,_6,_7){return __dlcall};}
|
||||||
else{return func(ptr,args...){return __dlcallv};}
|
else{return func(ptr,args...){return __dlcallv};}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,22 +32,66 @@ var z2 = {
|
||||||
listt2: y2,
|
listt2: y2,
|
||||||
};
|
};
|
||||||
|
|
||||||
println(w);#//1
|
println(w); #//1
|
||||||
println(x);#//hello
|
println(x); #//hello
|
||||||
println(y);#//[1,hello]
|
println(y); #//[1,hello]
|
||||||
println(z);#//{...}
|
println(z); #//{...}
|
||||||
println(z1);#//{...}
|
println(z1); #//{...}
|
||||||
println(y2);#//[...]
|
println(y2); #//[...]
|
||||||
println(y[0]);#//1
|
println(y[0]); #//1
|
||||||
println(y1[2][1]);#//hello
|
println(y1[2][1]); #//hello
|
||||||
println(z.numb);#//1
|
println(z.numb); #//1
|
||||||
println(z.listt[2][1]);#//hello
|
println(z.listt[2][1]); #//hello
|
||||||
println(z1.hashh.listt[2][1]);#//hello
|
println(z1.hashh.listt[2][1]); #//hello
|
||||||
println(y2[3].hashh.listt[2][1]);#//hello
|
println(y2[3].hashh.listt[2][1]);#//hello
|
||||||
println(f);#//func(..){..}
|
println(f); #//func(..){..}
|
||||||
f();#//f is called
|
f(); #//f is called
|
||||||
println(z.funcc);#//func(..){..}
|
println(z.funcc); #//func(..){..}
|
||||||
z.funcc();#//f is called
|
z.funcc(); #//f is called
|
||||||
println(z.funcccall);#//func(..){..}
|
println(z.funcccall); #//func(..){..}
|
||||||
z2.listt2[3].hashh.funcc();#//f is called
|
z2.listt2[3].hashh.funcc(); #//f is called
|
||||||
println(y1[f2()][w]);#//hello
|
println(y1[f2()][w]); #//hello
|
||||||
|
|
||||||
|
|
||||||
|
# ValKmjolnir
|
||||||
|
func(){
|
||||||
|
var tm=maketimestamp();
|
||||||
|
var duration=0;
|
||||||
|
var f1=func(){}
|
||||||
|
var f2=func(){var a=1;return a+1;}
|
||||||
|
var f3=func(){var (a,b)=(1,1);return a+b+1;}
|
||||||
|
tm.stamp();
|
||||||
|
for(var i=0;i<1e7;i+=1);
|
||||||
|
duration=tm.elapsedMSec()/1e3;
|
||||||
|
println("total ",duration," sec, ",str(int(1e7/duration/1e6))," M calc/sec");
|
||||||
|
tm.stamp();
|
||||||
|
for(var i=0;i<1e7;i+=1)f1();
|
||||||
|
duration=tm.elapsedMSec()/1e3;
|
||||||
|
println("total ",duration," sec, ",str(int(1e7/duration/1e6))," M calc/sec");
|
||||||
|
tm.stamp();
|
||||||
|
for(var i=0;i<1e7;i+=1)func{}();
|
||||||
|
duration=tm.elapsedMSec()/1e3;
|
||||||
|
println("total ",duration," sec, ",str(int(1e7/duration/1e6))," M calc/sec");
|
||||||
|
tm.stamp();
|
||||||
|
for(var i=0;i<1e7;i+=1)f2();
|
||||||
|
duration=tm.elapsedMSec()/1e3;
|
||||||
|
println("total ",duration," sec, ",str(int(1e7/duration/1e6))," M calc/sec");
|
||||||
|
for(var i=0;i<1e7;i+=1)
|
||||||
|
func{
|
||||||
|
var a=1;
|
||||||
|
return a+1;
|
||||||
|
}();
|
||||||
|
duration=tm.elapsedMSec()/1e3;
|
||||||
|
println("total ",duration," sec, ",str(int(1e7/duration/1e6))," M calc/sec");
|
||||||
|
tm.stamp();
|
||||||
|
for(var i=0;i<1e7;i+=1)f3();
|
||||||
|
duration=tm.elapsedMSec()/1e3;
|
||||||
|
println("total ",duration," sec, ",str(int(1e7/duration/1e6))," M calc/sec");
|
||||||
|
for(var i=0;i<1e7;i+=1)
|
||||||
|
func{
|
||||||
|
var (a,b)=(1,1);
|
||||||
|
return a+b+1;
|
||||||
|
}();
|
||||||
|
duration=tm.elapsedMSec()/1e3;
|
||||||
|
println("total ",duration," sec, ",str(int(1e7/duration/1e6))," M calc/sec");
|
||||||
|
}();
|
Loading…
Reference in New Issue