diff --git a/nasal_codegen.h b/nasal_codegen.h index 815bb5e..eb66dd5 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -14,10 +14,9 @@ enum op_code op_pzero, // push 0 to the stack op_pnil, // push constant nil to the stack op_pstr, // push constant string to the stack - op_newv, // push new vector to the stack + op_newv, // push new vector with initial values from stack op_newh, // push new hash to the stack op_newf, // push new function to the stack - op_vapp, // vector append op_happ, // hash append op_para, // normal parameter op_defpara, // default parameter @@ -88,7 +87,6 @@ struct {op_newv, "newv "}, {op_newh, "newh "}, {op_newf, "newf "}, - {op_vapp, "vapp "}, {op_happ, "happ "}, {op_para, "para "}, {op_defpara, "def "}, @@ -164,15 +162,15 @@ private: int error; int in_forindex; int in_foreach; - std::unordered_map number_table; - std::unordered_map string_table; - std::vector num_res_table; - std::vector str_res_table; - std::vector exec_code; - std::list > continue_ptr; - std::list > break_ptr; - std::vector global; - std::list > local; + std::unordered_map number_table; + std::unordered_map string_table; + std::vector num_res_table; + std::vector str_res_table; + std::vector exec_code; + std::list> continue_ptr; + std::list> break_ptr; + std::vector global; + std::list> local; void die(std::string,int); void regist_number(double); @@ -325,10 +323,9 @@ void nasal_codegen::str_gen(nasal_ast& ast) void nasal_codegen::vec_gen(nasal_ast& ast) { - gen(op_newv,0); for(auto& node:ast.get_children()) calc_gen(node); - gen(op_vapp,ast.get_children().size()); + gen(op_newv,ast.get_children().size()); return; } diff --git a/nasal_gc.h b/nasal_gc.h index ce2f94f..489d4da 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -242,7 +242,7 @@ std::string nasal_val::to_string() struct nasal_gc { -#define STACK_MAX_DEPTH (65536<<2) +#define STACK_MAX_DEPTH (65536<<1) 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 @@ -254,7 +254,7 @@ struct nasal_gc std::vector memory; // gc memory std::queue free_list[vm_type_size]; // gc free list std::vector global; - std::list > local; + std::list> local; void mark(); void sweep(); void gc_init(std::vector&,std::vector&); diff --git a/nasal_vm.h b/nasal_vm.h index 58d9807..f58df80 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -32,7 +32,6 @@ private: void opr_newv(); void opr_newh(); void opr_newf(); - void opr_vapp(); void opr_happ(); void opr_para(); void opr_defpara(); @@ -150,12 +149,12 @@ void nasal_vm::opr_intg() void nasal_vm::opr_intl() { (*stack_top)->ptr.func->closure.resize(exec_code[pc].num,gc.nil_addr); - (*stack_top)->ptr.func->closure[0]=gc.nil_addr;// me return; } void nasal_vm::opr_offset() { (*stack_top)->ptr.func->offset=exec_code[pc].num; + return; } void nasal_vm::opr_loadg() { @@ -194,8 +193,14 @@ void nasal_vm::opr_pstr() } void nasal_vm::opr_newv() { - nasal_val* vec=gc.gc_alloc(vm_vec); - *(++stack_top)=vec; + nasal_val* vec_addr=gc.gc_alloc(vm_vec); + nasal_val** begin=stack_top-exec_code[pc].num+1; + auto& vec=vec_addr->ptr.vec->elems;// stack_top-exec_code[pc].num stores the vector + vec.resize(exec_code[pc].num); + for(int i=0;iptr.vec->elems;// stack_top-exec_code[pc].num stores the vector - vec.resize(exec_code[pc].num); - for(int i=0;itype) { - case vm_num:num=val->ptr.num;break; - case vm_str:num=str2num(val->ptr.str->c_str());break; + case vm_num:num=(int)val->ptr.num;break; + case vm_str:num=(int)str2num(val->ptr.str->c_str());break; default:die("slc: error value type");break; } - nasal_val* res=(*stack_top)->ptr.vec->get_val((int)num); + nasal_val* res=(*stack_top)->ptr.vec->get_val(num); if(!res) die("slc: index out of range"); gc.slice_stack.back()->ptr.vec->elems.push_back(res); @@ -762,13 +757,18 @@ void nasal_vm::opr_slc2() die("slc2: begin index must be less than end index"); return; } - if(num1<-ref_size || num1>=ref_size || num2<-ref_size || num2>=ref_size) + else if(num1<-ref_size || num1>=ref_size) { - die("slc2: begin or end index out of range"); + die("slc2: begin index out of range: "+num2str(num1)); + return; + } + else if(num2<-ref_size || num2>=ref_size) + { + die("slc2: end index out of range: "+num2str(num2)); return; } for(int i=num1;i<=num2;++i) - aim.push_back(ref[i]); + aim.push_back(i>=0?ref[i]:ref[i+ref_size]); return; } void nasal_vm::opr_mcallg() @@ -849,6 +849,7 @@ void nasal_vm::opr_ret() pc=ret.top(); ret.pop(); nasal_val* ret_val=*stack_top--; + (*stack_top)->ptr.func->closure[0]=gc.nil_addr;// set me to nil *stack_top=ret_val; return; } @@ -870,7 +871,6 @@ void nasal_vm::run() &nasal_vm::opr_newv, &nasal_vm::opr_newh, &nasal_vm::opr_newf, - &nasal_vm::opr_vapp, &nasal_vm::opr_happ, &nasal_vm::opr_para, &nasal_vm::opr_defpara, diff --git a/test/ascii-art.nas b/test/ascii-art.nas index 2594565..bad2dbe 100644 --- a/test/ascii-art.nas +++ b/test/ascii-art.nas @@ -4,7 +4,7 @@ var char_ttf=[ [" ████╗"," ██╔██║"," ██╔╝██║"," ███████║","██╔═══██║","╚═╝ ╚═╝"], ["██████╗ ","██╔══██╗","██████╔╝","██╔══██╗","██████╔╝","╚═════╝ "], [" ██████╗","██╔════╝","██║ ","██║ ","╚██████╗"," ╚═════╝"], - ["██████╗ ","██╔══██╗","██║ ██║","██║ ██║","██████╔╝","╚═════╝ "], + ["██████╗ ","██╔══██╗","██║ ██║","██║ ██║","██████╔╝","╚═════╝ "], ["███████╗","██╔════╝","█████╗ ","██╔══╝ ","███████╗","╚══════╝"], ["███████╗","██╔════╝","█████╗ ","██╔══╝ ","██║ ","╚═╝ "], [" █████╗ ","██╔═══╝ ","██║ ██╗ ","██║ ╚██╗","╚█████╔╝"," ╚════╝ "],