mirror of
https://github.com/ValKmjolnir/Nasal-Interpreter.git
synced 2026-07-21 10:28:50 +08:00
bug fixed & test file changes
compare operators now run more efficiently.
This commit is contained in:
+267
-160
@@ -1,179 +1,286 @@
|
||||
import("lib.nas");
|
||||
|
||||
var s=io.fin(input());
|
||||
var len=size(s);
|
||||
var ptr=0;
|
||||
var cnt=0;
|
||||
var token=[];
|
||||
var tok_type=
|
||||
{
|
||||
tok_null:0,
|
||||
tok_num:1,
|
||||
tok_str:2,
|
||||
tok_id:3,
|
||||
tok_for:4,
|
||||
tok_forindex:5,
|
||||
tok_foreach:6,
|
||||
tok_while:7,
|
||||
tok_var:8,
|
||||
tok_func:9,
|
||||
tok_break:10,
|
||||
tok_continue:11,
|
||||
tok_ret:12,
|
||||
tok_if:13,
|
||||
tok_elsif:14,
|
||||
tok_else:15,
|
||||
tok_nil:16,
|
||||
tok_lcurve:17,
|
||||
tok_rcurve:18,
|
||||
tok_lbracket:19,
|
||||
tok_rbracket:20,
|
||||
tok_lbrace:21,
|
||||
tok_rbrace:22,
|
||||
tok_semi:23,
|
||||
tok_and:24,
|
||||
tok_or:25,
|
||||
tok_comma:26,
|
||||
tok_dot:27,
|
||||
tok_ellipsis:28,
|
||||
tok_quesmark:29,
|
||||
tok_colon:30,
|
||||
tok_add:31,
|
||||
tok_sub:32,
|
||||
tok_mult:33,
|
||||
tok_div:34,
|
||||
tok_link:35,
|
||||
tok_not:36,
|
||||
tok_eq:37,
|
||||
tok_addeq:38,
|
||||
tok_subeq:39,
|
||||
tok_multeq:40,
|
||||
tok_diveq:41,
|
||||
tok_lnkeq:42,
|
||||
tok_cmpeq:43,
|
||||
tok_neq:44,
|
||||
tok_less:45,
|
||||
tok_leq:46,
|
||||
tok_grt:47,
|
||||
tok_geq:48,
|
||||
tok_eof:49
|
||||
};
|
||||
|
||||
var jump_note=func()
|
||||
var lexer=func(filename)
|
||||
{
|
||||
while(ptr<len and chr(s[ptr])!='\n')
|
||||
ptr+=1;
|
||||
ptr+=1;
|
||||
return;
|
||||
}
|
||||
var generate_id=func()
|
||||
{
|
||||
var tmp="";
|
||||
while(ptr<len)
|
||||
var _={s:io.fin(filename),len:0,ptr:0,token:[]};
|
||||
_.len=size(_.s);
|
||||
return
|
||||
{
|
||||
if('a'<=chr(s[ptr]) and chr(s[ptr])<='z'
|
||||
or 'A'<=chr(s[ptr]) and chr(s[ptr])<='Z'
|
||||
or chr(s[ptr])=='_'
|
||||
or '0'<=chr(s[ptr]) and chr(s[ptr])<='9')
|
||||
tmp~=chr(s[ptr]);
|
||||
else
|
||||
break;
|
||||
ptr+=1;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
var generate_str=func()
|
||||
{
|
||||
var tok_str="";
|
||||
var mark=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
while(ptr<len and chr(s[ptr])!=mark)
|
||||
{
|
||||
if(chr(s[ptr])=='\\')
|
||||
jmp_note:func()
|
||||
{
|
||||
ptr+=1;
|
||||
if(chr(s[ptr])=='a') tok_str~='\a';
|
||||
elsif(chr(s[ptr])=='b') tok_str~='\b';
|
||||
elsif(chr(s[ptr])=='f') tok_str~='\f';
|
||||
elsif(chr(s[ptr])=='n') tok_str~='\n';
|
||||
elsif(chr(s[ptr])=='r') tok_str~='\r';
|
||||
elsif(chr(s[ptr])=='t') tok_str~='\t';
|
||||
elsif(chr(s[ptr])=='v') tok_str~='\v';
|
||||
elsif(chr(s[ptr])=='?') tok_str~='?';
|
||||
elsif(chr(s[ptr])=='0') tok_str~='\0';
|
||||
elsif(chr(s[ptr])=='\\') tok_str~='\\';
|
||||
elsif(chr(s[ptr])=='\'') tok_str~='\'';
|
||||
elsif(chr(s[ptr])=='\"') tok_str~='\"';
|
||||
else tok_str~=chr(s[ptr]);
|
||||
}
|
||||
else
|
||||
tok_str~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
if(ptr>=len)
|
||||
print("read eof when generating string.\n");
|
||||
ptr+=1;
|
||||
return tok_str;
|
||||
}
|
||||
var generate_number=func()
|
||||
{
|
||||
var number=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
if(chr(s[ptr])=='x')
|
||||
{
|
||||
ptr+=1;
|
||||
while(ptr<len and ('a'<=chr(s[ptr]) and chr(s[ptr])<='f' or '0'<=chr(s[ptr]) and chr(s[ptr])<='9'))
|
||||
while(_.ptr<_.len and chr(_.s[_.ptr])!='\n')
|
||||
_.ptr+=1;
|
||||
_.ptr+=1;
|
||||
},
|
||||
idgen:func()
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
return num(number);
|
||||
}
|
||||
elsif(chr(s[ptr])=='o')
|
||||
{
|
||||
ptr+=1;
|
||||
while(ptr<len and ('0'<=chr(s[ptr]) and chr(s[ptr])<='7'))
|
||||
var tmp="";
|
||||
while(_.ptr<_.len)
|
||||
{
|
||||
if('a'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='z'
|
||||
or 'A'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='Z'
|
||||
or '0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9'
|
||||
or chr(_.s[_.ptr])=='_')
|
||||
tmp~=chr(_.s[_.ptr]);
|
||||
else
|
||||
break;
|
||||
_.ptr+=1;
|
||||
}
|
||||
append(_.token,tmp);
|
||||
},
|
||||
strgen:func()
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
return num(number);
|
||||
}
|
||||
while(ptr<len and ('0'<=chr(s[ptr]) and chr(s[ptr])<='9'))
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
if(chr(s[ptr])=='.')
|
||||
number~=chr(s[ptr]);
|
||||
else
|
||||
return num(number);
|
||||
ptr+=1;
|
||||
while(ptr<len and ('0'<=chr(s[ptr]) and chr(s[ptr])<='9'))
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
if(chr(s[ptr])=='e' or chr(s[ptr])=='E')
|
||||
number~=chr(s[ptr]);
|
||||
else
|
||||
return num(number);
|
||||
ptr+=1;
|
||||
if(chr(s[ptr])=='-' or chr(s[ptr])=='+')
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
while(ptr<len and ('0'<=chr(s[ptr]) and chr(s[ptr])<='9'))
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
return num(number);
|
||||
}
|
||||
var generate_operator=func()
|
||||
{
|
||||
var tmp="";
|
||||
if(chr(s[ptr])=='+' or chr(s[ptr])=='-' or chr(s[ptr])=='~' or chr(s[ptr])=='/' or chr(s[ptr])=='*' or chr(s[ptr])=='>' or chr(s[ptr])=='<' or chr(s[ptr])=='!' or chr(s[ptr])=='=')
|
||||
{
|
||||
tmp=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
if(ptr<len and chr(s[ptr])=='=')
|
||||
var str="";
|
||||
var mark=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
while(_.ptr<_.len and chr(_.s[_.ptr])!=mark)
|
||||
{
|
||||
if(chr(_.s[_.ptr])=='\\')
|
||||
{
|
||||
_.ptr+=1;
|
||||
if (chr(_.s[_.ptr])=='a' ) str~='\a';
|
||||
elsif(chr(_.s[_.ptr])=='b' ) str~='\b';
|
||||
elsif(chr(_.s[_.ptr])=='f' ) str~='\f';
|
||||
elsif(chr(_.s[_.ptr])=='n' ) str~='\n';
|
||||
elsif(chr(_.s[_.ptr])=='r' ) str~='\r';
|
||||
elsif(chr(_.s[_.ptr])=='t' ) str~='\t';
|
||||
elsif(chr(_.s[_.ptr])=='v' ) str~='\v';
|
||||
elsif(chr(_.s[_.ptr])=='?' ) str~='?';
|
||||
elsif(chr(_.s[_.ptr])=='0' ) str~='\0';
|
||||
elsif(chr(_.s[_.ptr])=='\\') str~='\\';
|
||||
elsif(chr(_.s[_.ptr])=='\'') str~='\'';
|
||||
elsif(chr(_.s[_.ptr])=='\"') str~='\"';
|
||||
else str~=chr(_.s[_.ptr]);
|
||||
}
|
||||
else
|
||||
str~=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
if(_.ptr>=_.len)
|
||||
print("read eof when generating string.\n");
|
||||
_.ptr+=1;
|
||||
append(_.token,[tok_type.tok_str,str]);
|
||||
},
|
||||
numgen:func()
|
||||
{
|
||||
tmp~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
elsif(chr(s[ptr])=='.')
|
||||
{
|
||||
if(ptr+2<len and s[ptr+1]=='.' and s[ptr+2]=='.')
|
||||
var number=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
if(chr(_.s[_.ptr])=='x')
|
||||
{
|
||||
_.ptr+=1;
|
||||
while(_.ptr<_.len and
|
||||
('a'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='f'
|
||||
or '0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9'))
|
||||
{
|
||||
number~=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
append(_.token,[tok_type.tok_num,num(number)]);
|
||||
return;
|
||||
}
|
||||
elsif(chr(_.s[_.ptr])=='o')
|
||||
{
|
||||
_.ptr+=1;
|
||||
while(_.ptr<_.len and ('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='7'))
|
||||
{
|
||||
number~=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
append(_.token,[tok_type.tok_num,num(number)]);
|
||||
return;
|
||||
}
|
||||
while(_.ptr<_.len and ('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9'))
|
||||
{
|
||||
number~=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
if(chr(_.s[_.ptr])=='.')
|
||||
number~=chr(_.s[_.ptr]);
|
||||
else
|
||||
{
|
||||
append(_.token,[tok_type.tok_num,num(number)]);
|
||||
return;
|
||||
}
|
||||
_.ptr+=1;
|
||||
while(_.ptr<_.len and ('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9'))
|
||||
{
|
||||
number~=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
if(chr(_.s[_.ptr])=='e' or chr(_.s[_.ptr])=='E')
|
||||
number~=chr(_.s[_.ptr]);
|
||||
else
|
||||
{
|
||||
append(_.token,[tok_type.tok_num,num(number)]);
|
||||
return;
|
||||
}
|
||||
_.ptr+=1;
|
||||
if(chr(_.s[_.ptr])=='-' or chr(_.s[_.ptr])=='+')
|
||||
{
|
||||
number~=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
while(_.ptr<_.len and ('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9'))
|
||||
{
|
||||
number~=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
append(_.token,[tok_type.tok_num,num(number)]);
|
||||
},
|
||||
oprgen:func()
|
||||
{
|
||||
tmp='...';
|
||||
ptr+=3;
|
||||
}
|
||||
else
|
||||
var tmp="";
|
||||
if(chr(_.s[_.ptr])=='+'
|
||||
or chr(_.s[_.ptr])=='-'
|
||||
or chr(_.s[_.ptr])=='~'
|
||||
or chr(_.s[_.ptr])=='/'
|
||||
or chr(_.s[_.ptr])=='*'
|
||||
or chr(_.s[_.ptr])=='>'
|
||||
or chr(_.s[_.ptr])=='<'
|
||||
or chr(_.s[_.ptr])=='!'
|
||||
or chr(_.s[_.ptr])=='=')
|
||||
{
|
||||
tmp=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
if(_.ptr<_.len and chr(_.s[_.ptr])=='=')
|
||||
{
|
||||
tmp~=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
append(_.token,tmp);
|
||||
return;
|
||||
}
|
||||
elsif(chr(_.s[_.ptr])=='.')
|
||||
{
|
||||
if(_.ptr+2<_.len and _.s[_.ptr+1]=='.' and _.s[_.ptr+2]=='.')
|
||||
{
|
||||
tmp='...';
|
||||
_.ptr+=3;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp='.';
|
||||
_.ptr+=1;
|
||||
}
|
||||
append(_.token,tmp);
|
||||
return;
|
||||
}
|
||||
elsif(chr(_.s[_.ptr])!=' '
|
||||
and chr(_.s[_.ptr])!='\t'
|
||||
and chr(_.s[_.ptr])!='\n'
|
||||
and chr(_.s[_.ptr])!='\r'
|
||||
and chr(_.s[_.ptr])[0]>0)
|
||||
tmp=chr(_.s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
if(size(tmp))
|
||||
append(_.token,tmp);
|
||||
},
|
||||
main:func()
|
||||
{
|
||||
tmp='.';
|
||||
ptr+=1;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
elsif(chr(s[ptr])!=' ' and chr(s[ptr])!='\t' and chr(s[ptr])!='\n' and chr(s[ptr])!='\r' and chr(s[ptr])[0]>0)
|
||||
tmp=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
return tmp;
|
||||
while(_.ptr<_.len)
|
||||
{
|
||||
if(chr(_.s[_.ptr])=='#')
|
||||
me.jmp_note();
|
||||
elsif('a'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='z'
|
||||
or 'A'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='Z'
|
||||
or chr(_.s[_.ptr])=='_')
|
||||
me.idgen();
|
||||
elsif(chr(_.s[_.ptr])=='\'' or chr(_.s[_.ptr])=='\"')
|
||||
me.strgen();
|
||||
elsif('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9')
|
||||
me.numgen();
|
||||
else
|
||||
me.oprgen();
|
||||
if(_.ptr>=_.len)
|
||||
break;
|
||||
}
|
||||
return;
|
||||
},
|
||||
get_token:func(){return _.token;}
|
||||
};
|
||||
}
|
||||
|
||||
while(ptr<len)
|
||||
var parse=func(token)
|
||||
{
|
||||
if(chr(s[ptr])=='#')
|
||||
jump_note();
|
||||
elsif('a'<=chr(s[ptr]) and chr(s[ptr])<='z' or 'A'<=chr(s[ptr]) and chr(s[ptr])<='Z' or chr(s[ptr])=='_')
|
||||
append(token,generate_id());
|
||||
elsif(chr(s[ptr])=='\'' or chr(s[ptr])=='\"')
|
||||
append(token,generate_str());
|
||||
elsif('0'<=chr(s[ptr]) and chr(s[ptr])<='9')
|
||||
append(token,generate_number());
|
||||
else
|
||||
var _={error:0,size:0,token:token,ast:nil};
|
||||
_.size=size(token);
|
||||
return
|
||||
{
|
||||
var tmp=generate_operator();
|
||||
if(size(tmp))
|
||||
append(token,tmp);
|
||||
}
|
||||
if(ptr>=len)
|
||||
break;
|
||||
die:func(info)
|
||||
{
|
||||
_.error+=1;
|
||||
println(info);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
foreach(var i;token)
|
||||
var ast=func()
|
||||
{
|
||||
print("(",cnt," | ",i,")\n");
|
||||
cnt+=1;
|
||||
var _={type:nil,child:[]};
|
||||
return
|
||||
{
|
||||
set_type:func(type){_.type=type;},
|
||||
get_type:func(){return _.type;},
|
||||
add_child:func(child){append(_.child,child);},
|
||||
get_child:func(){return _.child;}
|
||||
};
|
||||
}
|
||||
|
||||
var nasal_lexer=lexer(input());
|
||||
nasal_lexer.main();
|
||||
println(nasal_lexer.get_token());
|
||||
var nasal_parse=parse(nasal_lexer.get_token());
|
||||
Reference in New Issue
Block a user