update
This commit is contained in:
parent
73c9f98f4f
commit
9eb72f8754
110
nasal.h
110
nasal.h
|
@ -1,11 +1,14 @@
|
||||||
#ifndef __NASAL_H__
|
#ifndef __NASAL_H__
|
||||||
#define __NASAL_H__
|
#define __NASAL_H__
|
||||||
|
|
||||||
|
#pragma GCC optimize(2)
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -18,7 +21,112 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "nasal_misc.h"
|
/*
|
||||||
|
check if a string can be converted to a number
|
||||||
|
if this string cannot be converted to a number,it will return nan
|
||||||
|
*/
|
||||||
|
inline double hex_to_double(std::string str,int len)
|
||||||
|
{
|
||||||
|
double ret=0;
|
||||||
|
for(int i=2;i<len;++i)
|
||||||
|
{
|
||||||
|
ret*=16;
|
||||||
|
if('0'<=str[i] && str[i]<='9')
|
||||||
|
ret+=(str[i]-'0');
|
||||||
|
else if('a'<=str[i] && str[i]<='f')
|
||||||
|
ret+=(str[i]-'a'+10);
|
||||||
|
else if('A'<=str[i] && str[i]<='F')
|
||||||
|
ret+=(str[i]-'A'+10);
|
||||||
|
else
|
||||||
|
return std::nan("");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline double oct_to_double(std::string str,int len)
|
||||||
|
{
|
||||||
|
double ret=0;
|
||||||
|
for(int i=2;i<len;++i)
|
||||||
|
{
|
||||||
|
ret*=8;
|
||||||
|
if('0'<=str[i] && str[i]<='8')
|
||||||
|
ret+=(str[i]-'0');
|
||||||
|
else
|
||||||
|
return std::nan("");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline double dec_to_double(std::string str,int len)
|
||||||
|
{
|
||||||
|
double ret=0;
|
||||||
|
int i=0;
|
||||||
|
while('0'<=str[i] && str[i]<='9' && i<len)
|
||||||
|
ret=ret*10+(str[i++]-'0');
|
||||||
|
if(i==len) return ret;
|
||||||
|
if(str[i]!='.' && str[i]!='e' && str[i]!='E')
|
||||||
|
return std::nan("");
|
||||||
|
if(str[i]=='.')
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if(i==len) return std::nan("");
|
||||||
|
double num_pow=0.1;
|
||||||
|
while('0'<=str[i] && str[i]<='9' && i<len)
|
||||||
|
{
|
||||||
|
ret+=num_pow*(str[i++]-'0');
|
||||||
|
num_pow*=0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i==len) return ret;
|
||||||
|
if(str[i]!='e' && str[i]!='E')
|
||||||
|
return std::nan("");
|
||||||
|
++i;
|
||||||
|
if(i==len) return std::nan("");
|
||||||
|
double negative=(str[i]=='-'? -1:1);
|
||||||
|
if(str[i]=='-' || str[i]=='+')
|
||||||
|
++i;
|
||||||
|
if(i==len) return std::nan("");
|
||||||
|
double num_pow=0;
|
||||||
|
for(;i<len;++i)
|
||||||
|
{
|
||||||
|
if('0'<=str[i] && str[i]<='9')
|
||||||
|
num_pow=num_pow*10+(str[i]-'0');
|
||||||
|
else
|
||||||
|
return std::nan("");
|
||||||
|
}
|
||||||
|
return ret*std::pow(10,negative*num_pow);
|
||||||
|
}
|
||||||
|
double trans_string_to_number(std::string str)
|
||||||
|
{
|
||||||
|
double is_negative=1;
|
||||||
|
int len=str.length();
|
||||||
|
double ret_num=0;
|
||||||
|
if(!len) return std::nan("");
|
||||||
|
if(str[0]=='-' || str[0]=='+')
|
||||||
|
{
|
||||||
|
if(len==1) return std::nan("");
|
||||||
|
is_negative=(str[0]=='-'?-1:1);
|
||||||
|
str=str.substr(1,len--);
|
||||||
|
}
|
||||||
|
if(len>2 && str[0]=='0' && str[1]=='x')
|
||||||
|
ret_num=hex_to_double(str,len);
|
||||||
|
else if(len>2 && str[0]=='0' && str[1]=='o')
|
||||||
|
ret_num=oct_to_double(str,len);
|
||||||
|
else
|
||||||
|
ret_num=dec_to_double(str,len);
|
||||||
|
return is_negative*ret_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
trans_number_to_string:
|
||||||
|
convert number to string
|
||||||
|
*/
|
||||||
|
std::string trans_number_to_string(double number)
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss<<number;
|
||||||
|
ss>>res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
#include "nasal_lexer.h"
|
#include "nasal_lexer.h"
|
||||||
#include "nasal_ast.h"
|
#include "nasal_ast.h"
|
||||||
#include "nasal_parse.h"
|
#include "nasal_parse.h"
|
||||||
|
|
|
@ -107,10 +107,10 @@ public:
|
||||||
void set_str(std::string&);
|
void set_str(std::string&);
|
||||||
void set_num(double);
|
void set_num(double);
|
||||||
void add_child(nasal_ast);
|
void add_child(nasal_ast);
|
||||||
int get_line();
|
int get_line();
|
||||||
int get_type();
|
int get_type();
|
||||||
std::string get_str();
|
std::string get_str();
|
||||||
double get_num();
|
double get_num();
|
||||||
std::vector<nasal_ast>& get_children();
|
std::vector<nasal_ast>& get_children();
|
||||||
void print_ast(int);
|
void print_ast(int);
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,7 +51,7 @@ int builtin_contains(int,nasal_virtual_machine&);
|
||||||
int builtin_delete(int,nasal_virtual_machine&);
|
int builtin_delete(int,nasal_virtual_machine&);
|
||||||
int builtin_getkeys(int,nasal_virtual_machine&);
|
int builtin_getkeys(int,nasal_virtual_machine&);
|
||||||
int builtin_import(int,nasal_virtual_machine&);
|
int builtin_import(int,nasal_virtual_machine&);
|
||||||
int builtin_die_state;// used in builtin_die
|
bool builtin_die_state;// used in builtin_die
|
||||||
int builtin_die(int,nasal_virtual_machine&);
|
int builtin_die(int,nasal_virtual_machine&);
|
||||||
int builtin_type(int,nasal_virtual_machine&);
|
int builtin_type(int,nasal_virtual_machine&);
|
||||||
int builtin_substr(int,nasal_virtual_machine&);
|
int builtin_substr(int,nasal_virtual_machine&);
|
||||||
|
@ -773,7 +773,7 @@ int builtin_die(int local_scope_addr,nasal_virtual_machine& nasal_vm)
|
||||||
std::cout<<">> [runtime] builtin_die: \"str\" has wrong type(must be string).\n";
|
std::cout<<">> [runtime] builtin_die: \"str\" has wrong type(must be string).\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
builtin_die_state=1;
|
builtin_die_state=true;
|
||||||
std::cout<<">> [runtime] error: "<<nasal_vm.gc_get(str_addr).get_string()<<'\n';
|
std::cout<<">> [runtime] error: "<<nasal_vm.gc_get(str_addr).get_string()<<'\n';
|
||||||
int ret_addr=nasal_vm.gc_alloc(vm_nil);
|
int ret_addr=nasal_vm.gc_alloc(vm_nil);
|
||||||
return ret_addr;
|
return ret_addr;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
class nasal_bytecode_vm
|
class nasal_bytecode_vm
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int error;
|
bool main_loop_break_mark;
|
||||||
int ptr;
|
int ptr;
|
||||||
int global_scope_addr;
|
int global_scope_addr;
|
||||||
// garbage collector and memory manager
|
// garbage collector and memory manager
|
||||||
|
@ -25,8 +25,6 @@ private:
|
||||||
std::vector<std::string> string_table;
|
std::vector<std::string> string_table;
|
||||||
// number table
|
// number table
|
||||||
std::vector<double> number_table;
|
std::vector<double> number_table;
|
||||||
// opcode -> function address table
|
|
||||||
std::vector<void (nasal_bytecode_vm::*)()> opr_table;
|
|
||||||
// builtin function address table
|
// builtin function address table
|
||||||
std::map<std::string,int (*)(int x,nasal_virtual_machine& vm)> builtin_func_hashmap;
|
std::map<std::string,int (*)(int x,nasal_virtual_machine& vm)> builtin_func_hashmap;
|
||||||
void die(std::string);
|
void die(std::string);
|
||||||
|
@ -89,92 +87,18 @@ private:
|
||||||
void opr_return();
|
void opr_return();
|
||||||
public:
|
public:
|
||||||
nasal_bytecode_vm();
|
nasal_bytecode_vm();
|
||||||
~nasal_bytecode_vm();
|
|
||||||
void clear();
|
void clear();
|
||||||
void run(std::vector<std::string>&,std::vector<double>&,std::vector<opcode>&);
|
void run(std::vector<std::string>&,std::vector<double>&,std::vector<opcode>&);
|
||||||
|
void nas_switch_threading(std::vector<std::string>&,std::vector<double>&,std::vector<opcode>&);
|
||||||
};
|
};
|
||||||
|
|
||||||
nasal_bytecode_vm::nasal_bytecode_vm()
|
nasal_bytecode_vm::nasal_bytecode_vm()
|
||||||
{
|
{
|
||||||
local_scope_stack.push(-1);
|
local_scope_stack.push(-1);
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int op;
|
|
||||||
void (nasal_bytecode_vm::*ptr)();
|
|
||||||
}function_table[]=
|
|
||||||
{
|
|
||||||
{op_nop, nasal_bytecode_vm::opr_nop},
|
|
||||||
{op_load, nasal_bytecode_vm::opr_load},
|
|
||||||
{op_pushnum, nasal_bytecode_vm::opr_pushnum},
|
|
||||||
{op_pushone, nasal_bytecode_vm::opr_pushone},
|
|
||||||
{op_pushzero, nasal_bytecode_vm::opr_pushzero},
|
|
||||||
{op_pushnil, nasal_bytecode_vm::opr_pushnil},
|
|
||||||
{op_pushstr, nasal_bytecode_vm::opr_pushstr},
|
|
||||||
{op_newvec, nasal_bytecode_vm::opr_newvec},
|
|
||||||
{op_newhash, nasal_bytecode_vm::opr_newhash},
|
|
||||||
{op_newfunc, nasal_bytecode_vm::opr_newfunc},
|
|
||||||
{op_vecapp, nasal_bytecode_vm::opr_vecapp},
|
|
||||||
{op_hashapp, nasal_bytecode_vm::opr_hashapp},
|
|
||||||
{op_para, nasal_bytecode_vm::opr_para},
|
|
||||||
{op_defpara, nasal_bytecode_vm::opr_defpara},
|
|
||||||
{op_dynpara, nasal_bytecode_vm::opr_dynpara},
|
|
||||||
{op_entry, nasal_bytecode_vm::opr_entry},
|
|
||||||
{op_unot, nasal_bytecode_vm::opr_unot},
|
|
||||||
{op_usub, nasal_bytecode_vm::opr_usub},
|
|
||||||
{op_add, nasal_bytecode_vm::opr_add},
|
|
||||||
{op_sub, nasal_bytecode_vm::opr_sub},
|
|
||||||
{op_mul, nasal_bytecode_vm::opr_mul},
|
|
||||||
{op_div, nasal_bytecode_vm::opr_div},
|
|
||||||
{op_lnk, nasal_bytecode_vm::opr_lnk},
|
|
||||||
{op_addeq, nasal_bytecode_vm::opr_addeq},
|
|
||||||
{op_subeq, nasal_bytecode_vm::opr_subeq},
|
|
||||||
{op_muleq, nasal_bytecode_vm::opr_muleq},
|
|
||||||
{op_diveq, nasal_bytecode_vm::opr_diveq},
|
|
||||||
{op_lnkeq, nasal_bytecode_vm::opr_lnkeq},
|
|
||||||
{op_meq, nasal_bytecode_vm::opr_meq},
|
|
||||||
{op_eq, nasal_bytecode_vm::opr_eq},
|
|
||||||
{op_neq, nasal_bytecode_vm::opr_neq},
|
|
||||||
{op_less, nasal_bytecode_vm::opr_less},
|
|
||||||
{op_leq, nasal_bytecode_vm::opr_leq},
|
|
||||||
{op_grt, nasal_bytecode_vm::opr_grt},
|
|
||||||
{op_geq, nasal_bytecode_vm::opr_geq},
|
|
||||||
{op_pop, nasal_bytecode_vm::opr_pop},
|
|
||||||
{op_jmp, nasal_bytecode_vm::opr_jmp},
|
|
||||||
{op_jmptrue, nasal_bytecode_vm::opr_jmptrue},
|
|
||||||
{op_jmpfalse, nasal_bytecode_vm::opr_jmpfalse},
|
|
||||||
{op_counter, nasal_bytecode_vm::opr_counter},
|
|
||||||
{op_forindex, nasal_bytecode_vm::opr_forindex},
|
|
||||||
{op_foreach, nasal_bytecode_vm::opr_foreach},
|
|
||||||
{op_call, nasal_bytecode_vm::opr_call},
|
|
||||||
{op_callv, nasal_bytecode_vm::opr_callv},
|
|
||||||
{op_callvi, nasal_bytecode_vm::opr_callvi},
|
|
||||||
{op_callh, nasal_bytecode_vm::opr_callh},
|
|
||||||
{op_callf, nasal_bytecode_vm::opr_callf},
|
|
||||||
{op_builtincall, nasal_bytecode_vm::opr_builtincall},
|
|
||||||
{op_slicebegin, nasal_bytecode_vm::opr_slicebegin},
|
|
||||||
{op_sliceend, nasal_bytecode_vm::opr_sliceend},
|
|
||||||
{op_slice, nasal_bytecode_vm::opr_slice},
|
|
||||||
{op_slice2, nasal_bytecode_vm::opr_slice2},
|
|
||||||
{op_mcall, nasal_bytecode_vm::opr_mcall},
|
|
||||||
{op_mcallv, nasal_bytecode_vm::opr_mcallv},
|
|
||||||
{op_mcallh, nasal_bytecode_vm::opr_mcallh},
|
|
||||||
{op_return, nasal_bytecode_vm::opr_return},
|
|
||||||
{-1,NULL}
|
|
||||||
};
|
|
||||||
for(int i=0;function_table[i].ptr;++i)
|
|
||||||
opr_table.push_back(NULL);
|
|
||||||
for(int i=0;function_table[i].ptr;++i)
|
|
||||||
opr_table[function_table[i].op]=function_table[i].ptr;
|
|
||||||
for(int i=0;builtin_func_table[i].func_pointer;++i)
|
for(int i=0;builtin_func_table[i].func_pointer;++i)
|
||||||
builtin_func_hashmap[builtin_func_table[i].func_name]=builtin_func_table[i].func_pointer;
|
builtin_func_hashmap[builtin_func_table[i].func_name]=builtin_func_table[i].func_pointer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nasal_bytecode_vm::~nasal_bytecode_vm()
|
|
||||||
{
|
|
||||||
opr_table.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void nasal_bytecode_vm::clear()
|
void nasal_bytecode_vm::clear()
|
||||||
{
|
{
|
||||||
vm.clear();
|
vm.clear();
|
||||||
|
@ -192,7 +116,6 @@ void nasal_bytecode_vm::clear()
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::die(std::string str)
|
void nasal_bytecode_vm::die(std::string str)
|
||||||
{
|
{
|
||||||
++error;
|
|
||||||
std::string numinfo="";
|
std::string numinfo="";
|
||||||
int num=ptr;
|
int num=ptr;
|
||||||
for(int i=0;i<8;++i)
|
for(int i=0;i<8;++i)
|
||||||
|
@ -202,6 +125,7 @@ void nasal_bytecode_vm::die(std::string str)
|
||||||
num>>=4;
|
num>>=4;
|
||||||
}
|
}
|
||||||
std::cout<<">> [vm] 0x"<<numinfo<<": "<<str<<'\n';
|
std::cout<<">> [vm] 0x"<<numinfo<<": "<<str<<'\n';
|
||||||
|
main_loop_break_mark=false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool nasal_bytecode_vm::check_condition(int value_addr)
|
bool nasal_bytecode_vm::check_condition(int value_addr)
|
||||||
|
@ -225,6 +149,8 @@ bool nasal_bytecode_vm::check_condition(int value_addr)
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_nop()
|
void nasal_bytecode_vm::opr_nop()
|
||||||
{
|
{
|
||||||
|
// nop is the end of this program
|
||||||
|
main_loop_break_mark=false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_load()
|
void nasal_bytecode_vm::opr_load()
|
||||||
|
@ -260,8 +186,7 @@ void nasal_bytecode_vm::opr_pushzero()
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_pushnil()
|
void nasal_bytecode_vm::opr_pushnil()
|
||||||
{
|
{
|
||||||
int val_addr=vm.gc_alloc(vm_nil);
|
value_stack.push(vm.gc_alloc(vm_nil));
|
||||||
value_stack.push(val_addr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_pushstr()
|
void nasal_bytecode_vm::opr_pushstr()
|
||||||
|
@ -273,14 +198,12 @@ void nasal_bytecode_vm::opr_pushstr()
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_newvec()
|
void nasal_bytecode_vm::opr_newvec()
|
||||||
{
|
{
|
||||||
int val_addr=vm.gc_alloc(vm_vector);
|
value_stack.push(vm.gc_alloc(vm_vector));
|
||||||
value_stack.push(val_addr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_newhash()
|
void nasal_bytecode_vm::opr_newhash()
|
||||||
{
|
{
|
||||||
int val_addr=vm.gc_alloc(vm_hash);
|
value_stack.push(vm.gc_alloc(vm_hash));
|
||||||
value_stack.push(val_addr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_newfunc()
|
void nasal_bytecode_vm::opr_newfunc()
|
||||||
|
@ -314,22 +237,19 @@ void nasal_bytecode_vm::opr_hashapp()
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_para()
|
void nasal_bytecode_vm::opr_para()
|
||||||
{
|
{
|
||||||
std::string str=string_table[exec_code[ptr].index];
|
vm.gc_get(value_stack.top()).get_func().add_para(string_table[exec_code[ptr].index]);
|
||||||
vm.gc_get(value_stack.top()).get_func().add_para(str);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_defpara()
|
void nasal_bytecode_vm::opr_defpara()
|
||||||
{
|
{
|
||||||
int val_addr=value_stack.top();
|
int val_addr=value_stack.top();
|
||||||
value_stack.pop();
|
value_stack.pop();
|
||||||
std::string str=string_table[exec_code[ptr].index];
|
vm.gc_get(value_stack.top()).get_func().add_para(string_table[exec_code[ptr].index],val_addr);
|
||||||
vm.gc_get(value_stack.top()).get_func().add_para(str,val_addr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_dynpara()
|
void nasal_bytecode_vm::opr_dynpara()
|
||||||
{
|
{
|
||||||
std::string str=string_table[exec_code[ptr].index];
|
vm.gc_get(value_stack.top()).get_func().add_para(string_table[exec_code[ptr].index],-1,true);
|
||||||
vm.gc_get(value_stack.top()).get_func().add_para(str,-1,true);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_entry()
|
void nasal_bytecode_vm::opr_entry()
|
||||||
|
@ -983,9 +903,8 @@ void nasal_bytecode_vm::opr_geq()
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_pop()
|
void nasal_bytecode_vm::opr_pop()
|
||||||
{
|
{
|
||||||
int val_addr=value_stack.top();
|
vm.del_reference(value_stack.top());
|
||||||
value_stack.pop();
|
value_stack.pop();
|
||||||
vm.del_reference(val_addr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_jmp()
|
void nasal_bytecode_vm::opr_jmp()
|
||||||
|
@ -1265,24 +1184,22 @@ void nasal_bytecode_vm::opr_builtincall()
|
||||||
if(builtin_func_hashmap.find(val_name)!=builtin_func_hashmap.end())
|
if(builtin_func_hashmap.find(val_name)!=builtin_func_hashmap.end())
|
||||||
{
|
{
|
||||||
ret_value_addr=(*builtin_func_hashmap[val_name])(local_scope_stack.top(),vm);
|
ret_value_addr=(*builtin_func_hashmap[val_name])(local_scope_stack.top(),vm);
|
||||||
error+=builtin_die_state;
|
main_loop_break_mark=!builtin_die_state;
|
||||||
}
|
}
|
||||||
value_stack.push(ret_value_addr);
|
value_stack.push(ret_value_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_slicebegin()
|
void nasal_bytecode_vm::opr_slicebegin()
|
||||||
{
|
{
|
||||||
int val_addr=vm.gc_alloc(vm_vector);
|
slice_stack.push(vm.gc_alloc(vm_vector));
|
||||||
slice_stack.push(val_addr);
|
|
||||||
if(vm.gc_get(value_stack.top()).get_type()!=vm_vector)
|
if(vm.gc_get(value_stack.top()).get_type()!=vm_vector)
|
||||||
die("slcbegin: must slice a vector");
|
die("slcbegin: must slice a vector");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_sliceend()
|
void nasal_bytecode_vm::opr_sliceend()
|
||||||
{
|
{
|
||||||
int val_addr=slice_stack.top();
|
value_stack.push(slice_stack.top());
|
||||||
slice_stack.pop();
|
slice_stack.pop();
|
||||||
value_stack.push(val_addr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_slice()
|
void nasal_bytecode_vm::opr_slice()
|
||||||
|
@ -1463,24 +1380,78 @@ void nasal_bytecode_vm::run(std::vector<std::string>& strs,std::vector<double>&
|
||||||
{
|
{
|
||||||
string_table=strs;
|
string_table=strs;
|
||||||
number_table=nums;
|
number_table=nums;
|
||||||
int size=exec.size();
|
exec_code=exec;
|
||||||
for(int i=0;i<size;++i)
|
|
||||||
|
static void (nasal_bytecode_vm::*opr_table[])()=
|
||||||
{
|
{
|
||||||
opcode tmp;
|
nasal_bytecode_vm::opr_nop,
|
||||||
tmp=exec[i];
|
nasal_bytecode_vm::opr_load,
|
||||||
exec_code.push_back(tmp);
|
nasal_bytecode_vm::opr_pushnum,
|
||||||
}
|
nasal_bytecode_vm::opr_pushone,
|
||||||
|
nasal_bytecode_vm::opr_pushzero,
|
||||||
error=0;
|
nasal_bytecode_vm::opr_pushnil,
|
||||||
|
nasal_bytecode_vm::opr_pushstr,
|
||||||
|
nasal_bytecode_vm::opr_newvec,
|
||||||
|
nasal_bytecode_vm::opr_newhash,
|
||||||
|
nasal_bytecode_vm::opr_newfunc,
|
||||||
|
nasal_bytecode_vm::opr_vecapp,
|
||||||
|
nasal_bytecode_vm::opr_hashapp,
|
||||||
|
nasal_bytecode_vm::opr_para,
|
||||||
|
nasal_bytecode_vm::opr_defpara,
|
||||||
|
nasal_bytecode_vm::opr_dynpara,
|
||||||
|
nasal_bytecode_vm::opr_entry,
|
||||||
|
nasal_bytecode_vm::opr_unot,
|
||||||
|
nasal_bytecode_vm::opr_usub,
|
||||||
|
nasal_bytecode_vm::opr_add,
|
||||||
|
nasal_bytecode_vm::opr_sub,
|
||||||
|
nasal_bytecode_vm::opr_mul,
|
||||||
|
nasal_bytecode_vm::opr_div,
|
||||||
|
nasal_bytecode_vm::opr_lnk,
|
||||||
|
nasal_bytecode_vm::opr_addeq,
|
||||||
|
nasal_bytecode_vm::opr_subeq,
|
||||||
|
nasal_bytecode_vm::opr_muleq,
|
||||||
|
nasal_bytecode_vm::opr_diveq,
|
||||||
|
nasal_bytecode_vm::opr_lnkeq,
|
||||||
|
nasal_bytecode_vm::opr_meq,
|
||||||
|
nasal_bytecode_vm::opr_eq,
|
||||||
|
nasal_bytecode_vm::opr_neq,
|
||||||
|
nasal_bytecode_vm::opr_less,
|
||||||
|
nasal_bytecode_vm::opr_leq,
|
||||||
|
nasal_bytecode_vm::opr_grt,
|
||||||
|
nasal_bytecode_vm::opr_geq,
|
||||||
|
nasal_bytecode_vm::opr_pop,
|
||||||
|
nasal_bytecode_vm::opr_jmp,
|
||||||
|
nasal_bytecode_vm::opr_jmptrue,
|
||||||
|
nasal_bytecode_vm::opr_jmpfalse,
|
||||||
|
nasal_bytecode_vm::opr_counter,
|
||||||
|
nasal_bytecode_vm::opr_forindex,
|
||||||
|
nasal_bytecode_vm::opr_foreach,
|
||||||
|
nasal_bytecode_vm::opr_call,
|
||||||
|
nasal_bytecode_vm::opr_callv,
|
||||||
|
nasal_bytecode_vm::opr_callvi,
|
||||||
|
nasal_bytecode_vm::opr_callh,
|
||||||
|
nasal_bytecode_vm::opr_callf,
|
||||||
|
nasal_bytecode_vm::opr_builtincall,
|
||||||
|
nasal_bytecode_vm::opr_slicebegin,
|
||||||
|
nasal_bytecode_vm::opr_sliceend,
|
||||||
|
nasal_bytecode_vm::opr_slice,
|
||||||
|
nasal_bytecode_vm::opr_slice2,
|
||||||
|
nasal_bytecode_vm::opr_mcall,
|
||||||
|
nasal_bytecode_vm::opr_mcallv,
|
||||||
|
nasal_bytecode_vm::opr_mcallh,
|
||||||
|
nasal_bytecode_vm::opr_return
|
||||||
|
};
|
||||||
|
|
||||||
|
main_loop_break_mark=true;
|
||||||
|
builtin_die_state=false;
|
||||||
|
|
||||||
global_scope_addr=vm.gc_alloc(vm_closure);
|
global_scope_addr=vm.gc_alloc(vm_closure);
|
||||||
size=exec_code.size();
|
|
||||||
time_t begin_time=std::time(NULL);
|
time_t begin_time=std::time(NULL);
|
||||||
for(ptr=0;ptr<size;++ptr)
|
|
||||||
{
|
// main loop
|
||||||
|
for(ptr=0;main_loop_break_mark;++ptr)
|
||||||
(this->*opr_table[exec_code[ptr].op])();
|
(this->*opr_table[exec_code[ptr].op])();
|
||||||
if(error)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
time_t end_time=std::time(NULL);
|
time_t end_time=std::time(NULL);
|
||||||
time_t total_run_time=end_time-begin_time;
|
time_t total_run_time=end_time-begin_time;
|
||||||
if(total_run_time>=1)
|
if(total_run_time>=1)
|
||||||
|
|
|
@ -77,9 +77,9 @@ struct
|
||||||
{op_meq, "memeq "},
|
{op_meq, "memeq "},
|
||||||
{op_eq, "eq "},
|
{op_eq, "eq "},
|
||||||
{op_neq, "neq "},
|
{op_neq, "neq "},
|
||||||
{op_less, "l "},
|
{op_less, "less "},
|
||||||
{op_leq, "leq "},
|
{op_leq, "leq "},
|
||||||
{op_grt, "g "},
|
{op_grt, "grt "},
|
||||||
{op_geq, "geq "},
|
{op_geq, "geq "},
|
||||||
{op_pop, "pop "},
|
{op_pop, "pop "},
|
||||||
{op_jmp, "jmp "},
|
{op_jmp, "jmp "},
|
||||||
|
@ -115,7 +115,7 @@ struct opcode
|
||||||
index=0;
|
index=0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
opcode& operator=(opcode& tmp)
|
opcode& operator=(const opcode& tmp)
|
||||||
{
|
{
|
||||||
op=tmp.op;
|
op=tmp.op;
|
||||||
index=tmp.index;
|
index=tmp.index;
|
||||||
|
@ -1205,15 +1205,7 @@ void nasal_codegen::main_progress(nasal_ast& ast)
|
||||||
void nasal_codegen::print_op(int index)
|
void nasal_codegen::print_op(int index)
|
||||||
{
|
{
|
||||||
// print opcode ptr
|
// print opcode ptr
|
||||||
std::string numinfo="";
|
printf("0x%.8x: ",index);
|
||||||
int num=index;
|
|
||||||
for(int i=0;i<8;++i)
|
|
||||||
{
|
|
||||||
int tmp=num&0x0f;
|
|
||||||
numinfo=(char)(tmp>9? 'a'+tmp-10:'0'+tmp)+numinfo;
|
|
||||||
num>>=4;
|
|
||||||
}
|
|
||||||
std::cout<<"0x"<<numinfo<<": ";
|
|
||||||
// print opcode name
|
// print opcode name
|
||||||
for(int i=0;code_table[i].name;++i)
|
for(int i=0;code_table[i].name;++i)
|
||||||
if(exec_code[index].op==code_table[i].type)
|
if(exec_code[index].op==code_table[i].type)
|
||||||
|
@ -1222,15 +1214,7 @@ void nasal_codegen::print_op(int index)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// print opcode index
|
// print opcode index
|
||||||
numinfo="";
|
printf("0x%.8x ",exec_code[index].index);
|
||||||
num=exec_code[index].index;
|
|
||||||
for(int i=0;i<8;++i)
|
|
||||||
{
|
|
||||||
int tmp=num&0x0f;
|
|
||||||
numinfo=(char)(tmp>9? 'a'+tmp-10:'0'+tmp)+numinfo;
|
|
||||||
num>>=4;
|
|
||||||
}
|
|
||||||
std::cout<<"0x"<<numinfo<<" ";
|
|
||||||
// print detail info
|
// print detail info
|
||||||
switch(exec_code[index].op)
|
switch(exec_code[index].op)
|
||||||
{
|
{
|
||||||
|
|
12
nasal_gc.h
12
nasal_gc.h
|
@ -756,19 +756,19 @@ int nasal_virtual_machine::gc_alloc(int val_type)
|
||||||
}
|
}
|
||||||
nasal_scalar& nasal_virtual_machine::gc_get(int value_address)
|
nasal_scalar& nasal_virtual_machine::gc_get(int value_address)
|
||||||
{
|
{
|
||||||
if(0<=value_address && value_address<garbage_collector_memory.size() && !garbage_collector_memory[value_address]->collected)
|
if(0<=value_address && !garbage_collector_memory[value_address]->collected)
|
||||||
return garbage_collector_memory[value_address]->elem;
|
return garbage_collector_memory[value_address]->elem;
|
||||||
return error_returned_value;
|
return error_returned_value;
|
||||||
}
|
}
|
||||||
void nasal_virtual_machine::add_reference(int value_address)
|
void nasal_virtual_machine::add_reference(int value_address)
|
||||||
{
|
{
|
||||||
if(0<=value_address && value_address<garbage_collector_memory.size() && !garbage_collector_memory[value_address]->collected)
|
if(0<=value_address && !garbage_collector_memory[value_address]->collected)
|
||||||
++garbage_collector_memory[value_address]->ref_cnt;
|
++garbage_collector_memory[value_address]->ref_cnt;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_virtual_machine::del_reference(int value_address)
|
void nasal_virtual_machine::del_reference(int value_address)
|
||||||
{
|
{
|
||||||
if(0<=value_address && value_address<garbage_collector_memory.size() && !garbage_collector_memory[value_address]->collected)
|
if(0<=value_address && !garbage_collector_memory[value_address]->collected)
|
||||||
--garbage_collector_memory[value_address]->ref_cnt;
|
--garbage_collector_memory[value_address]->ref_cnt;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
@ -798,7 +798,7 @@ void nasal_virtual_machine::mem_free(int memory_address)
|
||||||
{
|
{
|
||||||
// mem_free has helped scalar to delete the reference
|
// mem_free has helped scalar to delete the reference
|
||||||
// so don't need to delete reference again
|
// so don't need to delete reference again
|
||||||
if(0<=memory_address && memory_address<memory_manager_memory.size())
|
if(0<=memory_address)
|
||||||
{
|
{
|
||||||
this->del_reference(memory_manager_memory[memory_address]);
|
this->del_reference(memory_manager_memory[memory_address]);
|
||||||
memory_manager_free_space.push(memory_address);
|
memory_manager_free_space.push(memory_address);
|
||||||
|
@ -809,7 +809,7 @@ void nasal_virtual_machine::mem_change(int memory_address,int value_address)
|
||||||
{
|
{
|
||||||
// this progress is used to change a memory space's value address
|
// this progress is used to change a memory space's value address
|
||||||
// be careful! this process doesn't check if this mem_space is in use.
|
// be careful! this process doesn't check if this mem_space is in use.
|
||||||
if(0<=memory_address && memory_address<memory_manager_memory.size())
|
if(0<=memory_address)
|
||||||
{
|
{
|
||||||
this->del_reference(memory_manager_memory[memory_address]);
|
this->del_reference(memory_manager_memory[memory_address]);
|
||||||
memory_manager_memory[memory_address]=value_address;
|
memory_manager_memory[memory_address]=value_address;
|
||||||
|
@ -819,7 +819,7 @@ void nasal_virtual_machine::mem_change(int memory_address,int value_address)
|
||||||
int nasal_virtual_machine::mem_get(int memory_address)
|
int nasal_virtual_machine::mem_get(int memory_address)
|
||||||
{
|
{
|
||||||
// be careful! this process doesn't check if this mem_space is in use.
|
// be careful! this process doesn't check if this mem_space is in use.
|
||||||
if(0<=memory_address && memory_address<memory_manager_memory.size())
|
if(0<=memory_address)
|
||||||
return memory_manager_memory[memory_address];
|
return memory_manager_memory[memory_address];
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
191
nasal_misc.h
191
nasal_misc.h
|
@ -1,191 +0,0 @@
|
||||||
#ifndef __NASAL_MISC_H__
|
|
||||||
#define __NASAL_MISC_H__
|
|
||||||
|
|
||||||
/*
|
|
||||||
check if a string can be converted to a number
|
|
||||||
|
|
||||||
strings like these below is correct:
|
|
||||||
'0.00012'
|
|
||||||
'12314.234'
|
|
||||||
'1234'
|
|
||||||
'0xdeadbeef'
|
|
||||||
'0xDEADBEEF'
|
|
||||||
'0o71230'
|
|
||||||
'1e23'
|
|
||||||
'1E-123'
|
|
||||||
'1.34E10'
|
|
||||||
|
|
||||||
if this string cannot be converted to a number,it will return nan
|
|
||||||
*/
|
|
||||||
inline double hex_to_double(std::string str,int len)
|
|
||||||
{
|
|
||||||
double ret=0,num_pow=1;
|
|
||||||
for(int i=len-1;i>1;--i)
|
|
||||||
{
|
|
||||||
if('0'<=str[i] && str[i]<='9')
|
|
||||||
ret+=num_pow*(str[i]-'0');
|
|
||||||
else if('a'<=str[i] && str[i]<='f')
|
|
||||||
ret+=num_pow*(str[i]-'a'+10);
|
|
||||||
else if('A'<=str[i] && str[i]<='F')
|
|
||||||
ret+=num_pow*(str[i]-'A'+10);
|
|
||||||
else
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
num_pow*=16;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
inline double oct_to_double(std::string str,int len)
|
|
||||||
{
|
|
||||||
double ret=0,num_pow=1;
|
|
||||||
for(int i=len-1;i>1;--i)
|
|
||||||
{
|
|
||||||
if('0'<=str[i] && str[i]<='8')
|
|
||||||
ret+=num_pow*(str[i]-'0');
|
|
||||||
else
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
num_pow*=8;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
inline double dec_to_double(std::string str,int len)
|
|
||||||
{
|
|
||||||
double ret=0;
|
|
||||||
int i=0;
|
|
||||||
while('0'<=str[i] && str[i]<='9' && i<len)
|
|
||||||
{
|
|
||||||
ret=ret*10+(str[i]-'0');
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
if(i==len) return ret;
|
|
||||||
if(str[i]!='.' && str[i]!='e' && str[i]!='E')
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
if(str[i]=='.')
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
if(i==len)
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
double num_pow=0.1;
|
|
||||||
while('0'<=str[i] && str[i]<='9' && i<len)
|
|
||||||
{
|
|
||||||
ret+=num_pow*(str[i]-'0');
|
|
||||||
num_pow*=0.1;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(i==len) return ret;
|
|
||||||
if(str[i]!='e' && str[i]!='E')
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
if(str[i]=='e' || str[i]=='E')
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
if(i==len)
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
double negative=(str[i]=='-'? -1:1);
|
|
||||||
if(str[i]=='-' || str[i]=='+')
|
|
||||||
++i;
|
|
||||||
if(i==len)
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
double num_pow=0;
|
|
||||||
for(;i<len;++i)
|
|
||||||
{
|
|
||||||
if('0'<=str[i] && str[i]<='9')
|
|
||||||
num_pow=num_pow*10+(str[i]-'0');
|
|
||||||
else
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
}
|
|
||||||
num_pow=std::pow(10,negative*num_pow);
|
|
||||||
ret*=num_pow;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
double trans_string_to_number(std::string str)
|
|
||||||
{
|
|
||||||
bool is_negative=false;
|
|
||||||
int len=str.length();
|
|
||||||
double ret_num=0;
|
|
||||||
if(!len)
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
if(str[0]=='-' || str[0]=='+')
|
|
||||||
{
|
|
||||||
is_negative=(str[0]=='-');
|
|
||||||
std::string tmp="";
|
|
||||||
for(int i=1;i<len;++i)
|
|
||||||
tmp.push_back(str[i]);
|
|
||||||
str=tmp;
|
|
||||||
--len;
|
|
||||||
if(!len)
|
|
||||||
return (1/0.0)+(-1/0.0);
|
|
||||||
}
|
|
||||||
if(len>2 && str[0]=='0' && str[1]=='x')
|
|
||||||
ret_num=hex_to_double(str,len);
|
|
||||||
else if(len>2 && str[0]=='0' && str[1]=='o')
|
|
||||||
ret_num=oct_to_double(str,len);
|
|
||||||
else
|
|
||||||
ret_num=dec_to_double(str,len);
|
|
||||||
return is_negative?-ret_num:ret_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
trans_number_to_string:
|
|
||||||
convert number to string
|
|
||||||
*/
|
|
||||||
std::string trans_number_to_string(double number)
|
|
||||||
{
|
|
||||||
std::string trans_num_string="";
|
|
||||||
if(number<0)
|
|
||||||
{
|
|
||||||
trans_num_string+='-';
|
|
||||||
number=-number;
|
|
||||||
}
|
|
||||||
if(number==0)
|
|
||||||
return "0";
|
|
||||||
double integer_bit=1;
|
|
||||||
while(number>=integer_bit)
|
|
||||||
integer_bit*=10;
|
|
||||||
integer_bit/=10;
|
|
||||||
if(integer_bit==0.1)
|
|
||||||
trans_num_string+='0';
|
|
||||||
while(integer_bit!=0.1)
|
|
||||||
{
|
|
||||||
trans_num_string+=(char)('0'+(int(number/integer_bit)));
|
|
||||||
number-=(double)(int(number/integer_bit))*integer_bit;
|
|
||||||
integer_bit/=10;
|
|
||||||
}
|
|
||||||
if(number>0.000000001)
|
|
||||||
trans_num_string+='.';
|
|
||||||
while(number>0.000000001)
|
|
||||||
{
|
|
||||||
trans_num_string+=(char)('0'+int(number*10));
|
|
||||||
number*=10;
|
|
||||||
number-=(double)(int(number));
|
|
||||||
}
|
|
||||||
return trans_num_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
prt_hex:
|
|
||||||
transform int to hex format and print it out (std::cout)
|
|
||||||
*/
|
|
||||||
void prt_hex(const int ptr)
|
|
||||||
{
|
|
||||||
char hex[9];
|
|
||||||
hex[8]=0;
|
|
||||||
int tmp_plc=ptr;
|
|
||||||
if(tmp_plc<0)
|
|
||||||
{
|
|
||||||
tmp_plc=-tmp_plc;
|
|
||||||
std::cout<<"-0x";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
std::cout<<"0x";
|
|
||||||
for(int j=7;j>=0;--j)
|
|
||||||
{
|
|
||||||
int tmp=(tmp_plc & 0x0000000f);
|
|
||||||
hex[j]=tmp<10? (char)('0'+tmp):(char)('a'+tmp-10);
|
|
||||||
tmp_plc>>=4;
|
|
||||||
}
|
|
||||||
std::cout<<hex;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -122,7 +122,7 @@ void nasal_runtime::set_root(nasal_ast& parse_result)
|
||||||
void nasal_runtime::run()
|
void nasal_runtime::run()
|
||||||
{
|
{
|
||||||
// this state is reserved for builtin_die
|
// this state is reserved for builtin_die
|
||||||
builtin_die_state=0;
|
builtin_die_state=false;
|
||||||
|
|
||||||
this->error=0;
|
this->error=0;
|
||||||
this->function_returned_address=-1;
|
this->function_returned_address=-1;
|
||||||
|
|
Loading…
Reference in New Issue