🐛 fix bug that `int()` cannot convert numeric string

This commit is contained in:
ValKmjolnir 2022-09-12 22:45:35 +08:00
parent aa5b1d3d66
commit 26f4e1359f
6 changed files with 179 additions and 11 deletions

View File

@ -49,7 +49,7 @@ var id=func(object){
return __id(object); return __id(object);
} }
# int will get the integer of input number. # int will get the integer of input number/string.
# but carefully use it, because int has range between -2147483648~2147483647 # but carefully use it, because int has range between -2147483648~2147483647
var int=func(val){ var int=func(val){
return __int(val); return __int(val);

View File

@ -193,9 +193,9 @@ nas_ref builtin_id(nas_ref* local,nasal_gc& gc)
nas_ref builtin_int(nas_ref* local,nasal_gc& gc) nas_ref builtin_int(nas_ref* local,nasal_gc& gc)
{ {
nas_ref val=local[1]; nas_ref val=local[1];
if(val.type!=vm_num) if(val.type!=vm_num && val.type!=vm_str)
return nil; return nil;
return {vm_num,f64((i32)val.num())}; return {vm_num,f64((i32)val.tonum())};
} }
nas_ref builtin_floor(nas_ref* local,nasal_gc& gc) nas_ref builtin_floor(nas_ref* local,nasal_gc& gc)
{ {

View File

@ -49,7 +49,7 @@ var id=func(object){
return __id(object); return __id(object);
} }
# int will get the integer of input number. # int will get the integer of input number/string.
# but carefully use it, because int has range between -2147483648~2147483647 # but carefully use it, because int has range between -2147483648~2147483647
var int=func(val){ var int=func(val){
return __int(val); return __int(val);

View File

@ -57,6 +57,7 @@ var testfile=[
"loop.nas", "loop.nas",
"mandel.nas", "mandel.nas",
"mandelbrot.nas", "mandelbrot.nas",
"mcpu.nas",
"md5.nas", "md5.nas",
"md5compare.nas", "md5compare.nas",
"module_test.nas", "module_test.nas",
@ -97,12 +98,6 @@ var longest=func(vec...){
} }
var padding_length=longest(source,lib,testfile,module); var padding_length=longest(source,lib,testfile,module);
var getname=func(s){
var (len,ch)=(size(s),' '[0]);
for(var i=0;i<len and s[i]!=ch;i+=1);
return substr(s,0,i);
}
var count=func(s,c){ var count=func(s,c){
var cnt=0; var cnt=0;
foreach(var i;split(c,s)) foreach(var i;split(c,s))
@ -119,7 +114,7 @@ var calc=func(codetype,files,path=""){
println(codetype); println(codetype);
var (bytes,ctx,line,semi,line_cnt,semi_cnt)=(0,"",0,0,0,0); var (bytes,ctx,line,semi,line_cnt,semi_cnt)=(0,"",0,0,0,0);
forindex(var i;files){ forindex(var i;files){
var s=io.fin(getname(path~files[i])); var s=io.exists(path~files[i])?io.fin(path~files[i]):"";
(line_cnt,semi_cnt)=(count(s,'\n'),count(s,';')); (line_cnt,semi_cnt)=(count(s,'\n'),count(s,';'));
println(rightpad(files[i],padding_length),'| ', println(rightpad(files[i],padding_length),'| ',
column(line_cnt),'line | ', column(line_cnt),'line | ',

172
test/mcpu.nas Normal file
View File

@ -0,0 +1,172 @@
var inst={
inst_stop:0,
inst_mov_reg_reg:1,
inst_mov_reg_imm_low:2,
inst_mov_reg_imm_high:3,
inst_add:4,
inst_sub:5,
inst_mult:6,
inst_div:7,
inst_and:8,
inst_or:9,
inst_xor:10,
inst_not:11,
inst_nand:12,
inst_shl:13,
inst_shr:14,
inst_jmp:15,
inst_jt:16,
inst_jf:17,
inst_les:18,
inst_grt:19,
inst_leq:20,
inst_geq:21,
inst_eq:22,
inst_in:23,
inst_out:24
};
var hex=func(){
var vec=[];
foreach(var i;['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'])
foreach(var j;['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'])
append(vec,i~j);
return func(n){
return vec[n];
}
}();
var hex32=func(n){
return hex(bits.u32_and(n/math.pow(2,24),0xff))~
hex(bits.u32_and(n/math.pow(2,16),0xff))~
hex(bits.u32_and(n/math.pow(2,8),0xff))~
hex(bits.u32_and(n,0xff));
}
var machine=func(disk_file){
var reg=[];
var reg_size=32;
var pc=0;
var ir=[0,0,0,0]; # 32 bit instruction word
var mem=[];
var mem_size=1024*1024*1; # memory size, byte
var init=func(){
println("[",os.time(),"] init ",reg_size," registers.");
setsize(reg,reg_size); # 8 bit address wire
for(var i=0;i<reg_size;i+=1)
reg[i]=0;
println("[",os.time(),"] init memory, memory size: ",mem_size/1024/1024,"MB.");
setsize(mem,mem_size);
for(var i=0;i<mem_size;i+=1)
mem[i]=0;
println("[",os.time(),"] init completed.");
}
init();
var load=func(){
var vec=split(" ",disk_file);
println("[",os.time(),"] loading boot from disk: ",size(vec)," byte.");
forindex(var i;vec)
mem[i]=int("0x"~vec[i]);
println("[",os.time(),"] loading complete.");
}
load();
var ctx_info=func(){
var cnt=0;
println("pc : 0x",hex32(pc));
println("instr : 0x",hex(ir[0]),hex(ir[1]),hex(ir[2]),hex(ir[3]));
for(var i=0;i<reg_size;i+=1){
print("reg[",hex(i),"]: 0x",hex32(reg[i])," ");
if(cnt==3){
print("\n");
cnt=0;
}else{
cnt+=1;
}
}
}
var exec=func(info=1){
while(1){
ir=[mem[pc],mem[pc+1],mem[pc+2],mem[pc+3]];
if(info)ctx_info();
var op=ir[0];
if(op==inst.inst_stop){
break;
}elsif(op==inst.inst_mov_reg_reg){
reg[ir[1]]=reg[ir[2]];
}elsif(op==inst.inst_mov_reg_imm_low){
reg[ir[1]]=bits.u32_and(reg[ir[1]],0xffff0000);
reg[ir[1]]=bits.u32_or(reg[ir[1]],ir[2]*math.pow(2,8)+ir[3]);
}elsif(op==inst.inst_mov_reg_imm_high){
reg[ir[1]]=bits.u32_and(reg[ir[1]],0x0000ffff);
reg[ir[1]]=bits.u32_or(reg[ir[1]],ir[2]*math.pow(2,24)+ir[3]*math.pow(2,16));
}elsif(op==inst.inst_add){
reg[ir[1]]=bits.u32_and(reg[ir[2]]+reg[ir[3]],0xffffffff);
}elsif(op==inst.inst_sub){
reg[ir[1]]=bits.u32_and(reg[ir[2]]-reg[ir[3]],0xffffffff);
}elsif(op==inst.inst_mult){
reg[ir[1]]=bits.u32_and(reg[ir[2]]*reg[ir[3]],0xffffffff);
}elsif(op==inst.inst_div){
reg[ir[1]]=bits.u32_and(reg[ir[2]]/reg[ir[3]],0xffffffff);
}elsif(op==inst.inst_and){
reg[ir[1]]=bits.u32_and(reg[ir[2]],reg[ir[3]]);
}elsif(op==inst.inst_or){
reg[ir[1]]=bits.u32_or(reg[ir[2]],reg[ir[3]]);
}elsif(op==inst.inst_xor){
reg[ir[1]]=bits.u32_xor(reg[ir[2]],reg[ir[3]]);
}elsif(op==inst.inst_not){
reg[ir[1]]=bits.u32_not(reg[ir[2]]);
}elsif(op==inst.inst_nand){
reg[ir[1]]=bits.u32_nand(reg[ir[2]],reg[ir[3]]);
}elsif(op==inst.inst_shl){
reg[ir[1]]=bits.u32_and(reg[ir[2]]*math.pow(2,reg[ir[3]]),0xffffffff);
}elsif(op==inst.inst_shr){
reg[ir[1]]=bits.u32_and(reg[ir[2]]/math.pow(2,reg[ir[3]]),0xffffffff);
}elsif(op==inst.inst_jmp){
pc=reg[ir[1]];
}elsif(op==inst.inst_jt){
pc=reg[ir[1]]?reg[ir[2]]:pc;
}elsif(op==inst.inst_jf){
pc=reg[ir[1]]?pc:reg[ir[2]];
}elsif(op==inst.inst_les){
reg[ir[1]]=reg[ir[2]]<reg[ir[3]];
}elsif(op==inst.inst_grt){
reg[ir[1]]=reg[ir[2]]>reg[ir[3]];
}elsif(op==inst.inst_leq){
reg[ir[1]]=reg[ir[2]]<=reg[ir[3]];
}elsif(op==inst.inst_geq){
reg[ir[1]]=reg[ir[2]]>=reg[ir[3]];
}elsif(op==inst.inst_eq){
reg[ir[1]]=reg[ir[2]]==reg[ir[3]];
}elsif(op==inst.inst_in){
reg[0]=0; # unfinished
}elsif(op==inst.inst_out){
println("reg[",ir[1],"]: 0x",hex32(reg[ir[1]]));
}
pc+=4;
}
};
return {exec:exec};
}(
hex(inst.inst_mov_reg_imm_high)~" 01 ca fe "~ # reg[1]=0xcafe0000
hex(inst.inst_mov_reg_imm_low)~" 01 ba be "~ # reg[1]=0xcafebabe
hex(inst.inst_out)~" 01 00 00 "~ # output reg[1]
hex(inst.inst_mov_reg_imm_low)~" 02 00 20 "~ # reg[2]=0x10
hex(inst.inst_jmp)~" 02 00 00 "~ # jmp *reg[2]
hex(inst.inst_out)~" 01 00 00 "~
hex(inst.inst_out)~" 01 00 00 "~
hex(inst.inst_out)~" 01 00 00 "~
hex(inst.inst_out)~" 01 00 00 "~
hex(inst.inst_out)~" 01 00 00 "~ # should jump here
hex(inst.inst_jf)~" 01 02 00 "~ # should not jump
hex(inst.inst_mov_reg_imm_low)~" 03 00 04 "~ # reg[3]=4
hex(inst.inst_mov_reg_imm_low)~" 04 00 00 "~ # reg[4]=0
hex(inst.inst_out)~" 04 00 00 "~ # output reg[4]
hex(inst.inst_grt)~" 00 04 03 "~ # reg[0]=reg[4]>reg[3]
hex(inst.inst_mov_reg_imm_low)~" 05 00 30 "~ # reg[5]=0x2c
hex(inst.inst_mov_reg_imm_low)~" 06 00 01 "~ # reg[6]=1
hex(inst.inst_add)~" 04 04 06 "~ # reg[4]+=reg[6]
hex(inst.inst_jf)~" 00 05 00 " # jmp *reg[5] if reg[0]!=true
);
machine.exec(0);

View File

@ -51,6 +51,7 @@ var filechecksum=func(){
"./test/leetcode1319.nas", "./test/lexer.nas", "./test/leetcode1319.nas", "./test/lexer.nas",
"./test/life.nas", "./test/loop.nas", "./test/life.nas", "./test/loop.nas",
"./test/mandel.nas", "./test/mandelbrot.nas", "./test/mandel.nas", "./test/mandelbrot.nas",
"./test/mcpu.nas",
"./test/md5.nas", "./test/md5compare.nas", "./test/md5.nas", "./test/md5compare.nas",
"./test/module_test.nas", "./test/nasal_test.nas", "./test/module_test.nas", "./test/nasal_test.nas",
"./test/occupation.nas", "./test/pi.nas", "./test/occupation.nas", "./test/pi.nas",