forked from xxq250/Nasal-Interpreter
Compare commits
274 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d567f5abf8 | ||
|
|
f8692f1e4e | ||
|
|
712a047a43 | ||
|
|
396d55a207 | ||
|
|
c5171c735a | ||
|
|
07857d980c | ||
|
|
51a1279110 | ||
|
|
de262980cc | ||
|
|
23a5c1b1ad | ||
|
|
fd8a148d0c | ||
|
|
9c7f5f1a6e | ||
|
|
f049e1f9fb | ||
|
|
c4b7712e53 | ||
|
|
7417d5e635 | ||
|
|
785572634b | ||
|
|
2dc8459cbf | ||
|
|
6e035d1951 | ||
|
|
4f5fd3de33 | ||
|
|
fc25dd69e1 | ||
|
|
ca073499ae | ||
|
|
022460755f | ||
|
|
b6f174e869 | ||
|
|
7b160c4589 | ||
|
|
4503239731 | ||
|
|
c12e812651 | ||
|
|
87cff700e8 | ||
|
|
bf5737ecfd | ||
|
|
651ae4ef77 | ||
|
|
e846e51175 | ||
|
|
399b2f0ce9 | ||
|
|
aed5e27409 | ||
|
|
a2b51fe212 | ||
|
|
92b684624d | ||
|
|
83a8632e8e | ||
|
|
41b5304712 | ||
|
|
c5a12ade5c | ||
|
|
7a939b417d | ||
|
|
dd7740f1fd | ||
|
|
617ad03d33 | ||
|
|
b66ebbef4b | ||
|
|
7f22b25909 | ||
|
|
86f6296268 | ||
|
|
cf722fd98c | ||
|
|
1dd3fd445c | ||
|
|
27e25f84ec | ||
|
|
e6457651d3 | ||
|
|
c4d52a88cd | ||
|
|
9bcad59e45 | ||
|
|
9a099f66cb | ||
|
|
b79d60fab5 | ||
|
|
82e9e97a26 | ||
|
|
6a1338bb23 | ||
|
|
3b8a092f36 | ||
|
|
3d86a32b12 | ||
|
|
f26719e1d3 | ||
|
|
e54ef9620f | ||
|
|
d8156e839b | ||
|
|
61666d275d | ||
|
|
99f595e16f | ||
|
|
debe32b187 | ||
|
|
ca9b8581b4 | ||
|
|
a0b341deb5 | ||
|
|
d3df356299 | ||
|
|
cd808a5e6d | ||
|
|
40f61a9dd4 | ||
|
|
f312250d27 | ||
|
|
3fac8aa665 | ||
|
|
243aafd417 | ||
|
|
6bc03601d9 | ||
|
|
f05acaecc7 | ||
|
|
9456a903d7 | ||
|
|
984deed883 | ||
|
|
557cb2ebcf | ||
|
|
9c055a9a23 | ||
|
|
13a09343e6 | ||
|
|
8c67e04cc4 | ||
|
|
e77bb73a82 | ||
|
|
05fc5db337 | ||
|
|
a4738e8c7d | ||
|
|
5f6051e333 | ||
|
|
51afe3dacd | ||
|
|
0291908675 | ||
|
|
5fba784d05 | ||
|
|
9139e34c0b | ||
|
|
e7f503fae1 | ||
|
|
980350d70a | ||
|
|
0ccd3c9bd0 | ||
|
|
3e7ba4d774 | ||
|
|
a176022840 | ||
|
|
24a1e39ad3 | ||
|
|
a09c6ae2f9 | ||
|
|
2a85e92d4a | ||
|
|
92646840e4 | ||
|
|
c55ce758ed | ||
|
|
aa301aefc3 | ||
|
|
d6d90ab7c8 | ||
|
|
bf780514e6 | ||
|
|
eaa54035ff | ||
|
|
baa4f5a258 | ||
|
|
df24db5b58 | ||
|
|
4def93b4ad | ||
|
|
0a407437a4 | ||
|
|
05ab4640da | ||
|
|
b92eb4b089 | ||
|
|
5778d1e38d | ||
|
|
479e5a2c52 | ||
|
|
2f455c52c1 | ||
|
|
78c1f9b7a9 | ||
|
|
c68b4c5947 | ||
|
|
40344455e6 | ||
|
|
630c99c39a | ||
|
|
46716620e3 | ||
|
|
70a43c2f03 | ||
|
|
1923fc74e4 | ||
|
|
f0ae63bce5 | ||
|
|
30650bb64f | ||
|
|
d87aef82b7 | ||
|
|
e79d1eb8a4 | ||
|
|
189d49fa4a | ||
|
|
6a543f2aa7 | ||
|
|
c27c5b70ee | ||
|
|
0a246d2fc7 | ||
|
|
0956a08bec | ||
|
|
5a80258d20 | ||
|
|
85bb502191 | ||
|
|
ead49a657e | ||
|
|
df5be35af8 | ||
|
|
19d5952210 | ||
|
|
afd87da5e7 | ||
|
|
9861ecd03e | ||
|
|
aa191a9feb | ||
|
|
b8ef3cf6b6 | ||
|
|
0a8655eb4d | ||
|
|
52b49edbcf | ||
|
|
6a35c58df4 | ||
|
|
cd08b2d1bb | ||
|
|
f8e2918561 | ||
|
|
e4ea34db51 | ||
|
|
4bfce37f40 | ||
|
|
fd0d836c03 | ||
|
|
183446d32a | ||
|
|
540aeb73f4 | ||
|
|
4f0acc4d63 | ||
|
|
56280db2c7 | ||
|
|
885b57cd52 | ||
|
|
bbee31ea55 | ||
|
|
1bfa7d2638 | ||
|
|
d4a9412947 | ||
|
|
1b240b293e | ||
|
|
e41f728589 | ||
|
|
577546763f | ||
|
|
58ea303202 | ||
|
|
818685c48d | ||
|
|
5d13261516 | ||
|
|
56289b5d22 | ||
|
|
1733ac0573 | ||
|
|
d71b4f09e2 | ||
|
|
13d40e886e | ||
|
|
618ce59233 | ||
|
|
071d8bd1ce | ||
|
|
c498d5c8c4 | ||
|
|
11971267dc | ||
|
|
418531a44a | ||
|
|
59dc0d1423 | ||
|
|
385f0af17e | ||
|
|
ef9b781961 | ||
|
|
80cc8e9db7 | ||
|
|
b2be386be8 | ||
|
|
e4c598cae6 | ||
|
|
5fe6681b0d | ||
|
|
35fc848672 | ||
|
|
e3f3bd7387 | ||
|
|
638ec1c3a3 | ||
|
|
90ac468aa9 | ||
|
|
65dfef0a33 | ||
|
|
76a2548e95 | ||
|
|
40b690b67b | ||
|
|
2b17f3d702 | ||
|
|
5b6c78783e | ||
|
|
fa618eb97f | ||
|
|
d0616ef028 | ||
|
|
91771297d3 | ||
|
|
4e1a3c5f2d | ||
|
|
df634cb1b2 | ||
|
|
aa797142d1 | ||
|
|
816be43a98 | ||
|
|
9ebabfe737 | ||
|
|
884b56ac09 | ||
|
|
61677101e4 | ||
|
|
7a93f5b89b | ||
|
|
9fe7a86a3b | ||
|
|
9da029b8fe | ||
|
|
8b8e72c879 | ||
|
|
590c595522 | ||
|
|
57d6bcdc52 | ||
|
|
0b2fe61e6e | ||
|
|
706659ba3d | ||
|
|
3c9a10d710 | ||
|
|
fd57e9a47c | ||
|
|
ab99d2d1ed | ||
|
|
ae0dae5956 | ||
|
|
00c6e3b4fd | ||
|
|
cdf7b92a8e | ||
|
|
0e979a6e7b | ||
|
|
dd144305da | ||
|
|
4f3ddf803a | ||
|
|
de305d26ad | ||
|
|
9f30f45774 | ||
|
|
1ae47807eb | ||
|
|
3deea632f8 | ||
|
|
9f2c31149a | ||
|
|
b25a1bc3f4 | ||
|
|
fd7677f94f | ||
|
|
2e31a70406 | ||
|
|
8e29a3ec5b | ||
|
|
a68bf85f04 | ||
|
|
aae9395d66 | ||
|
|
a463af53b7 | ||
|
|
6adb991c04 | ||
|
|
c5f4736984 | ||
|
|
1a233fbe15 | ||
|
|
a7d6518bff | ||
|
|
0700ce14f7 | ||
|
|
c88620920b | ||
|
|
125fc8a9fe | ||
|
|
b06e1bb5dd | ||
|
|
c7316e9780 | ||
|
|
be1bcdfe2c | ||
|
|
144e6f45da | ||
|
|
569d5c6c6a | ||
|
|
7087c67d79 | ||
|
|
c4e6a89959 | ||
|
|
f60f674845 | ||
|
|
c21d40c466 | ||
|
|
19b590f3bb | ||
|
|
a421470715 | ||
|
|
79dc13f419 | ||
|
|
2e8208a752 | ||
|
|
1c40cca673 | ||
|
|
b1a5a5f6c0 | ||
|
|
64961877de | ||
|
|
9c9bb52818 | ||
|
|
02148f4766 | ||
|
|
767711c93a | ||
|
|
78ba0641a6 | ||
|
|
80683c381f | ||
|
|
6aac46adaf | ||
|
|
388ef66308 | ||
|
|
8faa4ef2db | ||
|
|
441c02d0fb | ||
|
|
953ad80482 | ||
|
|
e2ee9cff4c | ||
|
|
996ac59c79 | ||
|
|
944f713ee9 | ||
|
|
7329c70492 | ||
|
|
b5514fd269 | ||
|
|
3be50116fa | ||
|
|
125d6d3a7d | ||
|
|
bb746dfbfb | ||
|
|
8069a1b659 | ||
|
|
f0cb8b6ef3 | ||
|
|
9474ac9ef0 | ||
|
|
b862aa91eb | ||
|
|
bc64d530be | ||
|
|
ea5116e963 | ||
|
|
cc4e697246 | ||
|
|
515bef3f5d | ||
|
|
05800fe518 | ||
|
|
33d37771ce | ||
|
|
89540475cf | ||
|
|
e03da2f737 | ||
|
|
4617eb8f17 | ||
|
|
fed1e20085 | ||
|
|
9f30440286 |
34
.github/workflows/c-cpp.yml
vendored
Normal file
34
.github/workflows/c-cpp.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: C/C++ CI
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 16 * * *"
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: make
|
||||
run: make
|
||||
- name: Release file
|
||||
# You may pin to the exact commit or the version.
|
||||
# uses: djnicholson/release-action@e9a535b3eced09c460e07a84118fb74ae9b53236
|
||||
uses: marvinpinto/action-automatic-releases@v1.2.1
|
||||
with:
|
||||
# GitHub auth token
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Name of Release to add file to
|
||||
title: macOS Nightly build
|
||||
# Name of the tag for the release (will be associated with current branch)
|
||||
automatic_release_tag: next
|
||||
# File to release
|
||||
files: nasal
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -30,3 +30,7 @@
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
nasal
|
||||
.vscode
|
||||
dump
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 ValKmjolnir
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
602
lib.nas
602
lib.nas
@@ -1,167 +1,469 @@
|
||||
var import=func(filename)
|
||||
{
|
||||
nasal_call_import(filename);
|
||||
# lib.nas
|
||||
|
||||
# import is used to link another file, this lib function will do nothing.
|
||||
# because nasal_import will recognize this and link files before generating bytecode.
|
||||
var import=func(filename){
|
||||
return __builtin_import(filename);
|
||||
}
|
||||
|
||||
# print is used to print all things in nasal, try and see how it works.
|
||||
# this function uses std::cout/printf to output logs.
|
||||
var print=func(elems...){
|
||||
return __builtin_print(elems);
|
||||
}
|
||||
|
||||
# append is used to add values into a vector.
|
||||
var append=func(vec,elems...){
|
||||
return __builtin_append(vec,elems);
|
||||
}
|
||||
|
||||
# setsize is used to change the size of vector.
|
||||
# if the size is larger than before,
|
||||
# this function will fill vm_nil into uninitialized space.
|
||||
var setsize=func(vec,size){
|
||||
return __builtin_setsize(vec,size);
|
||||
}
|
||||
|
||||
# system has the same use in C.
|
||||
var system=func(str){
|
||||
return __builtin_system(str);
|
||||
}
|
||||
|
||||
# input uses std::cin and returns what we input.
|
||||
var input=func(){
|
||||
return __builtin_input();
|
||||
}
|
||||
|
||||
# split a string by separator for example:
|
||||
# split("ll","hello world") -> ["he","o world"]
|
||||
# this function will return a vector.
|
||||
var split=func(separator,str){
|
||||
return __builtin_split(separator,str);
|
||||
}
|
||||
|
||||
# rand has the same function as the rand in C
|
||||
# if seed is nil, it will return the random number.
|
||||
# if seed is not nil, it will be initialized by this seed.
|
||||
var rand=func(seed=nil){
|
||||
return __builtin_rand(seed);
|
||||
}
|
||||
|
||||
# id will return the pointer of an gc-object.
|
||||
# if this object is not managed by gc, it will return 0.
|
||||
var id=func(object){
|
||||
return __builtin_id(object);
|
||||
}
|
||||
|
||||
# int will get the integer of input number.
|
||||
# but carefully use it, because int has range between -2147483648~2147483647
|
||||
var int=func(val){
|
||||
return __builtin_int(val);
|
||||
}
|
||||
|
||||
# floor will get the integral number of input argument
|
||||
# which is less than or equal to this argument
|
||||
var floor=func(val){
|
||||
return __builtin_floor(val);
|
||||
}
|
||||
|
||||
# abort using std::abort
|
||||
var abort=func(){
|
||||
__builtin_abort();
|
||||
}
|
||||
|
||||
# abs gets absolute number.
|
||||
var abs=func(n){
|
||||
return n>0?n:-n;
|
||||
}
|
||||
|
||||
# num will change all the other types into number.
|
||||
# mostly used to change a numerable string.
|
||||
var num=func(val){
|
||||
return __builtin_num(val);
|
||||
}
|
||||
|
||||
# pop used to pop the last element in a vector.
|
||||
# this function will return the value that poped if vector has element(s).
|
||||
# if the vector is empty, it will return nil.
|
||||
var pop=func(vec){
|
||||
return __builtin_pop(vec);
|
||||
}
|
||||
|
||||
# str is used to change number into string.
|
||||
var str=func(num){
|
||||
return __builtin_str(num);
|
||||
}
|
||||
|
||||
# size can get the size of a string/vector/hashmap.
|
||||
# in fact it can also get the size of number, and the result is the number itself.
|
||||
# so don't do useless things, though it really works.
|
||||
var size=func(object){
|
||||
return __builtin_size(object);
|
||||
}
|
||||
|
||||
# contains is used to check if a key exists in a hashmap/dict.
|
||||
var contains=func(hash,key){
|
||||
return __builtin_contains(hash,key);
|
||||
}
|
||||
|
||||
# delete is used to delete a pair in a hashmap/dict by key.
|
||||
var delete=func(hash,key){
|
||||
return __builtin_delete(hash,key);
|
||||
}
|
||||
|
||||
# keys is used to get all keys in a hashmap/dict.
|
||||
# this function will return a vector.
|
||||
var keys=func(hash){
|
||||
return __builtin_keys(hash);
|
||||
}
|
||||
|
||||
# time has the same function in C.
|
||||
var time=func(begin){
|
||||
return __builtin_time(begin);
|
||||
}
|
||||
var systime=func(){
|
||||
return time(0);
|
||||
}
|
||||
|
||||
# die is a special native function.
|
||||
# use it at where you want the program to crash immediately.
|
||||
var die=func(str){
|
||||
return __builtin_die(str);
|
||||
}
|
||||
|
||||
# find will give the first position of the needle in haystack
|
||||
var find=func(needle,haystack){
|
||||
return __builtin_find(needle,haystack);
|
||||
}
|
||||
|
||||
# typeof is used to get the type of an object.
|
||||
# this function returns a string.
|
||||
var typeof=func(object){
|
||||
return __builtin_type(object);
|
||||
}
|
||||
|
||||
# subvec is used to get part of a vector
|
||||
var subvec=func(vec,begin,length=nil){
|
||||
return vec[begin:(length==nil?nil:begin+length-1)];
|
||||
}
|
||||
|
||||
# substr will get the sub-string.
|
||||
# it gets the string, the begin index and sub-string's length as arguments.
|
||||
var substr=func(str,begin,len){
|
||||
return __builtin_substr(str,begin,len);
|
||||
}
|
||||
|
||||
# streq is used to compare if two strings are the same.
|
||||
var streq=func(a,b){
|
||||
return __builtin_streq(a,b);
|
||||
}
|
||||
|
||||
# left is used to get the sub-string like substr.
|
||||
# but the begin index is 0.
|
||||
var left=func(str,len){
|
||||
return __builtin_left(str,len);
|
||||
}
|
||||
|
||||
# right i used to get the sub-string like substr.
|
||||
# but the begin index is strlen-len.
|
||||
var right=func(str,len){
|
||||
return __builtin_right(str,len);
|
||||
}
|
||||
|
||||
# cmp is used to compare two strings.
|
||||
# normal string will not be correctly compared by operators < > <= >=
|
||||
# because these operators will turn strings into numbers then compare.
|
||||
var cmp=func(a,b){
|
||||
return __builtin_cmp(a,b);
|
||||
}
|
||||
|
||||
# chr is used to get the character by ascii-number.
|
||||
# for example chr(65) -> 'A'
|
||||
var chr=func(code){
|
||||
return __builtin_chr(code);
|
||||
}
|
||||
|
||||
# mut is used to change unmutable strings to mutable.
|
||||
var mut=func(str){
|
||||
return str~"";
|
||||
}
|
||||
|
||||
# srand wraps up rand, using time(0) as the seed.
|
||||
var srand=func(){
|
||||
rand(time(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
# values() gets all values in a hash.
|
||||
var values=func(hash){
|
||||
return __builtin_values(hash);
|
||||
}
|
||||
|
||||
# println has the same function as print.
|
||||
# but it will output a '\n' after using print.
|
||||
var println=func(elems...){
|
||||
__builtin_print(elems);
|
||||
elems=['\n'];
|
||||
return __builtin_print(elems);
|
||||
}
|
||||
|
||||
var isfunc=func(f){
|
||||
return typeof(f)=="func";
|
||||
}
|
||||
|
||||
var isghost=func(g){
|
||||
die("this runtime has no ghost object");
|
||||
return 0;
|
||||
}
|
||||
|
||||
var ishash=func(h){
|
||||
return typeof(h)=="hash";
|
||||
}
|
||||
|
||||
var isint=func(x){
|
||||
return x==floor(x);
|
||||
}
|
||||
|
||||
var isnum=func(x){
|
||||
return typeof(x)=="num" or !math.isnan(num(x));
|
||||
}
|
||||
|
||||
var isscalar=func(s){
|
||||
var t=typeof(s);
|
||||
return (t=="num" or t=="str")?1:0;
|
||||
}
|
||||
|
||||
var isstr=func(s){
|
||||
return typeof(s)=="str";
|
||||
}
|
||||
|
||||
var isvec=func(v){
|
||||
return typeof(v)=="vec";
|
||||
}
|
||||
|
||||
|
||||
# get the index of val in the vec
|
||||
var vecindex=func(vec,val){
|
||||
forindex(var i;vec)
|
||||
if(val==vec[i])
|
||||
return i;
|
||||
return nil;
|
||||
}
|
||||
var print=func(elements...)
|
||||
{
|
||||
nasal_call_builtin_std_cout(elements);
|
||||
return nil;
|
||||
};
|
||||
var append=func(vector,elements...)
|
||||
{
|
||||
nasal_call_builtin_push_back(vector,elements);
|
||||
return nil;
|
||||
|
||||
# check if the object is an instance of the class
|
||||
var isa=func(object,class){
|
||||
if(!contains(object,"parents") or typeof(object.parents)!="vec")
|
||||
return 0;
|
||||
foreach(var elem;object.parents)
|
||||
if(elem==class)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
var setsize=func(vector,size)
|
||||
{
|
||||
nasal_call_builtin_set_size(vector,size);
|
||||
return nil;
|
||||
|
||||
# assert aborts when condition is not true
|
||||
var assert=func(condition,message="assertion failed!"){
|
||||
if(condition)
|
||||
return 1;
|
||||
die(message);
|
||||
}
|
||||
var system=func(str)
|
||||
{
|
||||
nasal_call_builtin_system(str);
|
||||
return;
|
||||
}
|
||||
var input=func()
|
||||
{
|
||||
return nasal_call_builtin_input();
|
||||
}
|
||||
var sleep=func(duration)
|
||||
{
|
||||
nasal_call_builtin_sleep(duration);
|
||||
return;
|
||||
}
|
||||
var split=func(delimeter,string)
|
||||
{
|
||||
return nasal_call_builtin_split(delimeter,string);
|
||||
}
|
||||
var rand=func(seed=nil)
|
||||
{
|
||||
return nasal_call_builtin_rand(seed);
|
||||
}
|
||||
var id=func(thing)
|
||||
{
|
||||
return nasal_call_builtin_get_id(thing);
|
||||
}
|
||||
var int=func(value)
|
||||
{
|
||||
return nasal_call_builtin_trans_int(value);
|
||||
}
|
||||
var num=func(value)
|
||||
{
|
||||
return nasal_call_builtin_trans_num(value);
|
||||
}
|
||||
var pop=func(vector)
|
||||
{
|
||||
return nasal_call_builtin_pop_back(vector);
|
||||
}
|
||||
var str=func(number)
|
||||
{
|
||||
return nasal_call_builtin_trans_str(number);
|
||||
}
|
||||
var size=func(object)
|
||||
{
|
||||
return nasal_call_builtin_size(object);
|
||||
}
|
||||
var contains=func(hash,key)
|
||||
{
|
||||
return nasal_call_builtin_contains(hash,key);
|
||||
}
|
||||
var delete=func(hash,key)
|
||||
{
|
||||
nasal_call_builtin_delete(hash,key);
|
||||
return;
|
||||
}
|
||||
var keys=func(hash)
|
||||
{
|
||||
return nasal_call_builtin_get_keys(hash);
|
||||
}
|
||||
var time=func(begin_time)
|
||||
{
|
||||
return nasal_call_builtin_time(begin_time);
|
||||
}
|
||||
var die=func(str)
|
||||
{
|
||||
nasal_call_builtin_die(str);
|
||||
return nil;
|
||||
}
|
||||
var typeof=func(object)
|
||||
{
|
||||
return nasal_call_builtin_type(object);
|
||||
}
|
||||
var substr=func(str,begin,length)
|
||||
{
|
||||
return nasal_call_builtin_substr(str,begin,length);
|
||||
|
||||
# md5
|
||||
var md5=func(str){
|
||||
return __builtin_md5(str);
|
||||
}
|
||||
|
||||
var io=
|
||||
{
|
||||
fin:func(filename)
|
||||
{
|
||||
return nasal_call_builtin_finput(filename);
|
||||
},
|
||||
fout:func(filename,str)
|
||||
{
|
||||
nasal_call_builtin_foutput(filename,str);
|
||||
return;
|
||||
}
|
||||
SEEK_SET:0,
|
||||
SEEK_CUR:1,
|
||||
SEEK_END:2,
|
||||
# get content of a file by filename. returns a string.
|
||||
fin: func(filename){return __builtin_fin(filename);},
|
||||
# input a string as the content of a file.
|
||||
fout: func(filename,str){return __builtin_fout(filename,str);},
|
||||
# same as C fopen. open file and get the FILE*.
|
||||
open: func(filename,mode="r"){return __builtin_open(filename,mode);},
|
||||
# same as C fclose. close file by FILE*.
|
||||
close: func(filehandle){return __builtin_close(filehandle);},
|
||||
# same as C fread. read file by FILE*.
|
||||
# caution: buf must be a mutable string.use mut("") to get an empty mutable string.
|
||||
read: func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);},
|
||||
# same as C fwrite. write file by FILE*.
|
||||
write: func(filehandle,str){return __builtin_write(filehandle,str);},
|
||||
# same as C fseek. seek place by FILE*.
|
||||
seek: func(filehandle,pos,whence){return __builtin_seek(filehandle,pos,whence);},
|
||||
# same as C ftell.
|
||||
tell: func(filehandle){return __builtin_tell(filehandle);},
|
||||
# read file by lines. use FILE*.
|
||||
# get nil if EOF
|
||||
readln:func(filehandle){return __builtin_readln(filehandle);},
|
||||
# same as C stat.
|
||||
stat: func(filename){return __builtin_stat(filename);},
|
||||
# same as C feof. check if FILE* gets the end of file(EOF).
|
||||
eof: func(filehandle){return __builtin_eof(filehandle);}
|
||||
};
|
||||
|
||||
# get file status. using data from io.stat
|
||||
var fstat=func(filename){
|
||||
var s=io.stat(filename);
|
||||
return {
|
||||
st_dev: s[0],
|
||||
st_ino: s[1],
|
||||
st_mode: s[2],
|
||||
st_nlink:s[3],
|
||||
st_uid: s[4],
|
||||
st_gid: s[5],
|
||||
st_rdev: s[6],
|
||||
st_size: s[7],
|
||||
st_atime:s[8],
|
||||
st_mtime:s[9],
|
||||
st_ctime:s[10]
|
||||
};
|
||||
}
|
||||
|
||||
# functions that do bitwise calculation.
|
||||
# carefully use it, all the calculations are based on integer.
|
||||
var bits=
|
||||
{
|
||||
bitxor:func(a,b)
|
||||
{
|
||||
return nasal_call_builtin_xor(a,b);
|
||||
},
|
||||
bitand:func(a,b)
|
||||
{
|
||||
return nasal_call_builtin_and(a,b);
|
||||
},
|
||||
bitor:func(a,b)
|
||||
{
|
||||
return nasal_call_builtin_or(a,b);
|
||||
},
|
||||
bitnand:func(a,b)
|
||||
{
|
||||
return nasal_call_builtin_nand(a,b);
|
||||
},
|
||||
bitnot:func(a)
|
||||
{
|
||||
return nasal_call_builtin_not(a);
|
||||
}
|
||||
# xor
|
||||
bitxor: func(a,b){return __builtin_xor(a,b); },
|
||||
# and
|
||||
bitand: func(a,b){return __builtin_and(a,b); },
|
||||
# or
|
||||
bitor: func(a,b){return __builtin_or(a,b); },
|
||||
# nand
|
||||
bitnand: func(a,b){return __builtin_nand(a,b);},
|
||||
# not
|
||||
bitnot: func(a) {return __builtin_not(a); },
|
||||
# get bit data from a special string. for example:
|
||||
# bits.fld(s,0,3);
|
||||
# if s stores 10100010(162)
|
||||
# will get 101(5).
|
||||
fld: func(str,startbit,len){return __builtin_fld;},
|
||||
# get sign-extended data from a special string. for example:
|
||||
# bits.sfld(s,0,3);
|
||||
# if s stores 10100010(162)
|
||||
# will get 101(5) then this will be signed extended to
|
||||
# 11111101(-3).
|
||||
sfld: func(str,startbit,len){return __builtin_sfld;},
|
||||
# set value into a special string to store it. little-endian, for example:
|
||||
# bits.setfld(s,0,8,69);
|
||||
# set 01000101(69) to string will get this:
|
||||
# 10100010(162)
|
||||
# so s[0]=162.
|
||||
setfld: func(str,startbit,len,val){return __builtin_setfld;},
|
||||
# get a special string filled by '\0' to use in setfld.
|
||||
buf: func(len){return __builtin_buf;}
|
||||
};
|
||||
|
||||
# mostly used math functions and special constants, you know.
|
||||
var math=
|
||||
{
|
||||
e:2.7182818284590452354,
|
||||
pi:3.14159265358979323846264338327950288,
|
||||
sin:func(x)
|
||||
{
|
||||
return nasal_call_builtin_sin(x);
|
||||
},
|
||||
cos:func(x)
|
||||
{
|
||||
return nasal_call_builtin_cos(x);
|
||||
},
|
||||
tan:func(x)
|
||||
{
|
||||
return nasal_call_builtin_tan(x);
|
||||
},
|
||||
exp:func(x)
|
||||
{
|
||||
return nasal_call_builtin_exp(x);
|
||||
},
|
||||
ln:func(x)
|
||||
{
|
||||
return nasal_call_builtin_cpp_math_ln(x);
|
||||
},
|
||||
sqrt:func(x)
|
||||
{
|
||||
return nasal_call_builtin_cpp_math_sqrt(x);
|
||||
},
|
||||
atan2:func(x,y)
|
||||
{
|
||||
return nasal_call_builtin_cpp_atan2(x,y);
|
||||
},
|
||||
e: 2.7182818284590452354,
|
||||
pi: 3.14159265358979323846264338327950288,
|
||||
inf: 1/0,
|
||||
nan: 0/0,
|
||||
abs: func(x) {return x>0?x:-x; },
|
||||
floor: func(x) {return __builtin_floor(x); },
|
||||
pow: func(x,y){return __builtin_pow(x,y); },
|
||||
sin: func(x) {return __builtin_sin(x); },
|
||||
cos: func(x) {return __builtin_cos(x); },
|
||||
tan: func(x) {return __builtin_tan(x); },
|
||||
exp: func(x) {return __builtin_exp(x); },
|
||||
lg: func(x) {return __builtin_lg(x); },
|
||||
ln: func(x) {return __builtin_ln(x); },
|
||||
sqrt: func(x) {return __builtin_sqrt(x); },
|
||||
atan2: func(x,y){return __builtin_atan2(x,y);},
|
||||
isnan: func(x) {return __builtin_isnan(x); },
|
||||
max: func(x,y){return x>y?x:y; },
|
||||
min: func(x,y){return x<y?x:y; }
|
||||
};
|
||||
|
||||
var unix=
|
||||
{
|
||||
pipe: func(){return __builtin_pipe;},
|
||||
fork: func(){return __builtin_fork;},
|
||||
dup2: func(fd0,fd1){die("not supported yet");},
|
||||
exec: func(filename,argv,envp){die("not supported yet");},
|
||||
waitpid: func(pid,nohang=0){return __builtin_waitpid;},
|
||||
isdir: func(path){return bits.bitand(io.stat(path)[2],0x4000);}, # S_IFDIR 0x4000
|
||||
isfile: func(path){return bits.bitand(io.stat(path)[2],0x8000);}, # S_IFREG 0x8000
|
||||
opendir: func(path){return __builtin_opendir;},
|
||||
readdir: func(handle){return __builtin_readdir;},
|
||||
closedir: func(handle){return __builtin_closedir;},
|
||||
time: func(){return time(0);},
|
||||
sleep: func(secs){return __builtin_sleep(secs);},
|
||||
chdir: func(path){return __builtin_chdir(path);},
|
||||
environ: func(){return __builtin_environ();},
|
||||
getcwd: func(){return __builtin_getcwd();},
|
||||
getenv: func(envvar){return __builtin_getenv(envvar);}
|
||||
};
|
||||
|
||||
# dylib is the core hashmap for developers to load their own library.
|
||||
# for safe using dynamic library, you could use 'module' in stl/module.nas
|
||||
var dylib=
|
||||
{
|
||||
# open dynamic lib.
|
||||
dlopen: func(libname){return __builtin_dlopen;},
|
||||
# load symbol from an open dynamic lib.
|
||||
dlsym: func(lib,sym){return __builtin_dlsym; },
|
||||
# close dynamic lib, this operation will make all the symbols loaded from it invalid.
|
||||
dlclose: func(lib){return __builtin_dlclose; },
|
||||
# call the loaded symbol.
|
||||
dlcall: func(funcptr,args...){return __builtin_dlcall}
|
||||
};
|
||||
|
||||
# os is used to use or get some os-related info/functions.
|
||||
# windows/macOS/linux are supported.
|
||||
var os=
|
||||
{
|
||||
# get a string that tell which os it runs on.
|
||||
platform: func(){return __builtin_platform;}
|
||||
};
|
||||
|
||||
# runtime gives us some functions that we could manage it manually.
|
||||
var runtime=
|
||||
{
|
||||
# do garbage collection manually.
|
||||
# carefully use it because using it frequently may make program running slower.
|
||||
gc: func(){return __builtin_gc;}
|
||||
};
|
||||
|
||||
# important global constants
|
||||
var D2R=math.pi/180;
|
||||
var FPS2KT=0.5925;
|
||||
var FT2M=0.3048;
|
||||
var GAL2L=3.7854;
|
||||
var IN2M=0.0254;
|
||||
var KG2LB=2.2046;
|
||||
var KT2FPS=1.6878;
|
||||
var KT2MPS=0.5144;
|
||||
var L2GAL=0.2642;
|
||||
var LB2KG=0.4536;
|
||||
var M2FT=3.2808;
|
||||
var M2IN=39.3701;
|
||||
var M2NM=0.00054;
|
||||
var MPS2KT=1.9438;
|
||||
var NM2M=1852;
|
||||
var R2D=180/math.pi;
|
||||
|
||||
# functions that not supported in this runtime:
|
||||
var bind=func(function,locals,outer_scope=nil){
|
||||
die("this runtime does not support bind");
|
||||
}
|
||||
|
||||
var call=func(function,args=nil,_me=nil,locals=nil,error=nil){
|
||||
die("this runtime does not support call");
|
||||
}
|
||||
|
||||
var caller=func(level=1){
|
||||
die("this runtime does not support caller");
|
||||
}
|
||||
|
||||
var closure=func(function,level=1){
|
||||
die("this runtime uses \"vm_upval\" instead of \"vm_hash\" as the closure");
|
||||
}
|
||||
|
||||
var compile=func(code,filename="<compile>"){
|
||||
die("this runtime uses static code generator");
|
||||
}
|
||||
375
main.cpp
375
main.cpp
@@ -1,221 +1,156 @@
|
||||
#include "nasal.h"
|
||||
|
||||
nasal_lexer lexer;
|
||||
nasal_parse parse;
|
||||
nasal_import import;
|
||||
std::string inputfile="null";
|
||||
nasal_runtime runtime;
|
||||
nasal_codegen code_generator;
|
||||
nasal_bytecode_vm bytevm;
|
||||
|
||||
void help()
|
||||
{
|
||||
std::cout<<">> [\"file\"] input a file name.\n";
|
||||
std::cout<<">> [help ] show help.\n";
|
||||
std::cout<<">> [clear ] clear the screen.\n";
|
||||
std::cout<<">> [del ] clear the input filename.\n";
|
||||
std::cout<<">> [lex ] use lexer to turn code into tokens.\n";
|
||||
std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n";
|
||||
std::cout<<">> [run ] run abstract syntax tree.\n";
|
||||
std::cout<<">> [code ] show byte code.\n";
|
||||
std::cout<<">> [exec ] execute program on bytecode vm.\n";
|
||||
std::cout<<">> [logo ] print logo of nasal .\n";
|
||||
std::cout<<">> [exit ] quit nasal interpreter.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
void logo()
|
||||
{
|
||||
std::cout<<" __ _ \n";
|
||||
std::cout<<" /\\ \\ \\__ _ ___ __ _| | \n";
|
||||
std::cout<<" / \\/ / _` / __|/ _` | | \n";
|
||||
std::cout<<" / /\\ / (_| \\__ \\ (_| | | \n";
|
||||
std::cout<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n";
|
||||
return;
|
||||
}
|
||||
|
||||
void del_func()
|
||||
{
|
||||
lexer.clear();
|
||||
parse.clear();
|
||||
inputfile="null";
|
||||
std::cout<<">> [Delete] complete.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
void die(std::string stage,std::string filename)
|
||||
{
|
||||
std::cout<<">> ["<<stage<<"] in <\""<<filename<<"\">: error(s) occurred,stop.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
void lex_func()
|
||||
{
|
||||
lexer.openfile(inputfile);
|
||||
lexer.scanner();
|
||||
if(lexer.get_error())
|
||||
{
|
||||
die("lexer",inputfile);
|
||||
return;
|
||||
}
|
||||
lexer.print_token();
|
||||
return;
|
||||
}
|
||||
|
||||
void ast_print()
|
||||
{
|
||||
lexer.openfile(inputfile);
|
||||
lexer.scanner();
|
||||
if(lexer.get_error())
|
||||
{
|
||||
die("lexer",inputfile);
|
||||
return;
|
||||
}
|
||||
parse.set_toklist(lexer.get_token_list());
|
||||
parse.main_process();
|
||||
if(parse.get_error())
|
||||
{
|
||||
die("parse",inputfile);
|
||||
return;
|
||||
}
|
||||
parse.get_root().print_ast(0);
|
||||
return;
|
||||
}
|
||||
|
||||
void runtime_start()
|
||||
{
|
||||
lexer.openfile(inputfile);
|
||||
lexer.scanner();
|
||||
if(lexer.get_error())
|
||||
{
|
||||
die("lexer",inputfile);
|
||||
return;
|
||||
}
|
||||
parse.set_toklist(lexer.get_token_list());
|
||||
parse.main_process();
|
||||
if(parse.get_error())
|
||||
{
|
||||
die("parse",inputfile);
|
||||
return;
|
||||
}
|
||||
import.link(parse.get_root());
|
||||
if(import.get_error())
|
||||
{
|
||||
die("import",inputfile);
|
||||
return;
|
||||
}
|
||||
runtime.set_root(import.get_root());
|
||||
runtime.run();
|
||||
return;
|
||||
}
|
||||
|
||||
void show_bytecode()
|
||||
{
|
||||
lexer.openfile(inputfile);
|
||||
lexer.scanner();
|
||||
if(lexer.get_error())
|
||||
{
|
||||
die("lexer",inputfile);
|
||||
return;
|
||||
}
|
||||
parse.set_toklist(lexer.get_token_list());
|
||||
parse.main_process();
|
||||
if(parse.get_error())
|
||||
{
|
||||
die("parse",inputfile);
|
||||
return;
|
||||
}
|
||||
import.link(parse.get_root());
|
||||
if(import.get_error())
|
||||
{
|
||||
die("import",inputfile);
|
||||
return;
|
||||
}
|
||||
code_generator.main_progress(import.get_root());
|
||||
code_generator.print_byte_code();
|
||||
return;
|
||||
}
|
||||
|
||||
void execute()
|
||||
{
|
||||
lexer.openfile(inputfile);
|
||||
lexer.scanner();
|
||||
if(lexer.get_error())
|
||||
{
|
||||
die("lexer",inputfile);
|
||||
return;
|
||||
}
|
||||
parse.set_toklist(lexer.get_token_list());
|
||||
parse.main_process();
|
||||
if(parse.get_error())
|
||||
{
|
||||
die("parse",inputfile);
|
||||
return;
|
||||
}
|
||||
import.link(parse.get_root());
|
||||
if(import.get_error())
|
||||
{
|
||||
die("import",inputfile);
|
||||
return;
|
||||
}
|
||||
code_generator.main_progress(import.get_root());
|
||||
bytevm.run(
|
||||
code_generator.get_string_table(),
|
||||
code_generator.get_number_table(),
|
||||
code_generator.get_exec_code()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string command;
|
||||
#ifdef _WIN32
|
||||
// use chcp 65001 to use unicode io
|
||||
system("chcp 65001");
|
||||
system("cls");
|
||||
#endif
|
||||
logo();
|
||||
std::cout<<">> Nasal interpreter ver 3.0 .\n";
|
||||
std::cout<<">> Code: https://github.com/ValKmjolnir/Nasal-Interpreter\n";
|
||||
std::cout<<">> Info: http://wiki.flightgear.org/Nasal_scripting_language\n";
|
||||
std::cout<<">> Input \"help\" to get help .\n";
|
||||
while(1)
|
||||
{
|
||||
std::cout<<">> ";
|
||||
std::cin>>command;
|
||||
if(command=="help")
|
||||
help();
|
||||
else if(command=="clear")
|
||||
{
|
||||
#ifdef _WIN32
|
||||
system("cls");
|
||||
#endif
|
||||
#ifdef _linux_
|
||||
system("clear");
|
||||
#endif
|
||||
#ifdef TARGET_OS_MAC
|
||||
system("clear");
|
||||
#endif
|
||||
}
|
||||
else if(command=="del")
|
||||
del_func();
|
||||
else if(command=="lex")
|
||||
lex_func();
|
||||
else if(command=="ast")
|
||||
ast_print();
|
||||
else if(command=="run")
|
||||
runtime_start();
|
||||
else if(command=="code")
|
||||
show_bytecode();
|
||||
else if(command=="exec")
|
||||
execute();
|
||||
else if(command=="logo")
|
||||
logo();
|
||||
else if(command=="exit")
|
||||
break;
|
||||
else
|
||||
inputfile=command;
|
||||
}
|
||||
return 0;
|
||||
#include "nasal.h"
|
||||
|
||||
const uint32_t VM_LEXINFO =0x01;
|
||||
const uint32_t VM_ASTINFO =0x02;
|
||||
const uint32_t VM_CODEINFO =0x04;
|
||||
const uint32_t VM_EXECTIME =0x08;
|
||||
const uint32_t VM_OPCALLNUM=0x10;
|
||||
const uint32_t VM_EXEC =0x20;
|
||||
const uint32_t VM_DBGINFO =0x40;
|
||||
const uint32_t VM_DEBUG =0x80;
|
||||
const uint32_t VM_OPTIMIZE =0x100;
|
||||
|
||||
void help()
|
||||
{
|
||||
std::cout
|
||||
#ifdef _WIN32
|
||||
<<"use command <chcp 65001> if want to use unicode.\n"
|
||||
#endif
|
||||
<<"nasal <option>\n"
|
||||
<<"option:\n"
|
||||
<<" -h, --help | get help.\n"
|
||||
<<" -v, --version | get version of nasal interpreter.\n\n"
|
||||
<<"nasal <file>\n"
|
||||
<<"file:\n"
|
||||
<<" input file name to execute script file.\n\n"
|
||||
<<"nasal [options...] <file>\n"
|
||||
<<"option:\n"
|
||||
<<" -l, --lex | view token info.\n"
|
||||
<<" -a, --ast | view abstract syntax tree.\n"
|
||||
<<" -c, --code | view bytecode.\n"
|
||||
<<" -e, --exec | execute.\n"
|
||||
<<" -t, --time | execute and get the running time.\n"
|
||||
<<" -o, --opcnt | execute and count used operands.\n"
|
||||
<<" -d, --detail | execute and get detail crash info.\n"
|
||||
<<" | get garbage collector info if didn't crash.\n"
|
||||
<<" -op, --optimize| use optimizer(beta).\n"
|
||||
<<" | if want to use -op and run, please use -op -e/-t/-o/-d.\n"
|
||||
<<" -dbg, --debug | debug mode (this will ignore -t -o -d -e).\n"
|
||||
<<"file:\n"
|
||||
<<" input file name to execute script file.\n";
|
||||
}
|
||||
|
||||
void logo()
|
||||
{
|
||||
std::cout
|
||||
<<" __ _\n"
|
||||
<<" /\\ \\ \\__ _ ___ __ _| |\n"
|
||||
<<" / \\/ / _` / __|/ _` | |\n"
|
||||
<<" / /\\ / (_| \\__ \\ (_| | |\n"
|
||||
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
|
||||
<<"nasal ver : "<<__nasver<<"\n"
|
||||
<<"c++ std : "<<__cplusplus<<"\n"
|
||||
<<"thanks to : https://github.com/andyross/nasal\n"
|
||||
<<"code repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
|
||||
<<"code repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
|
||||
<<"lang info : http://wiki.flightgear.org/Nasal_scripting_language\n"
|
||||
<<"input <nasal -h> to get help .\n";
|
||||
}
|
||||
|
||||
void err()
|
||||
{
|
||||
std::cout
|
||||
<<"invalid argument(s).\n"
|
||||
<<"use <nasal -h> to get help.\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
void execute(const std::string& file,const uint32_t cmd)
|
||||
{
|
||||
// front end use the same error module
|
||||
nasal_err nerr;
|
||||
nasal_lexer lexer(nerr);
|
||||
nasal_parse parse(nerr);
|
||||
nasal_import linker(nerr);
|
||||
nasal_codegen gen(nerr);
|
||||
// back end
|
||||
nasal_vm vm;
|
||||
|
||||
// lexer scans file to get tokens
|
||||
lexer.scan(file);
|
||||
if(cmd&VM_LEXINFO)
|
||||
lexer.print();
|
||||
|
||||
// parser gets lexer's token list to compile
|
||||
parse.compile(lexer);
|
||||
// linker gets parser's ast and load import files to this ast
|
||||
linker.link(parse,file);
|
||||
// optimizer does simple optimization on ast
|
||||
if(cmd&VM_OPTIMIZE)
|
||||
optimize(parse.ast());
|
||||
if(cmd&VM_ASTINFO)
|
||||
parse.print();
|
||||
|
||||
// code generator gets parser's ast and linker's import file list to generate code
|
||||
gen.compile(parse,linker);
|
||||
if(cmd&VM_CODEINFO)
|
||||
gen.print();
|
||||
|
||||
// run bytecode
|
||||
if(cmd&VM_DEBUG)
|
||||
{
|
||||
nasal_dbg debugger;
|
||||
debugger.run(gen,linker);
|
||||
}
|
||||
else if(cmd&VM_EXECTIME)
|
||||
{
|
||||
clock_t t=clock();
|
||||
vm.run(gen,linker,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO);
|
||||
std::cout<<"process exited after "<<((double)(clock()-t))/CLOCKS_PER_SEC<<"s.\n";
|
||||
}
|
||||
else if(cmd&VM_EXEC)
|
||||
vm.run(gen,linker,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO);
|
||||
}
|
||||
|
||||
int main(int argc,const char* argv[])
|
||||
{
|
||||
if(argc<=1)
|
||||
{
|
||||
logo();
|
||||
return 0;
|
||||
}
|
||||
if(argc==2)
|
||||
{
|
||||
std::string s(argv[1]);
|
||||
if(s=="-v" || s=="--version")
|
||||
logo();
|
||||
else if(s=="-h" || s=="--help")
|
||||
help();
|
||||
else if(s[0]!='-')
|
||||
execute(s,VM_EXEC);
|
||||
else
|
||||
err();
|
||||
return 0;
|
||||
}
|
||||
std::unordered_map<std::string,uint32_t> cmdlst={
|
||||
{"--lex",VM_LEXINFO},{"-l",VM_LEXINFO},
|
||||
{"--ast",VM_ASTINFO},{"-a",VM_ASTINFO},
|
||||
{"--code",VM_CODEINFO},{"-c",VM_CODEINFO},
|
||||
{"--exec",VM_EXEC},{"-e",VM_EXEC},
|
||||
{"--opcnt",VM_OPCALLNUM|VM_EXEC},{"-o",VM_OPCALLNUM|VM_EXEC},
|
||||
{"--time",VM_EXECTIME|VM_EXEC},{"-t",VM_EXECTIME|VM_EXEC},
|
||||
{"--detail",VM_DBGINFO|VM_EXEC},{"-d",VM_DBGINFO|VM_EXEC},
|
||||
{"--optimize",VM_OPTIMIZE},{"-op",VM_OPTIMIZE},
|
||||
{"--debug",VM_DEBUG},{"-dbg",VM_DEBUG}
|
||||
};
|
||||
uint32_t cmd=0;
|
||||
for(int i=1;i<argc-1;++i)
|
||||
{
|
||||
if(cmdlst.count(argv[i]))
|
||||
cmd|=cmdlst[argv[i]];
|
||||
else
|
||||
err();
|
||||
}
|
||||
execute(argv[argc-1],cmd);
|
||||
return 0;
|
||||
}
|
||||
47
makefile
Normal file
47
makefile
Normal file
@@ -0,0 +1,47 @@
|
||||
.PHONY=test
|
||||
nasal:main.cpp nasal_ast.h nasal_err.h nasal_builtin.h nasal_opt.h nasal_codegen.h\
|
||||
nasal_gc.h nasal_import.h nasal_lexer.h nasal_parse.h nasal_vm.h nasal_dbg.h nasal.h
|
||||
clang++ -std=c++11 -O3 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
|
||||
nasal.exe:main.cpp nasal_ast.h nasal_err.h nasal_builtin.h nasal_opt.h nasal_codegen.h\
|
||||
nasal_gc.h nasal_import.h nasal_lexer.h nasal_parse.h nasal_vm.h nasal_dbg.h nasal.h
|
||||
g++ -std=c++11 -O3 main.cpp -o nasal.exe -fno-exceptions -Wshadow -Wall -static
|
||||
test:nasal
|
||||
@ ./nasal -op -e test/ascii-art.nas
|
||||
@ ./nasal -op -a -c test/bf.nas
|
||||
@ ./nasal -op -a -c test/bfcolored.nas
|
||||
@ ./nasal -op -a -c test/bfconvertor.nas
|
||||
@ ./nasal -op -e -d test/bfs.nas
|
||||
@ ./nasal -op -t test/bigloop.nas
|
||||
@ ./nasal -op -e test/bp.nas
|
||||
@ ./nasal -op -e -d test/calc.nas
|
||||
@ ./nasal -op -e test/choice.nas
|
||||
@ ./nasal -op -e test/class.nas
|
||||
@ ./nasal -op -e test/diff.nas
|
||||
-@ ./nasal -op -d test/exception.nas
|
||||
@ ./nasal -op -t -d test/fib.nas
|
||||
@ ./nasal -op -e test/filesystem.nas
|
||||
@ ./nasal -op -e -d test/hexdump.nas
|
||||
@ ./nasal -op -e test/json.nas
|
||||
@ ./nasal -op -e test/leetcode1319.nas
|
||||
@ ./nasal -op -e -d test/lexer.nas
|
||||
@ ./nasal -op -e -d test/life.nas
|
||||
@ ./nasal -op -t test/loop.nas
|
||||
@ ./nasal -op -t -d test/mandel.nas
|
||||
@ ./nasal -op -t -d test/mandelbrot.nas
|
||||
@ ./nasal -op -t -d -o test/md5.nas
|
||||
-@ ./nasal -op -t -d -o test/md5compare.nas
|
||||
-@ ./nasal -op -d test/module_test.nas
|
||||
@ ./nasal -op -e test/nasal_test.nas
|
||||
@ ./nasal -op -t -d test/pi.nas
|
||||
@ ./nasal -op -t -d test/prime.nas
|
||||
@ ./nasal -op -t -d test/props_sim.nas
|
||||
@ ./nasal -op -e test/qrcode.nas
|
||||
@ ./nasal -op -t -d test/quick_sort.nas
|
||||
@ ./nasal -op -e test/scalar.nas
|
||||
-@ ./nasal -op -c -t test/snake.nas
|
||||
@ ./nasal -op -c -e test/trait.nas
|
||||
-@ ./nasal -op -c -t test/tetris.nas
|
||||
@ ./nasal -op -c -t -d test/turingmachine.nas
|
||||
@ ./nasal -op -c -t -d -o test/ycombinator.nas
|
||||
@ ./nasal -op -e test/wavecollapse.nas
|
||||
|
||||
34
module/fib.cpp
Normal file
34
module/fib.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <iostream>
|
||||
#include "../nasal.h"
|
||||
|
||||
double fibonaci(double x){
|
||||
if(x<=2)
|
||||
return x;
|
||||
return fibonaci(x-1)+fibonaci(x-2);
|
||||
}
|
||||
extern "C" nasal_ref fib(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
std::cout<<"[mod] this is the first test module of nasal\n";
|
||||
if(!args.size())
|
||||
return builtin_err("fib","lack arguments");
|
||||
nasal_ref num=args[0];
|
||||
if(num.type!=vm_num)
|
||||
return builtin_err("extern_fib","\"num\" must be number");
|
||||
return {vm_num,fibonaci(num.to_number())};
|
||||
}
|
||||
extern "C" nasal_ref quick_fib(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
std::cout<<"[mod] this is the first test module of nasal\n";
|
||||
if(!args.size())
|
||||
return builtin_err("fib","lack arguments");
|
||||
nasal_ref num=args[0];
|
||||
if(num.type!=vm_num)
|
||||
return builtin_err("extern_quick_fib","\"num\" must be number");
|
||||
if(num.num()<2)
|
||||
return num;
|
||||
double a=1,b=1,res=0;
|
||||
for(double i=1;i<num.num();i+=1){
|
||||
res=a+b;
|
||||
a=b;
|
||||
b=res;
|
||||
}
|
||||
return {vm_num,res};
|
||||
}
|
||||
74
module/keyboard.cpp
Normal file
74
module/keyboard.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "../nasal.h"
|
||||
#include <iostream>
|
||||
#ifdef _WIN32
|
||||
#include <conio.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
static struct termios init_termios;
|
||||
static struct termios new_termios;
|
||||
static int peek_char=-1;
|
||||
|
||||
int kbhit(){
|
||||
unsigned char ch=0;
|
||||
int nread=0;
|
||||
if(peek_char!=-1)
|
||||
return 1;
|
||||
int flag=fcntl(0,F_GETFL);
|
||||
fcntl(0,F_SETFL,flag|O_NONBLOCK);
|
||||
nread=read(0,&ch,1);
|
||||
fcntl(0,F_SETFL,flag);
|
||||
if(nread==1){
|
||||
peek_char=ch;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getch(){
|
||||
int ch=0;
|
||||
if(peek_char!=-1){
|
||||
ch=peek_char;
|
||||
peek_char=-1;
|
||||
return ch;
|
||||
}
|
||||
read(0,&ch,1);
|
||||
return ch;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" nasal_ref nas_getch(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
return {vm_num,(double)getch()};
|
||||
}
|
||||
extern "C" nasal_ref nas_kbhit(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
return {vm_num,(double)kbhit()};
|
||||
}
|
||||
extern "C" nasal_ref nas_noblock(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
if(kbhit())
|
||||
return {vm_num,(double)getch()};
|
||||
return nil;
|
||||
}
|
||||
extern "C" nasal_ref nas_init(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
#ifndef _WIN32
|
||||
tcflush(0,TCIOFLUSH);
|
||||
tcgetattr(0,&init_termios);
|
||||
new_termios=init_termios;
|
||||
new_termios.c_lflag&=~(ICANON|ECHO|ECHONL|ECHOE);
|
||||
// vmin=0 is nonblock input, but in wsl there is a bug that will block input
|
||||
// so we use fcntl to write the nonblock input
|
||||
new_termios.c_cc[VMIN]=1;
|
||||
new_termios.c_cc[VTIME]=0;
|
||||
tcsetattr(0,TCSANOW,&new_termios);
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
extern "C" nasal_ref nas_close(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
#ifndef _WIN32
|
||||
tcflush(0,TCIOFLUSH);
|
||||
tcsetattr(0,TCSANOW,&init_termios);
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
13
module/libfib.nas
Normal file
13
module/libfib.nas
Normal file
@@ -0,0 +1,13 @@
|
||||
import("lib.nas");
|
||||
|
||||
var libfib=func(){
|
||||
var dl=dylib.dlopen("./module/libfib."~(os.platform()=="windows"?"dll":"so"));
|
||||
var fib=dylib.dlsym(dl,"fib");
|
||||
var qfib=dylib.dlsym(dl,"quick_fib");
|
||||
var call=dylib.dlcall;
|
||||
return
|
||||
{
|
||||
fib: func(x){return call(fib,x)},
|
||||
qfib:func(x){return call(qfib,x)}
|
||||
};
|
||||
}();
|
||||
47
module/libkey.nas
Normal file
47
module/libkey.nas
Normal file
@@ -0,0 +1,47 @@
|
||||
import("lib.nas");
|
||||
|
||||
var libkey=func(){
|
||||
var lib=dylib.dlopen("./module/libkey"~(os.platform()=="windows"?".dll":".so"));
|
||||
var kb=dylib.dlsym(lib,"nas_kbhit");
|
||||
var gt=dylib.dlsym(lib,"nas_getch");
|
||||
var nb=dylib.dlsym(lib,"nas_noblock");
|
||||
var init=dylib.dlsym(lib,"nas_init");
|
||||
var cls=dylib.dlsym(lib,"nas_close");
|
||||
var call=dylib.dlcall;
|
||||
var is_init=0;
|
||||
return {
|
||||
init:func(){
|
||||
# change io mode to no echo
|
||||
call(init);
|
||||
is_init=1;
|
||||
},
|
||||
kbhit:func(){
|
||||
# check if kerboard is hit
|
||||
# if keyboard is hit this function will return 1
|
||||
# until getch() gets all the input characters
|
||||
# and the input flow becomes empty
|
||||
if(!is_init)
|
||||
me.init();
|
||||
return call(kb);
|
||||
},
|
||||
getch:func(){
|
||||
# get input one character without echo
|
||||
# block until get one input
|
||||
if(!is_init)
|
||||
me.init();
|
||||
return call(gt);
|
||||
},
|
||||
nonblock:func(){
|
||||
# nonblock input without echo
|
||||
if(!is_init)
|
||||
me.init();
|
||||
return call(nb);
|
||||
},
|
||||
close:func(){
|
||||
# must call this function before exiting the program
|
||||
# this will change terminal mode to normal io mode
|
||||
call(cls);
|
||||
dylib.dlclose(lib);
|
||||
}
|
||||
}
|
||||
}();
|
||||
23
module/makefile
Normal file
23
module/makefile
Normal file
@@ -0,0 +1,23 @@
|
||||
.PHONY=clean all mingw-all
|
||||
libfib.so: fib.cpp
|
||||
clang++ -c -O3 fib.cpp -fPIC -o fib.o
|
||||
clang++ -shared -o libfib.so fib.o
|
||||
rm fib.o
|
||||
libfib.dll: fib.cpp
|
||||
g++ -c -O3 fib.cpp -fPIC -o fib.o
|
||||
g++ -shared -o libfib.dll fib.o
|
||||
|
||||
libkey.so: keyboard.cpp
|
||||
clang++ -c -O3 keyboard.cpp -fPIC -o keyboard.o
|
||||
clang++ -shared -o libkey.so keyboard.o
|
||||
rm keyboard.o
|
||||
libkey.dll: keyboard.cpp
|
||||
g++ -c -O3 keyboard.cpp -fPIC -o keyboard.o -static
|
||||
g++ -shared -o libkey.dll keyboard.o -static
|
||||
|
||||
clean:
|
||||
rm *.o *.so *.dll *.dylib
|
||||
all: libfib.so libkey.so
|
||||
@ echo "build done"
|
||||
mingw-all: libfib.dll libkey.dll
|
||||
@ echo "build done"
|
||||
18
nasal.ebnf
18
nasal.ebnf
@@ -20,7 +20,7 @@ hashmember::=
|
||||
id|string ':' calculation
|
||||
;
|
||||
function::=
|
||||
func argument_list expressions
|
||||
func {argument_list} exprs|expr
|
||||
;
|
||||
argument_list::=
|
||||
'(' [{id ','} ([id '...']|{id '=' scalar ','})] ')'
|
||||
@@ -35,7 +35,7 @@ expr::=
|
||||
|continue_expr
|
||||
|break_expr
|
||||
;
|
||||
expressions::=
|
||||
exprs::=
|
||||
'{' {expr} '}'
|
||||
;
|
||||
calculation::=
|
||||
@@ -63,11 +63,11 @@ unary::=
|
||||
;
|
||||
scalar::=
|
||||
function {call_scalar}
|
||||
|[func] identifier {call_scalar}
|
||||
|vector {call_scalar}
|
||||
|hash {call_scalar}
|
||||
|number
|
||||
|string
|
||||
|nil
|
||||
|'(' calculation ')' {call_scalar}
|
||||
;
|
||||
call_scalar::=
|
||||
@@ -108,18 +108,18 @@ loop::=
|
||||
|forei_loop
|
||||
;
|
||||
while_loop::=
|
||||
while '(' calculation ')' expressions
|
||||
while '(' calculation ')' exprs
|
||||
;
|
||||
for_loop::=
|
||||
for '(' [definition|calculation] ';' [calculation] ';' [calculation] ')' expressions
|
||||
for '(' [definition|calculation] ';' [calculation] ';' [calculation] ')' exprs
|
||||
;
|
||||
forei_loop::=
|
||||
(forindex | foreach) '(' (definition | calculation) ';' calculation ')' expressions
|
||||
(forindex | foreach) '(' (definition | calculation) ';' calculation ')' exprs
|
||||
;
|
||||
conditional::=
|
||||
if '(' calculation ')' expressions
|
||||
{elsif '(' calculation ')' expressions}
|
||||
[else expressions]
|
||||
if '(' calculation ')' exprs
|
||||
{elsif '(' calculation ')' exprs}
|
||||
[else exprs]
|
||||
;
|
||||
continue_expr::=
|
||||
continue
|
||||
|
||||
259
nasal.h
259
nasal.h
@@ -1,11 +1,14 @@
|
||||
#ifndef __NASAL_H__
|
||||
#define __NASAL_H__
|
||||
|
||||
#pragma GCC optimize(2)
|
||||
#define __nasver "9.0"
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
@@ -14,127 +17,179 @@
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <thread>
|
||||
#include <list>
|
||||
#include <stack>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
/*
|
||||
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)
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#define PRTHEX64 "%lx"
|
||||
#define PRTHEX64_8 "%.8lx"
|
||||
#define PRTINT64 "%ld"
|
||||
#else
|
||||
#define PRTHEX64 "%llx"
|
||||
#define PRTHEX64_8 "%.8llx"
|
||||
#define PRTINT64 "%lld"
|
||||
#endif
|
||||
|
||||
inline double hex_to_double(const char* str)
|
||||
{
|
||||
double ret=0;
|
||||
for(int i=2;str[i];++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;
|
||||
double ret=0;
|
||||
for(;*str;++str)
|
||||
{
|
||||
ret*=16;
|
||||
if('0'<=*str && *str<='9')
|
||||
ret+=(*str-'0');
|
||||
else if('a'<=*str && *str<='f')
|
||||
ret+=(*str-'a'+10);
|
||||
else if('A'<=*str && *str<='F')
|
||||
ret+=(*str-'A'+10);
|
||||
else
|
||||
return nan("");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
inline double oct_to_double(std::string str)
|
||||
inline double oct_to_double(const char* str)
|
||||
{
|
||||
double ret=0;
|
||||
for(int i=2;str[i];++i)
|
||||
{
|
||||
ret*=8;
|
||||
if('0'<=str[i] && str[i]<='8')
|
||||
ret+=(str[i]-'0');
|
||||
else
|
||||
return std::nan("");
|
||||
}
|
||||
return ret;
|
||||
double ret=0;
|
||||
for(;*str;++str)
|
||||
{
|
||||
ret*=8;
|
||||
if('0'<=*str && *str<'8')
|
||||
ret+=(*str-'0');
|
||||
else
|
||||
return nan("");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
inline double dec_to_double(std::string str,int len)
|
||||
inline double dec_to_double(const char* str)
|
||||
{
|
||||
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 ret=0,negative=1,num_pow=0;
|
||||
while('0'<=*str && *str<='9')
|
||||
ret=ret*10+(*str++-'0');
|
||||
if(!*str) return ret;
|
||||
if(*str=='.')
|
||||
{
|
||||
if(!*++str) return nan("");
|
||||
num_pow=0.1;
|
||||
while('0'<=*str && *str<='9')
|
||||
{
|
||||
ret+=num_pow*(*str++-'0');
|
||||
num_pow*=0.1;
|
||||
}
|
||||
if(!*str) return ret;
|
||||
}
|
||||
if(*str!='e' && *str!='E')
|
||||
return nan("");
|
||||
if(!*++str) return nan("");
|
||||
if(*str=='-' || *str=='+')
|
||||
negative=(*str++=='-'? -1:1);
|
||||
if(!*str) return nan("");
|
||||
num_pow=0;
|
||||
for(;*str;++str)
|
||||
{
|
||||
if('0'<=*str && *str<='9')
|
||||
num_pow=num_pow*10+(*str-'0');
|
||||
else
|
||||
return nan("");
|
||||
}
|
||||
return ret*std::pow(10,negative*num_pow);
|
||||
}
|
||||
double trans_string_to_number(std::string str)
|
||||
double str2num(const char* 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>1 && str[0]=='0' && str[1]=='x')
|
||||
ret_num=hex_to_double(str);
|
||||
else if(len>1 && str[0]=='0' && str[1]=='o')
|
||||
ret_num=oct_to_double(str);
|
||||
else
|
||||
ret_num=dec_to_double(str,len);
|
||||
return is_negative*ret_num;
|
||||
bool is_negative=false;
|
||||
double ret_num=0;
|
||||
if(*str=='-' || *str=='+')
|
||||
is_negative=(*str++=='-');
|
||||
if(!*str)
|
||||
return nan("");
|
||||
if(str[0]=='0' && str[1]=='x')
|
||||
ret_num=hex_to_double(str+2);
|
||||
else if(str[0]=='0' && str[1]=='o')
|
||||
ret_num=oct_to_double(str+2);
|
||||
else
|
||||
ret_num=dec_to_double(str);
|
||||
return is_negative?-ret_num:ret_num;
|
||||
}
|
||||
|
||||
/*
|
||||
trans_number_to_string:
|
||||
convert number to string
|
||||
*/
|
||||
std::string trans_number_to_string(double number)
|
||||
int utf8_hdchk(char head)
|
||||
{
|
||||
std::string res;
|
||||
std::stringstream ss;
|
||||
ss<<number;
|
||||
ss>>res;
|
||||
return res;
|
||||
// RFC-2279 but in fact now we use RFC-3629 so nbytes is less than 4
|
||||
uint8_t c=(uint8_t)head;
|
||||
uint32_t nbytes=0;
|
||||
if((c>>5)==0x06) // 110x xxxx (10xx xxxx)^1
|
||||
nbytes=1;
|
||||
if((c>>4)==0x0e) // 1110 xxxx (10xx xxxx)^2
|
||||
nbytes=2;
|
||||
if((c>>3)==0x1e) // 1111 0xxx (10xx xxxx)^3
|
||||
nbytes=3;
|
||||
// these should not be true
|
||||
if((c>>2)==0x3e) // 1111 10xx (10xx xxxx)^4
|
||||
nbytes=4;
|
||||
if((c>>1)==0x7e) // 1111 110x (10xx xxxx)^5
|
||||
nbytes=5;
|
||||
if(c==0xfe) // 1111 1110 (10xx xxxx)^6
|
||||
nbytes=6;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
std::string rawstr(const std::string& str)
|
||||
{
|
||||
std::string ret("");
|
||||
for(auto i:str)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// windows ps or cmd doesn't output unicode normally
|
||||
// if 'chcp65001' is not enabled, so we output the hex
|
||||
if(i<=0)
|
||||
{
|
||||
ret+="\\x";
|
||||
ret+="0123456789abcdef"[(i>>4)&15];
|
||||
ret+="0123456789abcdef"[i&15];
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
switch(i)
|
||||
{
|
||||
case '\0': ret+="\\0"; break;
|
||||
case '\a': ret+="\\a"; break;
|
||||
case '\b': ret+="\\b"; break;
|
||||
case '\e': ret+="\\e"; break;
|
||||
case '\t': ret+="\\t"; break;
|
||||
case '\n': ret+="\\n"; break;
|
||||
case '\v': ret+="\\v"; break;
|
||||
case '\f': ret+="\\f"; break;
|
||||
case '\r': ret+="\\r"; break;
|
||||
case '\\': ret+="\\\\";break;
|
||||
case '\'': ret+="\\\'";break;
|
||||
case '\"': ret+="\\\"";break;
|
||||
default: ret+=i; break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#include "nasal_err.h"
|
||||
#include "nasal_lexer.h"
|
||||
#include "nasal_ast.h"
|
||||
#include "nasal_parse.h"
|
||||
#include "nasal_import.h"
|
||||
#include "nasal_opt.h"
|
||||
#include "nasal_gc.h"
|
||||
#include "nasal_builtin.h"
|
||||
#include "nasal_runtime.h"
|
||||
#include "nasal_codegen.h"
|
||||
#include "nasal_bytecode_vm.h"
|
||||
#include "nasal_vm.h"
|
||||
#include "nasal_dbg.h"
|
||||
|
||||
#endif
|
||||
|
||||
408
nasal_ast.h
408
nasal_ast.h
@@ -3,231 +3,245 @@
|
||||
|
||||
enum ast_node
|
||||
{
|
||||
ast_null=0,ast_root,ast_block,
|
||||
ast_nil,ast_number,ast_string,ast_identifier,ast_function,ast_hash,ast_vector,
|
||||
ast_hashmember,ast_call,ast_call_hash,ast_call_vec,ast_call_func,ast_subvec,
|
||||
ast_args,ast_default_arg,ast_dynamic_id,
|
||||
ast_and,ast_or,
|
||||
ast_equal,ast_add_equal,ast_sub_equal,ast_mult_equal,ast_div_equal,ast_link_equal,
|
||||
ast_cmp_equal,ast_cmp_not_equal,
|
||||
ast_less_than,ast_less_equal,
|
||||
ast_greater_than,ast_greater_equal,
|
||||
ast_add,ast_sub,ast_mult,ast_div,ast_link,
|
||||
ast_unary_sub,ast_unary_not,
|
||||
ast_trinocular,
|
||||
ast_for,ast_forindex,ast_foreach,ast_while,ast_new_iter,
|
||||
ast_conditional,ast_if,ast_elsif,ast_else,
|
||||
ast_multi_id,ast_multi_scalar,
|
||||
ast_definition,ast_multi_assign,
|
||||
ast_continue,ast_break,ast_return
|
||||
ast_null=0, // null node
|
||||
ast_root, // mark the root node of ast
|
||||
ast_block, // expression block
|
||||
ast_file, // used to store which file the sub-tree is on, only used in main block
|
||||
ast_nil, // nil keyword
|
||||
ast_num, // number, basic value type
|
||||
ast_str, // string, basic value type
|
||||
ast_id, // identifier
|
||||
ast_func, // func keyword
|
||||
ast_hash, // hash, basic value type
|
||||
ast_vec, // vector, basic value type
|
||||
ast_pair, // pair of key and value in hashmap
|
||||
ast_call, // mark a sub-tree of calling an identifier
|
||||
ast_callh, // id.name
|
||||
ast_callv, // id[index]
|
||||
ast_callf, // id()
|
||||
ast_subvec, // id[index:index]
|
||||
ast_args, // mark a sub-tree of function parameters
|
||||
ast_default, // default parameter
|
||||
ast_dynamic, // dynamic parameter
|
||||
ast_and, // and keyword
|
||||
ast_or, // or keyword
|
||||
ast_equal, // =
|
||||
ast_addeq, // +=
|
||||
ast_subeq, // -=
|
||||
ast_multeq, // *=
|
||||
ast_diveq, // /=
|
||||
ast_lnkeq, // ~=
|
||||
ast_cmpeq, // ==
|
||||
ast_neq, // !=
|
||||
ast_less, // <
|
||||
ast_leq, // <=
|
||||
ast_grt, // >
|
||||
ast_geq, // >=
|
||||
ast_add, // +
|
||||
ast_sub, // -
|
||||
ast_mult, // *
|
||||
ast_div, // /
|
||||
ast_link, // ~
|
||||
ast_neg, // -
|
||||
ast_not, // ~
|
||||
ast_trino, // ?:
|
||||
ast_for, // for keyword
|
||||
ast_forindex, // forindex keyword
|
||||
ast_foreach, // foreach keyword
|
||||
ast_while, // while
|
||||
ast_iter, // iterator, used in forindex/foreach
|
||||
ast_conditional, // mark a sub-tree of conditional expression
|
||||
ast_if, // if keyword
|
||||
ast_elsif, // elsif keyword
|
||||
ast_else, // else keyword
|
||||
ast_multi_id, // multi identifiers sub-tree
|
||||
ast_multi_scalar,// multi value sub-tree
|
||||
ast_def, // definition
|
||||
ast_multi_assign,// multi assignment sub-tree
|
||||
ast_continue, // continue keyword, only used in loop
|
||||
ast_break, // break keyword, only used in loop
|
||||
ast_ret // return keyword, only used in function block
|
||||
};
|
||||
|
||||
std::string ast_str(int type)
|
||||
const char* ast_name[]=
|
||||
{
|
||||
std::string str;
|
||||
switch(type)
|
||||
{
|
||||
case ast_null: str="null";break;
|
||||
case ast_root: str="root";break;
|
||||
case ast_block: str="block";break;
|
||||
case ast_nil: str="nil";break;
|
||||
case ast_number: str="number";break;
|
||||
case ast_string: str="string";break;
|
||||
case ast_identifier: str="id";break;
|
||||
case ast_function: str="function";break;
|
||||
case ast_hash: str="hash";break;
|
||||
case ast_vector: str="vector";break;
|
||||
case ast_hashmember: str="hashmember";break;
|
||||
case ast_call: str="call";break;
|
||||
case ast_call_hash: str="call_hash";break;
|
||||
case ast_call_vec: str="call_vector";break;
|
||||
case ast_call_func: str="call_func";break;
|
||||
case ast_subvec: str="subvec";break;
|
||||
case ast_args: str="arguments";break;
|
||||
case ast_default_arg: str="default_arg";break;
|
||||
case ast_dynamic_id: str="dynamic_id";break;
|
||||
case ast_and: str="and";break;
|
||||
case ast_or: str="or";break;
|
||||
case ast_equal: str="=";break;
|
||||
case ast_add_equal: str="+=";break;
|
||||
case ast_sub_equal: str="-=";break;
|
||||
case ast_mult_equal: str="*=";break;
|
||||
case ast_div_equal: str="/=";break;
|
||||
case ast_link_equal: str="~=";break;
|
||||
case ast_cmp_equal: str="==";break;
|
||||
case ast_cmp_not_equal:str="!=";break;
|
||||
case ast_less_than: str="<";break;
|
||||
case ast_less_equal: str="<=";break;
|
||||
case ast_greater_than: str=">";break;
|
||||
case ast_greater_equal:str=">=";break;
|
||||
case ast_add: str="+";break;
|
||||
case ast_sub: str="-";break;
|
||||
case ast_mult: str="*";break;
|
||||
case ast_div: str="/";break;
|
||||
case ast_link: str="~";break;
|
||||
case ast_unary_sub: str="unary-";break;
|
||||
case ast_unary_not: str="unary!";break;
|
||||
case ast_trinocular: str="trinocular";break;
|
||||
case ast_for: str="for";break;
|
||||
case ast_forindex: str="forindex";break;
|
||||
case ast_foreach: str="foreach";break;
|
||||
case ast_while: str="while";break;
|
||||
case ast_new_iter: str="new_iterator";break;
|
||||
case ast_conditional: str="conditional";break;
|
||||
case ast_if: str="if";break;
|
||||
case ast_elsif: str="elsif";break;
|
||||
case ast_else: str="else";break;
|
||||
case ast_multi_id: str="multi_id";break;
|
||||
case ast_multi_scalar: str="multi_scalar";break;
|
||||
case ast_definition: str="definition";break;
|
||||
case ast_multi_assign: str="multi_assignment";break;
|
||||
case ast_continue: str="continue";break;
|
||||
case ast_break: str="break";break;
|
||||
case ast_return: str="return";break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
"null",
|
||||
"root",
|
||||
"block",
|
||||
"file",
|
||||
"nil",
|
||||
"num",
|
||||
"str",
|
||||
"id",
|
||||
"func",
|
||||
"hash",
|
||||
"vec",
|
||||
"hashmember",
|
||||
"call",
|
||||
"callh",
|
||||
"callv",
|
||||
"callf",
|
||||
"subvec",
|
||||
"args",
|
||||
"default",
|
||||
"dynamic",
|
||||
"and",
|
||||
"or",
|
||||
"=",
|
||||
"+=",
|
||||
"-=",
|
||||
"*=",
|
||||
"/=",
|
||||
"~=",
|
||||
"==",
|
||||
"!=",
|
||||
"<",
|
||||
"<=",
|
||||
">",
|
||||
">=",
|
||||
"+",
|
||||
"-",
|
||||
"*",
|
||||
"/",
|
||||
"~",
|
||||
"unary-",
|
||||
"unary!",
|
||||
"trino",
|
||||
"for",
|
||||
"forindex",
|
||||
"foreach",
|
||||
"while",
|
||||
"iter",
|
||||
"conditional",
|
||||
"if",
|
||||
"elsif",
|
||||
"else",
|
||||
"multi-id",
|
||||
"multi-scalar",
|
||||
"def",
|
||||
"multi-assign",
|
||||
"continue",
|
||||
"break",
|
||||
"return",
|
||||
nullptr
|
||||
};
|
||||
|
||||
class nasal_ast
|
||||
{
|
||||
private:
|
||||
int line;
|
||||
int type;
|
||||
std::string str;
|
||||
double num;
|
||||
std::vector<nasal_ast> children;
|
||||
uint32_t _line;
|
||||
uint32_t _type;
|
||||
double _num;
|
||||
std::string _str;
|
||||
std::vector<nasal_ast> _child;
|
||||
public:
|
||||
nasal_ast(int,int);
|
||||
nasal_ast(const uint32_t l=0,const uint32_t t=ast_null):_line(l),_type(t),_num(0){}
|
||||
nasal_ast(const nasal_ast&);
|
||||
~nasal_ast();
|
||||
nasal_ast& operator=(const nasal_ast&);
|
||||
nasal_ast(nasal_ast&&);
|
||||
void print(int,bool);
|
||||
void clear();
|
||||
void set_line(int);
|
||||
void set_type(int);
|
||||
void set_str(std::string&);
|
||||
void set_num(double);
|
||||
void add_child(nasal_ast);
|
||||
int get_line();
|
||||
int get_type();
|
||||
std::string get_str();
|
||||
double get_num();
|
||||
std::vector<nasal_ast>& get_children();
|
||||
void print_ast(int);
|
||||
|
||||
nasal_ast& operator=(const nasal_ast&);
|
||||
nasal_ast& operator=(nasal_ast&&);
|
||||
nasal_ast& operator[](const int index){return _child[index];}
|
||||
const nasal_ast& operator[](const int index) const {return _child[index];}
|
||||
size_t size() const {return _child.size();}
|
||||
|
||||
void add(nasal_ast&& ast){_child.push_back(std::move(ast));}
|
||||
void add(const nasal_ast& ast){_child.push_back(ast);}
|
||||
void set_line(const uint32_t l){_line=l;}
|
||||
void set_type(const uint32_t t){_type=t;}
|
||||
void set_str(const std::string& s){_str=s;}
|
||||
void set_num(const double n){_num=n;}
|
||||
|
||||
inline uint32_t line() const {return _line;}
|
||||
inline uint32_t type() const {return _type;}
|
||||
inline double num() const {return _num;}
|
||||
inline const std::string& str() const {return _str;}
|
||||
inline const std::vector<nasal_ast>& child() const {return _child;}
|
||||
inline std::vector<nasal_ast>& child(){return _child;}
|
||||
};
|
||||
|
||||
nasal_ast::nasal_ast(int init_line=0,int init_type=ast_null)
|
||||
nasal_ast::nasal_ast(const nasal_ast& tmp):
|
||||
_str(tmp._str),_child(tmp._child)
|
||||
{
|
||||
this->line=init_line;
|
||||
this->type=init_type;
|
||||
return;
|
||||
_line=tmp._line;
|
||||
_type=tmp._type;
|
||||
_num =tmp._num;
|
||||
}
|
||||
|
||||
nasal_ast::nasal_ast(const nasal_ast& tmp)
|
||||
nasal_ast::nasal_ast(nasal_ast&& tmp)
|
||||
{
|
||||
this->line=tmp.line;
|
||||
this->type=tmp.type;
|
||||
this->str=tmp.str;
|
||||
this->num=tmp.num;
|
||||
this->children=tmp.children;
|
||||
return;
|
||||
}
|
||||
|
||||
nasal_ast::~nasal_ast()
|
||||
{
|
||||
this->children.clear();
|
||||
return;
|
||||
_line=tmp._line;
|
||||
_type=tmp._type;
|
||||
_num =tmp._num;
|
||||
_str.swap(tmp._str);
|
||||
_child.swap(tmp._child);
|
||||
}
|
||||
|
||||
nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
|
||||
{
|
||||
this->line=tmp.line;
|
||||
this->type=tmp.type;
|
||||
this->str=tmp.str;
|
||||
this->num=tmp.num;
|
||||
this->children=tmp.children;
|
||||
_line=tmp._line;
|
||||
_type=tmp._type;
|
||||
_num=tmp._num;
|
||||
_str=tmp._str;
|
||||
_child=tmp._child;
|
||||
return *this;
|
||||
}
|
||||
|
||||
nasal_ast& nasal_ast::operator=(nasal_ast&& tmp)
|
||||
{
|
||||
_line=tmp._line;
|
||||
_type=tmp._type;
|
||||
_num=tmp._num;
|
||||
_str.swap(tmp._str);
|
||||
_child.swap(tmp._child);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void nasal_ast::clear()
|
||||
{
|
||||
this->line=0;
|
||||
this->str="";
|
||||
this->num=0;
|
||||
this->type=ast_null;
|
||||
this->children.clear();
|
||||
return;
|
||||
_line=0;
|
||||
_num=0;
|
||||
_str="";
|
||||
_type=ast_null;
|
||||
_child.clear();
|
||||
}
|
||||
|
||||
void nasal_ast::set_line(int l)
|
||||
void nasal_ast::print(int depth,bool last=false)
|
||||
{
|
||||
this->line=l;
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_ast::set_type(int t)
|
||||
{
|
||||
this->type=t;
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_ast::set_str(std::string& s)
|
||||
{
|
||||
this->str=s;
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_ast::set_num(double n)
|
||||
{
|
||||
this->num=n;
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_ast::add_child(nasal_ast ast)
|
||||
{
|
||||
children.push_back(ast);
|
||||
return;
|
||||
}
|
||||
|
||||
int nasal_ast::get_line()
|
||||
{
|
||||
return this->line;
|
||||
}
|
||||
|
||||
int nasal_ast::get_type()
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
std::string nasal_ast::get_str()
|
||||
{
|
||||
return this->str;
|
||||
}
|
||||
|
||||
double nasal_ast::get_num()
|
||||
{
|
||||
return this->num;
|
||||
}
|
||||
|
||||
std::vector<nasal_ast>& nasal_ast::get_children()
|
||||
{
|
||||
return this->children;
|
||||
}
|
||||
|
||||
void nasal_ast::print_ast(int depth)
|
||||
{
|
||||
std::string indentation="";
|
||||
for(int i=0;i<depth;++i) indentation+="| ";
|
||||
indentation+=ast_str(this->type);
|
||||
std::cout<<indentation;
|
||||
if(this->type==ast_string || this->type==ast_identifier || this->type==ast_dynamic_id || this->type==ast_call_hash)
|
||||
std::cout<<":"<<this->str;
|
||||
else if(this->type==ast_number)
|
||||
std::cout<<":"<<this->num;
|
||||
std::cout<<std::endl;
|
||||
int child_size=this->children.size();
|
||||
for(int i=0;i<child_size;++i)
|
||||
this->children[i].print_ast(depth+1);
|
||||
return;
|
||||
static std::vector<std::string> intentation={};
|
||||
for(auto& i:intentation)
|
||||
std::cout<<i;
|
||||
std::cout<<ast_name[_type];
|
||||
if(
|
||||
_type==ast_str ||
|
||||
_type==ast_id ||
|
||||
_type==ast_default ||
|
||||
_type==ast_dynamic ||
|
||||
_type==ast_callh)
|
||||
std::cout<<":"<<rawstr(_str);
|
||||
else if(_type==ast_num || _type==ast_file)
|
||||
std::cout<<":"<<_num;
|
||||
std::cout<<'\n';
|
||||
if(last && depth)
|
||||
intentation.back()=" ";
|
||||
else if(!last && depth)
|
||||
#ifdef _WIN32
|
||||
intentation.back()="| ";
|
||||
#else
|
||||
intentation.back()="│ ";
|
||||
#endif
|
||||
for(uint32_t i=0;i<_child.size();++i)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
intentation.push_back(i==_child.size()-1?"`-":"|-");
|
||||
#else
|
||||
intentation.push_back(i==_child.size()-1?"└─":"├─");
|
||||
#endif
|
||||
_child[i].print(depth+1,i==_child.size()-1);
|
||||
intentation.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
1905
nasal_builtin.h
1905
nasal_builtin.h
File diff suppressed because it is too large
Load Diff
1466
nasal_bytecode_vm.h
1466
nasal_bytecode_vm.h
File diff suppressed because it is too large
Load Diff
2211
nasal_codegen.h
2211
nasal_codegen.h
File diff suppressed because it is too large
Load Diff
295
nasal_dbg.h
Normal file
295
nasal_dbg.h
Normal file
@@ -0,0 +1,295 @@
|
||||
#ifndef __NASAL_DBG_H__
|
||||
#define __NASAL_DBG_H__
|
||||
|
||||
#include "nasal_vm.h"
|
||||
|
||||
class nasal_dbg:public nasal_vm
|
||||
{
|
||||
private:
|
||||
bool next_step;
|
||||
uint16_t bk_fidx;
|
||||
uint32_t bk_line;
|
||||
file_line src;
|
||||
|
||||
std::vector<std::string> parse(const std::string&);
|
||||
uint16_t get_fileindex(const std::string&);
|
||||
void err();
|
||||
void help();
|
||||
void stepinfo();
|
||||
void interact();
|
||||
public:
|
||||
nasal_dbg():
|
||||
next_step(false),
|
||||
bk_fidx(0),bk_line(0){}
|
||||
void run(
|
||||
const nasal_codegen&,
|
||||
const nasal_import&
|
||||
);
|
||||
};
|
||||
|
||||
std::vector<std::string> nasal_dbg::parse(const std::string& cmd)
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
std::string tmp="";
|
||||
for(uint32_t i=0;i<cmd.length();++i)
|
||||
{
|
||||
if(cmd[i]==' ' && tmp.length())
|
||||
{
|
||||
res.push_back(tmp);
|
||||
tmp="";
|
||||
continue;
|
||||
}
|
||||
tmp+=cmd[i];
|
||||
}
|
||||
if(tmp.length())
|
||||
res.push_back(tmp);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint16_t nasal_dbg::get_fileindex(const std::string& filename)
|
||||
{
|
||||
for(uint16_t i=0;i<files_size;++i)
|
||||
if(filename==files[i])
|
||||
return i;
|
||||
return 65535;
|
||||
}
|
||||
|
||||
void nasal_dbg::err()
|
||||
{
|
||||
std::cerr
|
||||
<<"incorrect command\n"
|
||||
<<"input \'h\' to get help\n";
|
||||
}
|
||||
|
||||
void nasal_dbg::help()
|
||||
{
|
||||
std::cout
|
||||
<<"<option>\n"
|
||||
<<"\th, help | get help\n"
|
||||
<<"\tbt, backtrace | get function call trace\n"
|
||||
<<"\tc, continue | run program until break point or exit\n"
|
||||
<<"\tf, file | see all the compiled files\n"
|
||||
<<"\tg, global | see global values\n"
|
||||
<<"\tl, local | see local values\n"
|
||||
<<"\tu, upval | see upvalue\n"
|
||||
<<"\ta, all | show global,local and upvalue\n"
|
||||
<<"\tn, next | execute next bytecode\n"
|
||||
<<"\tq, exit | exit debugger\n"
|
||||
<<"<option> <filename> <line>\n"
|
||||
<<"\tbk, break | set break point\n";
|
||||
}
|
||||
|
||||
void nasal_dbg::stepinfo()
|
||||
{
|
||||
uint32_t begin,end;
|
||||
uint32_t line=bytecode[pc].line==0?0:bytecode[pc].line-1;
|
||||
src.load(files[bytecode[pc].fidx]);
|
||||
printf("\nsource code:\n");
|
||||
begin=(line>>3)==0?0:((line>>3)<<3);
|
||||
end=(1+(line>>3))<<3;
|
||||
for(uint32_t i=begin;i<end && i<src.size();++i)
|
||||
printf("%s\t%s\n",i==line?"-->":" ",src[i].c_str());
|
||||
printf("next bytecode:\n");
|
||||
begin=(pc>>3)==0?0:((pc>>3)<<3);
|
||||
end=(1+(pc>>3))<<3;
|
||||
for(uint32_t i=begin;i<end && bytecode[i].op!=op_exit;++i)
|
||||
bytecodeinfo(i==pc?"-->\t":" \t",i);
|
||||
stackinfo(5);
|
||||
}
|
||||
|
||||
void nasal_dbg::interact()
|
||||
{
|
||||
// special operand
|
||||
if(bytecode[pc].op==op_intg)
|
||||
{
|
||||
std::cout
|
||||
<<"[debug] nasal debug mode\n"
|
||||
<<"input \'h\' to get help\n";
|
||||
}
|
||||
else if(bytecode[pc].op==op_exit)
|
||||
return;
|
||||
|
||||
if(
|
||||
(bytecode[pc].fidx!=bk_fidx || bytecode[pc].line!=bk_line) && // break point
|
||||
!next_step // next step
|
||||
)return;
|
||||
|
||||
next_step=false;
|
||||
std::string cmd;
|
||||
stepinfo();
|
||||
while(1)
|
||||
{
|
||||
printf(">> ");
|
||||
std::getline(std::cin,cmd);
|
||||
auto res=parse(cmd);
|
||||
if(res.size()==1)
|
||||
{
|
||||
if(res[0]=="h" || res[0]=="help")
|
||||
help();
|
||||
else if(res[0]=="bt" || res[0]=="backtrace")
|
||||
traceback();
|
||||
else if(res[0]=="c" || res[0]=="continue")
|
||||
return;
|
||||
else if(res[0]=="f" || res[0]=="file")
|
||||
for(size_t i=0;i<files_size;++i)
|
||||
printf("[%zu] %s\n",i,files[i].c_str());
|
||||
else if(res[0]=="g" || res[0]=="global")
|
||||
global_state();
|
||||
else if(res[0]=="l" || res[0]=="local")
|
||||
local_state();
|
||||
else if(res[0]=="u" || res[0]=="upval")
|
||||
upval_state();
|
||||
else if(res[0]=="a" || res[0]=="all")
|
||||
detail();
|
||||
else if(res[0]=="n" || res[0]=="next")
|
||||
{
|
||||
next_step=true;
|
||||
return;
|
||||
}
|
||||
else if(res[0]=="q" || res[0]=="exit")
|
||||
std::exit(0);
|
||||
else
|
||||
err();
|
||||
}
|
||||
else if(res.size()==3 && (res[0]=="bk" || res[0]=="break"))
|
||||
{
|
||||
bk_fidx=get_fileindex(res[1]);
|
||||
if(bk_fidx==65535)
|
||||
{
|
||||
printf("cannot find file named \"%s\"\n",res[1].c_str());
|
||||
bk_fidx=0;
|
||||
}
|
||||
int tmp=atoi(res[2].c_str());
|
||||
if(tmp<=0)
|
||||
printf("incorrect line number \"%s\"\n",res[2].c_str());
|
||||
else
|
||||
bk_line=tmp;
|
||||
}
|
||||
else
|
||||
err();
|
||||
}
|
||||
}
|
||||
|
||||
void nasal_dbg::run(
|
||||
const nasal_codegen& gen,
|
||||
const nasal_import& linker)
|
||||
{
|
||||
detail_info=true;
|
||||
init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file());
|
||||
const void* opr_table[]=
|
||||
{
|
||||
&&vmexit, &&intg, &&intl, &&loadg,
|
||||
&&loadl, &&loadu, &&pnum, &&pnil,
|
||||
&&pstr, &&newv, &&newh, &&newf,
|
||||
&&happ, &¶, &&defpara,&&dynpara,
|
||||
&&unot, &&usub, &&add, &&sub,
|
||||
&&mul, &&div, &&lnk, &&addc,
|
||||
&&subc, &&mulc, &&divc, &&lnkc,
|
||||
&&addeq, &&subeq, &&muleq, &&diveq,
|
||||
&&lnkeq, &&addeqc, &&subeqc, &&muleqc,
|
||||
&&diveqc, &&lnkeqc, &&meq, &&eq,
|
||||
&&neq, &&less, &&leq, &&grt,
|
||||
&&geq, &&lessc, &&leqc, &&grtc,
|
||||
&&geqc, &&pop, &&jmp, &&jt,
|
||||
&&jf, &&counter, &&findex, &&feach,
|
||||
&&callg, &&calll, &&upval, &&callv,
|
||||
&&callvi, &&callh, &&callfv, &&callfh,
|
||||
&&callb, &&slcbegin, &&slcend, &&slc,
|
||||
&&slc2, &&mcallg, &&mcalll, &&mupval,
|
||||
&&mcallv, &&mcallh, &&ret
|
||||
};
|
||||
std::vector<const void*> code;
|
||||
for(auto& i:gen.get_code())
|
||||
{
|
||||
code.push_back(opr_table[i.op]);
|
||||
imm.push_back(i.num);
|
||||
}
|
||||
// goto the first operand
|
||||
goto *code[pc];
|
||||
|
||||
vmexit:
|
||||
if(gc.top>=canary)
|
||||
die("stack overflow");
|
||||
gc.clear();
|
||||
imm.clear();
|
||||
printf("[debug] debugger exited\n");
|
||||
return;
|
||||
#define dbg(op) {interact();op();if(gc.top<canary)goto *code[++pc];goto vmexit;}
|
||||
|
||||
intg: dbg(opr_intg );
|
||||
intl: dbg(opr_intl );
|
||||
loadg: dbg(opr_loadg );
|
||||
loadl: dbg(opr_loadl );
|
||||
loadu: dbg(opr_loadu );
|
||||
pnum: dbg(opr_pnum );
|
||||
pnil: dbg(opr_pnil );
|
||||
pstr: dbg(opr_pstr );
|
||||
newv: dbg(opr_newv );
|
||||
newh: dbg(opr_newh );
|
||||
newf: dbg(opr_newf );
|
||||
happ: dbg(opr_happ );
|
||||
para: dbg(opr_para );
|
||||
defpara: dbg(opr_defpara );
|
||||
dynpara: dbg(opr_dynpara );
|
||||
unot: dbg(opr_unot );
|
||||
usub: dbg(opr_usub );
|
||||
add: dbg(opr_add );
|
||||
sub: dbg(opr_sub );
|
||||
mul: dbg(opr_mul );
|
||||
div: dbg(opr_div );
|
||||
lnk: dbg(opr_lnk );
|
||||
addc: dbg(opr_addc );
|
||||
subc: dbg(opr_subc );
|
||||
mulc: dbg(opr_mulc );
|
||||
divc: dbg(opr_divc );
|
||||
lnkc: dbg(opr_lnkc );
|
||||
addeq: dbg(opr_addeq );
|
||||
subeq: dbg(opr_subeq );
|
||||
muleq: dbg(opr_muleq );
|
||||
diveq: dbg(opr_diveq );
|
||||
lnkeq: dbg(opr_lnkeq );
|
||||
addeqc: dbg(opr_addeqc );
|
||||
subeqc: dbg(opr_subeqc );
|
||||
muleqc: dbg(opr_muleqc );
|
||||
diveqc: dbg(opr_diveqc );
|
||||
lnkeqc: dbg(opr_lnkeqc );
|
||||
meq: dbg(opr_meq );
|
||||
eq: dbg(opr_eq );
|
||||
neq: dbg(opr_neq );
|
||||
less: dbg(opr_less );
|
||||
leq: dbg(opr_leq );
|
||||
grt: dbg(opr_grt );
|
||||
geq: dbg(opr_geq );
|
||||
lessc: dbg(opr_lessc );
|
||||
leqc: dbg(opr_leqc );
|
||||
grtc: dbg(opr_grtc );
|
||||
geqc: dbg(opr_geqc );
|
||||
pop: dbg(opr_pop );
|
||||
jmp: dbg(opr_jmp );
|
||||
jt: dbg(opr_jt );
|
||||
jf: dbg(opr_jf );
|
||||
counter: dbg(opr_counter );
|
||||
findex: dbg(opr_findex );
|
||||
feach: dbg(opr_feach );
|
||||
callg: dbg(opr_callg );
|
||||
calll: dbg(opr_calll );
|
||||
upval: dbg(opr_upval );
|
||||
callv: dbg(opr_callv );
|
||||
callvi: dbg(opr_callvi );
|
||||
callh: dbg(opr_callh );
|
||||
callfv: dbg(opr_callfv );
|
||||
callfh: dbg(opr_callfh );
|
||||
callb: dbg(opr_callb );
|
||||
slcbegin:dbg(opr_slcbegin);
|
||||
slcend: dbg(opr_slcend );
|
||||
slc: dbg(opr_slc );
|
||||
slc2: dbg(opr_slc2 );
|
||||
mcallg: dbg(opr_mcallg );
|
||||
mcalll: dbg(opr_mcalll );
|
||||
mupval: dbg(opr_mupval );
|
||||
mcallv: dbg(opr_mcallv );
|
||||
mcallh: dbg(opr_mcallh );
|
||||
ret: dbg(opr_ret );
|
||||
}
|
||||
|
||||
#endif
|
||||
78
nasal_err.h
Normal file
78
nasal_err.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef __NASAL_ERR_H__
|
||||
#define __NASAL_ERR_H__
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
|
||||
class file_line
|
||||
{
|
||||
protected:
|
||||
std::string file;
|
||||
std::vector<std::string> res;
|
||||
public:
|
||||
void load(const std::string& f)
|
||||
{
|
||||
if(file==f) // don't need to load a loaded file
|
||||
return;
|
||||
file=f;
|
||||
res.clear();
|
||||
std::ifstream fin(f,std::ios::binary);
|
||||
if(fin.fail())
|
||||
{
|
||||
std::cerr<<"[src] cannot open file <"<<f<<">\n";
|
||||
std::exit(1);
|
||||
}
|
||||
std::string line;
|
||||
while(!fin.eof())
|
||||
{
|
||||
std::getline(fin,line);
|
||||
res.push_back(line);
|
||||
}
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
std::vector<std::string> tmp;
|
||||
res.swap(tmp);
|
||||
}
|
||||
const std::string& operator[](const uint32_t line){return res[line];}
|
||||
const std::string& name(){return file;}
|
||||
size_t size(){return res.size();}
|
||||
};
|
||||
|
||||
class nasal_err:public file_line
|
||||
{
|
||||
private:
|
||||
uint32_t error;
|
||||
public:
|
||||
nasal_err():error(0){}
|
||||
void err(const char* stage,const std::string& info,const char end='\n')
|
||||
{
|
||||
++error;
|
||||
std::cerr<<"["<<stage<<"] "<<info<<end;
|
||||
}
|
||||
void err(const char* stage,uint32_t line,uint32_t column,const std::string& info)
|
||||
{
|
||||
++error;
|
||||
if(!line)
|
||||
{
|
||||
std::cerr<<"["<<stage<<"] "<<file<<": "<<info<<'\n';
|
||||
return;
|
||||
}
|
||||
std::cerr<<"["<<stage<<"] "<<file<<":"<<line<<":"<<column<<" "<<info<<"\n"<<res[line-1]<<'\n';
|
||||
for(int i=0;i<(int)column-1;++i)
|
||||
std::cerr<<char(" \t"[res[line-1][i]=='\t']);
|
||||
std::cerr<<"^\n";
|
||||
}
|
||||
void err(const char* stage,uint32_t line,const std::string& info)
|
||||
{
|
||||
++error;
|
||||
if(!line)
|
||||
std::cerr<<"["<<stage<<"] "<<file<<": "<<info<<'\n';
|
||||
else
|
||||
std::cerr<<"["<<stage<<"] "<<file<<":"<<line<<" "<<info<<"\n"<<res[line-1]<<'\n';
|
||||
}
|
||||
void chkerr(){if(error)std::exit(1);}
|
||||
};
|
||||
|
||||
#endif
|
||||
1162
nasal_gc.h
1162
nasal_gc.h
File diff suppressed because it is too large
Load Diff
326
nasal_import.h
326
nasal_import.h
@@ -1,177 +1,151 @@
|
||||
#ifndef __NASAL_IMPORT_H__
|
||||
#define __NASAL_IMPORT_H__
|
||||
|
||||
class nasal_import
|
||||
{
|
||||
private:
|
||||
nasal_lexer import_lex;
|
||||
nasal_parse import_par;
|
||||
nasal_ast import_ast;
|
||||
std::vector<std::string> filename_table;
|
||||
int error;
|
||||
void die(std::string,std::string);
|
||||
void init();
|
||||
bool check_import(nasal_ast&);
|
||||
bool check_exist(std::string);
|
||||
void linker(nasal_ast&,nasal_ast&);
|
||||
nasal_ast file_import(nasal_ast&);
|
||||
nasal_ast load(nasal_ast&);
|
||||
public:
|
||||
nasal_import();
|
||||
int get_error();
|
||||
void link(nasal_ast&);
|
||||
nasal_ast& get_root();
|
||||
};
|
||||
|
||||
nasal_import::nasal_import()
|
||||
{
|
||||
import_lex.clear();
|
||||
import_par.clear();
|
||||
import_ast.clear();
|
||||
filename_table.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_import::die(std::string filename,std::string error_stage)
|
||||
{
|
||||
++error;
|
||||
std::cout<<">> [import] in <\""<<filename<<"\">: error(s) occurred in "<<error_stage<<"."<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_import::init()
|
||||
{
|
||||
import_lex.clear();
|
||||
import_par.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
bool nasal_import::check_import(nasal_ast& node)
|
||||
{
|
||||
/*
|
||||
only this kind of node can be recognized as 'import':
|
||||
|
||||
call
|
||||
id:import
|
||||
call_func
|
||||
string:'filename'
|
||||
*/
|
||||
if(node.get_type()!=ast_call)
|
||||
return false;
|
||||
std::vector<nasal_ast>& ref_vec=node.get_children();
|
||||
if(ref_vec.size()!=2)
|
||||
return false;
|
||||
if(ref_vec[0].get_str()!="import")
|
||||
return false;
|
||||
if(ref_vec[1].get_type()!=ast_call_func)
|
||||
return false;
|
||||
if(ref_vec[1].get_children().size()!=1 || ref_vec[1].get_children()[0].get_type()!=ast_string)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nasal_import::check_exist(std::string filename)
|
||||
{
|
||||
// avoid importing the same file
|
||||
int size=filename_table.size();
|
||||
for(int i=0;i<size;++i)
|
||||
if(filename==filename_table[i])
|
||||
return true;
|
||||
filename_table.push_back(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
void nasal_import::linker(nasal_ast& root,nasal_ast& add_root)
|
||||
{
|
||||
// add children of add_root to the back of root
|
||||
std::vector<nasal_ast>& ref_vec=add_root.get_children();
|
||||
int size=ref_vec.size();
|
||||
for(int i=0;i<size;++i)
|
||||
root.add_child(ref_vec[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
nasal_ast nasal_import::file_import(nasal_ast& node)
|
||||
{
|
||||
// initializing
|
||||
nasal_ast tmp;
|
||||
tmp.set_line(0);
|
||||
tmp.set_type(ast_root);
|
||||
init();
|
||||
|
||||
// get filename and set node to ast_null
|
||||
std::string filename=node.get_children()[1].get_children()[0].get_str();
|
||||
node.clear();
|
||||
node.set_type(ast_null);
|
||||
|
||||
// avoid infinite loading loop
|
||||
if(check_exist(filename))
|
||||
return tmp;
|
||||
|
||||
// start importing...
|
||||
import_lex.openfile(filename);
|
||||
import_lex.scanner();
|
||||
if(import_lex.get_error())
|
||||
{
|
||||
this->die(filename,"lexer");
|
||||
return tmp;
|
||||
}
|
||||
import_par.set_toklist(import_lex.get_token_list());
|
||||
import_par.main_process();
|
||||
if(import_par.get_error())
|
||||
{
|
||||
this->die(filename,"parser");
|
||||
return tmp;
|
||||
}
|
||||
tmp=import_par.get_root();
|
||||
|
||||
// check if tmp has 'import'
|
||||
return load(tmp);
|
||||
}
|
||||
|
||||
nasal_ast nasal_import::load(nasal_ast& root)
|
||||
{
|
||||
nasal_ast new_root;
|
||||
new_root.set_line(0);
|
||||
new_root.set_type(ast_root);
|
||||
|
||||
std::vector<nasal_ast>& ref_vec=root.get_children();
|
||||
int size=ref_vec.size();
|
||||
for(int i=0;i<size;++i)
|
||||
{
|
||||
if(check_import(ref_vec[i]))
|
||||
{
|
||||
nasal_ast tmp=file_import(ref_vec[i]);
|
||||
// add tmp to the back of new_root
|
||||
linker(new_root,tmp);
|
||||
}
|
||||
}
|
||||
// add root to the back of new_root
|
||||
linker(new_root,root);
|
||||
|
||||
// oops,i think it is not efficient if the root is too ... large?
|
||||
return new_root;
|
||||
}
|
||||
|
||||
void nasal_import::link(nasal_ast& root)
|
||||
{
|
||||
// initializing
|
||||
error=0;
|
||||
filename_table.clear();
|
||||
import_ast.clear();
|
||||
// scan root and import files,then generate a new ast and return to import_ast
|
||||
import_ast=load(root);
|
||||
return;
|
||||
}
|
||||
|
||||
nasal_ast& nasal_import::get_root()
|
||||
{
|
||||
return import_ast;
|
||||
}
|
||||
|
||||
int nasal_import::get_error()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifndef __NASAL_IMPORT_H__
|
||||
#define __NASAL_IMPORT_H__
|
||||
|
||||
class nasal_import
|
||||
{
|
||||
private:
|
||||
bool lib_loaded;
|
||||
nasal_err& nerr;
|
||||
std::vector<std::string> files;
|
||||
bool check_import(const nasal_ast&);
|
||||
bool check_exist(const std::string&);
|
||||
void linker(nasal_ast&,nasal_ast&&);
|
||||
nasal_ast file_import(nasal_ast&);
|
||||
nasal_ast lib_import();
|
||||
nasal_ast load(nasal_ast&,uint16_t);
|
||||
public:
|
||||
nasal_import(nasal_err& e):lib_loaded(false),nerr(e){}
|
||||
void link(nasal_parse&,const std::string&);
|
||||
const std::vector<std::string>& get_file() const {return files;}
|
||||
};
|
||||
|
||||
bool nasal_import::check_import(const nasal_ast& node)
|
||||
{
|
||||
/*
|
||||
only this kind of node can be recognized as 'import':
|
||||
call
|
||||
|_id:import
|
||||
|_call_func
|
||||
|_string:'filename'
|
||||
*/
|
||||
return (
|
||||
node.type()==ast_call &&
|
||||
node.size()==2 &&
|
||||
node[0].str()=="import" &&
|
||||
node[1].type()==ast_callf &&
|
||||
node[1].size()==1 &&
|
||||
node[1][0].type()==ast_str
|
||||
);
|
||||
}
|
||||
|
||||
bool nasal_import::check_exist(const std::string& file)
|
||||
{
|
||||
// avoid importing the same file
|
||||
for(auto& fname:files)
|
||||
if(file==fname)
|
||||
return true;
|
||||
files.push_back(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
void nasal_import::linker(nasal_ast& root,nasal_ast&& add_root)
|
||||
{
|
||||
// add children of add_root to the back of root
|
||||
for(auto& i:add_root.child())
|
||||
root.add(std::move(i));
|
||||
}
|
||||
|
||||
nasal_ast nasal_import::file_import(nasal_ast& node)
|
||||
{
|
||||
nasal_lexer lex(nerr);
|
||||
nasal_parse par(nerr);
|
||||
// get filename and set node to ast_null
|
||||
std::string filename=node[1][0].str();
|
||||
node.clear();
|
||||
|
||||
// avoid infinite loading loop
|
||||
if(check_exist(filename))
|
||||
return {0,ast_root};
|
||||
if(access(filename.c_str(),F_OK)==-1)
|
||||
{
|
||||
nerr.err("link","cannot open file <"+filename+">");
|
||||
return {0,ast_root};
|
||||
}
|
||||
|
||||
// start importing...
|
||||
lex.scan(filename);
|
||||
par.compile(lex);
|
||||
nasal_ast tmp=std::move(par.ast());
|
||||
// check if tmp has 'import'
|
||||
return load(tmp,files.size()-1);
|
||||
}
|
||||
|
||||
nasal_ast nasal_import::lib_import()
|
||||
{
|
||||
nasal_lexer lex(nerr);
|
||||
nasal_parse par(nerr);
|
||||
|
||||
const std::vector<std::string> libpath=
|
||||
{
|
||||
"lib.nas",
|
||||
"stl/lib.nas"
|
||||
};
|
||||
|
||||
std::string filename="";
|
||||
for(auto& i:libpath)
|
||||
if(access(i.c_str(),F_OK)!=-1)
|
||||
{
|
||||
filename=i;
|
||||
break;
|
||||
}
|
||||
if(!filename.length())
|
||||
{
|
||||
std::string paths="";
|
||||
for(auto& i:libpath)
|
||||
paths+=" "+i+"\n";
|
||||
nerr.err("link","cannot find lib file in these paths:\n"+paths,' ');
|
||||
nerr.chkerr();
|
||||
return {0,ast_root};
|
||||
}
|
||||
|
||||
// avoid infinite loading loop
|
||||
if(check_exist(filename))
|
||||
return {0,ast_root};
|
||||
|
||||
// start importing...
|
||||
lex.scan(filename);
|
||||
par.compile(lex);
|
||||
nasal_ast tmp=std::move(par.ast());
|
||||
// check if tmp has 'import'
|
||||
return load(tmp,files.size()-1);
|
||||
}
|
||||
|
||||
nasal_ast nasal_import::load(nasal_ast& root,uint16_t fileindex)
|
||||
{
|
||||
nasal_ast new_root(0,ast_root);
|
||||
if(!lib_loaded)
|
||||
{
|
||||
linker(new_root,lib_import());
|
||||
lib_loaded=true;
|
||||
}
|
||||
for(auto& i:root.child())
|
||||
if(check_import(i))
|
||||
linker(new_root,file_import(i));
|
||||
// add root to the back of new_root
|
||||
nasal_ast file_head(0,ast_file);
|
||||
file_head.set_num(fileindex);
|
||||
new_root.add(std::move(file_head));
|
||||
linker(new_root,std::move(root));
|
||||
return new_root;
|
||||
}
|
||||
|
||||
void nasal_import::link(nasal_parse& parse,const std::string& self)
|
||||
{
|
||||
// initializing
|
||||
files={self};
|
||||
// scan root and import files,then generate a new ast and return to import_ast
|
||||
// the main file's index is 0
|
||||
parse.ast()=load(parse.ast(),0);
|
||||
}
|
||||
|
||||
#endif
|
||||
855
nasal_lexer.h
855
nasal_lexer.h
@@ -1,464 +1,393 @@
|
||||
#ifndef __NASAL_LEXER_H__
|
||||
#define __NASAL_LEXER_H__
|
||||
|
||||
#define IS_IDENTIFIER(c) ((c=='_')||('a'<=c && c<='z')||('A'<=c&&c<='Z'))
|
||||
#define IS_HEX_NUMBER(c) (('0'<=c&&c<='9')||('a'<=c&&c<='f')||('A'<=c && c<='F'))
|
||||
#define IS_OCT_NUMEBR(c) ('0'<=c&&c<='7')
|
||||
#define IS_DIGIT(c) ('0'<=c&&c<='9')
|
||||
#define IS_STRING(c) (c=='\''||c=='\"'||c=='`')
|
||||
// single operators have only one character
|
||||
#define IS_SINGLE_OPRATOR(c) (c=='('||c==')'||c=='['||c==']'||c=='{'||c=='}'||c==','||c==';'||c=='|'||c==':'||\
|
||||
c=='?'||c=='`'||c=='&'||c=='@'||c=='%'||c=='$'||c=='^'||c=='\\')
|
||||
// calculation operators may have two chars, for example: += -= *= /= ~= != == >= <=
|
||||
#define IS_CALC_OPERATOR(c) (c=='='||c=='+'||c=='-'||c=='*'||c=='!'||c=='/'||c=='<'||c=='>'||c=='~')
|
||||
#define IS_NOTE(c) (c=='#')
|
||||
|
||||
enum token_type
|
||||
{
|
||||
tok_null=0,
|
||||
tok_number,tok_string,tok_identifier,
|
||||
tok_for,tok_forindex,tok_foreach,tok_while,
|
||||
tok_var,tok_func,tok_break,tok_continue,
|
||||
tok_return,tok_if,tok_elsif,tok_else,tok_nil,
|
||||
tok_left_curve,tok_right_curve,
|
||||
tok_left_bracket,tok_right_bracket,
|
||||
tok_left_brace,tok_right_brace,
|
||||
tok_semi,tok_and,tok_or,tok_comma,tok_dot,tok_ellipsis,tok_quesmark,
|
||||
tok_colon,tok_add,tok_sub,tok_mult,tok_div,tok_link,tok_not,
|
||||
tok_equal,
|
||||
tok_add_equal,tok_sub_equal,tok_mult_equal,tok_div_equal,tok_link_equal,
|
||||
tok_cmp_equal,tok_cmp_not_equal,tok_less_than,tok_less_equal,tok_greater_than,tok_greater_equal
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
const char* str;
|
||||
int tok_type;
|
||||
}token_table[]=
|
||||
{
|
||||
{"for" ,tok_for },
|
||||
{"forindex",tok_forindex },
|
||||
{"foreach" ,tok_foreach },
|
||||
{"while" ,tok_while },
|
||||
{"var" ,tok_var },
|
||||
{"func" ,tok_func },
|
||||
{"break" ,tok_break },
|
||||
{"continue",tok_continue },
|
||||
{"return" ,tok_return },
|
||||
{"if" ,tok_if },
|
||||
{"elsif" ,tok_elsif },
|
||||
{"else" ,tok_else },
|
||||
{"nil" ,tok_nil },
|
||||
{"(" ,tok_left_curve },
|
||||
{")" ,tok_right_curve },
|
||||
{"[" ,tok_left_bracket },
|
||||
{"]" ,tok_right_bracket},
|
||||
{"{" ,tok_left_brace },
|
||||
{"}" ,tok_right_brace },
|
||||
{";" ,tok_semi },
|
||||
{"and" ,tok_and },
|
||||
{"or" ,tok_or },
|
||||
{"," ,tok_comma },
|
||||
{"." ,tok_dot },
|
||||
{"..." ,tok_ellipsis },
|
||||
{"?" ,tok_quesmark },
|
||||
{":" ,tok_colon },
|
||||
{"+" ,tok_add },
|
||||
{"-" ,tok_sub },
|
||||
{"*" ,tok_mult },
|
||||
{"/" ,tok_div },
|
||||
{"~" ,tok_link },
|
||||
{"!" ,tok_not },
|
||||
{"=" ,tok_equal },
|
||||
{"+=" ,tok_add_equal },
|
||||
{"-=" ,tok_sub_equal },
|
||||
{"*=" ,tok_mult_equal },
|
||||
{"/=" ,tok_div_equal },
|
||||
{"~=" ,tok_link_equal },
|
||||
{"==" ,tok_cmp_equal },
|
||||
{"!=" ,tok_cmp_not_equal},
|
||||
{"<" ,tok_less_than },
|
||||
{"<=" ,tok_less_equal },
|
||||
{">" ,tok_greater_than },
|
||||
{">=" ,tok_greater_equal},
|
||||
{NULL ,-1 }
|
||||
};
|
||||
|
||||
struct token
|
||||
{
|
||||
int line;
|
||||
int type;
|
||||
std::string str;
|
||||
};
|
||||
|
||||
class nasal_lexer
|
||||
{
|
||||
private:
|
||||
int error;
|
||||
int res_size;
|
||||
int line;
|
||||
int ptr;
|
||||
std::string line_code;
|
||||
std::vector<char> res;
|
||||
std::vector<token> token_list;
|
||||
std::string identifier_gen();
|
||||
std::string number_gen();
|
||||
std::string string_gen();
|
||||
public:
|
||||
void clear();
|
||||
void openfile(std::string);
|
||||
void die(std::string,int,int);
|
||||
void scanner();
|
||||
void print_token();
|
||||
int get_error();
|
||||
std::vector<token>& get_token_list();
|
||||
};
|
||||
|
||||
void nasal_lexer::clear()
|
||||
{
|
||||
error=0;
|
||||
res_size=0;
|
||||
line=0;
|
||||
ptr=0;
|
||||
line_code="";
|
||||
res.clear();
|
||||
token_list.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_lexer::openfile(std::string filename)
|
||||
{
|
||||
error=0;
|
||||
res.clear();
|
||||
std::ifstream fin(filename,std::ios::binary);
|
||||
if(fin.fail())
|
||||
{
|
||||
++error;
|
||||
std::cout<<">> [lexer] cannot open file \""<<filename<<"\".\n";
|
||||
fin.close();
|
||||
return;
|
||||
}
|
||||
while(!fin.eof())
|
||||
{
|
||||
char c=fin.get();
|
||||
if(fin.eof())
|
||||
break;
|
||||
res.push_back(c);
|
||||
}
|
||||
fin.close();
|
||||
res_size=res.size();
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_lexer::die(std::string error_info,int line=-1,int column=-1)
|
||||
{
|
||||
++error;
|
||||
std::cout<<">> [lexer] line "<<line<<" column "<<column<<": "<<error_info<<"\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::string nasal_lexer::identifier_gen()
|
||||
{
|
||||
std::string token_str="";
|
||||
while(ptr<res_size && (IS_IDENTIFIER(res[ptr])||IS_DIGIT(res[ptr])))
|
||||
token_str+=res[ptr++];
|
||||
line_code+=token_str;
|
||||
return token_str;
|
||||
// after running this process, ptr will point to the next token's beginning character
|
||||
}
|
||||
|
||||
std::string nasal_lexer::number_gen()
|
||||
{
|
||||
bool scientific_notation=false;// numbers like 1e8 are scientific_notation
|
||||
std::string token_str="";
|
||||
// generate hex number
|
||||
if(res[ptr]=='0' && ptr+1<res_size && res[ptr+1]=='x')
|
||||
{
|
||||
token_str="0x";
|
||||
ptr+=2;
|
||||
while(ptr<res_size && IS_HEX_NUMBER(res[ptr]))
|
||||
token_str+=res[ptr++];
|
||||
line_code+=token_str;
|
||||
if(token_str=="0x")
|
||||
{
|
||||
die("["+line_code+"_] incorrect number.",line,line_code.length());
|
||||
return "0";
|
||||
}
|
||||
return token_str;
|
||||
}
|
||||
// generate oct number
|
||||
else if(res[ptr]=='0' && ptr+1<res_size && res[ptr+1]=='o')
|
||||
{
|
||||
token_str="0o";
|
||||
ptr+=2;
|
||||
while(ptr<res_size && IS_OCT_NUMEBR(res[ptr]))
|
||||
token_str+=res[ptr++];
|
||||
line_code+=token_str;
|
||||
if(token_str=="0o")
|
||||
{
|
||||
die("["+line_code+"_] incorrect number.",line,line_code.length());
|
||||
return "0";
|
||||
}
|
||||
return token_str;
|
||||
}
|
||||
// generate dec number
|
||||
// dec number -> [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*)
|
||||
while(ptr<res_size && IS_DIGIT(res[ptr]))
|
||||
token_str+=res[ptr++];
|
||||
if(ptr<res_size && res[ptr]=='.')
|
||||
{
|
||||
token_str+=res[ptr++];
|
||||
// "xxxx." is not a correct number
|
||||
if(ptr>=res_size)
|
||||
{
|
||||
line_code+=token_str;
|
||||
die("["+line_code+"_] incorrect number.",line,line_code.length());
|
||||
return "0";
|
||||
}
|
||||
while(ptr<res_size && IS_DIGIT(res[ptr]))
|
||||
token_str+=res[ptr++];
|
||||
// "xxxx." is not a correct number
|
||||
if(token_str.back()=='.')
|
||||
{
|
||||
line_code+=token_str;
|
||||
die("["+line_code+"_] incorrect number.",line,line_code.length());
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
if(ptr<res_size && (res[ptr]=='e' || res[ptr]=='E'))
|
||||
{
|
||||
token_str+=res[ptr++];
|
||||
// "xxxe" is not a correct number
|
||||
if(ptr>=res_size)
|
||||
{
|
||||
line_code+=token_str;
|
||||
die("["+line_code+"_] incorrect number.",line,line_code.length());
|
||||
return "0";
|
||||
}
|
||||
if(ptr<res_size && (res[ptr]=='-' || res[ptr]=='+'))
|
||||
token_str+=res[ptr++];
|
||||
if(ptr>=res_size)
|
||||
{
|
||||
line_code+=token_str;
|
||||
die("["+line_code+"_] incorrect number.",line,line_code.length());
|
||||
return "0";
|
||||
}
|
||||
if(ptr<res_size && res[ptr]=='0')
|
||||
token_str+=res[ptr++];
|
||||
while(ptr<res_size && IS_DIGIT(res[ptr]))
|
||||
token_str+=res[ptr++];
|
||||
// "xxxe(-|+)" is not a correct number
|
||||
if(token_str.back()=='e' || token_str.back()=='E' || token_str.back()=='-' || token_str.back()=='+')
|
||||
{
|
||||
line_code+=token_str;
|
||||
die("["+line_code+"_] incorrect number.",line,line_code.length());
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
line_code+=token_str;
|
||||
return token_str;
|
||||
}
|
||||
|
||||
std::string nasal_lexer::string_gen()
|
||||
{
|
||||
std::string token_str="";
|
||||
line_code+=res[ptr];
|
||||
char str_begin=res[ptr++];
|
||||
while(ptr<res_size && res[ptr]!=str_begin)
|
||||
{
|
||||
line_code+=res[ptr];
|
||||
if(res[ptr]=='\n')
|
||||
{
|
||||
line_code="";
|
||||
++line;
|
||||
}
|
||||
if(res[ptr]=='\\' && ptr+1<res_size)
|
||||
{
|
||||
++ptr;
|
||||
line_code+=res[ptr];
|
||||
switch(res[ptr])
|
||||
{
|
||||
case 'a':token_str.push_back('\a');break;
|
||||
case 'b':token_str.push_back('\b');break;
|
||||
case 'f':token_str.push_back('\f');break;
|
||||
case 'n':token_str.push_back('\n');break;
|
||||
case 'r':token_str.push_back('\r');break;
|
||||
case 't':token_str.push_back('\t');break;
|
||||
case 'v':token_str.push_back('\v');break;
|
||||
case '?':token_str.push_back('\?');break;
|
||||
case '0':token_str.push_back('\0');break;
|
||||
case '\\':token_str.push_back('\\');break;
|
||||
case '\'':token_str.push_back('\'');break;
|
||||
case '\"':token_str.push_back('\"');break;
|
||||
default: token_str.push_back(res[ptr]);break;
|
||||
}
|
||||
}
|
||||
else
|
||||
token_str+=res[ptr];
|
||||
++ptr;
|
||||
}
|
||||
// check if this string ends with a " or '
|
||||
if(ptr>=res_size)
|
||||
die("["+line_code+"_] get EOF when generating string.",line,line_code.length());
|
||||
++ptr;
|
||||
return token_str;
|
||||
}
|
||||
|
||||
void nasal_lexer::scanner()
|
||||
{
|
||||
token_list.clear();
|
||||
line=1;
|
||||
ptr=0;
|
||||
line_code="";
|
||||
|
||||
std::string token_str;
|
||||
while(ptr<res_size)
|
||||
{
|
||||
while(ptr<res_size && (res[ptr]==' ' || res[ptr]=='\n' || res[ptr]=='\t' || res[ptr]=='\r' || res[ptr]<0))
|
||||
{
|
||||
// these characters will be ignored, and '\n' will cause ++line
|
||||
line_code+=res[ptr];
|
||||
if(res[ptr]=='\n')
|
||||
{
|
||||
++line;
|
||||
line_code="";
|
||||
}
|
||||
++ptr;
|
||||
}
|
||||
if(ptr>=res_size) break;
|
||||
if(IS_IDENTIFIER(res[ptr]))
|
||||
{
|
||||
token_str=identifier_gen();
|
||||
token new_token;
|
||||
new_token.line=line;
|
||||
new_token.str=token_str;
|
||||
new_token.type=0;
|
||||
for(int i=0;token_table[i].str;++i)
|
||||
if(token_str==token_table[i].str)
|
||||
{
|
||||
new_token.type=token_table[i].tok_type;
|
||||
break;
|
||||
}
|
||||
if(!new_token.type)
|
||||
new_token.type=tok_identifier;
|
||||
token_list.push_back(new_token);
|
||||
}
|
||||
else if(IS_DIGIT(res[ptr]))
|
||||
{
|
||||
token_str=number_gen();
|
||||
token new_token;
|
||||
new_token.line=line;
|
||||
new_token.str=token_str;
|
||||
new_token.type=tok_number;
|
||||
token_list.push_back(new_token);
|
||||
}
|
||||
else if(IS_STRING(res[ptr]))
|
||||
{
|
||||
token_str=string_gen();
|
||||
token new_token;
|
||||
new_token.line=line;
|
||||
new_token.type=tok_string;
|
||||
new_token.str=token_str;
|
||||
token_list.push_back(new_token);
|
||||
}
|
||||
else if(IS_SINGLE_OPRATOR(res[ptr]))
|
||||
{
|
||||
token_str="";
|
||||
token_str+=res[ptr];
|
||||
line_code+=res[ptr];
|
||||
token new_token;
|
||||
new_token.line=line;
|
||||
new_token.str=token_str;
|
||||
new_token.type=-1;
|
||||
for(int i=0;token_table[i].str;++i)
|
||||
if(token_str==token_table[i].str)
|
||||
{
|
||||
new_token.type=token_table[i].tok_type;
|
||||
break;
|
||||
}
|
||||
if(new_token.type<0)
|
||||
die("["+line_code+"_] incorrect operator.",line,line_code.length());
|
||||
token_list.push_back(new_token);
|
||||
++ptr;
|
||||
}
|
||||
else if(res[ptr]=='.')
|
||||
{
|
||||
if(ptr+2<res_size && res[ptr+1]=='.' && res[ptr+2]=='.')
|
||||
{
|
||||
token_str="...";
|
||||
ptr+=3;
|
||||
}
|
||||
else
|
||||
{
|
||||
token_str=".";
|
||||
++ptr;
|
||||
}
|
||||
line_code+=token_str;
|
||||
token new_token;
|
||||
new_token.line=line;
|
||||
new_token.str=token_str;
|
||||
for(int i=0;token_table[i].str;++i)
|
||||
if(token_str==token_table[i].str)
|
||||
{
|
||||
new_token.type=token_table[i].tok_type;
|
||||
break;
|
||||
}
|
||||
token_list.push_back(new_token);
|
||||
}
|
||||
else if(IS_CALC_OPERATOR(res[ptr]))
|
||||
{
|
||||
// get calculation operator
|
||||
token_str=res[ptr];
|
||||
++ptr;
|
||||
if(ptr<res.size() && res[ptr]=='=')
|
||||
{
|
||||
token_str+=res[ptr];
|
||||
++ptr;
|
||||
}
|
||||
line_code+=token_str;
|
||||
token new_token;
|
||||
new_token.line=line;
|
||||
new_token.str=token_str;
|
||||
for(int i=0;token_table[i].str;++i)
|
||||
if(token_str==token_table[i].str)
|
||||
{
|
||||
new_token.type=token_table[i].tok_type;
|
||||
break;
|
||||
}
|
||||
token_list.push_back(new_token);
|
||||
}
|
||||
else if(IS_NOTE(res[ptr]))
|
||||
{
|
||||
// avoid note
|
||||
while(ptr<res_size && res[ptr]!='\n') ++ptr;
|
||||
// after this process ptr will point to a '\n'
|
||||
// don't ++ptr then the counter for line can work correctly
|
||||
}
|
||||
else
|
||||
{
|
||||
line_code+=res[ptr];
|
||||
die("["+line_code+"_] unknown character.",line,line_code.length());
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_lexer::print_token()
|
||||
{
|
||||
int size=token_list.size();
|
||||
for(int i=0;i<size;++i)
|
||||
std::cout<<"("<<token_list[i].line<<" | "<<token_list[i].str<<")\n";
|
||||
return;
|
||||
}
|
||||
|
||||
int nasal_lexer::get_error()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
std::vector<token>& nasal_lexer::get_token_list()
|
||||
{
|
||||
return token_list;
|
||||
}
|
||||
#ifndef __NASAL_LEXER_H__
|
||||
#define __NASAL_LEXER_H__
|
||||
|
||||
#define ID(c) ((c=='_')||('a'<=c && c<='z')||('A'<=c&&c<='Z')||(c<0))
|
||||
#define HEX(c) (('0'<=c&&c<='9')||('a'<=c&&c<='f')||('A'<=c && c<='F'))
|
||||
#define OCT(c) ('0'<=c&&c<='7')
|
||||
#define DIGIT(c) ('0'<=c&&c<='9')
|
||||
#define STR(c) (c=='\''||c=='\"'||c=='`')
|
||||
// single operators have only one character
|
||||
#define SINGLE_OPERATOR(c) (c=='('||c==')'||c=='['||c==']'||c=='{'||c=='}'||c==','||c==';'||c=='|'||c==':'||\
|
||||
c=='?'||c=='`'||c=='&'||c=='@'||c=='%'||c=='$'||c=='^'||c=='\\')
|
||||
// calculation operators may have two chars, for example: += -= *= /= ~= != == >= <=
|
||||
#define CALC_OPERATOR(c) (c=='='||c=='+'||c=='-'||c=='*'||c=='!'||c=='/'||c=='<'||c=='>'||c=='~')
|
||||
#define NOTE(c) (c=='#')
|
||||
|
||||
enum token_type
|
||||
{
|
||||
tok_null=0,// null token default token type
|
||||
tok_num, // number basic token type
|
||||
tok_str, // string basic token type
|
||||
tok_id, // identifier basic token type
|
||||
tok_for,tok_forindex,tok_foreach,tok_while,
|
||||
tok_var,tok_func,tok_break,tok_continue,
|
||||
tok_ret,tok_if,tok_elsif,tok_else,tok_nil,
|
||||
tok_lcurve,tok_rcurve,
|
||||
tok_lbracket,tok_rbracket,
|
||||
tok_lbrace,tok_rbrace,
|
||||
tok_semi,tok_and,tok_or,tok_comma,tok_dot,tok_ellipsis,tok_quesmark,
|
||||
tok_colon,tok_add,tok_sub,tok_mult,tok_div,tok_link,tok_not,
|
||||
tok_eq,
|
||||
tok_addeq,tok_subeq,tok_multeq,tok_diveq,tok_lnkeq,
|
||||
tok_cmpeq,tok_neq,tok_less,tok_leq,tok_grt,tok_geq,
|
||||
tok_eof // end of token list
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
const char* str;
|
||||
const uint32_t tok_type;
|
||||
}token_table[]=
|
||||
{
|
||||
{"for" ,tok_for },
|
||||
{"forindex",tok_forindex },
|
||||
{"foreach" ,tok_foreach },
|
||||
{"while" ,tok_while },
|
||||
{"var" ,tok_var },
|
||||
{"func" ,tok_func },
|
||||
{"break" ,tok_break },
|
||||
{"continue",tok_continue },
|
||||
{"return" ,tok_ret },
|
||||
{"if" ,tok_if },
|
||||
{"elsif" ,tok_elsif },
|
||||
{"else" ,tok_else },
|
||||
{"nil" ,tok_nil },
|
||||
{"(" ,tok_lcurve },
|
||||
{")" ,tok_rcurve },
|
||||
{"[" ,tok_lbracket },
|
||||
{"]" ,tok_rbracket },
|
||||
{"{" ,tok_lbrace },
|
||||
{"}" ,tok_rbrace },
|
||||
{";" ,tok_semi },
|
||||
{"and" ,tok_and },
|
||||
{"or" ,tok_or },
|
||||
{"," ,tok_comma },
|
||||
{"." ,tok_dot },
|
||||
{"..." ,tok_ellipsis },
|
||||
{"?" ,tok_quesmark },
|
||||
{":" ,tok_colon },
|
||||
{"+" ,tok_add },
|
||||
{"-" ,tok_sub },
|
||||
{"*" ,tok_mult },
|
||||
{"/" ,tok_div },
|
||||
{"~" ,tok_link },
|
||||
{"!" ,tok_not },
|
||||
{"=" ,tok_eq },
|
||||
{"+=" ,tok_addeq },
|
||||
{"-=" ,tok_subeq },
|
||||
{"*=" ,tok_multeq },
|
||||
{"/=" ,tok_diveq },
|
||||
{"~=" ,tok_lnkeq },
|
||||
{"==" ,tok_cmpeq },
|
||||
{"!=" ,tok_neq },
|
||||
{"<" ,tok_less },
|
||||
{"<=" ,tok_leq },
|
||||
{">" ,tok_grt },
|
||||
{">=" ,tok_geq },
|
||||
{nullptr ,0 }
|
||||
};
|
||||
|
||||
struct token
|
||||
{
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
uint32_t type;
|
||||
std::string str;
|
||||
token(uint32_t l=0,uint32_t c=0,uint32_t t=tok_null,const std::string& s=""):str(s)
|
||||
{
|
||||
line=l;
|
||||
column=c;
|
||||
type=t;
|
||||
}
|
||||
};
|
||||
|
||||
class nasal_lexer
|
||||
{
|
||||
private:
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
uint32_t ptr;
|
||||
nasal_err& nerr;
|
||||
std::string res;
|
||||
std::vector<token> tokens;
|
||||
|
||||
uint32_t get_type(const std::string&);
|
||||
void die(std::string info){nerr.err("lexer",line,column,info);};
|
||||
void open(const std::string&);
|
||||
std::string utf8_gen();
|
||||
std::string id_gen();
|
||||
std::string num_gen();
|
||||
std::string str_gen();
|
||||
public:
|
||||
nasal_lexer(nasal_err& e):line(0),column(0),ptr(0),nerr(e){}
|
||||
void scan(const std::string&);
|
||||
void print();
|
||||
const std::vector<token>& get_tokens() const {return tokens;}
|
||||
};
|
||||
|
||||
void nasal_lexer::open(const std::string& file)
|
||||
{
|
||||
struct stat buffer;
|
||||
if(stat(file.c_str(),&buffer)==0 && !S_ISREG(buffer.st_mode))
|
||||
{
|
||||
nerr.err("lexer","<"+file+"> is not a regular file.");
|
||||
res="";
|
||||
return;
|
||||
}
|
||||
std::ifstream fin(file,std::ios::binary);
|
||||
if(fin.fail())
|
||||
nerr.err("lexer","failed to open <"+file+">.");
|
||||
else
|
||||
nerr.load(file);
|
||||
std::stringstream ss;
|
||||
ss<<fin.rdbuf();
|
||||
res=ss.str();
|
||||
}
|
||||
|
||||
uint32_t nasal_lexer::get_type(const std::string& tk_str)
|
||||
{
|
||||
for(int i=0;token_table[i].str;++i)
|
||||
if(tk_str==token_table[i].str)
|
||||
return token_table[i].tok_type;
|
||||
return tok_null;
|
||||
}
|
||||
|
||||
std::string nasal_lexer::utf8_gen()
|
||||
{
|
||||
std::string str="";
|
||||
while(ptr<res.size() && res[ptr]<0)
|
||||
{
|
||||
std::string tmp="";
|
||||
uint32_t nbytes=utf8_hdchk(res[ptr]);
|
||||
if(nbytes)
|
||||
{
|
||||
tmp+=res[ptr++];
|
||||
for(uint32_t i=0;i<nbytes;++i,++ptr)
|
||||
if(ptr<res.size() && (res[ptr]&0xc0)==0x80)
|
||||
tmp+=res[ptr];
|
||||
if(tmp.length()!=1+nbytes)
|
||||
die("invalid utf-8 character here");
|
||||
str+=tmp;
|
||||
++column;
|
||||
}
|
||||
else
|
||||
++ptr;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string nasal_lexer::id_gen()
|
||||
{
|
||||
std::string str="";
|
||||
while(ptr<res.size() && (ID(res[ptr])||DIGIT(res[ptr])))
|
||||
{
|
||||
if(res[ptr]<0) // utf-8
|
||||
str+=utf8_gen();
|
||||
else // ascii
|
||||
{
|
||||
str+=res[ptr++];
|
||||
++column;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string nasal_lexer::num_gen()
|
||||
{
|
||||
// generate hex number
|
||||
if(ptr+1<res.size() && res[ptr]=='0' && res[ptr+1]=='x')
|
||||
{
|
||||
std::string str="0x";
|
||||
ptr+=2;
|
||||
while(ptr<res.size() && HEX(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
column+=str.length();
|
||||
if(str.length()<3)// "0x"
|
||||
die("invalid number:"+str);
|
||||
return str;
|
||||
}
|
||||
// generate oct number
|
||||
else if(ptr+1<res.size() && res[ptr]=='0' && res[ptr+1]=='o')
|
||||
{
|
||||
std::string str="0o";
|
||||
ptr+=2;
|
||||
while(ptr<res.size() && OCT(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
column+=str.length();
|
||||
if(str.length()<3)// "0o"
|
||||
die("invalid number:"+str);
|
||||
return str;
|
||||
}
|
||||
// generate dec number
|
||||
// dec number -> [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*)
|
||||
std::string str="";
|
||||
while(ptr<res.size() && DIGIT(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
if(ptr<res.size() && res[ptr]=='.')
|
||||
{
|
||||
str+=res[ptr++];
|
||||
while(ptr<res.size() && DIGIT(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
// "xxxx." is not a correct number
|
||||
if(str.back()=='.')
|
||||
{
|
||||
column+=str.length();
|
||||
die("invalid number:"+str);
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
if(ptr<res.size() && (res[ptr]=='e' || res[ptr]=='E'))
|
||||
{
|
||||
str+=res[ptr++];
|
||||
if(ptr<res.size() && (res[ptr]=='-' || res[ptr]=='+'))
|
||||
str+=res[ptr++];
|
||||
while(ptr<res.size() && DIGIT(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
// "xxxe(-|+)" is not a correct number
|
||||
if(str.back()=='e' || str.back()=='E' || str.back()=='-' || str.back()=='+')
|
||||
{
|
||||
column+=str.length();
|
||||
die("invalid number:"+str);
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
column+=str.length();
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string nasal_lexer::str_gen()
|
||||
{
|
||||
std::string str="";
|
||||
char begin=res[ptr];
|
||||
++column;
|
||||
while(++ptr<res.size() && res[ptr]!=begin)
|
||||
{
|
||||
++column;
|
||||
if(res[ptr]=='\n')
|
||||
{
|
||||
column=0;
|
||||
++line;
|
||||
}
|
||||
if(res[ptr]=='\\' && ptr+1<res.size())
|
||||
{
|
||||
++column;
|
||||
++ptr;
|
||||
switch(res[ptr])
|
||||
{
|
||||
case '0': str+='\0'; break;
|
||||
case 'a': str+='\a'; break;
|
||||
case 'b': str+='\b'; break;
|
||||
case 'e': str+='\e'; break;
|
||||
case 't': str+='\t'; break;
|
||||
case 'n': str+='\n'; break;
|
||||
case 'v': str+='\v'; break;
|
||||
case 'f': str+='\f'; break;
|
||||
case 'r': str+='\r'; break;
|
||||
case '?': str+='\?'; break;
|
||||
case '\\':str+='\\'; break;
|
||||
case '\'':str+='\''; break;
|
||||
case '\"':str+='\"'; break;
|
||||
default: str+=res[ptr];break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
str+=res[ptr];
|
||||
}
|
||||
// check if this string ends with a " or '
|
||||
if(ptr++>=res.size())
|
||||
{
|
||||
die("get EOF when generating string.");
|
||||
return str;
|
||||
}
|
||||
++column;
|
||||
if(begin=='`' && str.length()!=1)
|
||||
die("\'`\' is used for string that includes one character.");
|
||||
return str;
|
||||
}
|
||||
|
||||
void nasal_lexer::scan(const std::string& file)
|
||||
{
|
||||
line=1;
|
||||
column=0;
|
||||
ptr=0;
|
||||
open(file);
|
||||
|
||||
std::string str;
|
||||
while(ptr<res.size())
|
||||
{
|
||||
while(ptr<res.size() && (res[ptr]==' ' || res[ptr]=='\n' || res[ptr]=='\t' || res[ptr]=='\r'))// || res[ptr]<0))
|
||||
{
|
||||
// these characters will be ignored, and '\n' will cause ++line
|
||||
++column;
|
||||
if(res[ptr++]=='\n')
|
||||
{
|
||||
++line;
|
||||
column=0;
|
||||
}
|
||||
}
|
||||
if(ptr>=res.size()) break;
|
||||
if(ID(res[ptr]))
|
||||
{
|
||||
str=id_gen();
|
||||
uint32_t type=get_type(str);
|
||||
tokens.push_back({line,column,type?type:tok_id,str});
|
||||
}
|
||||
else if(DIGIT(res[ptr]))
|
||||
{
|
||||
str=num_gen(); // make sure column is correct
|
||||
tokens.push_back({line,column,tok_num,str});
|
||||
}
|
||||
else if(STR(res[ptr]))
|
||||
{
|
||||
str=str_gen(); // make sure column is correct
|
||||
tokens.push_back({line,column,tok_str,str});
|
||||
}
|
||||
else if(SINGLE_OPERATOR(res[ptr]))
|
||||
{
|
||||
str=res[ptr];
|
||||
++column;
|
||||
uint32_t type=get_type(str);
|
||||
if(!type)
|
||||
die("invalid operator:"+str);
|
||||
tokens.push_back({line,column,type,str});
|
||||
++ptr;
|
||||
}
|
||||
else if(res[ptr]=='.')
|
||||
{
|
||||
str=".";
|
||||
if(ptr+2<res.size() && res[ptr+1]=='.' && res[ptr+2]=='.')
|
||||
str+="..";
|
||||
ptr+=str.length();
|
||||
column+=str.length();
|
||||
tokens.push_back({line,column,get_type(str),str});
|
||||
}
|
||||
else if(CALC_OPERATOR(res[ptr]))
|
||||
{
|
||||
// get calculation operator
|
||||
str=res[ptr++];
|
||||
if(ptr<res.size() && res[ptr]=='=')
|
||||
str+=res[ptr++];
|
||||
column+=str.length();
|
||||
tokens.push_back({line,column,get_type(str),str});
|
||||
}
|
||||
else if(NOTE(res[ptr]))// avoid note, after this process ptr will point to a '\n', so next loop line counter+1
|
||||
while(++ptr<res.size() && res[ptr]!='\n');
|
||||
else
|
||||
{
|
||||
++column;
|
||||
++ptr;
|
||||
die("unknown character.");
|
||||
}
|
||||
}
|
||||
tokens.push_back({line,column,tok_eof,"eof"});
|
||||
res="";
|
||||
nerr.chkerr();
|
||||
}
|
||||
|
||||
void nasal_lexer::print()
|
||||
{
|
||||
for(auto& tok:tokens)
|
||||
std::cout<<"("<<tok.line<<" | "<<rawstr(tok.str)<<")\n";
|
||||
}
|
||||
|
||||
#endif
|
||||
70
nasal_opt.h
Normal file
70
nasal_opt.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef __NASAL_OPT_H__
|
||||
#define __NASAL_OPT_H__
|
||||
|
||||
void const_str(nasal_ast& root)
|
||||
{
|
||||
auto& vec=root.child();
|
||||
root.set_str(vec[0].str()+vec[1].str());
|
||||
root.child().clear();
|
||||
root.set_type(ast_str);
|
||||
}
|
||||
|
||||
void const_num(nasal_ast& root)
|
||||
{
|
||||
auto& vec=root.child();
|
||||
double res;
|
||||
switch(root.type())
|
||||
{
|
||||
case ast_add: res=vec[0].num()+vec[1].num(); break;
|
||||
case ast_sub: res=vec[0].num()-vec[1].num(); break;
|
||||
case ast_mult:res=vec[0].num()*vec[1].num(); break;
|
||||
case ast_div: res=vec[0].num()/vec[1].num(); break;
|
||||
case ast_less:res=vec[0].num()<vec[1].num(); break;
|
||||
case ast_leq: res=vec[0].num()<=vec[1].num();break;
|
||||
case ast_grt: res=vec[0].num()>vec[1].num(); break;
|
||||
case ast_geq: res=vec[0].num()>=vec[1].num();break;
|
||||
}
|
||||
// inf and nan will cause number hashmap error in codegen
|
||||
if(std::isinf(res) || std::isnan(res))
|
||||
return;
|
||||
root.set_num(res);
|
||||
root.child().clear();
|
||||
root.set_type(ast_num);
|
||||
}
|
||||
|
||||
void calc_const(nasal_ast& root)
|
||||
{
|
||||
auto& vec=root.child();
|
||||
for(auto& i:vec)
|
||||
calc_const(i);
|
||||
if(vec.size()==1 && root.type()==ast_neg && vec[0].type()==ast_num)
|
||||
{
|
||||
double res=-vec[0].num();
|
||||
root.set_num(res);
|
||||
root.child().clear();
|
||||
root.set_type(ast_num);
|
||||
return;
|
||||
}
|
||||
if(vec.size()!=2)
|
||||
return;
|
||||
if(root.type()!=ast_add &&
|
||||
root.type()!=ast_sub &&
|
||||
root.type()!=ast_mult &&
|
||||
root.type()!=ast_div &&
|
||||
root.type()!=ast_link &&
|
||||
root.type()!=ast_less &&
|
||||
root.type()!=ast_leq &&
|
||||
root.type()!=ast_grt &&
|
||||
root.type()!=ast_geq)
|
||||
return;
|
||||
if(root.type()==ast_link && vec[0].type()==ast_str && vec[1].type()==ast_str)
|
||||
const_str(root);
|
||||
else if(root.type()!=ast_link && vec[0].type()==ast_num && vec[1].type()==ast_num)
|
||||
const_num(root);
|
||||
}
|
||||
void optimize(nasal_ast& root)
|
||||
{
|
||||
for(auto& i:root.child())
|
||||
calc_const(i);
|
||||
}
|
||||
#endif
|
||||
2699
nasal_parse.h
2699
nasal_parse.h
File diff suppressed because it is too large
Load Diff
1896
nasal_runtime.h
1896
nasal_runtime.h
File diff suppressed because it is too large
Load Diff
1083
nasal_vm.h
Normal file
1083
nasal_vm.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
pic/benchmark.png
Normal file
BIN
pic/benchmark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
pic/mandelbrot.png
Normal file
BIN
pic/mandelbrot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 62 KiB |
26
stl/file.nas
Normal file
26
stl/file.nas
Normal file
@@ -0,0 +1,26 @@
|
||||
# lib file.nas
|
||||
# ValKmjolnir 2022/3/6
|
||||
import("lib.nas");
|
||||
|
||||
var file={
|
||||
SEEK_SET:io.SEEK_SET,
|
||||
SEEK_CUR:io.SEEK_CUR,
|
||||
SEEK_END:io.SEEK_END,
|
||||
new: func(filename,mode="r"){
|
||||
var fd=io.open(filename,mode);
|
||||
return {
|
||||
close: func(){io.close(fd);},
|
||||
read: func(len){
|
||||
var buf=mut("");
|
||||
io.read(fd,buf,len);
|
||||
return buf;
|
||||
},
|
||||
write: func(str){return io.write(fd,str);},
|
||||
seek: func(pos,whence){return io.seek(fd,pos,whence);},
|
||||
tell: func(){return io.tell(fd);},
|
||||
readln: func(){return io.readln(fd);},
|
||||
stat: func(){return io.stat(filename);},
|
||||
eof: func(){return io.eof(fd);}
|
||||
};
|
||||
}
|
||||
};
|
||||
469
stl/lib.nas
Normal file
469
stl/lib.nas
Normal file
@@ -0,0 +1,469 @@
|
||||
# lib.nas
|
||||
|
||||
# import is used to link another file, this lib function will do nothing.
|
||||
# because nasal_import will recognize this and link files before generating bytecode.
|
||||
var import=func(filename){
|
||||
return __builtin_import(filename);
|
||||
}
|
||||
|
||||
# print is used to print all things in nasal, try and see how it works.
|
||||
# this function uses std::cout/printf to output logs.
|
||||
var print=func(elems...){
|
||||
return __builtin_print(elems);
|
||||
}
|
||||
|
||||
# append is used to add values into a vector.
|
||||
var append=func(vec,elems...){
|
||||
return __builtin_append(vec,elems);
|
||||
}
|
||||
|
||||
# setsize is used to change the size of vector.
|
||||
# if the size is larger than before,
|
||||
# this function will fill vm_nil into uninitialized space.
|
||||
var setsize=func(vec,size){
|
||||
return __builtin_setsize(vec,size);
|
||||
}
|
||||
|
||||
# system has the same use in C.
|
||||
var system=func(str){
|
||||
return __builtin_system(str);
|
||||
}
|
||||
|
||||
# input uses std::cin and returns what we input.
|
||||
var input=func(){
|
||||
return __builtin_input();
|
||||
}
|
||||
|
||||
# split a string by separator for example:
|
||||
# split("ll","hello world") -> ["he","o world"]
|
||||
# this function will return a vector.
|
||||
var split=func(separator,str){
|
||||
return __builtin_split(separator,str);
|
||||
}
|
||||
|
||||
# rand has the same function as the rand in C
|
||||
# if seed is nil, it will return the random number.
|
||||
# if seed is not nil, it will be initialized by this seed.
|
||||
var rand=func(seed=nil){
|
||||
return __builtin_rand(seed);
|
||||
}
|
||||
|
||||
# id will return the pointer of an gc-object.
|
||||
# if this object is not managed by gc, it will return 0.
|
||||
var id=func(object){
|
||||
return __builtin_id(object);
|
||||
}
|
||||
|
||||
# int will get the integer of input number.
|
||||
# but carefully use it, because int has range between -2147483648~2147483647
|
||||
var int=func(val){
|
||||
return __builtin_int(val);
|
||||
}
|
||||
|
||||
# floor will get the integral number of input argument
|
||||
# which is less than or equal to this argument
|
||||
var floor=func(val){
|
||||
return __builtin_floor(val);
|
||||
}
|
||||
|
||||
# abort using std::abort
|
||||
var abort=func(){
|
||||
__builtin_abort();
|
||||
}
|
||||
|
||||
# abs gets absolute number.
|
||||
var abs=func(n){
|
||||
return n>0?n:-n;
|
||||
}
|
||||
|
||||
# num will change all the other types into number.
|
||||
# mostly used to change a numerable string.
|
||||
var num=func(val){
|
||||
return __builtin_num(val);
|
||||
}
|
||||
|
||||
# pop used to pop the last element in a vector.
|
||||
# this function will return the value that poped if vector has element(s).
|
||||
# if the vector is empty, it will return nil.
|
||||
var pop=func(vec){
|
||||
return __builtin_pop(vec);
|
||||
}
|
||||
|
||||
# str is used to change number into string.
|
||||
var str=func(num){
|
||||
return __builtin_str(num);
|
||||
}
|
||||
|
||||
# size can get the size of a string/vector/hashmap.
|
||||
# in fact it can also get the size of number, and the result is the number itself.
|
||||
# so don't do useless things, though it really works.
|
||||
var size=func(object){
|
||||
return __builtin_size(object);
|
||||
}
|
||||
|
||||
# contains is used to check if a key exists in a hashmap/dict.
|
||||
var contains=func(hash,key){
|
||||
return __builtin_contains(hash,key);
|
||||
}
|
||||
|
||||
# delete is used to delete a pair in a hashmap/dict by key.
|
||||
var delete=func(hash,key){
|
||||
return __builtin_delete(hash,key);
|
||||
}
|
||||
|
||||
# keys is used to get all keys in a hashmap/dict.
|
||||
# this function will return a vector.
|
||||
var keys=func(hash){
|
||||
return __builtin_keys(hash);
|
||||
}
|
||||
|
||||
# time has the same function in C.
|
||||
var time=func(begin){
|
||||
return __builtin_time(begin);
|
||||
}
|
||||
var systime=func(){
|
||||
return time(0);
|
||||
}
|
||||
|
||||
# die is a special native function.
|
||||
# use it at where you want the program to crash immediately.
|
||||
var die=func(str){
|
||||
return __builtin_die(str);
|
||||
}
|
||||
|
||||
# find will give the first position of the needle in haystack
|
||||
var find=func(needle,haystack){
|
||||
return __builtin_find(needle,haystack);
|
||||
}
|
||||
|
||||
# typeof is used to get the type of an object.
|
||||
# this function returns a string.
|
||||
var typeof=func(object){
|
||||
return __builtin_type(object);
|
||||
}
|
||||
|
||||
# subvec is used to get part of a vector
|
||||
var subvec=func(vec,begin,length=nil){
|
||||
return vec[begin:(length==nil?nil:begin+length-1)];
|
||||
}
|
||||
|
||||
# substr will get the sub-string.
|
||||
# it gets the string, the begin index and sub-string's length as arguments.
|
||||
var substr=func(str,begin,len){
|
||||
return __builtin_substr(str,begin,len);
|
||||
}
|
||||
|
||||
# streq is used to compare if two strings are the same.
|
||||
var streq=func(a,b){
|
||||
return __builtin_streq(a,b);
|
||||
}
|
||||
|
||||
# left is used to get the sub-string like substr.
|
||||
# but the begin index is 0.
|
||||
var left=func(str,len){
|
||||
return __builtin_left(str,len);
|
||||
}
|
||||
|
||||
# right i used to get the sub-string like substr.
|
||||
# but the begin index is strlen-len.
|
||||
var right=func(str,len){
|
||||
return __builtin_right(str,len);
|
||||
}
|
||||
|
||||
# cmp is used to compare two strings.
|
||||
# normal string will not be correctly compared by operators < > <= >=
|
||||
# because these operators will turn strings into numbers then compare.
|
||||
var cmp=func(a,b){
|
||||
return __builtin_cmp(a,b);
|
||||
}
|
||||
|
||||
# chr is used to get the character by ascii-number.
|
||||
# for example chr(65) -> 'A'
|
||||
var chr=func(code){
|
||||
return __builtin_chr(code);
|
||||
}
|
||||
|
||||
# mut is used to change unmutable strings to mutable.
|
||||
var mut=func(str){
|
||||
return str~"";
|
||||
}
|
||||
|
||||
# srand wraps up rand, using time(0) as the seed.
|
||||
var srand=func(){
|
||||
rand(time(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
# values() gets all values in a hash.
|
||||
var values=func(hash){
|
||||
return __builtin_values(hash);
|
||||
}
|
||||
|
||||
# println has the same function as print.
|
||||
# but it will output a '\n' after using print.
|
||||
var println=func(elems...){
|
||||
__builtin_print(elems);
|
||||
elems=['\n'];
|
||||
return __builtin_print(elems);
|
||||
}
|
||||
|
||||
var isfunc=func(f){
|
||||
return typeof(f)=="func";
|
||||
}
|
||||
|
||||
var isghost=func(g){
|
||||
die("this runtime has no ghost object");
|
||||
return 0;
|
||||
}
|
||||
|
||||
var ishash=func(h){
|
||||
return typeof(h)=="hash";
|
||||
}
|
||||
|
||||
var isint=func(x){
|
||||
return x==floor(x);
|
||||
}
|
||||
|
||||
var isnum=func(x){
|
||||
return typeof(x)=="num" or !math.isnan(num(x));
|
||||
}
|
||||
|
||||
var isscalar=func(s){
|
||||
var t=typeof(s);
|
||||
return (t=="num" or t=="str")?1:0;
|
||||
}
|
||||
|
||||
var isstr=func(s){
|
||||
return typeof(s)=="str";
|
||||
}
|
||||
|
||||
var isvec=func(v){
|
||||
return typeof(v)=="vec";
|
||||
}
|
||||
|
||||
|
||||
# get the index of val in the vec
|
||||
var vecindex=func(vec,val){
|
||||
forindex(var i;vec)
|
||||
if(val==vec[i])
|
||||
return i;
|
||||
return nil;
|
||||
}
|
||||
|
||||
# check if the object is an instance of the class
|
||||
var isa=func(object,class){
|
||||
if(!contains(object,"parents") or typeof(object.parents)!="vec")
|
||||
return 0;
|
||||
foreach(var elem;object.parents)
|
||||
if(elem==class)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# assert aborts when condition is not true
|
||||
var assert=func(condition,message="assertion failed!"){
|
||||
if(condition)
|
||||
return 1;
|
||||
die(message);
|
||||
}
|
||||
|
||||
# md5
|
||||
var md5=func(str){
|
||||
return __builtin_md5(str);
|
||||
}
|
||||
|
||||
var io=
|
||||
{
|
||||
SEEK_SET:0,
|
||||
SEEK_CUR:1,
|
||||
SEEK_END:2,
|
||||
# get content of a file by filename. returns a string.
|
||||
fin: func(filename){return __builtin_fin(filename);},
|
||||
# input a string as the content of a file.
|
||||
fout: func(filename,str){return __builtin_fout(filename,str);},
|
||||
# same as C fopen. open file and get the FILE*.
|
||||
open: func(filename,mode="r"){return __builtin_open(filename,mode);},
|
||||
# same as C fclose. close file by FILE*.
|
||||
close: func(filehandle){return __builtin_close(filehandle);},
|
||||
# same as C fread. read file by FILE*.
|
||||
# caution: buf must be a mutable string.use mut("") to get an empty mutable string.
|
||||
read: func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);},
|
||||
# same as C fwrite. write file by FILE*.
|
||||
write: func(filehandle,str){return __builtin_write(filehandle,str);},
|
||||
# same as C fseek. seek place by FILE*.
|
||||
seek: func(filehandle,pos,whence){return __builtin_seek(filehandle,pos,whence);},
|
||||
# same as C ftell.
|
||||
tell: func(filehandle){return __builtin_tell(filehandle);},
|
||||
# read file by lines. use FILE*.
|
||||
# get nil if EOF
|
||||
readln:func(filehandle){return __builtin_readln(filehandle);},
|
||||
# same as C stat.
|
||||
stat: func(filename){return __builtin_stat(filename);},
|
||||
# same as C feof. check if FILE* gets the end of file(EOF).
|
||||
eof: func(filehandle){return __builtin_eof(filehandle);}
|
||||
};
|
||||
|
||||
# get file status. using data from io.stat
|
||||
var fstat=func(filename){
|
||||
var s=io.stat(filename);
|
||||
return {
|
||||
st_dev: s[0],
|
||||
st_ino: s[1],
|
||||
st_mode: s[2],
|
||||
st_nlink:s[3],
|
||||
st_uid: s[4],
|
||||
st_gid: s[5],
|
||||
st_rdev: s[6],
|
||||
st_size: s[7],
|
||||
st_atime:s[8],
|
||||
st_mtime:s[9],
|
||||
st_ctime:s[10]
|
||||
};
|
||||
}
|
||||
|
||||
# functions that do bitwise calculation.
|
||||
# carefully use it, all the calculations are based on integer.
|
||||
var bits=
|
||||
{
|
||||
# xor
|
||||
bitxor: func(a,b){return __builtin_xor(a,b); },
|
||||
# and
|
||||
bitand: func(a,b){return __builtin_and(a,b); },
|
||||
# or
|
||||
bitor: func(a,b){return __builtin_or(a,b); },
|
||||
# nand
|
||||
bitnand: func(a,b){return __builtin_nand(a,b);},
|
||||
# not
|
||||
bitnot: func(a) {return __builtin_not(a); },
|
||||
# get bit data from a special string. for example:
|
||||
# bits.fld(s,0,3);
|
||||
# if s stores 10100010(162)
|
||||
# will get 101(5).
|
||||
fld: func(str,startbit,len){return __builtin_fld;},
|
||||
# get sign-extended data from a special string. for example:
|
||||
# bits.sfld(s,0,3);
|
||||
# if s stores 10100010(162)
|
||||
# will get 101(5) then this will be signed extended to
|
||||
# 11111101(-3).
|
||||
sfld: func(str,startbit,len){return __builtin_sfld;},
|
||||
# set value into a special string to store it. little-endian, for example:
|
||||
# bits.setfld(s,0,8,69);
|
||||
# set 01000101(69) to string will get this:
|
||||
# 10100010(162)
|
||||
# so s[0]=162.
|
||||
setfld: func(str,startbit,len,val){return __builtin_setfld;},
|
||||
# get a special string filled by '\0' to use in setfld.
|
||||
buf: func(len){return __builtin_buf;}
|
||||
};
|
||||
|
||||
# mostly used math functions and special constants, you know.
|
||||
var math=
|
||||
{
|
||||
e: 2.7182818284590452354,
|
||||
pi: 3.14159265358979323846264338327950288,
|
||||
inf: 1/0,
|
||||
nan: 0/0,
|
||||
abs: func(x) {return x>0?x:-x; },
|
||||
floor: func(x) {return __builtin_floor(x); },
|
||||
pow: func(x,y){return __builtin_pow(x,y); },
|
||||
sin: func(x) {return __builtin_sin(x); },
|
||||
cos: func(x) {return __builtin_cos(x); },
|
||||
tan: func(x) {return __builtin_tan(x); },
|
||||
exp: func(x) {return __builtin_exp(x); },
|
||||
lg: func(x) {return __builtin_lg(x); },
|
||||
ln: func(x) {return __builtin_ln(x); },
|
||||
sqrt: func(x) {return __builtin_sqrt(x); },
|
||||
atan2: func(x,y){return __builtin_atan2(x,y);},
|
||||
isnan: func(x) {return __builtin_isnan(x); },
|
||||
max: func(x,y){return x>y?x:y; },
|
||||
min: func(x,y){return x<y?x:y; }
|
||||
};
|
||||
|
||||
var unix=
|
||||
{
|
||||
pipe: func(){return __builtin_pipe;},
|
||||
fork: func(){return __builtin_fork;},
|
||||
dup2: func(fd0,fd1){die("not supported yet");},
|
||||
exec: func(filename,argv,envp){die("not supported yet");},
|
||||
waitpid: func(pid,nohang=0){return __builtin_waitpid;},
|
||||
isdir: func(path){return bits.bitand(io.stat(path)[2],0x4000);}, # S_IFDIR 0x4000
|
||||
isfile: func(path){return bits.bitand(io.stat(path)[2],0x8000);}, # S_IFREG 0x8000
|
||||
opendir: func(path){return __builtin_opendir;},
|
||||
readdir: func(handle){return __builtin_readdir;},
|
||||
closedir: func(handle){return __builtin_closedir;},
|
||||
time: func(){return time(0);},
|
||||
sleep: func(secs){return __builtin_sleep(secs);},
|
||||
chdir: func(path){return __builtin_chdir(path);},
|
||||
environ: func(){return __builtin_environ();},
|
||||
getcwd: func(){return __builtin_getcwd();},
|
||||
getenv: func(envvar){return __builtin_getenv(envvar);}
|
||||
};
|
||||
|
||||
# dylib is the core hashmap for developers to load their own library.
|
||||
# for safe using dynamic library, you could use 'module' in stl/module.nas
|
||||
var dylib=
|
||||
{
|
||||
# open dynamic lib.
|
||||
dlopen: func(libname){return __builtin_dlopen;},
|
||||
# load symbol from an open dynamic lib.
|
||||
dlsym: func(lib,sym){return __builtin_dlsym; },
|
||||
# close dynamic lib, this operation will make all the symbols loaded from it invalid.
|
||||
dlclose: func(lib){return __builtin_dlclose; },
|
||||
# call the loaded symbol.
|
||||
dlcall: func(funcptr,args...){return __builtin_dlcall}
|
||||
};
|
||||
|
||||
# os is used to use or get some os-related info/functions.
|
||||
# windows/macOS/linux are supported.
|
||||
var os=
|
||||
{
|
||||
# get a string that tell which os it runs on.
|
||||
platform: func(){return __builtin_platform;}
|
||||
};
|
||||
|
||||
# runtime gives us some functions that we could manage it manually.
|
||||
var runtime=
|
||||
{
|
||||
# do garbage collection manually.
|
||||
# carefully use it because using it frequently may make program running slower.
|
||||
gc: func(){return __builtin_gc;}
|
||||
};
|
||||
|
||||
# important global constants
|
||||
var D2R=math.pi/180;
|
||||
var FPS2KT=0.5925;
|
||||
var FT2M=0.3048;
|
||||
var GAL2L=3.7854;
|
||||
var IN2M=0.0254;
|
||||
var KG2LB=2.2046;
|
||||
var KT2FPS=1.6878;
|
||||
var KT2MPS=0.5144;
|
||||
var L2GAL=0.2642;
|
||||
var LB2KG=0.4536;
|
||||
var M2FT=3.2808;
|
||||
var M2IN=39.3701;
|
||||
var M2NM=0.00054;
|
||||
var MPS2KT=1.9438;
|
||||
var NM2M=1852;
|
||||
var R2D=180/math.pi;
|
||||
|
||||
# functions that not supported in this runtime:
|
||||
var bind=func(function,locals,outer_scope=nil){
|
||||
die("this runtime does not support bind");
|
||||
}
|
||||
|
||||
var call=func(function,args=nil,_me=nil,locals=nil,error=nil){
|
||||
die("this runtime does not support call");
|
||||
}
|
||||
|
||||
var caller=func(level=1){
|
||||
die("this runtime does not support caller");
|
||||
}
|
||||
|
||||
var closure=func(function,level=1){
|
||||
die("this runtime uses \"vm_upval\" instead of \"vm_hash\" as the closure");
|
||||
}
|
||||
|
||||
var compile=func(code,filename="<compile>"){
|
||||
die("this runtime uses static code generator");
|
||||
}
|
||||
52
stl/list.nas
Normal file
52
stl/list.nas
Normal file
@@ -0,0 +1,52 @@
|
||||
# lib list.nas
|
||||
# valkmjolnir 2021/3/31
|
||||
var list=func()
|
||||
{
|
||||
var (begin,end)=(nil,nil);
|
||||
return{
|
||||
push_back:func(elem){
|
||||
var tmp={elem:elem,prev:nil,next:nil};
|
||||
if(end!=nil){
|
||||
end.next=tmp;
|
||||
tmp.prev=end;
|
||||
end=tmp;
|
||||
}
|
||||
else
|
||||
begin=end=tmp;
|
||||
},
|
||||
push_front:func(elem){
|
||||
var tmp={elem:elem,prev:nil,next:nil};
|
||||
if(begin!=nil){
|
||||
begin.prev=tmp;
|
||||
tmp.next=begin;
|
||||
begin=tmp;
|
||||
}
|
||||
else
|
||||
begin=end=tmp;
|
||||
},
|
||||
pop_back:func(){
|
||||
if(end!=nil)
|
||||
end=end.prev;
|
||||
if(end==nil)
|
||||
begin=nil;
|
||||
else
|
||||
end.next=nil;
|
||||
},
|
||||
pop_front:func(){
|
||||
if(begin!=nil)
|
||||
begin=begin.next;
|
||||
if(begin==nil)
|
||||
end=nil;
|
||||
else
|
||||
begin.prev=nil;
|
||||
},
|
||||
front:func(){
|
||||
if(begin!=nil)
|
||||
return begin.elem;
|
||||
},
|
||||
back:func(){
|
||||
if(end!=nil)
|
||||
return end.elem;
|
||||
},
|
||||
};
|
||||
}
|
||||
43
stl/module.nas
Normal file
43
stl/module.nas
Normal file
@@ -0,0 +1,43 @@
|
||||
# lib module.nas
|
||||
# ValKmjolnir 2022/3/5
|
||||
|
||||
# this provides safe usage of dylib
|
||||
# when dylib is closed,
|
||||
# all the invalid functions cannot be called
|
||||
|
||||
var module_call_func=func(fptr,args){
|
||||
return __builtin_dlcall;
|
||||
}
|
||||
var extern={
|
||||
new: func(fptr){
|
||||
var isopen=1;
|
||||
return {
|
||||
close:func(){isopen=0;},
|
||||
call:func(args...){
|
||||
return (!isopen)?
|
||||
nil:
|
||||
module_call_func(fptr,args);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
var module={
|
||||
new: func(name){
|
||||
var lib=dylib.dlopen(name);
|
||||
var f={};
|
||||
return {
|
||||
get:func(symbol){
|
||||
if(contains(f,symbol))
|
||||
return f[symbol];
|
||||
var fp=extern.new(dylib.dlsym(lib,symbol));
|
||||
f[symbol]=fp;
|
||||
return fp;
|
||||
},
|
||||
close: func(){
|
||||
foreach(var i;keys(f))
|
||||
f[i].close();
|
||||
dylib.dlclose(lib);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
36
stl/queue.nas
Normal file
36
stl/queue.nas
Normal file
@@ -0,0 +1,36 @@
|
||||
# lib queue.nas
|
||||
# valkmjolnir 2021/3/31
|
||||
var queue=func()
|
||||
{
|
||||
var (begin,end)=(nil,nil);
|
||||
return{
|
||||
push:func(elem){
|
||||
var new_node={
|
||||
elem:elem,
|
||||
next:nil
|
||||
};
|
||||
if(begin==nil)
|
||||
begin=end=new_node;
|
||||
else{
|
||||
end.next=new_node;
|
||||
end=new_node;
|
||||
}
|
||||
},
|
||||
pop:func(){
|
||||
if(begin!=nil)
|
||||
begin=begin.next;
|
||||
if(begin==nil)
|
||||
end=nil;
|
||||
},
|
||||
front:func(){
|
||||
if(begin!=nil)
|
||||
return begin.elem;
|
||||
},
|
||||
clear:func(){
|
||||
begin=end=nil;
|
||||
},
|
||||
empty:func(){
|
||||
return begin==nil;
|
||||
}
|
||||
};
|
||||
}
|
||||
28
stl/result.nas
Normal file
28
stl/result.nas
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
import("lib.nas");
|
||||
var ResultTrait={
|
||||
Ok:func(val){
|
||||
me.ok=val;
|
||||
me.flag=0;
|
||||
return me;
|
||||
},
|
||||
Err:func(info){
|
||||
me.err=info;
|
||||
me.flag=1;
|
||||
return me;
|
||||
},
|
||||
unwrap:func(){
|
||||
if(me.flag)
|
||||
die(me.err);
|
||||
return me.ok;
|
||||
}
|
||||
};
|
||||
|
||||
var Result=func(){
|
||||
return{
|
||||
ok:nil,
|
||||
err:"",
|
||||
flag:1,
|
||||
parents:[ResultTrait]
|
||||
};
|
||||
};
|
||||
20
stl/sort.nas
Normal file
20
stl/sort.nas
Normal file
@@ -0,0 +1,20 @@
|
||||
# lib sort.nas
|
||||
# valkmjolnir 2021/4/2
|
||||
var sort=func(vec,left,right,cmp=func(a,b){return a<=b;})
|
||||
{
|
||||
if(left>=right) return nil;
|
||||
var (L,R,tmp)=(left,right,vec[left]);
|
||||
while(left<right)
|
||||
{
|
||||
while(left<right and cmp(tmp,vec[right]))
|
||||
right-=1;
|
||||
while(left<right and cmp(vec[left],tmp))
|
||||
left+=1;
|
||||
if(left!=right)
|
||||
(vec[left],vec[right])=(vec[right],vec[left]);
|
||||
}
|
||||
(vec[L],vec[left])=(vec[left],tmp);
|
||||
sort(vec,L,left-1,cmp);
|
||||
sort(vec,left+1,R,cmp);
|
||||
return nil;
|
||||
}
|
||||
25
stl/stack.nas
Normal file
25
stl/stack.nas
Normal file
@@ -0,0 +1,25 @@
|
||||
# lib stack.nas
|
||||
# valkmjolnir 2021/3/31
|
||||
var stack=func()
|
||||
{
|
||||
var next=nil;
|
||||
return{
|
||||
push:func(elem){
|
||||
next={elem:elem,next:next};
|
||||
},
|
||||
pop:func(){
|
||||
if(next!=nil)
|
||||
next=next.next;
|
||||
},
|
||||
top:func(){
|
||||
if(next!=nil)
|
||||
return next.elem;
|
||||
},
|
||||
clear:func(){
|
||||
next=nil;
|
||||
},
|
||||
empty:func(){
|
||||
return next==nil;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
# NasNeuron lib written by ValKmjolnir
|
||||
|
||||
# Basic Class NasMatrix
|
||||
# NasMatGen : generate a new matrix
|
||||
# NasMatAdd : add two matrixes
|
||||
# NasMatSub : sub two matrixes
|
||||
# NasMatMul : multiply two matrix
|
||||
# NasMatTrans: transpose a matrix
|
||||
# NasMatPrt : print a matrix
|
||||
var NasMatrix=
|
||||
{
|
||||
NasMatGen:func(row,col)
|
||||
{
|
||||
var GenMat={Row:row,Col:col,Elem:[]};
|
||||
for(var i=0;i<row;i+=1)
|
||||
{
|
||||
var TmpVec=[];
|
||||
for(var j=0;j<col;j+=1)
|
||||
append(TmpVec,0);
|
||||
append(GenMat.Elem,TmpVec);
|
||||
}
|
||||
return GenMat;
|
||||
},
|
||||
NasMatAdd:func(mat1,mat2)
|
||||
{
|
||||
var ResultMat=nil;
|
||||
if(mat1.Row==mat2.Row and mat1.Col==mat2.Col)
|
||||
{
|
||||
ResultMat=me.NasMatGen(mat1.Row,mat1.Col);
|
||||
for(var i=0;i<ResultMat.Row;i+=1)
|
||||
for(var j=0;j<ResultMat.Col;j+=1)
|
||||
ResultMat.Elem[i][j]=mat1.Elem[i][j]+mat2.Elem[i][j];
|
||||
}
|
||||
else
|
||||
print("NasNeuron: Mat1 and Mat2 have different rows and cols.");
|
||||
return ResultMat;
|
||||
},
|
||||
NasMatSub:func(mat1,mat2)
|
||||
{
|
||||
var ResultMat=nil;
|
||||
if(mat1.Row==mat2.Row and mat1.Col==mat2.Col)
|
||||
{
|
||||
ResultMat=me.NasMatGen(mat1.Row,mat1.Col);
|
||||
for(var i=0;i<ResultMat.Row;i+=1)
|
||||
for(var j=0;j<ResultMat.Col;j+=1)
|
||||
ResultMat.Elem[i][j]=mat1.Elem[i][j]-mat2.Elem[i][j];
|
||||
}
|
||||
else
|
||||
print("NasNeuron: Mat1 and Mat2 have different rows and cols.");
|
||||
return ResultMat;
|
||||
},
|
||||
NasMatMul:func(mat1,mat2)
|
||||
{
|
||||
var ResultMat=nil;
|
||||
if(mat1.Col==mat2.Row)
|
||||
{
|
||||
ResultMat=me.NasMatGen(mat1.Row,mat2.Col);
|
||||
for(var i=0;i<ResultMat.Row;i+=1)
|
||||
for(var j=0;j<ResultMat.Col;j+=1)
|
||||
{
|
||||
var sum=0;
|
||||
for(var k=0;k<mat1.Col;k+=1)
|
||||
sum+=mat1.Elem[i][k]*mat2.Elem[k][j];
|
||||
ResultMat.Elem[i][j]=sum;
|
||||
}
|
||||
}
|
||||
else
|
||||
print("NasNeuron: Mat1's Col is different from Mat2's Row.");
|
||||
return ResultMat;
|
||||
},
|
||||
NasMatTrans:func(mat)
|
||||
{
|
||||
var ResultMat=nil;
|
||||
ResultMat=me.NasMatGen(mat.Col,mat.Row);
|
||||
for(var i=0;i<ResultMat.Row;i+=1)
|
||||
for(var j=0;j<ResultMat.Col;j+=1)
|
||||
ResultMat.Elem[i][j]=mat.Elem[j][i];
|
||||
return ResultMat;
|
||||
},
|
||||
NasMatPrt:func(mat)
|
||||
{
|
||||
for(var i=0;i<mat.Row;i+=1)
|
||||
{
|
||||
for(var j=0;j<mat.Col;j+=1)
|
||||
print(mat.Elem[i][j],' ');
|
||||
print('\n');
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
};
|
||||
|
||||
NasMatrix.NasMatPrt(
|
||||
NasMatrix.NasMatGen(
|
||||
10,100
|
||||
)
|
||||
);
|
||||
335
test/ai.nas
335
test/ai.nas
@@ -1,335 +0,0 @@
|
||||
import("lib.nas");
|
||||
var activate_function=
|
||||
{
|
||||
sigmoid_func:func(x)
|
||||
{
|
||||
return 1.0/(1.0+math.exp(-x));
|
||||
},
|
||||
diffsigmoid_func:func(x)
|
||||
{
|
||||
var t=func(x){return 1.0/(1.0+math.exp(-x));}(x);
|
||||
return t*(1-t);
|
||||
},
|
||||
tanh_func:func(x)
|
||||
{
|
||||
var t1=math.exp(x);
|
||||
var t2=math.exp(-x);
|
||||
return (t1-t2)/(t1+t2);
|
||||
},
|
||||
difftanh_func:func(x)
|
||||
{
|
||||
var t1=math.exp(x);
|
||||
var t2=math.exp(-x);
|
||||
var t=(t1-t2)/(t1+t2);
|
||||
return 1-t*t;
|
||||
},
|
||||
relu_func:func(x)
|
||||
{
|
||||
return x>0? x:0;
|
||||
},
|
||||
diffrelu_func:func(x)
|
||||
{
|
||||
return x>0;
|
||||
},
|
||||
leaky_relu_func:func(k,x)
|
||||
{
|
||||
return x>0? x:k*x;
|
||||
},
|
||||
diffleaky_relu_func:func(k,x)
|
||||
{
|
||||
return x>0? 1:k;
|
||||
}
|
||||
};
|
||||
|
||||
var matrix=
|
||||
{
|
||||
new:func(col,row)
|
||||
{
|
||||
var new_mat=
|
||||
{
|
||||
col:col,
|
||||
row:row,
|
||||
mat:[]
|
||||
};
|
||||
for(var i=0;i<row;i+=1)
|
||||
{
|
||||
append(new_mat.mat,[]);
|
||||
for(var j=0;j<col;j+=1)
|
||||
append(new_mat.mat[i],nil);
|
||||
}
|
||||
return new_mat;
|
||||
},
|
||||
srand:func(x)
|
||||
{
|
||||
rand(x);
|
||||
return nil;
|
||||
},
|
||||
rand_init:func(mat)
|
||||
{
|
||||
for(var i=0;i<mat.row;i+=1)
|
||||
for(var j=0;j<mat.col;j+=1)
|
||||
{
|
||||
if(rand()>0.5)
|
||||
mat.mat[i][j]=-rand();
|
||||
else
|
||||
mat.mat[i][j]=rand();
|
||||
}
|
||||
return;
|
||||
},
|
||||
prt_mat:func(mat)
|
||||
{
|
||||
var prt_s='[\n';
|
||||
foreach(var i;mat.mat)
|
||||
{
|
||||
var s='[';
|
||||
foreach(var j;i)
|
||||
s~=(j~',');
|
||||
s~='],\n';
|
||||
prt_s~=s;
|
||||
}
|
||||
prt_s~=']';
|
||||
print(prt_s);
|
||||
return nil;
|
||||
},
|
||||
mult_mat:func(mat1,mat2)
|
||||
{
|
||||
if(mat1.col!=mat2.row)
|
||||
{
|
||||
die("[error-mult] mat1\'s col does not match mat2\'s row.");
|
||||
return nil;
|
||||
}
|
||||
var new_mat=me.new(mat2.col,mat1.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
{
|
||||
var sum=0;
|
||||
for(var k=0;k<mat1.col;k+=1)
|
||||
sum+=mat1.mat[i][k]*mat2.mat[k][j];
|
||||
new_mat.mat[i][j]=sum;
|
||||
}
|
||||
return new_mat;
|
||||
},
|
||||
add_mat:func(mat1,mat2)
|
||||
{
|
||||
if(mat1.col!=mat2.col or mat1.row!=mat2.row)
|
||||
{
|
||||
die("[error-add] mat1\'s col or row does not match mat2\'s.");
|
||||
return nil;
|
||||
}
|
||||
var new_mat=me.new(mat1.col,mat1.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=mat1.mat[i][j]+mat2.mat[i][j];
|
||||
return new_mat;
|
||||
},
|
||||
sub_mat:func(mat1,mat2)
|
||||
{
|
||||
if(mat1.col!=mat2.col or mat1.row!=mat2.row)
|
||||
{
|
||||
die("[error-sub] mat1\'s col or row does not match mat2\'s.");
|
||||
return nil;
|
||||
}
|
||||
var new_mat=me.new(mat1.col,mat1.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=mat1.mat[i][j]-mat2.mat[i][j];
|
||||
return new_mat;
|
||||
},
|
||||
hadamard:func(mat1,mat2)
|
||||
{
|
||||
if(mat1.col!=mat2.col or mat1.row!=mat2.row)
|
||||
{
|
||||
die("[error-hadamard] mat1\'s col or row does not match mat2\'s.");
|
||||
return nil;
|
||||
}
|
||||
var new_mat=me.new(mat1.col,mat1.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=mat1.mat[i][j]*mat2.mat[i][j];
|
||||
return new_mat;
|
||||
},
|
||||
transpose:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.row,mat.col);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=mat.mat[j][i];
|
||||
return new_mat;
|
||||
},
|
||||
sigmoid:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.sigmoid_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
diffsigmoid:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.diffsigmoid_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
tanh:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.tanh_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
difftanh:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.difftanh_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
relu:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.relu_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
diffrelu:func(mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.diffrelu_func(mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
leaky_relu:func(k,mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.leaky_relu_func(k,mat.mat[i][j]);
|
||||
return new_mat;
|
||||
},
|
||||
diffleaky_relu:func(k,mat)
|
||||
{
|
||||
var new_mat=me.new(mat.col,mat.row);
|
||||
for(var i=0;i<new_mat.row;i+=1)
|
||||
for(var j=0;j<new_mat.col;j+=1)
|
||||
new_mat.mat[i][j]=activate_function.diffleaky_relu_func(k,mat.mat[i][j]);
|
||||
return new_mat;
|
||||
}
|
||||
};
|
||||
|
||||
var bp=
|
||||
{
|
||||
inum:2,
|
||||
hnum:4,
|
||||
onum:1,
|
||||
learning_rate:nil,
|
||||
hidden_layer:nil,
|
||||
hidden_res:nil,
|
||||
output_layer:nil,
|
||||
output_res:nil,
|
||||
result:nil,
|
||||
training_set:[],
|
||||
expect_set:[],
|
||||
init:func()
|
||||
{
|
||||
matrix.srand(time(0));
|
||||
me.hidden_layer=matrix.new(me.hnum,me.inum);
|
||||
matrix.rand_init(me.hidden_layer);
|
||||
me.output_layer=matrix.new(me.onum,me.hnum);
|
||||
matrix.rand_init(me.output_layer);
|
||||
return;
|
||||
},
|
||||
set_learning_rate:func(lr)
|
||||
{
|
||||
me.learning_rate=matrix.new(me.onum,1);
|
||||
for(var i=0;i<me.onum;i+=1)
|
||||
me.learning_rate.mat[i][0]=lr;
|
||||
return;
|
||||
},
|
||||
set_training_set:func()
|
||||
{
|
||||
for(var i=0;i<4;i+=1)
|
||||
append(me.training_set,matrix.new(me.inum,1));
|
||||
me.training_set[0].mat[0][0]=0;
|
||||
me.training_set[0].mat[0][1]=0;
|
||||
me.training_set[1].mat[0][0]=0;
|
||||
me.training_set[1].mat[0][1]=1;
|
||||
me.training_set[2].mat[0][0]=1;
|
||||
me.training_set[2].mat[0][1]=0;
|
||||
me.training_set[3].mat[0][0]=1;
|
||||
me.training_set[3].mat[0][1]=1;
|
||||
return;
|
||||
},
|
||||
set_expect_set:func()
|
||||
{
|
||||
for(var i=0;i<4;i+=1)
|
||||
append(me.expect_set,matrix.new(me.onum,1))
|
||||
me.expect_set[0].mat[0][0]=0;
|
||||
me.expect_set[1].mat[0][0]=1;
|
||||
me.expect_set[2].mat[0][0]=1;
|
||||
me.expect_set[3].mat[0][0]=0;
|
||||
return;
|
||||
},
|
||||
forward:func(i)
|
||||
{
|
||||
var tmp=nil;
|
||||
me.hidden_res=matrix.mult_mat(me.training_set[i],me.hidden_layer);
|
||||
tmp=matrix.sigmoid(me.hidden_res);
|
||||
me.output_res=matrix.mult_mat(tmp,me.output_layer);
|
||||
tmp=matrix.sigmoid(me.output_res);
|
||||
me.result=tmp;
|
||||
return;
|
||||
},
|
||||
backward:func(i)
|
||||
{
|
||||
var output_diff=matrix.sub_mat(me.expect_set[i],me.result);
|
||||
output_diff=matrix.hadamard(output_diff,me.learning_rate);
|
||||
output_diff=matrix.hadamard(output_diff,matrix.diffsigmoid(me.output_res));
|
||||
output_diff=matrix.mult_mat(output_diff,matrix.transpose(me.output_layer));
|
||||
matrix.prt_mat(output_diff);
|
||||
var hidden_diff=matrix.mult_mat();
|
||||
matrix.prt_mat(hidden_diff);
|
||||
|
||||
output_layer=matrix.add_mat(output_layer,output_diff);
|
||||
var error=0;
|
||||
foreach(var i;tmp.mat[0])
|
||||
error+=i;
|
||||
error*=0.5;
|
||||
return error;
|
||||
},
|
||||
training_process:func()
|
||||
{
|
||||
var cnt=0;
|
||||
var error=1e8;
|
||||
while(error>0.01)
|
||||
{
|
||||
error=0;
|
||||
for(var i=0;i<4;i+=1)
|
||||
{
|
||||
me.forward(i);
|
||||
error+=me.backward(i);
|
||||
}
|
||||
print(error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
var main=func()
|
||||
{
|
||||
bp.init();
|
||||
bp.set_learning_rate(0.1);
|
||||
bp.set_training_set();
|
||||
bp.set_expect_set();
|
||||
bp.training_process();
|
||||
return nil;
|
||||
}
|
||||
|
||||
# var (a,b,c)=[1,2,3];
|
||||
# (a,b,c)=(b,c,a);
|
||||
# print(a,b,c);
|
||||
main();
|
||||
@@ -1,10 +1,9 @@
|
||||
import("lib.nas");
|
||||
var char_ttf=[
|
||||
[" "," "," "," "," "," "],
|
||||
[" ████╗"," ██╔██║"," ██╔╝██║"," ███████║","██╔═══██║","╚═╝ ╚═╝"],
|
||||
["██████╗ ","██╔══██╗","██████╔╝","██╔══██╗","██████╔╝","╚═════╝ "],
|
||||
[" ██████╗","██╔════╝","██║ ","██║ ","╚██████╗"," ╚═════╝"],
|
||||
["██████╗ ","██╔══██╗","██║ ██║","██║ ██║","██████╔╝","╚═════╝ "],
|
||||
["██████╗ ","██╔══██╗","██║ ██║","██║ ██║","██████╔╝","╚═════╝ "],
|
||||
["███████╗","██╔════╝","█████╗ ","██╔══╝ ","███████╗","╚══════╝"],
|
||||
["███████╗","██╔════╝","█████╗ ","██╔══╝ ","██║ ","╚═╝ "],
|
||||
[" █████╗ ","██╔═══╝ ","██║ ██╗ ","██║ ╚██╗","╚█████╔╝"," ╚════╝ "],
|
||||
@@ -45,7 +44,7 @@ var trans_ttf=func(string)
|
||||
str[j]~=char_ttf[0][j];
|
||||
}
|
||||
foreach(var i;str)
|
||||
print(i);
|
||||
println(i);
|
||||
return;
|
||||
}
|
||||
var curve1=func()
|
||||
@@ -53,9 +52,9 @@ var curve1=func()
|
||||
var shadow=["░","▒","▓","█","▀","▄","▐","▌"];
|
||||
rand(100);
|
||||
var s="";
|
||||
for(var i=0;i<25;i+=1)
|
||||
for(var i=0;i<10;i+=1)
|
||||
{
|
||||
for(var j=0;j<100;j+=1)
|
||||
for(var j=0;j<40;j+=1)
|
||||
s~=shadow[int(8*rand())];
|
||||
s~='\n';
|
||||
}
|
||||
@@ -66,28 +65,15 @@ var curve2=func()
|
||||
var table=["╚","═","╝","╔","║","╗"];
|
||||
rand(100);
|
||||
var s="";
|
||||
for(var i=0;i<25;i+=1)
|
||||
for(var i=0;i<10;i+=1)
|
||||
{
|
||||
for(var j=0;j<100;j+=1)
|
||||
for(var j=0;j<40;j+=1)
|
||||
s~=table[int(6*rand())];
|
||||
s~='\n';
|
||||
}
|
||||
print(s);
|
||||
}
|
||||
var curve3=func()
|
||||
{
|
||||
var block=["░░","▒▒","▓▓","██","▀▀","▄▄","▄▀","▀▄","▐▐","▌▌"];
|
||||
rand(100);
|
||||
var s="";
|
||||
for(var i=0;i<25;i+=1)
|
||||
{
|
||||
for(var j=0;j<50;j+=1)
|
||||
s~=block[int(10*rand())];
|
||||
s~='\n';
|
||||
}
|
||||
print(s);
|
||||
}
|
||||
var curve4=func()
|
||||
{
|
||||
var s=["","","","","",""];
|
||||
var cnt=0;
|
||||
@@ -100,7 +86,7 @@ var curve4=func()
|
||||
{
|
||||
forindex(var i;s)
|
||||
{
|
||||
print(s[i]);
|
||||
println(s[i]);
|
||||
s[i]='';
|
||||
}
|
||||
cnt=0;
|
||||
@@ -108,12 +94,12 @@ var curve4=func()
|
||||
}
|
||||
return;
|
||||
}
|
||||
var curve5=func()
|
||||
var curve4=func()
|
||||
{
|
||||
for(var loop=0;loop<100;loop+=1)
|
||||
var arr=[0,1,2,3,4,5,6,7,8,0,1,2,3,4,5,6,7,8,0,1,2,3,4,5,6,7,8];
|
||||
for(var loop=0;loop<10;loop+=1)
|
||||
{
|
||||
var arr=[0,1,2,3,4,5,6,7,8,0,1,2,3,4,5,6,7,8];
|
||||
for(var i=17;i>=0;i-=1)
|
||||
for(var i=26;i>=0;i-=1)
|
||||
{
|
||||
var rand_index=int(i*rand());
|
||||
(arr[i],arr[rand_index])=(arr[rand_index],arr[i]);
|
||||
@@ -123,13 +109,47 @@ var curve5=func()
|
||||
var s="";
|
||||
for(var i=0;i<size(arr);i+=1)
|
||||
s~=shadow[arr[i]];
|
||||
print(s);
|
||||
println(s);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var curve5=func(){
|
||||
for(var i=0;i<=9;i+=1)
|
||||
println(i,"\e["~i~"mh \e[0m");
|
||||
for(var i=30;i<=37;i+=1)
|
||||
println(i,"\e["~i~"mh \e[0m");
|
||||
for(var i=40;i<=47;i+=1)
|
||||
println(i,"\e["~i~"mh \e[0m");
|
||||
for(var i=90;i<=97;i+=1)
|
||||
println(i,"\e["~i~"mh \e[0m");
|
||||
for(var i=100;i<=107;i+=1)
|
||||
println(i,"\e["~i~"mh \e[0m");
|
||||
}
|
||||
var curve6=func(){
|
||||
var shadow=["m░\e[0m","m▒\e[0m","m▓\e[0m","m█\e[0m","m▀\e[0m","m▄\e[0m","m▐\e[0m","m▌\e[0m"];
|
||||
var front=[
|
||||
"30","31","32","33","34","35","36","37",
|
||||
"90","91","92","93","94","95","96","97"
|
||||
];
|
||||
var back=[
|
||||
"40","41","42","43","44","45","46","47",
|
||||
"100","101","102","103","104","105","106","107"
|
||||
];
|
||||
rand(time(0));
|
||||
for(var i=0;i<15;i+=1){
|
||||
for(var j=0;j<45;j+=1)
|
||||
print("\e["~front[16*rand()]~";"~back[16*rand()]~shadow[8*rand()]);
|
||||
print('\n');
|
||||
}
|
||||
}
|
||||
if(os.platform()=="windows")
|
||||
system("chcp 65001");
|
||||
trans_ttf("just for test");
|
||||
trans_ttf(" ValKmjolnir ");
|
||||
trans_ttf("just for fun");
|
||||
curve1();
|
||||
curve2();
|
||||
curve3();
|
||||
curve4();
|
||||
curve5();
|
||||
curve5();
|
||||
curve6();
|
||||
@@ -1,5 +1,9 @@
|
||||
# Road check and auto pilot(??) by ValKmjolnir
|
||||
|
||||
# Road check and auto pilot by ValKmjolnir
|
||||
import("test/props_sim.nas");
|
||||
var dt=0.01;
|
||||
var intergral=0;
|
||||
var derivative=0;
|
||||
var previous_error=0;
|
||||
var position_change = func(position_val,value){
|
||||
if(position_val+value>180)
|
||||
position_val += value-360;
|
||||
@@ -10,12 +14,11 @@ var position_change = func(position_val,value){
|
||||
return position_val;
|
||||
}
|
||||
var road_check_func = func(){
|
||||
|
||||
|
||||
var lat = props.getNode("/position/latitude-deg",1).getValue();
|
||||
var lon = props.getNode("/position/longitude-deg",1).getValue();
|
||||
var position_info = geodinfo(lat,lon);
|
||||
var position_names = position_info[1].names;
|
||||
# the friction_factor of freeway runway and road is 1
|
||||
|
||||
if((position_names[0]=="Freeway") or (position_names[0]=="Road"))
|
||||
{
|
||||
@@ -24,14 +27,14 @@ var road_check_func = func(){
|
||||
var lon_change = 0;
|
||||
var left_range = 0;
|
||||
var right_range = 0;
|
||||
|
||||
|
||||
for(var i=0;i>-0.00005;i-=0.000001)
|
||||
{
|
||||
car_heading = props.getNode("/orientation/heading-deg",1).getValue();
|
||||
lat_change = math.sin(math.pi*car_heading/180);
|
||||
lon_change = -math.cos(math.pi*car_heading/180);
|
||||
lat = props.getNode("/position/latitude-deg",1).getValue()+0.0001*math.cos(math.pi*car_heading/180);
|
||||
lon = props.getNode("/position/longitude-deg",1).getValue()+0.0001*math.sin(math.pi*car_heading/180);
|
||||
lat_change = math.sin(D2R*car_heading);
|
||||
lon_change = -math.cos(D2R*car_heading);
|
||||
lat = props.getNode("/position/latitude-deg",1).getValue()+0.0001*math.cos(D2R*car_heading);
|
||||
lon = props.getNode("/position/longitude-deg",1).getValue()+0.0001*math.sin(D2R*car_heading);
|
||||
var other_position_info = geodinfo(position_change(lat,i*lat_change),position_change(lon,i*lon_change));
|
||||
var other_names = other_position_info[1].names;
|
||||
if((other_names[0]=="Freeway") or (other_names[0]=="Road"))
|
||||
@@ -42,10 +45,10 @@ var road_check_func = func(){
|
||||
for(var i=0;i<0.00005;i+=0.000001)
|
||||
{
|
||||
car_heading = props.getNode("/orientation/heading-deg",1).getValue();
|
||||
lat_change = math.sin(math.pi*car_heading/180);
|
||||
lon_change = -math.cos(math.pi*car_heading/180);
|
||||
lat = props.getNode("/position/latitude-deg",1).getValue()+0.0001*math.cos(math.pi*car_heading/180);
|
||||
lon = props.getNode("/position/longitude-deg",1).getValue()+0.0001*math.sin(math.pi*car_heading/180);
|
||||
lat_change = math.sin(D2R*car_heading);
|
||||
lon_change = -math.cos(D2R*car_heading);
|
||||
lat = props.getNode("/position/latitude-deg",1).getValue()+0.0001*math.cos(D2R*car_heading);
|
||||
lon = props.getNode("/position/longitude-deg",1).getValue()+0.0001*math.sin(D2R*car_heading);
|
||||
var other_position_info = geodinfo(position_change(lat,i*lat_change),position_change(lon,i*lon_change));
|
||||
var other_names = other_position_info[1].names;
|
||||
if((other_names[0]=="Freeway") or (other_names[0]=="Road"))
|
||||
@@ -53,25 +56,26 @@ var road_check_func = func(){
|
||||
else
|
||||
break;
|
||||
}
|
||||
#if(left_range>right_range)
|
||||
#{
|
||||
# setprop("/controls/flight/rudder",-(right_range-left_range)*(right_range-left_range)/10000);
|
||||
# print("right ",right_range);
|
||||
#}
|
||||
#else if(left_range<right_range)
|
||||
#{
|
||||
# setprop("/controls/flight/rudder",(right_range-left_range)*(right_range-left_range)/10000);
|
||||
# print("left ",left_range);
|
||||
#}
|
||||
#else
|
||||
# setprop("/controls/flight/rudder",0);
|
||||
props.getNode("/controls/flight/rudder",1).setValue((right_range-left_range)/200);
|
||||
var error=right_range-left_range;
|
||||
intergral+=error*dt;
|
||||
derivative=(error-previous_error)/dt;
|
||||
var (Kp,Ki,Kd)=(1/900,0.05,0.005);
|
||||
# print("change p ",Kp*error*error,' i ',Ki*intergral,' d ',Kd*derivative);
|
||||
if(error<0)
|
||||
props.getNode("/", 1).setValue("/controls/flight/rudder",-Kp*error*error+Ki*intergral+Kd*derivative);
|
||||
else if(error>0)
|
||||
props.getNode("/", 1).setValue("/controls/flight/rudder",Kp*error*error+Ki*intergral+Kd*derivative);
|
||||
else
|
||||
props.getNode("/", 1).setValue("/controls/flight/rudder",0);
|
||||
previous_error=error;
|
||||
}
|
||||
};
|
||||
var road_check_timer = maketimer(0.1,road_check_func);
|
||||
|
||||
var road_check_timer = maketimer(0.01,road_check_func);
|
||||
var toggle_auto_pilot = func(){
|
||||
if(!road_check_timer.isRunning)
|
||||
{
|
||||
intergral=0;
|
||||
road_check_timer.start();
|
||||
props.getNode("/sim/messages/copilot",1).setValue("ze dong sheng teaan see tong yee tse yung. Auto Sheng Teaan System Activated!");
|
||||
}
|
||||
@@ -80,4 +84,4 @@ var toggle_auto_pilot = func(){
|
||||
road_check_timer.stop();
|
||||
props.getNode("/sim/messages/copilot",1).setValue("ze dong sheng teaan see tong yee guan bee. Auto Sheng Teaan System is off.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
227
test/bf.nas
Normal file
227
test/bf.nas
Normal file
@@ -0,0 +1,227 @@
|
||||
var mandelbrot=
|
||||
"[A mandelbrot set fractal viewer in brainf*** written by Erik Bosman]
|
||||
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[
|
||||
>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+
|
||||
<<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+[>>>>>>[>>>>>>>[-]>>]<<<<<<<<<[<<<<<<<<<]>>
|
||||
>>>>>[-]+<<<<<<++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<+++++++[-[->>>
|
||||
>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[[-]>>>>>>[>>>>>
|
||||
>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>
|
||||
[>>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<
|
||||
<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>+++++++++++++++[[
|
||||
>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[
|
||||
>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[
|
||||
-<<+>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<
|
||||
<<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<
|
||||
[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>
|
||||
>>>>[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+
|
||||
<<<<<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>
|
||||
>>>>>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<
|
||||
+>>>>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<
|
||||
<]<+<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>
|
||||
>>>>>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
|
||||
>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<
|
||||
<<<]>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<
|
||||
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->
|
||||
>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<
|
||||
<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++++++++++++++++
|
||||
+++++++>>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>[<<<<<<<+<[-<+>>>>+<<[-]]>[-<<[->+>>>-
|
||||
<<<<]>>>]>>>>>>>>>>>>>[>>[-]>[-]>[-]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>>>>>>[>>>>>
|
||||
[-<<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>[-<<<<<<<<
|
||||
<+>>>>>>>>>]>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>>]+>[-
|
||||
]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>>>>>>>]<<<
|
||||
<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+>>]<
|
||||
<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[->>>>
|
||||
>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-]<->>>
|
||||
[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<
|
||||
<<<<+>>>>>]<<<<<[->>>>>+<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+>>>>>>>>
|
||||
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+
|
||||
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
|
||||
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
|
||||
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
|
||||
[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>
|
||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++
|
||||
+++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-<<<<<<<+
|
||||
>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[
|
||||
-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>>]>[-<<<<<<[->>>>>+<++<<<<]>>>>>[-<
|
||||
<<<<+>>>>>]<->+>]<[->+<]<<<<<[->>>>>+<<<<<]>>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<
|
||||
[->>>>->>>>>[>>[-<<->>]+<<[->>->[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]
|
||||
+>>>>>>[>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<<<<<<<<<<[<<<<<
|
||||
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<
|
||||
[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<
|
||||
<<<+<[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<
|
||||
<<<<<+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<
|
||||
<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+<]>>>>>>>>]<<<
|
||||
<<<<<+<[>[->>>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>[->>>>+<<<<]>]<[->>>>-<<<<<<<
|
||||
<<<<<<<+>>>>>>>>>>]<]>>[->>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>>+<<<<
|
||||
]<<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>>>>>>>>>]<<<<<<<<<
|
||||
[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<<<<<<
|
||||
+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<<<<<<
|
||||
<<<<<]]>[-]>>[-]>[-]>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<
|
||||
<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[
|
||||
[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+
|
||||
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>
|
||||
[-<<+>>]<<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<
|
||||
<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[
|
||||
>[-]<->>>[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[
|
||||
>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>
|
||||
>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>[-]>>>>+++++++++++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<
|
||||
<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<
|
||||
<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-
|
||||
<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>
|
||||
>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>>>
|
||||
[-<<<->>>]<<<[->>>+<<<]>>>>>>>>]<<<<<<<<+<[>[->+>[-<-<<<<<<<<<<+>>>>>>>>>>>>[-<<
|
||||
+>>]<]>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<<<]>>[-<+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<]>
|
||||
[-<<+>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>
|
||||
>>>>>>]<<<<<<<<+<[>[->+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>[-<+>]>]<[-<-<<<<<<<<<<+>>>>
|
||||
>>>>>>>]<<]>>>[-<<+>[-<-<<<<<<<<<<+>>>>>>>>>>>]>]<[-<+>]<<<<<<<<<<<<]>>>>>+<<<<<
|
||||
]>>>>>>>>>[>>>[-]>[-]>[-]>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>>>[-<<<<<
|
||||
<+>>>>>>]<<<<<<[->>>>>>+<<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>
|
||||
>]>>[-<<<<<<<[->>>>>+<++<<<<]>>>>>[-<<<<<+>>>>>]<->+>>]<<[->>+<<]<<<<<[->>>>>+<<
|
||||
<<<]+>>>>[-<<<<->>>>]+<<<<[->>>>->>>>>[>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<
|
||||
<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>[-<<->>]+<<[->>->[-<<<+>>>]<
|
||||
<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<
|
||||
<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+
|
||||
<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>[->>>+<<<]>]<[->>>-
|
||||
<<<<<<<<<<<<<+>>>>>>>>>>]<]>>[->>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>+<<<
|
||||
]<<<<<<<<<<<]>>>>>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]]>>>>[-<<<<+>
|
||||
>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<<[->>>-
|
||||
<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[
|
||||
->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>
|
||||
>>]<<<<[->>>>+>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>[>>>>>>
|
||||
>>>]<<<<<<<<<[>[->>>>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<
|
||||
<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<
|
||||
<<<<]]>>>>>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>[-<<<<+
|
||||
>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<+>>>>>
|
||||
]<<<<<[->>>>>+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
|
||||
>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>
|
||||
>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[-<<+
|
||||
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
|
||||
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
|
||||
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
|
||||
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<
|
||||
<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>
|
||||
>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<+>>>
|
||||
>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+
|
||||
<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>
|
||||
>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>
|
||||
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<<<<]
|
||||
>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<
|
||||
]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->>>+<
|
||||
<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>
|
||||
>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>->>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>]<<+>>>>[-<<<<
|
||||
->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[-<<<<<<<.>>>>>>>]<<<[-]>[-]>[-]>[-]>[-]>[-]>>>[
|
||||
>[-]>[-]>[-]>[-]>[-]>[-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]>>>>]<<<<<<<<<
|
||||
[<<<<<<<<<]>+++++++++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+>>>>>>>>>+<<<<<<<<
|
||||
<<<<<<[<<<<<<<<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+[-]>>[>>>>>>>>>]<<<<<
|
||||
<<<<[>>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<[<<<<<<<<<]>>>>>>>[-]+>>>]<<<<
|
||||
<<<<<<]]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+>>[>+>>>>[-<<<<->>>>]<<<<[->>>
|
||||
>+<<<<]>>>>>>>>]<<+<<<<<<<[>>>>>[->>+<<]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<
|
||||
<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<<<<<[->>>>>>+<<<<<<]<
|
||||
+<<<<<<<<<]>>>>>>>-<<<<[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>->>[>>
|
||||
>>>[->>+<<]>>>>]<<<<<<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<
|
||||
<<<<[->>>>>>+<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+<<<
|
||||
<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>->>[-<<<<<<<+>>>>>>>]<<<<
|
||||
<<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>[-<
|
||||
<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<
|
||||
<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<
|
||||
<<[<<<<<<<<<]>>>>[-]<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>-<<<<<[<<<<<<<
|
||||
<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++[-[->>>>>>>>
|
||||
>+<<<<<<<<<]>>>>>>>>>]>>>>>+>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<
|
||||
<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+[-]>[>>>>>>>>>]<<<<<<<<<[>>>>>>>>[-<<<<<<<+>>>>>>
|
||||
>]<<<<<<<[->>>>>>>+<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<
|
||||
<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+>[>+>>>>>[-<<<<<->>>>>]<<<<<[->>>>>+<<<<<]>>>>>>
|
||||
>>]<+<<<<<<<<[>>>>>>[->>+<<]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<-
|
||||
>>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<
|
||||
<<<]>>>>>>>>-<<<<<[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>->[>>>
|
||||
>>>[->>+<<]>>>]<<<<<<<<<[>[-]<->>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<
|
||||
<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>
|
||||
+>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<->>>>>>]+<
|
||||
<<<<<[->>>>>>->>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<
|
||||
<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>
|
||||
-<<[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>
|
||||
>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<++++
|
||||
+[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>->>>>>>>>>>>>>>>>>>>>>>>>>>>-<<<<<<[<<<<
|
||||
<<<<<]]>>>]";
|
||||
|
||||
var paper=[];
|
||||
var (ptr,pc)=(0,0);
|
||||
var (code,inum,stack)=([],[],[]);
|
||||
var (add,mov,jt,jf,in,out)=(0,1,2,3,4,5);
|
||||
|
||||
var funcs=[
|
||||
func{paper[ptr]+=inum[pc];},
|
||||
func{ptr+=inum[pc];},
|
||||
func{if(paper[ptr])pc=inum[pc];},
|
||||
func{if(!paper[ptr])pc=inum[pc];},
|
||||
func{paper[ptr]=input()[0];},
|
||||
func{print(chr(paper[ptr]));}
|
||||
];
|
||||
|
||||
var bf=func(program){
|
||||
setsize(paper,131072);
|
||||
var len=size(program);
|
||||
for(var i=0;i<len;i+=1){
|
||||
var c=chr(program[i]);
|
||||
if(c=='+' or c=='-'){
|
||||
append(code,add);
|
||||
append(inum,0);
|
||||
for(;i<len;i+=1){
|
||||
if(chr(program[i])=='+')
|
||||
inum[-1]+=1;
|
||||
elsif(chr(program[i])=='-')
|
||||
inum[-1]-=1;
|
||||
elsif(chr(program[i])!='\n'){
|
||||
i-=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif(c=='<' or c=='>'){
|
||||
append(code,mov);
|
||||
append(inum,0);
|
||||
for(;i<len;i+=1){
|
||||
if(chr(program[i])=='>')
|
||||
inum[-1]+=1;
|
||||
elsif(chr(program[i])=='<')
|
||||
inum[-1]-=1;
|
||||
elsif(chr(program[i])!='\n'){
|
||||
i-=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif(c==','){
|
||||
append(code,in);
|
||||
append(inum,0);
|
||||
}
|
||||
elsif(c=='.'){
|
||||
append(code,out);
|
||||
append(inum,0);
|
||||
}
|
||||
elsif(c=='['){
|
||||
append(code,jf);
|
||||
append(inum,0);
|
||||
append(stack,size(code)-1);
|
||||
}
|
||||
elsif(c==']'){
|
||||
if(!size(stack))
|
||||
die("lack [");
|
||||
var label=pop(stack);
|
||||
append(code,jt);
|
||||
append(inum,label-1);
|
||||
inum[label]=size(code)-2;
|
||||
}
|
||||
}
|
||||
if(size(stack)){
|
||||
die("lack ]");
|
||||
return;
|
||||
}
|
||||
len=size(code);
|
||||
for(pc=0;pc<len;pc+=1)
|
||||
funcs[code[pc]]();
|
||||
return;
|
||||
}
|
||||
|
||||
bf(mandelbrot);
|
||||
242
test/bfcolored.nas
Normal file
242
test/bfcolored.nas
Normal file
@@ -0,0 +1,242 @@
|
||||
var mandelbrot=
|
||||
"[A mandelbrot set fractal viewer in brainf*** written by Erik Bosman]
|
||||
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[
|
||||
>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+
|
||||
<<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+[>>>>>>[>>>>>>>[-]>>]<<<<<<<<<[<<<<<<<<<]>>
|
||||
>>>>>[-]+<<<<<<++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<+++++++[-[->>>
|
||||
>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[[-]>>>>>>[>>>>>
|
||||
>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>
|
||||
[>>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<
|
||||
<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>+++++++++++++++[[
|
||||
>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[
|
||||
>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[
|
||||
-<<+>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<
|
||||
<<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<
|
||||
[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>
|
||||
>>>>[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+
|
||||
<<<<<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>
|
||||
>>>>>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<
|
||||
+>>>>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<
|
||||
<]<+<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>
|
||||
>>>>>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
|
||||
>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<
|
||||
<<<]>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<
|
||||
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->
|
||||
>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<
|
||||
<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++++++++++++++++
|
||||
+++++++>>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>[<<<<<<<+<[-<+>>>>+<<[-]]>[-<<[->+>>>-
|
||||
<<<<]>>>]>>>>>>>>>>>>>[>>[-]>[-]>[-]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>>>>>>[>>>>>
|
||||
[-<<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>[-<<<<<<<<
|
||||
<+>>>>>>>>>]>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>>]+>[-
|
||||
]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>>>>>>>]<<<
|
||||
<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+>>]<
|
||||
<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[->>>>
|
||||
>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-]<->>>
|
||||
[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<
|
||||
<<<<+>>>>>]<<<<<[->>>>>+<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+>>>>>>>>
|
||||
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+
|
||||
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
|
||||
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
|
||||
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
|
||||
[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>
|
||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++
|
||||
+++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-<<<<<<<+
|
||||
>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[
|
||||
-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>>]>[-<<<<<<[->>>>>+<++<<<<]>>>>>[-<
|
||||
<<<<+>>>>>]<->+>]<[->+<]<<<<<[->>>>>+<<<<<]>>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<
|
||||
[->>>>->>>>>[>>[-<<->>]+<<[->>->[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]
|
||||
+>>>>>>[>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<<<<<<<<<<[<<<<<
|
||||
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<
|
||||
[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<
|
||||
<<<+<[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<
|
||||
<<<<<+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<
|
||||
<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+<]>>>>>>>>]<<<
|
||||
<<<<<+<[>[->>>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>[->>>>+<<<<]>]<[->>>>-<<<<<<<
|
||||
<<<<<<<+>>>>>>>>>>]<]>>[->>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>>+<<<<
|
||||
]<<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>>>>>>>>>]<<<<<<<<<
|
||||
[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<<<<<<
|
||||
+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<<<<<<
|
||||
<<<<<]]>[-]>>[-]>[-]>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<
|
||||
<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[
|
||||
[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+
|
||||
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>
|
||||
[-<<+>>]<<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<
|
||||
<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[
|
||||
>[-]<->>>[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[
|
||||
>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>
|
||||
>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>[-]>>>>+++++++++++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<
|
||||
<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<
|
||||
<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-
|
||||
<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>
|
||||
>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>>>
|
||||
[-<<<->>>]<<<[->>>+<<<]>>>>>>>>]<<<<<<<<+<[>[->+>[-<-<<<<<<<<<<+>>>>>>>>>>>>[-<<
|
||||
+>>]<]>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<<<]>>[-<+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<]>
|
||||
[-<<+>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>
|
||||
>>>>>>]<<<<<<<<+<[>[->+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>[-<+>]>]<[-<-<<<<<<<<<<+>>>>
|
||||
>>>>>>>]<<]>>>[-<<+>[-<-<<<<<<<<<<+>>>>>>>>>>>]>]<[-<+>]<<<<<<<<<<<<]>>>>>+<<<<<
|
||||
]>>>>>>>>>[>>>[-]>[-]>[-]>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>>>[-<<<<<
|
||||
<+>>>>>>]<<<<<<[->>>>>>+<<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>
|
||||
>]>>[-<<<<<<<[->>>>>+<++<<<<]>>>>>[-<<<<<+>>>>>]<->+>>]<<[->>+<<]<<<<<[->>>>>+<<
|
||||
<<<]+>>>>[-<<<<->>>>]+<<<<[->>>>->>>>>[>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<
|
||||
<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>[-<<->>]+<<[->>->[-<<<+>>>]<
|
||||
<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<
|
||||
<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+
|
||||
<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>[->>>+<<<]>]<[->>>-
|
||||
<<<<<<<<<<<<<+>>>>>>>>>>]<]>>[->>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>+<<<
|
||||
]<<<<<<<<<<<]>>>>>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]]>>>>[-<<<<+>
|
||||
>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<<[->>>-
|
||||
<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[
|
||||
->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>
|
||||
>>]<<<<[->>>>+>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>[>>>>>>
|
||||
>>>]<<<<<<<<<[>[->>>>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<
|
||||
<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<
|
||||
<<<<]]>>>>>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>[-<<<<+
|
||||
>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<+>>>>>
|
||||
]<<<<<[->>>>>+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
|
||||
>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>
|
||||
>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[-<<+
|
||||
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
|
||||
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
|
||||
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
|
||||
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<
|
||||
<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>
|
||||
>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<+>>>
|
||||
>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+
|
||||
<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>
|
||||
>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>
|
||||
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<<<<]
|
||||
>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<
|
||||
]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->>>+<
|
||||
<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>
|
||||
>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>->>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>]<<+>>>>[-<<<<
|
||||
->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[-<<<<<<<.>>>>>>>]<<<[-]>[-]>[-]>[-]>[-]>[-]>>>[
|
||||
>[-]>[-]>[-]>[-]>[-]>[-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]>>>>]<<<<<<<<<
|
||||
[<<<<<<<<<]>+++++++++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+>>>>>>>>>+<<<<<<<<
|
||||
<<<<<<[<<<<<<<<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+[-]>>[>>>>>>>>>]<<<<<
|
||||
<<<<[>>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<[<<<<<<<<<]>>>>>>>[-]+>>>]<<<<
|
||||
<<<<<<]]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+>>[>+>>>>[-<<<<->>>>]<<<<[->>>
|
||||
>+<<<<]>>>>>>>>]<<+<<<<<<<[>>>>>[->>+<<]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<
|
||||
<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<<<<<[->>>>>>+<<<<<<]<
|
||||
+<<<<<<<<<]>>>>>>>-<<<<[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>->>[>>
|
||||
>>>[->>+<<]>>>>]<<<<<<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<
|
||||
<<<<[->>>>>>+<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+<<<
|
||||
<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>->>[-<<<<<<<+>>>>>>>]<<<<
|
||||
<<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>[-<
|
||||
<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<
|
||||
<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<
|
||||
<<[<<<<<<<<<]>>>>[-]<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>-<<<<<[<<<<<<<
|
||||
<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++[-[->>>>>>>>
|
||||
>+<<<<<<<<<]>>>>>>>>>]>>>>>+>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<
|
||||
<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+[-]>[>>>>>>>>>]<<<<<<<<<[>>>>>>>>[-<<<<<<<+>>>>>>
|
||||
>]<<<<<<<[->>>>>>>+<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<
|
||||
<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+>[>+>>>>>[-<<<<<->>>>>]<<<<<[->>>>>+<<<<<]>>>>>>
|
||||
>>]<+<<<<<<<<[>>>>>>[->>+<<]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<-
|
||||
>>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<
|
||||
<<<]>>>>>>>>-<<<<<[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>->[>>>
|
||||
>>>[->>+<<]>>>]<<<<<<<<<[>[-]<->>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<
|
||||
<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>
|
||||
+>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<->>>>>>]+<
|
||||
<<<<<[->>>>>>->>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<
|
||||
<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>
|
||||
-<<[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>
|
||||
>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<++++
|
||||
+[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>->>>>>>>>>>>>>>>>>>>>>>>>>>>-<<<<<<[<<<<
|
||||
<<<<<]]>>>]";
|
||||
|
||||
var paper=[];
|
||||
var (ptr,pc)=(0,0);
|
||||
var (code,inum,stack)=([],[],[]);
|
||||
var (add,mov,jt,jf,in,out)=(0,1,2,3,4,5);
|
||||
|
||||
var color=[
|
||||
"\e[31m","\e[32m","\e[33m","\e[34m","\e[35m","\e[36m",
|
||||
"\e[90m","\e[91m","\e[92m","\e[93m","\e[94m","\e[95m","\e[96m"
|
||||
];
|
||||
var table=[];
|
||||
func(){
|
||||
var cnt=0;
|
||||
for(var i=0;i<256;i+=1){
|
||||
append(table,color[cnt]~chr(i)~"\e[0m");
|
||||
cnt+=1;
|
||||
if(cnt>12)
|
||||
cnt=0;
|
||||
}
|
||||
}();
|
||||
|
||||
var funcs=[
|
||||
func{paper[ptr]+=inum[pc];},
|
||||
func{ptr+=inum[pc];},
|
||||
func{if(paper[ptr])pc=inum[pc];},
|
||||
func{if(!paper[ptr])pc=inum[pc];},
|
||||
func{paper[ptr]=input()[0];},
|
||||
func{print(table[paper[ptr]]);}
|
||||
];
|
||||
|
||||
var bf=func(program){
|
||||
setsize(paper,131072);
|
||||
var len=size(program);
|
||||
for(var i=0;i<len;i+=1){
|
||||
var c=chr(program[i]);
|
||||
if(c=='+' or c=='-'){
|
||||
append(code,add);
|
||||
append(inum,0);
|
||||
for(;i<len;i+=1){
|
||||
if(chr(program[i])=='+')
|
||||
inum[-1]+=1;
|
||||
elsif(chr(program[i])=='-')
|
||||
inum[-1]-=1;
|
||||
elsif(chr(program[i])!='\n'){
|
||||
i-=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif(c=='<' or c=='>'){
|
||||
append(code,mov);
|
||||
append(inum,0);
|
||||
for(;i<len;i+=1){
|
||||
if(chr(program[i])=='>')
|
||||
inum[-1]+=1;
|
||||
elsif(chr(program[i])=='<')
|
||||
inum[-1]-=1;
|
||||
elsif(chr(program[i])!='\n'){
|
||||
i-=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif(c==','){
|
||||
append(code,in);
|
||||
append(inum,0);
|
||||
}
|
||||
elsif(c=='.'){
|
||||
append(code,out);
|
||||
append(inum,0);
|
||||
}
|
||||
elsif(c=='['){
|
||||
append(code,jf);
|
||||
append(inum,0);
|
||||
append(stack,size(code)-1);
|
||||
}
|
||||
elsif(c==']'){
|
||||
if(!size(stack))
|
||||
die("lack [");
|
||||
var label=pop(stack);
|
||||
append(code,jt);
|
||||
append(inum,label-1);
|
||||
inum[label]=size(code)-2;
|
||||
}
|
||||
}
|
||||
if(size(stack)){
|
||||
die("lack ]");
|
||||
return;
|
||||
}
|
||||
len=size(code);
|
||||
for(pc=0;pc<len;pc+=1)
|
||||
funcs[code[pc]]();
|
||||
return;
|
||||
}
|
||||
|
||||
bf(mandelbrot);
|
||||
248
test/bfconvertor.nas
Normal file
248
test/bfconvertor.nas
Normal file
@@ -0,0 +1,248 @@
|
||||
import("lib.nas");
|
||||
|
||||
var mandelbrot=
|
||||
"[A mandelbrot set fractal viewer in brainf*** written by Erik Bosman]
|
||||
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[
|
||||
>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+
|
||||
<<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+[>>>>>>[>>>>>>>[-]>>]<<<<<<<<<[<<<<<<<<<]>>
|
||||
>>>>>[-]+<<<<<<++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<+++++++[-[->>>
|
||||
>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[[-]>>>>>>[>>>>>
|
||||
>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>
|
||||
[>>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<
|
||||
<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>+++++++++++++++[[
|
||||
>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[
|
||||
>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[
|
||||
-<<+>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<
|
||||
<<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<
|
||||
[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>
|
||||
>>>>[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+
|
||||
<<<<<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>
|
||||
>>>>>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<
|
||||
+>>>>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<
|
||||
<]<+<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>
|
||||
>>>>>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
|
||||
>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<
|
||||
<<<]>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<
|
||||
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->
|
||||
>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<
|
||||
<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++++++++++++++++
|
||||
+++++++>>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>[<<<<<<<+<[-<+>>>>+<<[-]]>[-<<[->+>>>-
|
||||
<<<<]>>>]>>>>>>>>>>>>>[>>[-]>[-]>[-]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>>>>>>[>>>>>
|
||||
[-<<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>[-<<<<<<<<
|
||||
<+>>>>>>>>>]>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>>]+>[-
|
||||
]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>>>>>>>]<<<
|
||||
<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+>>]<
|
||||
<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[->>>>
|
||||
>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-]<->>>
|
||||
[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<
|
||||
<<<<+>>>>>]<<<<<[->>>>>+<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+>>>>>>>>
|
||||
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+
|
||||
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
|
||||
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
|
||||
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
|
||||
[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>
|
||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++
|
||||
+++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-<<<<<<<+
|
||||
>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[
|
||||
-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>>]>[-<<<<<<[->>>>>+<++<<<<]>>>>>[-<
|
||||
<<<<+>>>>>]<->+>]<[->+<]<<<<<[->>>>>+<<<<<]>>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<
|
||||
[->>>>->>>>>[>>[-<<->>]+<<[->>->[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]
|
||||
+>>>>>>[>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<<<<<<<<<<[<<<<<
|
||||
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<
|
||||
[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<
|
||||
<<<+<[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<
|
||||
<<<<<+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<
|
||||
<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+<]>>>>>>>>]<<<
|
||||
<<<<<+<[>[->>>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>[->>>>+<<<<]>]<[->>>>-<<<<<<<
|
||||
<<<<<<<+>>>>>>>>>>]<]>>[->>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>>+<<<<
|
||||
]<<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>>>>>>>>>]<<<<<<<<<
|
||||
[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<<<<<<
|
||||
+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<<<<<<
|
||||
<<<<<]]>[-]>>[-]>[-]>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<
|
||||
<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[
|
||||
[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+
|
||||
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>
|
||||
[-<<+>>]<<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<
|
||||
<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[
|
||||
>[-]<->>>[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[
|
||||
>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>
|
||||
>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>[-]>>>>+++++++++++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<
|
||||
<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<
|
||||
<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-
|
||||
<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>
|
||||
>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>>>
|
||||
[-<<<->>>]<<<[->>>+<<<]>>>>>>>>]<<<<<<<<+<[>[->+>[-<-<<<<<<<<<<+>>>>>>>>>>>>[-<<
|
||||
+>>]<]>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<<<]>>[-<+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<]>
|
||||
[-<<+>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>
|
||||
>>>>>>]<<<<<<<<+<[>[->+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>[-<+>]>]<[-<-<<<<<<<<<<+>>>>
|
||||
>>>>>>>]<<]>>>[-<<+>[-<-<<<<<<<<<<+>>>>>>>>>>>]>]<[-<+>]<<<<<<<<<<<<]>>>>>+<<<<<
|
||||
]>>>>>>>>>[>>>[-]>[-]>[-]>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>>>[-<<<<<
|
||||
<+>>>>>>]<<<<<<[->>>>>>+<<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>
|
||||
>]>>[-<<<<<<<[->>>>>+<++<<<<]>>>>>[-<<<<<+>>>>>]<->+>>]<<[->>+<<]<<<<<[->>>>>+<<
|
||||
<<<]+>>>>[-<<<<->>>>]+<<<<[->>>>->>>>>[>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<
|
||||
<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>[-<<->>]+<<[->>->[-<<<+>>>]<
|
||||
<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<
|
||||
<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+
|
||||
<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>[->>>+<<<]>]<[->>>-
|
||||
<<<<<<<<<<<<<+>>>>>>>>>>]<]>>[->>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>+<<<
|
||||
]<<<<<<<<<<<]>>>>>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]]>>>>[-<<<<+>
|
||||
>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<<[->>>-
|
||||
<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[
|
||||
->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>
|
||||
>>]<<<<[->>>>+>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>[>>>>>>
|
||||
>>>]<<<<<<<<<[>[->>>>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<
|
||||
<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<
|
||||
<<<<]]>>>>>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>[-<<<<+
|
||||
>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<+>>>>>
|
||||
]<<<<<[->>>>>+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
|
||||
>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>
|
||||
>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[-<<+
|
||||
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
|
||||
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
|
||||
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
|
||||
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<
|
||||
<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>
|
||||
>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<+>>>
|
||||
>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+
|
||||
<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>
|
||||
>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>
|
||||
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<<<<]
|
||||
>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<
|
||||
]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->>>+<
|
||||
<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>
|
||||
>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>->>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>]<<+>>>>[-<<<<
|
||||
->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[-<<<<<<<.>>>>>>>]<<<[-]>[-]>[-]>[-]>[-]>[-]>>>[
|
||||
>[-]>[-]>[-]>[-]>[-]>[-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]>>>>]<<<<<<<<<
|
||||
[<<<<<<<<<]>+++++++++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+>>>>>>>>>+<<<<<<<<
|
||||
<<<<<<[<<<<<<<<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+[-]>>[>>>>>>>>>]<<<<<
|
||||
<<<<[>>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<[<<<<<<<<<]>>>>>>>[-]+>>>]<<<<
|
||||
<<<<<<]]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+>>[>+>>>>[-<<<<->>>>]<<<<[->>>
|
||||
>+<<<<]>>>>>>>>]<<+<<<<<<<[>>>>>[->>+<<]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<
|
||||
<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<<<<<[->>>>>>+<<<<<<]<
|
||||
+<<<<<<<<<]>>>>>>>-<<<<[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>->>[>>
|
||||
>>>[->>+<<]>>>>]<<<<<<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<
|
||||
<<<<[->>>>>>+<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+<<<
|
||||
<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>->>[-<<<<<<<+>>>>>>>]<<<<
|
||||
<<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>[-<
|
||||
<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<
|
||||
<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<
|
||||
<<[<<<<<<<<<]>>>>[-]<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>-<<<<<[<<<<<<<
|
||||
<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++[-[->>>>>>>>
|
||||
>+<<<<<<<<<]>>>>>>>>>]>>>>>+>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<
|
||||
<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+[-]>[>>>>>>>>>]<<<<<<<<<[>>>>>>>>[-<<<<<<<+>>>>>>
|
||||
>]<<<<<<<[->>>>>>>+<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<
|
||||
<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+>[>+>>>>>[-<<<<<->>>>>]<<<<<[->>>>>+<<<<<]>>>>>>
|
||||
>>]<+<<<<<<<<[>>>>>>[->>+<<]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<-
|
||||
>>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<
|
||||
<<<]>>>>>>>>-<<<<<[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>->[>>>
|
||||
>>>[->>+<<]>>>]<<<<<<<<<[>[-]<->>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<
|
||||
<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>
|
||||
+>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<->>>>>>]+<
|
||||
<<<<<[->>>>>>->>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<
|
||||
<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>
|
||||
-<<[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>
|
||||
>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<++++
|
||||
+[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>->>>>>>>>>>>>>>>>>>>>>>>>>>>-<<<<<<[<<<<
|
||||
<<<<<]]>>>]";
|
||||
|
||||
var bf=func(program)
|
||||
{
|
||||
var stack=[];
|
||||
var len=size(program);
|
||||
var f="#automatically generated by bfconvertor.nas\nimport('lib.nas');\nvar ptr=0;\nvar paper=[];\nsetsize(paper,131072);\n";
|
||||
for(var i=0;i<len;i+=1)
|
||||
{
|
||||
var c=chr(program[i]);
|
||||
if(c=='+' or c=='-')
|
||||
{
|
||||
var cnt=0;
|
||||
for(;i<len;i+=1)
|
||||
{
|
||||
if(chr(program[i])=='+')
|
||||
cnt+=1;
|
||||
elsif(chr(program[i])=='-')
|
||||
cnt-=1;
|
||||
elsif(chr(program[i])!='\n')
|
||||
{
|
||||
i-=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(cnt!=0)
|
||||
for(var j=0;j<size(stack);j+=1)
|
||||
f~='\t';
|
||||
if(cnt>0)
|
||||
f~="paper[ptr]+="~cnt~";\n";
|
||||
elsif(cnt<0)
|
||||
f~="paper[ptr]-="~(-cnt)~";\n";
|
||||
}
|
||||
elsif(c=='<' or c=='>')
|
||||
{
|
||||
var cnt=0;
|
||||
for(;i<len;i+=1)
|
||||
{
|
||||
if(chr(program[i])=='>')
|
||||
cnt+=1;
|
||||
elsif(chr(program[i])=='<')
|
||||
cnt-=1;
|
||||
elsif(chr(program[i])!='\n')
|
||||
{
|
||||
i-=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(cnt!=0)
|
||||
for(var j=0;j<size(stack);j+=1)
|
||||
f~='\t';
|
||||
if(cnt>0)
|
||||
f~="ptr+="~cnt~";\n";
|
||||
elsif(cnt<0)
|
||||
f~="ptr-="~(-cnt)~";\n";
|
||||
}
|
||||
elsif(c==',')
|
||||
{
|
||||
for(var j=0;j<size(stack);j+=1)
|
||||
f~='\t';
|
||||
f~="paper[ptr]=input();\n";
|
||||
}
|
||||
elsif(c=='.')
|
||||
{
|
||||
for(var j=0;j<size(stack);j+=1)
|
||||
f~='\t';
|
||||
f~="print(chr(paper[ptr]));\n";
|
||||
}
|
||||
elsif(c=='[')
|
||||
{
|
||||
for(var j=0;j<size(stack);j+=1)
|
||||
f~='\t';
|
||||
f~="while(paper[ptr])\n";
|
||||
for(var j=0;j<size(stack);j+=1)
|
||||
f~='\t';
|
||||
f~="{\n";
|
||||
append(stack,0);
|
||||
}
|
||||
elsif(c==']')
|
||||
{
|
||||
if(!size(stack))
|
||||
{
|
||||
println("lack [");
|
||||
return;
|
||||
}
|
||||
pop(stack);
|
||||
for(var j=0;j<size(stack);j+=1)
|
||||
f~='\t';
|
||||
f~="}\n";
|
||||
}
|
||||
}
|
||||
if(size(stack))
|
||||
{
|
||||
println("lack ]");
|
||||
return;
|
||||
}
|
||||
io.fout("mandel.nas",f);
|
||||
return;
|
||||
}
|
||||
|
||||
bf(mandelbrot);
|
||||
56
test/bfs.nas
56
test/bfs.nas
@@ -1,65 +1,65 @@
|
||||
import("lib.nas");
|
||||
import("queue.nas");
|
||||
import("stl/queue.nas");
|
||||
|
||||
rand(time(0));
|
||||
|
||||
var pixel=[' ','#','.','*'];
|
||||
var map=[];
|
||||
for(var i=0;i<10;i+=1)
|
||||
{
|
||||
append(map,[]);
|
||||
for(var j=0;j<10;j+=1)
|
||||
for(var j=0;j<20;j+=1)
|
||||
append(map[i],(rand()>0.7));
|
||||
}
|
||||
|
||||
var prt=func()
|
||||
{
|
||||
var s="";
|
||||
var s="\e[0;0H+--------------------+\n";
|
||||
for(var i=0;i<10;i+=1)
|
||||
{
|
||||
for(var j=0;j<10;j+=1)
|
||||
s~=map[i][j];
|
||||
s~='\n';
|
||||
s~="|";
|
||||
for(var j=0;j<20;j+=1)
|
||||
s~=pixel[map[i][j]];
|
||||
s~='|\n';
|
||||
}
|
||||
s~='+--------------------+\n';
|
||||
print(s);
|
||||
unix.sleep(1/144);
|
||||
}
|
||||
|
||||
var bfs=func(begin,end)
|
||||
{
|
||||
var move=[[1,0],[0,1],[-1,0],[0,-1]];
|
||||
var queue=new_queue();
|
||||
queue_push(queue,begin);
|
||||
map[begin[0]][begin[1]]=3;
|
||||
while(!queue_empty(queue))
|
||||
var que=queue();
|
||||
que.push(begin);
|
||||
map[begin[0]][begin[1]]=2;
|
||||
map[end[0]][end[1]]=0;
|
||||
while(!que.empty())
|
||||
{
|
||||
var vertex=queue_front(queue);
|
||||
queue_pop(queue);
|
||||
var vertex=que.front();
|
||||
que.pop();
|
||||
foreach(var i;move)
|
||||
{
|
||||
var x=vertex[0]+i[0];
|
||||
var y=vertex[1]+i[1];
|
||||
if(x==end[0] and y==end[1])
|
||||
{
|
||||
map[x][y]='*';
|
||||
map[x][y]=3;
|
||||
prt();
|
||||
print("reached.\n");
|
||||
return;
|
||||
}
|
||||
if(0<=x and x<10 and 0<=y and y<10 and map[x][y]==0)
|
||||
if(0<=x and x<10 and 0<=y and y<20 and map[x][y]==0)
|
||||
{
|
||||
queue_push(queue,[x,y]);
|
||||
map[x][y]=3;
|
||||
que.push([x,y]);
|
||||
map[x][y]=2;
|
||||
}
|
||||
}
|
||||
prt();
|
||||
}
|
||||
print("cannot reach.");
|
||||
print("cannot reach.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
prt();
|
||||
var x=num(input());
|
||||
var y=num(input());
|
||||
var begin=[x,y];
|
||||
x=num(input());
|
||||
y=num(input());
|
||||
var end=[x,y];
|
||||
bfs(begin,end);
|
||||
prt();
|
||||
if(os.platform()=="windows")
|
||||
system("chcp 65001");
|
||||
print("\ec");
|
||||
bfs([0,0],[9,19]);
|
||||
1
test/bigloop.nas
Normal file
1
test/bigloop.nas
Normal file
@@ -0,0 +1 @@
|
||||
for(var i=0;i<4e6;i+=1);
|
||||
44
test/bp.nas
44
test/bp.nas
@@ -1,17 +1,14 @@
|
||||
import("lib.nas");
|
||||
|
||||
rand(time(0));
|
||||
|
||||
var new_neuron=func()
|
||||
{
|
||||
var neuron={
|
||||
return {
|
||||
in:0,
|
||||
out:0,
|
||||
w:[],
|
||||
bia:0,
|
||||
diff:0
|
||||
};
|
||||
return neuron;
|
||||
}
|
||||
|
||||
var sigmoid=func(x)
|
||||
@@ -24,12 +21,9 @@ var diffsigmoid=func(x)
|
||||
return x*(1-x);
|
||||
}
|
||||
|
||||
var inum=2;
|
||||
var hnum=4;
|
||||
var onum=1;
|
||||
var lr=0.1;
|
||||
var (inum,hnum,onum,lr)=(2,4,1,0.1);
|
||||
var training_set=[[0,0],[0,1],[1,0],[1,1]];
|
||||
var expect=[[0],[1],[1],[0]];
|
||||
var expect=[0,1,1,0];
|
||||
|
||||
var hidden=[];
|
||||
for(var i=0;i<hnum;i+=1)
|
||||
@@ -89,19 +83,12 @@ var run=func(vec)
|
||||
}
|
||||
var get_error=func(x)
|
||||
{
|
||||
var error=0;
|
||||
var expect_set=expect[x];
|
||||
for(var i=0;i<onum;i+=1)
|
||||
error+=(expect_set[i]-output[i].out)*(expect_set[i]-output[i].out);
|
||||
error*=0.5;
|
||||
return error;
|
||||
return 0.5*(expect[x]-output[0].out)*(expect[x]-output[0].out);
|
||||
}
|
||||
var backward=func(x)
|
||||
{
|
||||
var input=training_set[x];
|
||||
var expect_set=expect[x];
|
||||
for(var i=0;i<onum;i+=1)
|
||||
output[i].diff=(expect_set[i]-output[i].out)*diffsigmoid(output[i].in);
|
||||
output[0].diff=(expect[x]-output[0].out)*diffsigmoid(output[0].in);
|
||||
for(var i=0;i<hnum;i+=1)
|
||||
{
|
||||
hidden[i].diff=0;
|
||||
@@ -124,9 +111,8 @@ var backward=func(x)
|
||||
return;
|
||||
}
|
||||
|
||||
var cnt=0;
|
||||
var error=1e8;
|
||||
while(error>0.01)
|
||||
var (cnt,error)=(0,100);
|
||||
while(error>0.0005)
|
||||
{
|
||||
error=0;
|
||||
for(var i=0;i<4;i+=1)
|
||||
@@ -136,18 +122,10 @@ while(error>0.01)
|
||||
backward(i);
|
||||
}
|
||||
cnt+=1;
|
||||
print('epoch ',cnt,':',error);
|
||||
}
|
||||
print('\afinished.');
|
||||
while(1)
|
||||
print('finished after ',cnt,' epoch.\n');
|
||||
foreach(var v;training_set)
|
||||
{
|
||||
var vec=[];
|
||||
var command=input();
|
||||
if(command=="exit")break;
|
||||
append(vec,num(command));
|
||||
command=input();
|
||||
if(command=="exit")break;
|
||||
append(vec,num(command));
|
||||
run(vec);
|
||||
print(output[0].out);
|
||||
run(v);
|
||||
print(v,': ',output[0].out,'\n');
|
||||
}
|
||||
110
test/calc.nas
Normal file
110
test/calc.nas
Normal file
@@ -0,0 +1,110 @@
|
||||
var source=[
|
||||
"main.cpp ",
|
||||
"nasal_err.h ",
|
||||
"nasal_ast.h ",
|
||||
"nasal_builtin.h ",
|
||||
"nasal_codegen.h ",
|
||||
"nasal_opt.h ",
|
||||
"nasal_gc.h ",
|
||||
"nasal_import.h ",
|
||||
"nasal_lexer.h ",
|
||||
"nasal_parse.h ",
|
||||
"nasal_vm.h ",
|
||||
"nasal_dbg.h ",
|
||||
"nasal.h "
|
||||
];
|
||||
|
||||
var lib=[
|
||||
"stl/file.nas ",
|
||||
"stl/lib.nas ",
|
||||
"stl/list.nas ",
|
||||
"stl/module.nas ",
|
||||
"stl/queue.nas ",
|
||||
"stl/result.nas ",
|
||||
"stl/sort.nas ",
|
||||
"stl/stack.nas "
|
||||
];
|
||||
|
||||
var testfile=[
|
||||
"test/ascii-art.nas ",
|
||||
"test/auto_crash.nas ",
|
||||
"test/bf.nas ",
|
||||
"test/bfcolored.nas ",
|
||||
"test/bfconvertor.nas ",
|
||||
"test/bfs.nas ",
|
||||
"test/bigloop.nas ",
|
||||
"test/bp.nas ",
|
||||
"test/calc.nas ",
|
||||
"test/choice.nas ",
|
||||
"test/class.nas ",
|
||||
"test/diff.nas ",
|
||||
"test/exception.nas ",
|
||||
"test/fib.nas ",
|
||||
"test/filesystem.nas ",
|
||||
"test/hexdump.nas ",
|
||||
"test/json.nas ",
|
||||
"test/leetcode1319.nas ",
|
||||
"test/lexer.nas ",
|
||||
"test/life.nas ",
|
||||
"test/loop.nas ",
|
||||
"test/mandel.nas ",
|
||||
"test/mandelbrot.nas ",
|
||||
"test/md5.nas ",
|
||||
"test/md5compare.nas ",
|
||||
"test/module_test.nas ",
|
||||
"test/nasal_test.nas ",
|
||||
"test/pi.nas ",
|
||||
"test/prime.nas ",
|
||||
"test/props_sim.nas ",
|
||||
"test/props.nas ",
|
||||
"test/qrcode.nas ",
|
||||
"test/quick_sort.nas ",
|
||||
"test/scalar.nas ",
|
||||
"test/snake.nas ",
|
||||
"test/tetris.nas ",
|
||||
"test/trait.nas ",
|
||||
"test/turingmachine.nas",
|
||||
"test/utf8chk.nas ",
|
||||
"test/wavecollapse.nas ",
|
||||
"test/ycombinator.nas "
|
||||
];
|
||||
|
||||
var module=[
|
||||
"module/fib.cpp ",
|
||||
"module/keyboard.cpp ",
|
||||
"module/libfib.nas ",
|
||||
"module/libkey.nas "
|
||||
];
|
||||
|
||||
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 (cnt,len,ch)=(0,size(s),c[0]);
|
||||
for(var i=0;i<len;i+=1)
|
||||
cnt+=(s[i]==ch);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
var calc=func(codetype,files){
|
||||
println(codetype);
|
||||
var (bytes,line,semi,line_cnt,semi_cnt)=(0,0,0,0,0);
|
||||
forindex(var i;files){
|
||||
var s=io.fin(getname(files[i]));
|
||||
(line_cnt,semi_cnt)=(count(s,'\n'),count(s,';'));
|
||||
println(files[i],'| ',line_cnt,' \tline | ',semi_cnt,' \tsemi');
|
||||
bytes+=size(s);
|
||||
line+=line_cnt;
|
||||
semi+=semi_cnt;
|
||||
}
|
||||
println('total: | ',line,' \tline | ',semi,' \tsemi');
|
||||
println(' | ',bytes,'\tbytes| ',int(bytes/1024),' \tkb');
|
||||
}
|
||||
|
||||
calc("source code:",source);
|
||||
calc("lib:",lib);
|
||||
calc("test file:",testfile);
|
||||
calc("module:",module);
|
||||
@@ -1,30 +0,0 @@
|
||||
id[0] and id[1];
|
||||
1 or 2;
|
||||
"str" ==1;
|
||||
1*1/1+1;
|
||||
2*3*4/1-2+3;
|
||||
1-1+20-2*10;
|
||||
1+s1*(s2+s3[0])-1;
|
||||
var e=1+s1*(s2+s3[0])-1;
|
||||
id;
|
||||
"str";
|
||||
id(id);
|
||||
id("str",1,1);
|
||||
var e=1;
|
||||
var x=10*2-20;
|
||||
var id;
|
||||
var id=[1,2,3,4];
|
||||
var id={id:"str"};
|
||||
id();
|
||||
id.id();
|
||||
id.id.id();
|
||||
id[0].id.id(id,"str",1,2,3,4).id[10];
|
||||
id(0)[1].id;
|
||||
var hash={
|
||||
h:"hello",
|
||||
parent:[id],
|
||||
};
|
||||
function_test([1,2,3,4,55],1,2,3,{str:"str"});
|
||||
var (i,j,k,l,m,n) =[1,2,3,4,5,6];
|
||||
(var i,j,k)=[1,2,3];
|
||||
e=e[1:][0];
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
var condition_true=1;
|
||||
var condition_false=0;
|
||||
if(condition_true)
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
if(this_token.type==__if)
|
||||
{
|
||||
parse.push(this_token);
|
||||
return;
|
||||
}
|
||||
elsif(this_token.type==__elsif)
|
||||
{
|
||||
parse.push(this_token);
|
||||
return;
|
||||
}
|
||||
else if(this_token.type!=__else)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
elsif(this_token.type==__elsif)
|
||||
{
|
||||
parse.push(this_token);
|
||||
return;
|
||||
}
|
||||
elsif(this_token.type==__elsif)
|
||||
{
|
||||
parse.push(this_token);
|
||||
return;
|
||||
}
|
||||
else if(this==(1+2+3*1))
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
parse.push(this_token);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!id)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
62
test/class.nas
Normal file
62
test/class.nas
Normal file
@@ -0,0 +1,62 @@
|
||||
var student=func(n,a){
|
||||
return {
|
||||
print_info:func println(n,' ',a),
|
||||
set_age: func(age) a=age,
|
||||
get_age: func return a,
|
||||
set_name: func(name) n=name,
|
||||
get_name: func return n
|
||||
};
|
||||
}
|
||||
var s=student('valk',24);
|
||||
s.print_info();
|
||||
println(s.get_age(),' ',s.get_name());
|
||||
s.set_age(20);
|
||||
s.set_name('aluo');
|
||||
s.print_info();
|
||||
println(s.get_age(),' ',s.get_name());
|
||||
s.set_age(20);
|
||||
s.set_name('Sidi Liang');
|
||||
s.print_info();
|
||||
println(s.get_age(),' ',s.get_name());
|
||||
# flightgear nasal-console cannot use this kind of object initializing
|
||||
var m=func(){
|
||||
var (_1,_2)=(0,1);
|
||||
return {
|
||||
a:func(){
|
||||
print(_1,' ',_2,'\n');
|
||||
},
|
||||
b:func(x){
|
||||
_1=x;
|
||||
},
|
||||
c:func(x){
|
||||
_2=x;
|
||||
},
|
||||
d:func(x){
|
||||
return func{
|
||||
print(_1,' ',_2,' ',x,'\n');
|
||||
};
|
||||
},
|
||||
g:func(x){
|
||||
var y=x;
|
||||
return func{
|
||||
print(_1,' ',_2,' ',x,' ',y,'\n');
|
||||
}
|
||||
},
|
||||
h:func(){
|
||||
return func(x){
|
||||
_1=x;
|
||||
}
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
m.a(); # 0 1
|
||||
m.b(2048);
|
||||
m.c(1024);
|
||||
var a=m.d(-1);
|
||||
var b=m.g(1);
|
||||
a(); # 2048 1024 -1
|
||||
b(); # 2048 1024 1 1
|
||||
|
||||
m.h()(2147483647);
|
||||
m.a();# 2147483647 1024
|
||||
129
test/diff.nas
Normal file
129
test/diff.nas
Normal file
@@ -0,0 +1,129 @@
|
||||
var myers=func(src,dst,show_table=0){
|
||||
(src,dst)=(split("\n",src),split("\n",dst));
|
||||
append(src,"");
|
||||
append(dst,"");
|
||||
var (src_len,dst_len)=(size(src),size(dst));
|
||||
|
||||
var mat=[];
|
||||
setsize(mat,dst_len*src_len);
|
||||
forindex(var i;mat){
|
||||
mat[i]=0;
|
||||
}
|
||||
var visited=[];
|
||||
setsize(visited,dst_len*src_len);
|
||||
forindex(var i;visited){
|
||||
visited[i]=0;
|
||||
}
|
||||
|
||||
forindex(var y;dst)
|
||||
forindex(var x;src)
|
||||
mat[y*src_len+x]=(src[x]==dst[y]);
|
||||
|
||||
if(show_table){
|
||||
var curve=[
|
||||
["+---",
|
||||
"| "],
|
||||
[
|
||||
"+---",
|
||||
"| \\ "]
|
||||
];
|
||||
var s="";
|
||||
forindex(var y;dst){
|
||||
forindex(var t;curve[0]){
|
||||
forindex(var x;src){
|
||||
s~=curve[mat[y*src_len+x]][t];
|
||||
}
|
||||
s~=["+","|"][t]~"\n";
|
||||
}
|
||||
}
|
||||
forindex(var i;src)
|
||||
s~="+---";
|
||||
print(s~"+\n");
|
||||
}
|
||||
|
||||
var total=[];
|
||||
var path=[];
|
||||
var vec=[[0,0,-1]];
|
||||
visited[0]=1;
|
||||
while(size(vec)){
|
||||
append(total,vec);
|
||||
var tmp=[];
|
||||
forindex(var i;vec){
|
||||
var elem=vec[i];
|
||||
var (x,y)=(elem[1],elem[0]);
|
||||
|
||||
# find solution
|
||||
if(x==src_len-1 and y==dst_len-1){
|
||||
append(path,vec[i]);
|
||||
for(var (prev,iter)=(elem[2],size(total)-1);iter>0;iter-=1){
|
||||
var t=total[iter-1][prev];
|
||||
append(path,t);
|
||||
prev=t[2];
|
||||
}
|
||||
|
||||
if(show_table){
|
||||
for(var t=size(path)-1;t>=0;t-=1)
|
||||
print("("~path[t][1]~","~path[t][0]~")",t==0?"":"->");
|
||||
println();
|
||||
}
|
||||
|
||||
# reverse path
|
||||
for(var t=0;t<size(path)/2;t+=1)
|
||||
(path[t],path[-1-t])=(path[-1-t],path[t]);
|
||||
# print diff
|
||||
for(var t=1;t<size(path);t+=1){
|
||||
var (prev_x,prev_y)=(path[t-1][1],path[t-1][0]);
|
||||
var (x,y)=(path[t][1],path[t][0]);
|
||||
var (sub_x,sub_y)=(x-prev_x,y-prev_y);
|
||||
if(sub_x==1 and sub_y==1){
|
||||
if(show_table)
|
||||
println(" ",src[prev_x]);
|
||||
}elsif(sub_x==1 and sub_y==0){
|
||||
println("\e[31m - ",src[prev_x],"\e[0m");
|
||||
}elsif(sub_x==0 and sub_y==1){
|
||||
println("\e[32m + ",dst[prev_y],"\e[0m");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# do bfs
|
||||
if(mat[y*src_len+x]==1){
|
||||
if(x+1<src_len and y+1<dst_len and visited[(y+1)*src_len+x+1]==0){
|
||||
append(tmp,[y+1,x+1,i]);
|
||||
visited[(y+1)*src_len+x+1]=1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(x+1<src_len and visited[y*src_len+x+1]==0){
|
||||
append(tmp,[y,x+1,i]);
|
||||
visited[y*src_len+x+1]=1;
|
||||
}
|
||||
if(y+1<dst_len and visited[(y+1)*src_len+x]==0){
|
||||
append(tmp,[y+1,x,i]);
|
||||
visited[(y+1)*src_len+x]=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
vec=tmp;
|
||||
}
|
||||
}
|
||||
|
||||
func(diff){
|
||||
diff(
|
||||
"var a=0;\nvar b=1;\nprint(\"hello \",a);\nvar c=2;\nc=[];\nvar d=3;\nvar l=list();\nvar q=queue();\n",
|
||||
"var a=0;\nvar b=1;\nb=[];\nprintln(\"hello \",a);\nvar c=2;\nvar d=3;\nprintln(\"hello world!\");\nvar l=list();\nvar q=queue();\n",
|
||||
1
|
||||
);
|
||||
print("\n");
|
||||
diff(
|
||||
"A\nB\nC\nA\nB\nB\nA\n",
|
||||
"C\nB\nA\nB\nA\nC\n",
|
||||
1
|
||||
);
|
||||
print("\n");
|
||||
diff(
|
||||
io.fin("test/bf.nas"),
|
||||
io.fin("test/bfcolored.nas")
|
||||
);
|
||||
}(myers);
|
||||
2044
test/efb.nas
2044
test/efb.nas
File diff suppressed because it is too large
Load Diff
37
test/exception.nas
Normal file
37
test/exception.nas
Normal file
@@ -0,0 +1,37 @@
|
||||
var ResultTrait={
|
||||
Ok:func(val){
|
||||
me.ok=val;
|
||||
me.flag=0;
|
||||
return me;
|
||||
},
|
||||
Err:func(info){
|
||||
me.err=info;
|
||||
me.flag=1;
|
||||
return me;
|
||||
},
|
||||
unwrap:func(){
|
||||
if(me.flag)
|
||||
die(me.err);
|
||||
return me.ok;
|
||||
}
|
||||
};
|
||||
|
||||
var Result=func(){
|
||||
return{
|
||||
ok:nil,
|
||||
err:"",
|
||||
flag:1,
|
||||
parents:[ResultTrait]
|
||||
};
|
||||
};
|
||||
|
||||
var a=func(){
|
||||
return Result().Ok("hello world");
|
||||
}
|
||||
|
||||
var b=func(){
|
||||
return Result().Err("exception test");
|
||||
}
|
||||
|
||||
println(a().unwrap());
|
||||
b().unwrap();
|
||||
8
test/fib.nas
Normal file
8
test/fib.nas
Normal file
@@ -0,0 +1,8 @@
|
||||
var fib=func(x)
|
||||
{
|
||||
if(x<2) return x;
|
||||
return fib(x-1)+fib(x-2);
|
||||
}
|
||||
for(var i=0;i<31;i+=1)
|
||||
print(fib(i),'\n');
|
||||
|
||||
34
test/filesystem.nas
Normal file
34
test/filesystem.nas
Normal file
@@ -0,0 +1,34 @@
|
||||
var fd=io.open("test/filesystem.nas");
|
||||
while((var line=io.readln(fd))!=nil)
|
||||
println(line);
|
||||
io.close(fd);
|
||||
println(io.stat("test/filesystem.nas"));
|
||||
|
||||
var dd=unix.opendir("test");
|
||||
while(var name=unix.readdir(dd))
|
||||
println(name);
|
||||
unix.closedir(dd);
|
||||
|
||||
var files=func(dir){
|
||||
var dd=unix.opendir(dir);
|
||||
var res=[];
|
||||
while(var n=unix.readdir(dd))
|
||||
append(res,n);
|
||||
unix.closedir(dd);
|
||||
return res;
|
||||
}
|
||||
var prt=func(s,path){
|
||||
foreach(var i;files(path)){
|
||||
print(s,i);
|
||||
if(unix.isdir(path~'/'~i)){
|
||||
print(' <dir>\n');
|
||||
if(i!='.' and i!='..')
|
||||
prt(s~' |',path~'/'~i);
|
||||
}
|
||||
elsif(unix.isfile(path~'/'~i))
|
||||
print(" <file>\n");
|
||||
else
|
||||
print(' <unknown>\n');
|
||||
}
|
||||
}
|
||||
prt('',".");
|
||||
210
test/final.nas
210
test/final.nas
@@ -1,210 +0,0 @@
|
||||
var smartScreen = canvas.new({
|
||||
"name": "smartScreen", # The name is optional but allow for easier identification
|
||||
"size": [2048, 2048], # Size of the underlying texture (should be a power of 2, required) [Resolution]
|
||||
"view": [768, 768], # Virtual resolution (Defines the coordinate system of the canvas [Dimensions]
|
||||
# which will be stretched the size of the texture, required)
|
||||
"mipmapping": 1 # Enable mipmapping (optional)
|
||||
});
|
||||
|
||||
smartScreen.addPlacement({"node": "screen", "texture": "screen.jpeg"});
|
||||
var group = smartScreen.createGroup();
|
||||
|
||||
# Create a text element and set some values
|
||||
var text = group.createChild("text", "optional-id-for element")
|
||||
.setTranslation(10, 20) # The origin is in the top left corner
|
||||
.setAlignment("left-center") # All values from osgText are supported (see $FG_ROOT/Docs/README.osgtext)
|
||||
.setFont("LiberationFonts/LiberationSans-Regular.ttf") # Fonts are loaded either from $AIRCRAFT_DIR/Fonts or $FG_ROOT/Fonts
|
||||
.setFontSize(14, 1.2) # Set fontsize and optionally character aspect ratio
|
||||
.setColor(1,0,0) # Text color
|
||||
.setText("This is a text element");
|
||||
text.hide();
|
||||
text.setText("SELF TEST NORMAL").show();
|
||||
|
||||
|
||||
|
||||
var ui_root = smartScreen.createGroup();
|
||||
var vbox = canvas.VBoxLayout.new();
|
||||
smartScreen.setLayout(vbox);
|
||||
|
||||
|
||||
var button_onl = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}).setText("Online OSM").listen("clicked", func showOnlineMap());
|
||||
var button_offl = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}).setText("Offline OSM").listen("clicked", func showOfflineMap());
|
||||
button_onl.setSizeHint([32, 128]);
|
||||
button_offl.setSizeHint([32, 128]);
|
||||
|
||||
var label = canvas.gui.widgets.Label.new(ui_root, canvas.style, {});
|
||||
|
||||
var button_box = canvas.HBoxLayout.new();
|
||||
button_box.addItem(button_onl);
|
||||
button_box.addItem(button_offl);
|
||||
button_box.addItem(label);
|
||||
button_box.addStretch(1);
|
||||
|
||||
vbox.addItem(button_box);
|
||||
vbox.addStretch(1);
|
||||
|
||||
|
||||
var showOnlineMap = func(){
|
||||
TestMap.show();
|
||||
g.hide();
|
||||
label.setText("Online Mode");
|
||||
}
|
||||
|
||||
|
||||
var showOfflineMap = func(){
|
||||
TestMap.hide();
|
||||
g.show();
|
||||
label.setText("Offline Mode");
|
||||
}
|
||||
|
||||
|
||||
# Online Map using MapStructure
|
||||
var TestMap = smartScreen.createGroup().createChild("map");
|
||||
TestMap.setTranslation(smartScreen.get("view[0]")/2,smartScreen.get("view[1]")/2);
|
||||
|
||||
|
||||
var ctrl_ns = canvas.Map.Controller.get("Aircraft position");
|
||||
var source = ctrl_ns.SOURCES["map-dialog"];
|
||||
if (source == nil) {
|
||||
# TODO: amend
|
||||
var source = ctrl_ns.SOURCES["map-dialog"] = {
|
||||
getPosition: func subvec(geo.aircraft_position().latlon(), 0, 2),# ? ? ?
|
||||
getAltitude: func getprop('/position/altitude-ft'),
|
||||
getHeading: func {
|
||||
if (me.aircraft_heading)
|
||||
getprop('/orientation/heading-deg');
|
||||
else
|
||||
0;
|
||||
},
|
||||
aircraft_heading: 1,
|
||||
};
|
||||
}
|
||||
setlistener("/sim/gui/dialogs/map-canvas/aircraft-heading-up", func(n){source.aircraft_heading = n.getBoolValue();}, 1);
|
||||
TestMap.setController("Aircraft position", "map-dialog");
|
||||
TestMap.setRange(1);
|
||||
|
||||
var r = func(name,vis=1,zindex=nil){return caller(0)[0];};
|
||||
# TODO: we'll need some z-indexing here, right now it's just random
|
||||
|
||||
foreach(var type; [r('APS')] ){
|
||||
TestMap.addLayer(factory: canvas.SymbolLayer, type_arg: type.name, visible: type.vis, priority: 2);
|
||||
}
|
||||
|
||||
foreach(var type; [ r('OSM')]) {
|
||||
TestMap.addLayer(factory: canvas.OverlayLayer,
|
||||
type_arg: type.name,
|
||||
visible: type.vis,
|
||||
priority: 1);
|
||||
}
|
||||
|
||||
|
||||
TestMap.hide();
|
||||
|
||||
# Offline map
|
||||
|
||||
var g = smartScreen.createGroup();
|
||||
var zoom = 15;
|
||||
var type = "intl";
|
||||
var tile_size = 256;
|
||||
|
||||
|
||||
var changeZoom = func(d)
|
||||
{
|
||||
zoom = math.max(2, math.min(19, zoom + d));
|
||||
updateTiles();
|
||||
}
|
||||
|
||||
# http://polymaps.org/docs/
|
||||
# https://github.com/simplegeo/polymaps
|
||||
# https://github.com/Leaflet/Leaflet
|
||||
|
||||
var maps_base = getprop("/sim/fg-home") ~ '/cache/maps';
|
||||
|
||||
var makePath =
|
||||
string.compileTemplate(maps_base ~ '/osm-{type}/{z}/{x}/{y}.jpg');
|
||||
var num_tiles = [4, 4];
|
||||
|
||||
var center_tile_offset = [(num_tiles[0]-1)/2, (num_tiles[1]-1)/ 2];
|
||||
|
||||
# simple aircraft icon at current position/center of the map
|
||||
g.createChild("path")
|
||||
.moveTo( tile_size*center_tile_offset[0]-10, tile_size*center_tile_offset[1])
|
||||
.horiz(20)
|
||||
.move(-10,-10)
|
||||
.vert(20)
|
||||
.set("stroke", "red")
|
||||
.set("stroke-width", 2)
|
||||
.set("z-index", 1);
|
||||
|
||||
# initialize the map by setting up
|
||||
# a grid of raster images
|
||||
|
||||
var tiles = setsize([], num_tiles[0]);
|
||||
for(var x=0; x<num_tiles[0]; x+=1)
|
||||
{
|
||||
tiles[x] = setsize([], num_tiles[1]);
|
||||
for(var y=0; y<num_tiles[1]; y+=1)
|
||||
tiles[x][y] = g.createChild("image", "map-tile");
|
||||
}
|
||||
|
||||
var last_tile = [-1,-1];
|
||||
var last_type = type;
|
||||
|
||||
# this is the callback that will be regularly called by the timer
|
||||
# to update the map
|
||||
var updateTiles = func()
|
||||
{
|
||||
# get current position
|
||||
var lat = getprop('/position/latitude-deg');
|
||||
var lon = getprop('/position/longitude-deg');
|
||||
|
||||
var n = math.pow(2, zoom);
|
||||
var offset = [n*((lon+180)/360)-center_tile_offset[0], (1-math.ln(math.tan(lat*math.pi/180)+1/math.cos(lat*math.pi/180))/math.pi)/2*n-center_tile_offset[1]];
|
||||
var tile_index = [int(offset[0]), int(offset[1])];
|
||||
|
||||
var ox = tile_index[0] - offset[0];
|
||||
var oy = tile_index[1] - offset[1];
|
||||
|
||||
for(var x = 0; x < num_tiles[0]; x += 1)
|
||||
for(var y = 0; y < num_tiles[1]; y += 1)
|
||||
tiles[x][y].setTranslation(int((ox + x) * tile_size + 0.5), int((oy + y) * tile_size + 0.5));
|
||||
|
||||
if( tile_index[0] != last_tile[0]
|
||||
or tile_index[1] != last_tile[1]
|
||||
or type != last_type )
|
||||
{
|
||||
for(var x = 0; x < num_tiles[0]; x += 1)
|
||||
for(var y = 0; y < num_tiles[1]; y += 1)
|
||||
{
|
||||
var pos = {
|
||||
z: zoom,
|
||||
x: int(offset[0] + x),
|
||||
y: int(offset[1] + y),
|
||||
type: type
|
||||
};
|
||||
|
||||
(func {
|
||||
var img_path = makePath(pos);
|
||||
var tile = tiles[x][y];
|
||||
print('loading ' ~ img_path);
|
||||
tile.set("src", img_path);
|
||||
})();
|
||||
# lambda
|
||||
}
|
||||
|
||||
last_tile = tile_index;
|
||||
last_type = type;
|
||||
}
|
||||
};
|
||||
|
||||
# set up a timer that will invoke updateTiles at 2-second intervals
|
||||
var update_timer = maketimer(2, updateTiles);
|
||||
# actually start the timer
|
||||
update_timer.start();
|
||||
|
||||
# set up default zoom level
|
||||
changeZoom(0);
|
||||
|
||||
#g.hide();
|
||||
|
||||
|
||||
643
test/final2.nas
643
test/final2.nas
@@ -1,643 +0,0 @@
|
||||
###############################################################################
|
||||
##
|
||||
## Nasal module for dual control over the multiplayer network.
|
||||
##
|
||||
## Copyright (C) 2007 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
|
||||
## This file is licensed under the GPL license version 2 or later.
|
||||
##
|
||||
###############################################################################
|
||||
## MP properties
|
||||
var lat_mpp = "position/latitude-deg";
|
||||
var lon_mpp = "position/longitude-deg";
|
||||
var alt_mpp = "position/altitude-ft";
|
||||
var heading_mpp = "orientation/true-heading-deg";
|
||||
var pitch_mpp = "orientation/pitch-deg";
|
||||
var roll_mpp = "orientation/roll-deg";
|
||||
|
||||
# Import components from the mp_broadcast module.
|
||||
var Binary = mp_broadcast.Binary;
|
||||
var MessageChannel = mp_broadcast.MessageChannel;
|
||||
|
||||
###############################################################################
|
||||
# Utility classes
|
||||
|
||||
############################################################
|
||||
# Translate a property into another.
|
||||
# Factor and offsets are only used for numeric values.
|
||||
# src - source : property node
|
||||
# dest - destination : property node
|
||||
# factor - : double
|
||||
# offset - : double
|
||||
var Translator = {};
|
||||
Translator.new = func (src = nil, dest = nil, factor = 1, offset = 0) {
|
||||
var obj = { parents : [Translator],
|
||||
src : src,
|
||||
dest : dest,
|
||||
factor : factor,
|
||||
offset : offset };
|
||||
if (obj.src == nil or obj.dest == nil) {
|
||||
print("Translator[");
|
||||
print(" ", debug.string(obj.src));
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
Translator.update = func () {
|
||||
var v = me.src.getValue();
|
||||
if (is_num(v)) {
|
||||
me.dest.setValue(me.factor * v + me.offset);
|
||||
} else {
|
||||
if (typeof(v) == "scalar")
|
||||
me.dest.setValue(v);
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Detects flanks on two insignals encoded in a property.
|
||||
# - positive signal up/down flank
|
||||
# - negative signal up/down flank
|
||||
# n - source : property node
|
||||
# on_positive_flank - action : func (v)
|
||||
# on_negative_flank - action : func (v)
|
||||
var EdgeTrigger = {};
|
||||
EdgeTrigger.new = func (n, on_positive_flank, on_negative_flank) {
|
||||
var obj = { parents : [EdgeTrigger],
|
||||
old : 0,
|
||||
node : n,
|
||||
pos_flank : on_positive_flank,
|
||||
neg_flank : on_negative_flank };
|
||||
if (obj.node == nil) {
|
||||
print("EdgeTrigger[");
|
||||
print(" ", debug.string(obj.node));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
EdgeTrigger.update = func {
|
||||
# NOTE: float MP properties get interpolated.
|
||||
# This detector relies on that steady state is reached between
|
||||
# flanks.
|
||||
var val = me.node.getValue();
|
||||
if (!is_num(val)) return;
|
||||
if (me.old == 1) {
|
||||
if (val < me.old) {
|
||||
me.pos_flank(0);
|
||||
}
|
||||
} elsif (me.old == 0) {
|
||||
if (val > me.old) {
|
||||
me.pos_flank(1);
|
||||
} elsif (val < me.old) {
|
||||
me.neg_flank(1);
|
||||
}
|
||||
} elsif (me.old == -1) {
|
||||
if (val > me.old) {
|
||||
me.neg_flank(0);
|
||||
}
|
||||
}
|
||||
me.old = val;
|
||||
}
|
||||
|
||||
############################################################
|
||||
# StableTrigger: Triggers an action when a MPP property
|
||||
# becomes stable (i.e. doesn't change for
|
||||
# MIN_STABLE seconds).
|
||||
# src - MP prop : property node
|
||||
# action - action to take when the value becomes stable : [func(v)]
|
||||
# An action is triggered when value has stabilized.
|
||||
var StableTrigger = {};
|
||||
StableTrigger.new = func (src, action) {
|
||||
var obj = { parents : [StableTrigger],
|
||||
src : src,
|
||||
action : action,
|
||||
old : 0,
|
||||
stable_since : 0,
|
||||
wait : 0,
|
||||
MIN_STABLE : 0.01 };
|
||||
# Error checking.
|
||||
var bad = (obj.src == nil) or (action = nil);
|
||||
|
||||
if (bad) {
|
||||
print("StableTrigger[");
|
||||
print(" ", debug.string(obj.src));
|
||||
print(" ", debug.string(obj.action));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
StableTrigger.update = func () {
|
||||
var v = me.src.getValue();
|
||||
if (!is_num(v)) return;
|
||||
var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time.
|
||||
|
||||
if ((me.old == v) and
|
||||
((t - me.stable_since) > me.MIN_STABLE) and (me.wait == 1)) {
|
||||
# Trigger action.
|
||||
me.action(v);
|
||||
|
||||
me.wait = 0;
|
||||
} elsif (me.old == v) {
|
||||
# Wait. This is either before the signal is stable or after the action.
|
||||
} else {
|
||||
me.stable_since = t;
|
||||
me.wait = 1;
|
||||
me.old = me.src.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Selects the most recent value of two properties.
|
||||
# src1 - : property node
|
||||
# src2 - : property node
|
||||
# dest - : property node
|
||||
# threshold - : double
|
||||
var MostRecentSelector = {};
|
||||
MostRecentSelector.new = func (src1, src2, dest, threshold) {
|
||||
var obj = { parents : [MostRecentSelector],
|
||||
old1 : 0,
|
||||
old2 : 0,
|
||||
src1 : src1,
|
||||
src2 : src2,
|
||||
dest : dest,
|
||||
thres : threshold };
|
||||
if (obj.src1 == nil or obj.src2 == nil or obj.dest == nil) {
|
||||
print("MostRecentSelector[");
|
||||
print(" ", debug.string(obj.src1));
|
||||
print(" ", debug.string(obj.src2));
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
MostRecentSelector.update = func {
|
||||
var v1 = me.src1.getValue();
|
||||
var v2 = me.src2.getValue();
|
||||
if (!is_num(v1) and !is_num(v2)) return;
|
||||
elsif (!is_num(v1)) me.dest.setValue(v2);
|
||||
elsif (!is_num(v2)) me.dest.setValue(v1);
|
||||
else {
|
||||
if (abs (v2 - me.old2) > me.thres) {
|
||||
me.old2 = v2;
|
||||
me.dest.setValue(me.old2);
|
||||
}
|
||||
if (abs (v1 - me.old1) > me.thres) {
|
||||
me.old1 = v1;
|
||||
me.dest.setValue(me.old1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Adds two input properties.
|
||||
# src1 - : property node
|
||||
# src2 - : property node
|
||||
# dest - : property node
|
||||
var Adder = {};
|
||||
Adder.new = func (src1, src2, dest) {
|
||||
var obj = { parents : [DeltaAccumulator],
|
||||
src1 : src1,
|
||||
src2 : src2,
|
||||
dest : dest };
|
||||
if (obj.src1 == nil or obj.src2 == nil or obj.dest == nil) {
|
||||
print("Adder[");
|
||||
print(" ", debug.string(obj.src1));
|
||||
print(" ", debug.string(obj.src2));
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
Adder.update = func () {
|
||||
var v1 = me.src1.getValue();
|
||||
var v2 = me.src2.getValue();
|
||||
if (!is_num(v1) or !is_num(v2)) return;
|
||||
me.dest.setValue(v1 + v2);
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Adds the delta of src to dest.
|
||||
# src - : property node
|
||||
# dest - : property node
|
||||
var DeltaAdder = {};
|
||||
DeltaAdder.new = func (src, dest) {
|
||||
var obj = { parents : [DeltaAdder],
|
||||
old : 0,
|
||||
src : src,
|
||||
dest : dest };
|
||||
if (obj.src == nil or obj.dest == nil) {
|
||||
print("DeltaAdder[", debug.string(obj.src), ", ",
|
||||
debug.string(obj.dest), "]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
DeltaAdder.update = func () {
|
||||
var v = me.src.getValue();
|
||||
if (!is_num(v)) return;
|
||||
me.dest.setValue((v - me.old) + me.dest.getValue());
|
||||
me.old = v;
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Switch encoder: Encodes upto 32 boolean properties in one
|
||||
# int property.
|
||||
# inputs - list of property nodes
|
||||
# dest - where the bitmask is stored : property node
|
||||
var SwitchEncoder = {};
|
||||
SwitchEncoder.new = func (inputs, dest) {
|
||||
var obj = { parents : [SwitchEncoder],
|
||||
inputs : inputs,
|
||||
dest : dest };
|
||||
# Error checking.
|
||||
var bad = (obj.dest == nil);
|
||||
foreach (var i; inputs) {
|
||||
if (i == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("SwitchEncoder[");
|
||||
foreach (var i; inputs) {
|
||||
print(" ", debug.string(i));
|
||||
}
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
SwitchEncoder.update = func () {
|
||||
var v = 0;
|
||||
var b = 1;
|
||||
forindex (var i; me.inputs) {
|
||||
if (me.inputs[i].getBoolValue()) {
|
||||
v = v + b;
|
||||
}
|
||||
b *= 2;
|
||||
}
|
||||
me.dest.setIntValue(v);
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Switch decoder: Decodes a bitmask in an int property.
|
||||
# src - : property node
|
||||
# actions - list of actions : [func(b)]
|
||||
# Actions are triggered when their input bit change.
|
||||
# Due to interpolation the decoder needs to wait for a
|
||||
# stable input value.
|
||||
var SwitchDecoder = {};
|
||||
SwitchDecoder.new = func (src, actions) {
|
||||
var obj = { parents : [SwitchDecoder],
|
||||
wait : 0,
|
||||
old : 0,
|
||||
old_stable : 0,
|
||||
stable_since : 0,
|
||||
reset : 1,
|
||||
src : src,
|
||||
actions : actions,
|
||||
MIN_STABLE : 0.1 };
|
||||
# Error checking.
|
||||
var bad = (obj.src == nil);
|
||||
foreach (var a; obj.actions) {
|
||||
if (a == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("SwitchDecoder[");
|
||||
print(" ", debug.string(obj.src));
|
||||
foreach (var a; obj.actions) {
|
||||
print(" ", debug.string(a));
|
||||
}
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
SwitchDecoder.update = func () {
|
||||
var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time.
|
||||
var v = me.src.getValue();
|
||||
if (!is_num(v)) return;
|
||||
|
||||
if ((me.old == v) and ((t - me.stable_since) > me.MIN_STABLE) and
|
||||
(me.wait == 1)) {
|
||||
var ov = me.old_stable;
|
||||
# Use this to improve.
|
||||
#<cptf> here's the boring version: var bittest = func(u, b) { while (b) { u = int(u / 2); b -= 1; } u != int(u / 2) * 2; }
|
||||
forindex (var i; me.actions) {
|
||||
var m = math.mod(v, 2);
|
||||
var om = math.mod(ov, 2);
|
||||
if ((m != om or me.reset)) { me.actions[i](m?1:0); }
|
||||
v = (v - m)/2;
|
||||
ov = (ov - om)/2;
|
||||
}
|
||||
me.old_stable = me.src.getValue();
|
||||
me.wait = 0;
|
||||
me.reset = 0;
|
||||
} elsif (me.old == v) {
|
||||
# Wait. This is either before the bitmask is stable or after
|
||||
# it has been processed.
|
||||
} else {
|
||||
me.stable_since = t;
|
||||
me.wait = 1;
|
||||
me.old = me.src.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Time division multiplexing encoder: Transmits a list of
|
||||
# properties over a MP enabled string property.
|
||||
# inputs - input properties : [property node]
|
||||
# dest - MP string prop : property node
|
||||
# Note: TDM can have high latency so it is best used for
|
||||
# non-time critical properties.
|
||||
var TDMEncoder = {};
|
||||
TDMEncoder.new = func (inputs, dest) {
|
||||
var obj = { parents : [TDMEncoder],
|
||||
inputs : inputs,
|
||||
channel : MessageChannel.new(dest,
|
||||
func (msg) {
|
||||
print("This should not happen!");
|
||||
}),
|
||||
MIN_INT : 0.25,
|
||||
last_time : 0,
|
||||
next_item : 0,
|
||||
old : [] };
|
||||
# Error checking.
|
||||
var bad = (dest == nil) or (obj.channel == nil);
|
||||
foreach (var i; inputs) {
|
||||
if (i == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("TDMEncoder[");
|
||||
foreach (var i; inputs) {
|
||||
print(" ", debug.string(i));
|
||||
}
|
||||
print(" ", debug.string(dest));
|
||||
print("]");
|
||||
}
|
||||
|
||||
setsize(obj.old, size(obj.inputs));
|
||||
|
||||
return obj;
|
||||
}
|
||||
TDMEncoder.update = func () {
|
||||
var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time.
|
||||
if (t > me.last_time + me.MIN_INT) {
|
||||
var n = size(me.inputs);
|
||||
while (1) {
|
||||
var v = me.inputs[me.next_item].getValue();
|
||||
|
||||
if ((n <= 0) or (me.old[me.next_item] != v)) {
|
||||
# Set the MP properties to send the next item.
|
||||
me.channel.send(Binary.encodeByte(me.next_item) ~
|
||||
Binary.encodeDouble(v));
|
||||
|
||||
me.old[me.next_item] = v;
|
||||
|
||||
me.last_time = t;
|
||||
me.next_item += 1;
|
||||
if (me.next_item >= size(me.inputs)) { me.next_item = 0; }
|
||||
return;
|
||||
} else {
|
||||
# Search for changed property.
|
||||
n -= 1;
|
||||
me.next_item += 1;
|
||||
if (me.next_item >= size(me.inputs)) { me.next_item = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Time division multiplexing decoder: Receives a list of
|
||||
# properties over a MP enabled string property.
|
||||
# src - MP string prop : property node
|
||||
# actions - list of actions : [func(v)]
|
||||
# An action is triggered when its value is received.
|
||||
# Note: TDM can have high latency so it is best used for
|
||||
# non-time critical properties.
|
||||
var TDMDecoder = {};
|
||||
TDMDecoder.new = func (src, actions) {
|
||||
var obj = { parents : [TDMDecoder],
|
||||
actions : actions };
|
||||
obj.channel = MessageChannel.new(src,
|
||||
func (msg) {
|
||||
obj.process(msg);
|
||||
});
|
||||
|
||||
# Error checking.
|
||||
var bad = (src == nil) or (obj.channel == nil);
|
||||
foreach (var a; actions) {
|
||||
if (a == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("TDMDecoder[");
|
||||
print(" ", debug.string(src));
|
||||
foreach (var a; actions) {
|
||||
print(" ", debug.string(a));
|
||||
}
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
TDMDecoder.process = func (msg) {
|
||||
var v1 = Binary.decodeByte(msg);
|
||||
var v2 = Binary.decodeDouble(substr(msg, 1));
|
||||
# Trigger action.
|
||||
me.actions[v1](v2);
|
||||
}
|
||||
TDMDecoder.update = func {
|
||||
me.channel.update();
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Internal utility functions
|
||||
|
||||
var is_num = func (v) {
|
||||
return num(v) != nil;
|
||||
}
|
||||
|
||||
# fail causes a Nasal runtime error so we get a backtrace.
|
||||
var fail = func {
|
||||
error_detected_in_calling_context();
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# Copilot selection dialog.
|
||||
#
|
||||
# Usage: dual_control_tools.copilot_dialog.show(<copilot type string>);
|
||||
#
|
||||
var COPILOT_DLG = 0;
|
||||
var copilot_dialog = {};
|
||||
############################################################
|
||||
copilot_dialog.init = func (copilot_type, x = nil, y = nil) {
|
||||
me.x = x;
|
||||
me.y = y;
|
||||
me.bg = [0, 0, 0, 0.3]; # background color
|
||||
me.fg = [[1.0, 1.0, 1.0, 1.0]];
|
||||
#
|
||||
# "private"
|
||||
if (contains(aircraft_dual_control, "copilot_view")) {
|
||||
me.title = "Pilot selection";
|
||||
} else {
|
||||
me.title = "Copilot selection";
|
||||
}
|
||||
me.basenode = props.globals.getNode("sim/remote", 1);
|
||||
me.dialog = nil;
|
||||
me.namenode = props.Node.new({"dialog-name" : me.title });
|
||||
me.listeners = [];
|
||||
me.copilot_type = copilot_type;
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.create = func {
|
||||
if (me.dialog != nil)
|
||||
me.close();
|
||||
|
||||
me.dialog = gui.Widget.new();
|
||||
me.dialog.set("name", me.title);
|
||||
if (me.x != nil)
|
||||
me.dialog.set("x", me.x);
|
||||
if (me.y != nil)
|
||||
me.dialog.set("y", me.y);
|
||||
|
||||
me.dialog.set("layout", "vbox");
|
||||
me.dialog.set("default-padding", 0);
|
||||
var titlebar = me.dialog.addChild("group");
|
||||
titlebar.set("layout", "hbox");
|
||||
titlebar.addChild("empty").set("stretch", 1);
|
||||
if (contains(aircraft_dual_control, "copilot_view")) {
|
||||
titlebar.addChild("text").set("label", "Book your flight");
|
||||
} else {
|
||||
titlebar.addChild("text").set("label", "Passengers online");
|
||||
}
|
||||
var w = titlebar.addChild("button");
|
||||
w.set("pref-width", 16);
|
||||
w.set("pref-height", 16);
|
||||
w.set("legend", "");
|
||||
w.set("default", 0);
|
||||
w.set("key", "esc");
|
||||
w.setBinding("nasal", "dual_control_tools.copilot_dialog.destroy(); ");
|
||||
w.setBinding("dialog-close");
|
||||
me.dialog.addChild("hrule");
|
||||
|
||||
var content = me.dialog.addChild("group");
|
||||
content.set("layout", "vbox");
|
||||
content.set("halign", "center");
|
||||
content.set("default-padding", 5);
|
||||
|
||||
# Generate the dialog contents.
|
||||
me.players = me.find_copilot_players();
|
||||
var i = 0;
|
||||
var tmpbase = me.basenode.getNode("dialog", 1);
|
||||
var selected = me.basenode.getNode("pilot-callsign").getValue();
|
||||
foreach (var p; me.players) {
|
||||
var tmp = tmpbase.getNode("b[" ~ i ~ "]", 1);
|
||||
tmp.setBoolValue(streq(selected, p));
|
||||
var w = content.addChild("checkbox");
|
||||
w.node.setValues({"label" : p,
|
||||
"halign" : "left",
|
||||
"property" : tmp.getPath()});
|
||||
w.setBinding
|
||||
("nasal",
|
||||
"dual_control_tools.copilot_dialog.select_action(" ~ i ~ ");");
|
||||
i = i + 1;
|
||||
}
|
||||
me.dialog.addChild("hrule");
|
||||
|
||||
# Display the dialog.
|
||||
fgcommand("dialog-new", me.dialog.prop());
|
||||
fgcommand("dialog-show", me.namenode);
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.close = func {
|
||||
fgcommand("dialog-close", me.namenode);
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.destroy = func {
|
||||
COPILOT_DLG = 0;
|
||||
me.close();
|
||||
foreach(var l; me.listeners)
|
||||
removelistener(l);
|
||||
delete(gui.dialog, "\"" ~ me.title ~ "\"");
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.show = func (copilot_type) {
|
||||
# print("Showing MPCopilots dialog!");
|
||||
if (!COPILOT_DLG) {
|
||||
COPILOT_DLG = int(getprop("/sim/time/elapsed-sec"));
|
||||
me.init(copilot_type);
|
||||
me.create();
|
||||
me._update_(COPILOT_DLG);
|
||||
}
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog._redraw_ = func {
|
||||
if (me.dialog != nil) {
|
||||
me.close();
|
||||
me.create();
|
||||
}
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog._update_ = func (id) {
|
||||
if (COPILOT_DLG != id) return;
|
||||
me._redraw_();
|
||||
settimer(func { me._update_(id); }, 4.1);
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.select_action = func (n) {
|
||||
var selected = me.basenode.getNode("pilot-callsign").getValue();
|
||||
var bs = me.basenode.getNode("dialog").getChildren();
|
||||
# Assumption: There are two true b:s or none. The one not matching selected
|
||||
# is the new selection.
|
||||
var i = 0;
|
||||
me.basenode.getNode("pilot-callsign").setValue("");
|
||||
foreach (var b; bs) {
|
||||
if (!b.getValue() and (i == n)) {
|
||||
b.setValue(1);
|
||||
me.basenode.getNode("pilot-callsign").setValue(me.players[i]);
|
||||
} else {
|
||||
b.setValue(0);
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
dual_control.main.reset();
|
||||
me._redraw_();
|
||||
}
|
||||
############################################################
|
||||
# Return a list containing all nearby copilot players of the right type.
|
||||
copilot_dialog.find_copilot_players = func {
|
||||
var mpplayers =
|
||||
props.globals.getNode("ai/models").getChildren("multiplayer");
|
||||
|
||||
var res = [];
|
||||
foreach (var pilot; mpplayers) {
|
||||
if ((pilot.getNode("valid") != nil) and
|
||||
(pilot.getNode("valid").getValue()) and
|
||||
(pilot.getNode("sim/model/path") != nil)) {
|
||||
var type = pilot.getNode("sim/model/path").getValue();
|
||||
|
||||
if (type == me.copilot_type) {
|
||||
append(res, pilot.getNode("callsign").getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
# debug.dump(res);
|
||||
return res;
|
||||
}
|
||||
###############################################################################
|
||||
@@ -1,6 +0,0 @@
|
||||
print("hello world!\n");
|
||||
print("This is the first program for nasal--\n");
|
||||
var cnt=0;
|
||||
for(var i=1;i<101;i+=1)
|
||||
cnt+=i;
|
||||
print(cnt);
|
||||
7564
test/fmz.nas
7564
test/fmz.nas
File diff suppressed because it is too large
Load Diff
@@ -1,10 +0,0 @@
|
||||
var f=func(n,m,dynamic...)
|
||||
{
|
||||
print(n+m," ",dynamic);
|
||||
n=dynamic;
|
||||
m=dynamic;
|
||||
n+=m;
|
||||
return dynamic;
|
||||
};
|
||||
print(f(1,1,0,0,0,0,0,(1+2+3+(1+2+3+4)))[3]);
|
||||
function([0,1,2,3],{str:"str"});
|
||||
84
test/hexdump.nas
Normal file
84
test/hexdump.nas
Normal file
@@ -0,0 +1,84 @@
|
||||
# hexdump.nas by ValKmjolnir
|
||||
# 2021/8/13
|
||||
|
||||
# init
|
||||
var hex_num=[
|
||||
'0','1','2','3',
|
||||
'4','5','6','7',
|
||||
'8','9','a','b',
|
||||
'c','d','e','f'
|
||||
];
|
||||
var hex=[];
|
||||
foreach(var i;hex_num)
|
||||
foreach(var j;hex_num)
|
||||
append(hex,i~j);
|
||||
|
||||
# read file
|
||||
var s=func(){
|
||||
var filename=[
|
||||
"nasal.h",
|
||||
"main.cpp",
|
||||
"nasal_ast.h",
|
||||
"nasal_builtin.h",
|
||||
"nasal_codegen.h",
|
||||
"nasal_gc.h",
|
||||
"nasal_import.h",
|
||||
"nasal_lexer.h",
|
||||
"nasal_parse.h",
|
||||
"nasal_vm.h",
|
||||
];
|
||||
var ret="";
|
||||
foreach(var elem;filename)
|
||||
ret~=io.fin(elem);
|
||||
return ret;
|
||||
}();
|
||||
|
||||
# used to change line and control the spaces
|
||||
var cnt=0;
|
||||
|
||||
# used to print hex index
|
||||
var hex_index=[0,0,0,0];
|
||||
|
||||
# print binary in text format
|
||||
var textprint=func(index){
|
||||
var info='';
|
||||
for(var i=index-cnt;i<index;i+=1)
|
||||
info~=(0<=s[i] and s[i]<32)?'.':chr(s[i]);
|
||||
for(var i=cnt;i<16;i+=1)
|
||||
info~='.';
|
||||
return ' |'~info~'|\n';
|
||||
}
|
||||
|
||||
# print index
|
||||
var indexprint=func(index){
|
||||
forindex(var i;hex_index){
|
||||
hex_index[i]=index-int(index/256)*256;
|
||||
index=int(index/256);
|
||||
}
|
||||
var info='';
|
||||
for(var i=3;i>=0;i-=1)
|
||||
info~=hex[hex_index[i]];
|
||||
return info~' ';
|
||||
}
|
||||
|
||||
# main
|
||||
func(){
|
||||
var info=indexprint(0);
|
||||
for(var i=0;i<size(s);i+=1){
|
||||
if(cnt==16){
|
||||
info~=textprint(i);
|
||||
print(info);
|
||||
cnt=0;
|
||||
info=indexprint(i);
|
||||
}elsif(cnt==8)
|
||||
info~=' ';
|
||||
cnt+=1;
|
||||
info~=hex[s[i]]~' ';
|
||||
}
|
||||
for(var l=cnt;l<16;l+=1)
|
||||
info~=' ';
|
||||
if(cnt<=8)
|
||||
info~=' ';
|
||||
info~=textprint(i);
|
||||
print(info);
|
||||
}();
|
||||
475
test/json.nas
475
test/json.nas
@@ -1,195 +1,322 @@
|
||||
#lib json.nas
|
||||
var json={
|
||||
text:'',
|
||||
line:1,
|
||||
size:0,
|
||||
ptr:0,
|
||||
get:nil,
|
||||
check:nil,
|
||||
next:nil,
|
||||
match:nil,
|
||||
hash_gen:nil,
|
||||
vec_gen:nil,
|
||||
member:nil,
|
||||
parse:nil,
|
||||
token:{content:'',type:''},
|
||||
content:[],
|
||||
};
|
||||
var JSON=func(){
|
||||
|
||||
json.get=func(filename)
|
||||
{
|
||||
me.line=1;
|
||||
me.ptr=0;
|
||||
me.content=[];
|
||||
me.token={content:'',type:''};
|
||||
me.text=io.fin(filename);
|
||||
if(!size(me.text))
|
||||
die("cannot open "~filename);
|
||||
me.text=split('',me.text);
|
||||
me.size=size(me.text);
|
||||
return;
|
||||
}
|
||||
var (
|
||||
j_eof,
|
||||
j_lbrace,
|
||||
j_rbrace,
|
||||
j_lbracket,
|
||||
j_rbracket,
|
||||
j_comma,
|
||||
j_colon,
|
||||
j_str,
|
||||
j_num,
|
||||
j_id
|
||||
)=(
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
);
|
||||
var j_content=[
|
||||
"eof",
|
||||
"`{`",
|
||||
"`}`",
|
||||
"`[`",
|
||||
"`]`",
|
||||
"`,`",
|
||||
"`:`",
|
||||
"string",
|
||||
"number",
|
||||
"identifier"
|
||||
];
|
||||
|
||||
json.check=func(ptr)
|
||||
{
|
||||
var str=me.text[ptr];
|
||||
return (str=='{' or str=='}' or str=='[' or str==']' or str==',' or str==':' or str=='\"' or ('0'<=str and str<='9'));
|
||||
}
|
||||
|
||||
json.next=func()
|
||||
{
|
||||
while(me.ptr<me.size and !json.check(me.ptr))
|
||||
{
|
||||
if(me.text[me.ptr]=='\n')
|
||||
me.line+=1;
|
||||
me.ptr+=1;
|
||||
var text='';
|
||||
var line=1;
|
||||
var text_size=0;
|
||||
var ptr=0;
|
||||
var token={content:'',type:''};
|
||||
var content={};
|
||||
var init=func(){
|
||||
line=1;
|
||||
text_size=0;
|
||||
ptr=0;
|
||||
content={};
|
||||
token={content:'',type:''};
|
||||
text='';
|
||||
}
|
||||
if(me.ptr>=me.size)
|
||||
|
||||
var isnum=func(c){
|
||||
return '0'<=c and c<='9';
|
||||
}
|
||||
var isid=func(c){
|
||||
var tmp=c[0];
|
||||
return ('a'[0]<=tmp and tmp<='z'[0]) or
|
||||
('A'[0]<=tmp and tmp<='Z'[0]) or
|
||||
c=='_';
|
||||
}
|
||||
var check=func()
|
||||
{
|
||||
me.token.content="";
|
||||
me.token.type="eof";
|
||||
var c=text[ptr];
|
||||
return (
|
||||
c=='{' or c=='}' or
|
||||
c=='[' or c==']' or
|
||||
c==',' or c==':' or
|
||||
c=='\"' or c=='\'' or
|
||||
isnum(c) or isid(c)
|
||||
);
|
||||
}
|
||||
|
||||
var get=func(str)
|
||||
{
|
||||
init();
|
||||
if(!size(str))
|
||||
die("empty string");
|
||||
text=split('',str);
|
||||
text_size=size(text);
|
||||
return;
|
||||
}
|
||||
|
||||
if(me.text[me.ptr]=='{')
|
||||
var next=func()
|
||||
{
|
||||
me.token.content='{';
|
||||
me.token.type="left brace";
|
||||
}
|
||||
elsif(me.text[me.ptr]=='}')
|
||||
{
|
||||
me.token.content='}';
|
||||
me.token.type="right brace";
|
||||
}
|
||||
elsif(me.text[me.ptr]=='[')
|
||||
{
|
||||
me.token.content='[';
|
||||
me.token.type="left bracket";
|
||||
}
|
||||
elsif(me.text[me.ptr]==']')
|
||||
{
|
||||
me.token.content=']';
|
||||
me.token.type="right bracket";
|
||||
}
|
||||
elsif(me.text[me.ptr]==',')
|
||||
{
|
||||
me.token.content=',';
|
||||
me.token.type="comma";
|
||||
}
|
||||
elsif(me.text[me.ptr]==':')
|
||||
{
|
||||
me.token.content=':';
|
||||
me.token.type="colon";
|
||||
}
|
||||
elsif(me.text[me.ptr]=='\"')
|
||||
{
|
||||
var s="";
|
||||
me.ptr+=1;
|
||||
while(me.ptr<me.size and me.text[me.ptr]!='\"')
|
||||
while(ptr<text_size and !check())
|
||||
{
|
||||
s~=me.text[me.ptr];
|
||||
me.ptr+=1;
|
||||
if(text[ptr]=='\n')
|
||||
line+=1;
|
||||
ptr+=1;
|
||||
}
|
||||
me.token.content=s;
|
||||
me.token.type="string";
|
||||
}
|
||||
elsif('0'<=me.text[me.ptr] and me.text[me.ptr]<='9')
|
||||
{
|
||||
var s=me.text[me.ptr];
|
||||
me.ptr+=1;
|
||||
while(me.ptr<me.size and (('0'<=me.text[me.ptr] and me.text[me.ptr]<='9') or me.text[me.ptr]=='.'))
|
||||
if(ptr>=text_size)
|
||||
{
|
||||
s~=me.text[me.ptr];
|
||||
me.ptr+=1;
|
||||
token.content="eof";
|
||||
token.type=j_eof;
|
||||
return;
|
||||
}
|
||||
me.ptr-=1;
|
||||
me.token.content=num(s);
|
||||
me.token.type="number";
|
||||
}
|
||||
me.ptr+=1;
|
||||
return;
|
||||
}
|
||||
|
||||
json.match=func(type)
|
||||
{
|
||||
if(me.token.type!=type)
|
||||
print("line ",me.line,": expect ",type," but get ",me.token.content,".");
|
||||
me.next();
|
||||
return;
|
||||
}
|
||||
|
||||
json.hash_gen=func()
|
||||
{
|
||||
var hash={};
|
||||
me.match("left brace");
|
||||
me.member(hash);
|
||||
while(me.token.type=="comma")
|
||||
{
|
||||
me.match("comma");
|
||||
me.member(hash);
|
||||
}
|
||||
me.match("right brace");
|
||||
return hash;
|
||||
}
|
||||
|
||||
json.vec_gen=func()
|
||||
{
|
||||
var vec=[];
|
||||
me.match("left bracket");
|
||||
if(me.token.type=="left brace")
|
||||
append(vec,me.hash_gen());
|
||||
elsif(me.token.type=="left bracket")
|
||||
append(vec,me.vec_gen());
|
||||
elsif(me.token.type=="string" or me.token.type=="number")
|
||||
{
|
||||
append(vec,me.token.content);
|
||||
me.next();
|
||||
}
|
||||
while(me.token.type=="comma")
|
||||
{
|
||||
me.match("comma");
|
||||
if(me.token.type=="left brace")
|
||||
append(vec,me.hash_gen());
|
||||
elsif(me.token.type=="left bracket")
|
||||
append(vec,me.vec_gen());
|
||||
elsif(me.token.type=="string" or me.token.type=="number")
|
||||
|
||||
var c=text[ptr];
|
||||
if(c=='{')
|
||||
{
|
||||
append(vec,me.token.content);
|
||||
me.next();
|
||||
token.content='{';
|
||||
token.type=j_lbrace;
|
||||
}
|
||||
elsif(c=='}')
|
||||
{
|
||||
token.content='}';
|
||||
token.type=j_rbrace;
|
||||
}
|
||||
elsif(c=='[')
|
||||
{
|
||||
token.content='[';
|
||||
token.type=j_lbracket;
|
||||
}
|
||||
elsif(c==']')
|
||||
{
|
||||
token.content=']';
|
||||
token.type=j_rbracket;
|
||||
}
|
||||
elsif(c==',')
|
||||
{
|
||||
token.content=',';
|
||||
token.type=j_comma;
|
||||
}
|
||||
elsif(c==':')
|
||||
{
|
||||
token.content=':';
|
||||
token.type=j_colon;
|
||||
}
|
||||
elsif(c=='\"' or c=='\'')
|
||||
{
|
||||
var strbegin=c;
|
||||
var s="";
|
||||
ptr+=1;
|
||||
while(ptr<text_size and text[ptr]!=strbegin)
|
||||
{
|
||||
s~=text[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
token.content=s;
|
||||
token.type=j_str;
|
||||
}
|
||||
elsif(isnum(c))
|
||||
{
|
||||
var s=c;
|
||||
ptr+=1;
|
||||
while(ptr<text_size and ((isnum(text[ptr]) or text[ptr]=='.')))
|
||||
{
|
||||
s~=text[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
ptr-=1;
|
||||
token.content=num(s);
|
||||
token.type=j_num;
|
||||
}
|
||||
elsif(isid(c))
|
||||
{
|
||||
var s=c;
|
||||
ptr+=1;
|
||||
while(ptr<text_size and (isid(text[ptr]) or isnum(text[ptr])))
|
||||
{
|
||||
s~=text[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
ptr-=1;
|
||||
token.content=s;
|
||||
token.type=j_id;
|
||||
}
|
||||
ptr+=1;
|
||||
return;
|
||||
}
|
||||
me.match("right bracket");
|
||||
return vec;
|
||||
}
|
||||
|
||||
json.member=func(hash)
|
||||
{
|
||||
var name=me.token.content;
|
||||
me.match("string");
|
||||
me.match("colon");
|
||||
if(me.token.type=="left brace")
|
||||
hash[name]=me.hash_gen();
|
||||
elsif(me.token.type=="left bracket")
|
||||
hash[name]=me.vec_gen();
|
||||
elsif(me.token.type=="string" or me.token.type=="number")
|
||||
var match=func(type)
|
||||
{
|
||||
hash[name]=me.token.content;
|
||||
me.next();
|
||||
if(token.type!=type)
|
||||
print("line ",line,": expect ",j_content[type]," but get `",token.content,"`.\n");
|
||||
next();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
json.parse=func()
|
||||
{
|
||||
me.content={};
|
||||
me.next();
|
||||
me.match("left brace");
|
||||
me.member(me.content);
|
||||
while(me.token.type=="comma")
|
||||
var hash_gen=func()
|
||||
{
|
||||
me.match("comma");
|
||||
me.member(me.content);
|
||||
var hash={};
|
||||
match(j_lbrace);
|
||||
member(hash);
|
||||
while(token.type==j_comma)
|
||||
{
|
||||
match(j_comma);
|
||||
member(hash);
|
||||
}
|
||||
match(j_rbrace);
|
||||
return hash;
|
||||
}
|
||||
me.match("right brace");
|
||||
return;
|
||||
}
|
||||
|
||||
var vec_gen=func()
|
||||
{
|
||||
var vec=[];
|
||||
match(j_lbracket);
|
||||
if(token.type==j_lbrace)
|
||||
append(vec,hash_gen());
|
||||
elsif(token.type==j_lbracket)
|
||||
append(vec,vec_gen());
|
||||
elsif(token.type==j_str or token.type==j_num)
|
||||
{
|
||||
append(vec,token.content);
|
||||
next();
|
||||
}
|
||||
while(token.type==j_comma)
|
||||
{
|
||||
match(j_comma);
|
||||
if(token.type==j_lbrace)
|
||||
append(vec,me.hash_gen());
|
||||
elsif(token.type==j_lbracket)
|
||||
append(vec,vec_gen());
|
||||
elsif(token.type==j_str or token.type==j_num)
|
||||
{
|
||||
append(vec,token.content);
|
||||
next();
|
||||
}
|
||||
}
|
||||
match(j_rbracket);
|
||||
return vec;
|
||||
}
|
||||
|
||||
var member=func(hash)
|
||||
{
|
||||
var name=token.content;
|
||||
if(token.type==j_str)
|
||||
match(j_str);
|
||||
else
|
||||
match(j_id);
|
||||
match(j_colon);
|
||||
if(token.type==j_lbrace)
|
||||
hash[name]=hash_gen();
|
||||
elsif(token.type==j_lbracket)
|
||||
hash[name]=vec_gen();
|
||||
elsif(token.type==j_str or token.type==j_num)
|
||||
{
|
||||
hash[name]=token.content;
|
||||
next();
|
||||
}
|
||||
return;
|
||||
}
|
||||
return {
|
||||
parse:func(str)
|
||||
{
|
||||
if(typeof(str)!="str")
|
||||
die("JSON.parse: must use string");
|
||||
get(str);
|
||||
next();
|
||||
|
||||
match(j_lbrace);
|
||||
member(content);
|
||||
while(token.type==j_comma)
|
||||
{
|
||||
match(j_comma);
|
||||
member(content);
|
||||
}
|
||||
match(j_rbrace);
|
||||
|
||||
var res=content;
|
||||
init();
|
||||
return res;
|
||||
},
|
||||
stringify:func(hash){
|
||||
if(typeof(hash)!="hash")
|
||||
die("JSON.stringify: must use hashmap");
|
||||
var s="";
|
||||
var gen=func(elem){
|
||||
var t=typeof(elem);
|
||||
if(t=="num")
|
||||
s~=elem;
|
||||
elsif(t=="str")
|
||||
s~='"'~elem~'"';
|
||||
elsif(t=="vec")
|
||||
vgen(elem);
|
||||
elsif(t=="hash")
|
||||
hgen(elem);
|
||||
else
|
||||
s~='"undefined"';
|
||||
}
|
||||
var vgen=func(v){
|
||||
s~="[";
|
||||
var vsize=size(v);
|
||||
for(var i=0;i<vsize;i+=1){
|
||||
gen(v[i]);
|
||||
if(i!=vsize-1)
|
||||
s~=",";
|
||||
}
|
||||
s~="]";
|
||||
}
|
||||
var hgen=func(h){
|
||||
s~="{";
|
||||
var k=keys(h);
|
||||
var vsize=size(k);
|
||||
for(var i=0;i<vsize;i+=1){
|
||||
s~=k[i]~":";
|
||||
gen(h[k[i]]);
|
||||
if(i!=vsize-1)
|
||||
s~=",";
|
||||
}
|
||||
s~="}";
|
||||
}
|
||||
hgen(hash);
|
||||
return s;
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
var ss=JSON.stringify({
|
||||
vec:[0,1,2],
|
||||
hash:{
|
||||
m1:0,
|
||||
m2:"str",
|
||||
m3:[114514],
|
||||
m4:{year:1919,month:8,date:10}
|
||||
},
|
||||
function:func(){}
|
||||
});
|
||||
println(ss);
|
||||
println(JSON.parse(ss));
|
||||
31
test/leetcode1319.nas
Normal file
31
test/leetcode1319.nas
Normal file
@@ -0,0 +1,31 @@
|
||||
# union set
|
||||
var n=4;
|
||||
var input=[[0,1],[0,2],[1,2]];
|
||||
|
||||
var find_root=func(x,parent)
|
||||
{
|
||||
while(parent[x]!=nil)
|
||||
x=parent[x];
|
||||
return x;
|
||||
}
|
||||
var union_root=func(x,y,parent)
|
||||
{
|
||||
var x_root=find_root(x,parent);
|
||||
var y_root=find_root(y,parent);
|
||||
if(x_root==y_root) return 0;
|
||||
else parent[x_root]=y_root;
|
||||
return 1;
|
||||
}
|
||||
var makeConnect=func(n,connections)
|
||||
{
|
||||
if(size(connections)<n-1) return -1;
|
||||
var cnt=n-1;
|
||||
var parent=[];
|
||||
setsize(parent,n);
|
||||
foreach(var i;connections)
|
||||
if(union_root(i[0],i[1],parent))
|
||||
cnt-=1;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
println(makeConnect(n,input));
|
||||
377
test/lexer.nas
377
test/lexer.nas
@@ -1,183 +1,210 @@
|
||||
import("lib.nas");
|
||||
|
||||
var s=io.fin("a.nas");
|
||||
s=split('',s);
|
||||
var len=size(s);
|
||||
var ptr=0;
|
||||
|
||||
var jump_note=func()
|
||||
var lexer=func(file)
|
||||
{
|
||||
while(ptr<len and s[ptr]!='\n')
|
||||
ptr+=1;
|
||||
ptr+=1;
|
||||
return;
|
||||
}
|
||||
|
||||
var generate_id=func()
|
||||
{
|
||||
var tmp="";
|
||||
while(ptr<len)
|
||||
var (ptr,token)=(0,[]);
|
||||
var s=io.fin(file);
|
||||
var len=size(s);
|
||||
var line=0;
|
||||
var gen=func(tok)
|
||||
{
|
||||
if('a'<=s[ptr] and s[ptr]<='z'
|
||||
or 'A'<=s[ptr] and s[ptr]<='Z'
|
||||
or s[ptr]=='_'
|
||||
or '0'<=s[ptr] and s[ptr]<='9')
|
||||
tmp~=s[ptr];
|
||||
else
|
||||
break;
|
||||
ptr+=1;
|
||||
append(token,{
|
||||
line:line,
|
||||
token:tok
|
||||
});
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
var generate_str=func()
|
||||
{
|
||||
var tok_str="";
|
||||
var mark=s[ptr];
|
||||
ptr+=1;
|
||||
while(ptr<len and s[ptr]!=mark)
|
||||
return
|
||||
{
|
||||
if(s[ptr]=='\\')
|
||||
jmp_note:func()
|
||||
{
|
||||
while(ptr<len and s[ptr]!='\n'[0])
|
||||
ptr+=1;
|
||||
if(ptr<len and s[ptr]=='\n'[0])
|
||||
line+=1;
|
||||
ptr+=1;
|
||||
if(s[ptr]=='a') tok_str~='\a';
|
||||
elsif(s[ptr]=='b') tok_str~='\b';
|
||||
elsif(s[ptr]=='f') tok_str~='\f';
|
||||
elsif(s[ptr]=='n') tok_str~='\n';
|
||||
elsif(s[ptr]=='r') tok_str~='\r';
|
||||
elsif(s[ptr]=='t') tok_str~='\t';
|
||||
elsif(s[ptr]=='v') tok_str~='\v';
|
||||
elsif(s[ptr]=='?') tok_str~='?';
|
||||
elsif(s[ptr]=='0') tok_str~='\0';
|
||||
elsif(s[ptr]=='\\') tok_str~='\\';
|
||||
elsif(s[ptr]=='\'') tok_str~='\'';
|
||||
elsif(s[ptr]=='\"') tok_str~='\"';
|
||||
else tok_str~=s[ptr];
|
||||
}
|
||||
else
|
||||
tok_str~=s[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
if(ptr>=len)
|
||||
print("read eof when generating string.");
|
||||
ptr+=1;
|
||||
return tok_str;
|
||||
},
|
||||
id_gen:func()
|
||||
{
|
||||
var tmp="";
|
||||
while(ptr<len)
|
||||
{
|
||||
var c=s[ptr];
|
||||
if(('a'[0]<=c and c<='z'[0])
|
||||
or ('A'[0]<=c and c<='Z'[0])
|
||||
or ('0'[0]<=c and c<='9'[0])
|
||||
or c=='_'[0])
|
||||
tmp~=chr(c);
|
||||
else
|
||||
break;
|
||||
ptr+=1;
|
||||
}
|
||||
gen(tmp);
|
||||
},
|
||||
str_gen:func()
|
||||
{
|
||||
var str="";
|
||||
var mark=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
while(ptr<len and chr(s[ptr])!=mark)
|
||||
{
|
||||
if(chr(s[ptr])=='\\')
|
||||
{
|
||||
ptr+=1;
|
||||
var c=chr(s[ptr]);
|
||||
if (c=='a' ) str~='\a';
|
||||
elsif(c=='b' ) str~='\b';
|
||||
elsif(c=='e' ) str~='\e';
|
||||
elsif(c=='f' ) str~='\f';
|
||||
elsif(c=='n' ) str~='\n';
|
||||
elsif(c=='r' ) str~='\r';
|
||||
elsif(c=='t' ) str~='\t';
|
||||
elsif(c=='v' ) str~='\v';
|
||||
elsif(c=='?' ) str~='\?';
|
||||
elsif(c=='0' ) str~='\0';
|
||||
elsif(c=='\\') str~='\\';
|
||||
elsif(c=='\'') str~='\'';
|
||||
elsif(c=='\"') str~='\"';
|
||||
else str~=c;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(s[ptr]=='\n'[0])
|
||||
line+=1;
|
||||
str~=chr(s[ptr]);
|
||||
}
|
||||
ptr+=1;
|
||||
}
|
||||
if(ptr>=len)
|
||||
print("read eof when generating string.\n");
|
||||
ptr+=1;
|
||||
gen(str);
|
||||
},
|
||||
num_gen:func()
|
||||
{
|
||||
var number=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
if(ptr<len and chr(s[ptr])=='x')
|
||||
{
|
||||
ptr+=1;
|
||||
while(ptr<len and
|
||||
('a'[0]<=s[ptr] and s[ptr]<='f'[0]
|
||||
or '0'[0]<=s[ptr] and s[ptr]<='9'[0]))
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
gen(num(number));
|
||||
return;
|
||||
}
|
||||
elsif(ptr<len and chr(s[ptr])=='o')
|
||||
{
|
||||
ptr+=1;
|
||||
while(ptr<len and ('0'[0]<=s[ptr] and s[ptr]<='7'[0]))
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
gen(num(number));
|
||||
return;
|
||||
}
|
||||
while(ptr<len and ('0'[0]<=s[ptr] and s[ptr]<='9'[0]))
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
if(ptr<len and chr(s[ptr])=='.')
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
while(ptr<len and ('0'[0]<=s[ptr] and s[ptr]<='9'[0]))
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
}
|
||||
if(chr(s[ptr])=='e' or chr(s[ptr])=='E')
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
if(chr(s[ptr])=='-' or chr(s[ptr])=='+')
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
while(ptr<len and ('0'[0]<=s[ptr] and s[ptr]<='9'[0]))
|
||||
{
|
||||
number~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
}
|
||||
var last_c=chr(number[-1]);
|
||||
if(last_c=='.' or last_c=='e' or last_c=='E' or last_c=='-' or last_c=='+')
|
||||
println("error number: ",number);
|
||||
gen(num(number));
|
||||
},
|
||||
opr_gen:func()
|
||||
{
|
||||
var c=chr(s[ptr]);
|
||||
if(c=='+' or c=='-' or c=='~' or c=='/' or c=='*' or c=='>' or c=='<' or c=='!' or c=='=')
|
||||
{
|
||||
var tmp=c;
|
||||
ptr+=1;
|
||||
if(ptr<len and chr(s[ptr])=='=')
|
||||
{
|
||||
tmp~=chr(s[ptr]);
|
||||
ptr+=1;
|
||||
}
|
||||
gen(tmp);
|
||||
return;
|
||||
}
|
||||
elsif(c=='.')
|
||||
{
|
||||
if(ptr+2<len and chr(s[ptr+1])=='.' and chr(s[ptr+2])=='.')
|
||||
{
|
||||
gen("...");
|
||||
ptr+=3;
|
||||
}
|
||||
else
|
||||
{
|
||||
gen(".");
|
||||
ptr+=1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
elsif(c!=' ' and c!='\t' and c!='\n' and c!='\r' and s[ptr]>0)
|
||||
gen(c);
|
||||
ptr+=1;
|
||||
return;
|
||||
},
|
||||
compile:func()
|
||||
{
|
||||
line=1;
|
||||
while(ptr<len)
|
||||
{
|
||||
var c=s[ptr];
|
||||
if(c=='#'[0])
|
||||
me.jmp_note();
|
||||
elsif(c=='\n'[0])
|
||||
{
|
||||
line+=1;
|
||||
ptr+=1;
|
||||
}
|
||||
elsif('a'[0]<=c and c<='z'[0]
|
||||
or 'A'[0]<=c and c<='Z'[0]
|
||||
or c=='_'[0])
|
||||
me.id_gen();
|
||||
elsif(c=='\''[0] or c=='\"'[0])
|
||||
me.str_gen();
|
||||
elsif('0'[0]<=c and c<='9'[0])
|
||||
me.num_gen();
|
||||
else
|
||||
me.opr_gen();
|
||||
}
|
||||
return;
|
||||
},
|
||||
get_token:func(){return token;}
|
||||
};
|
||||
}
|
||||
|
||||
var generate_number=func()
|
||||
{
|
||||
var number=s[ptr];
|
||||
ptr+=1;
|
||||
if(s[ptr]=='x')
|
||||
{
|
||||
ptr+=1;
|
||||
while(ptr<len and ('a'<=s[ptr] and s[ptr]<='f' or '0'<=s[ptr] and s[ptr]<='9'))
|
||||
{
|
||||
number~=s[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
return num(number);
|
||||
}
|
||||
elsif(s[ptr]=='o')
|
||||
{
|
||||
ptr+=1;
|
||||
while(ptr<len and ('0'<=s[ptr] and s[ptr]<='7'))
|
||||
{
|
||||
number~=s[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
return num(number);
|
||||
}
|
||||
|
||||
while(ptr<len and ('0'<=s[ptr] and s[ptr]<='9'))
|
||||
{
|
||||
number~=s[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
if(s[ptr]=='.')
|
||||
number~=s[ptr];
|
||||
else
|
||||
return num(number);
|
||||
ptr+=1;
|
||||
while(ptr<len and ('0'<=s[ptr] and s[ptr]<='9'))
|
||||
{
|
||||
number~=s[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
if(s[ptr]=='e' or s[ptr]=='E')
|
||||
number~=s[ptr];
|
||||
else
|
||||
return num(number);
|
||||
ptr+=1;
|
||||
if(s[ptr]=='-' or s[ptr]=='+')
|
||||
{
|
||||
number~=s[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
while(ptr<len and ('0'<=s[ptr] and s[ptr]<='9'))
|
||||
{
|
||||
number~=s[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
return num(number);
|
||||
}
|
||||
|
||||
var generate_operator=func()
|
||||
{
|
||||
var tmp="";
|
||||
if(s[ptr]=='+' or s[ptr]=='-' or s[ptr]=='~' or s[ptr]=='/' or s[ptr]=='*' or s[ptr]=='>' or s[ptr]=='<' or s[ptr]=='!' or s[ptr]=='=')
|
||||
{
|
||||
tmp=s[ptr];
|
||||
ptr+=1;
|
||||
if(ptr<len and s[ptr]=='=')
|
||||
{
|
||||
tmp~=s[ptr];
|
||||
ptr+=1;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
elsif(s[ptr]=='.')
|
||||
{
|
||||
if(ptr+2<len and s[ptr+1]=='.' and s[ptr+2]=='.')
|
||||
{
|
||||
tmp='...';
|
||||
ptr+=3;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp='.';
|
||||
ptr+=1;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
elsif(s[ptr]!=' ' and s[ptr]!='\t' and s[ptr]!='\n' and s[ptr]!='\r' and s[ptr][0]>0)
|
||||
tmp=s[ptr];
|
||||
ptr+=1;
|
||||
return tmp;
|
||||
}
|
||||
var cnt=0;
|
||||
var token=[];
|
||||
while(ptr<len)
|
||||
{
|
||||
if(s[ptr]=='#')
|
||||
jump_note();
|
||||
elsif('a'<=s[ptr] and s[ptr]<='z' or 'A'<=s[ptr] and s[ptr]<='Z' or s[ptr]=='_')
|
||||
append(token,generate_id());
|
||||
elsif(s[ptr]=='\'' or s[ptr]=='\"')
|
||||
append(token,generate_str());
|
||||
elsif('0'<=s[ptr] and s[ptr]<='9')
|
||||
append(token,generate_number());
|
||||
else
|
||||
{
|
||||
var tmp=generate_operator();
|
||||
if(size(tmp))
|
||||
append(token,tmp);
|
||||
}
|
||||
if(ptr>=len)
|
||||
break;
|
||||
}
|
||||
foreach(var i;token)
|
||||
{
|
||||
print("(",cnt," | ",i,")");
|
||||
cnt+=1;
|
||||
}
|
||||
var lex=lexer("test/props.nas");
|
||||
lex.compile();
|
||||
foreach(var tok;lex.get_token())
|
||||
print('(',tok.line,' | ',tok.token,')\n');
|
||||
167
test/lib.nas
167
test/lib.nas
@@ -1,167 +0,0 @@
|
||||
var import=func(filename)
|
||||
{
|
||||
nasal_call_import(filename);
|
||||
return nil;
|
||||
}
|
||||
var print=func(elements...)
|
||||
{
|
||||
nasal_call_builtin_std_cout(elements);
|
||||
return nil;
|
||||
};
|
||||
var append=func(vector,elements...)
|
||||
{
|
||||
nasal_call_builtin_push_back(vector,elements);
|
||||
return nil;
|
||||
}
|
||||
var setsize=func(vector,size)
|
||||
{
|
||||
nasal_call_builtin_set_size(vector,size);
|
||||
return nil;
|
||||
}
|
||||
var system=func(str)
|
||||
{
|
||||
nasal_call_builtin_system(str);
|
||||
return;
|
||||
}
|
||||
var input=func()
|
||||
{
|
||||
return nasal_call_builtin_input();
|
||||
}
|
||||
var sleep=func(duration)
|
||||
{
|
||||
nasal_call_builtin_sleep(duration);
|
||||
return;
|
||||
}
|
||||
var split=func(delimeter,string)
|
||||
{
|
||||
return nasal_call_builtin_split(delimeter,string);
|
||||
}
|
||||
var rand=func(seed=nil)
|
||||
{
|
||||
return nasal_call_builtin_rand(seed);
|
||||
}
|
||||
var id=func(thing)
|
||||
{
|
||||
return nasal_call_builtin_get_id(thing);
|
||||
}
|
||||
var int=func(value)
|
||||
{
|
||||
return nasal_call_builtin_trans_int(value);
|
||||
}
|
||||
var num=func(value)
|
||||
{
|
||||
return nasal_call_builtin_trans_num(value);
|
||||
}
|
||||
var pop=func(vector)
|
||||
{
|
||||
return nasal_call_builtin_pop_back(vector);
|
||||
}
|
||||
var str=func(number)
|
||||
{
|
||||
return nasal_call_builtin_trans_str(number);
|
||||
}
|
||||
var size=func(object)
|
||||
{
|
||||
return nasal_call_builtin_size(object);
|
||||
}
|
||||
var contains=func(hash,key)
|
||||
{
|
||||
return nasal_call_builtin_contains(hash,key);
|
||||
}
|
||||
var delete=func(hash,key)
|
||||
{
|
||||
nasal_call_builtin_delete(hash,key);
|
||||
return;
|
||||
}
|
||||
var keys=func(hash)
|
||||
{
|
||||
return nasal_call_builtin_get_keys(hash);
|
||||
}
|
||||
var time=func(begin_time)
|
||||
{
|
||||
return nasal_call_builtin_time(begin_time);
|
||||
}
|
||||
var die=func(str)
|
||||
{
|
||||
nasal_call_builtin_die(str);
|
||||
return nil;
|
||||
}
|
||||
var typeof=func(object)
|
||||
{
|
||||
return nasal_call_builtin_type(object);
|
||||
}
|
||||
var substr=func(str,begin,length)
|
||||
{
|
||||
return nasal_call_builtin_substr(str,begin,length);
|
||||
}
|
||||
|
||||
var io=
|
||||
{
|
||||
fin:func(filename)
|
||||
{
|
||||
return nasal_call_builtin_finput(filename);
|
||||
},
|
||||
fout:func(filename,str)
|
||||
{
|
||||
nasal_call_builtin_foutput(filename,str);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
var bits=
|
||||
{
|
||||
bitxor:func(a,b)
|
||||
{
|
||||
return nasal_call_builtin_xor(a,b);
|
||||
},
|
||||
bitand:func(a,b)
|
||||
{
|
||||
return nasal_call_builtin_and(a,b);
|
||||
},
|
||||
bitor:func(a,b)
|
||||
{
|
||||
return nasal_call_builtin_or(a,b);
|
||||
},
|
||||
bitnand:func(a,b)
|
||||
{
|
||||
return nasal_call_builtin_nand(a,b);
|
||||
},
|
||||
bitnot:func(a)
|
||||
{
|
||||
return nasal_call_builtin_not(a);
|
||||
}
|
||||
};
|
||||
|
||||
var math=
|
||||
{
|
||||
e:2.7182818284590452354,
|
||||
pi:3.14159265358979323846,
|
||||
sin:func(x)
|
||||
{
|
||||
return nasal_call_builtin_sin(x);
|
||||
},
|
||||
cos:func(x)
|
||||
{
|
||||
return nasal_call_builtin_cos(x);
|
||||
},
|
||||
tan:func(x)
|
||||
{
|
||||
return nasal_call_builtin_tan(x);
|
||||
},
|
||||
exp:func(x)
|
||||
{
|
||||
return nasal_call_builtin_exp(x);
|
||||
},
|
||||
ln:func(x)
|
||||
{
|
||||
return nasal_call_builtin_cpp_math_ln(x);
|
||||
},
|
||||
sqrt:func(x)
|
||||
{
|
||||
return nasal_call_builtin_cpp_math_sqrt(x);
|
||||
},
|
||||
atan2:func(x,y)
|
||||
{
|
||||
return nasal_call_builtin_cpp_atan2(x,y);
|
||||
},
|
||||
};
|
||||
63
test/life.nas
Normal file
63
test/life.nas
Normal file
@@ -0,0 +1,63 @@
|
||||
var map=nil;
|
||||
|
||||
var check=func(x,y)
|
||||
{
|
||||
if(x>14) x=0;
|
||||
if(y>19) y=0;
|
||||
return map[x][y];
|
||||
}
|
||||
|
||||
var new_map=func()
|
||||
{
|
||||
var tmp=[];
|
||||
setsize(tmp,15);
|
||||
forindex(var i;tmp)
|
||||
{
|
||||
tmp[i]=[];
|
||||
setsize(tmp[i],20);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
var prt=func()
|
||||
{
|
||||
var s='\e[0;0H';
|
||||
foreach(var line;map)
|
||||
{
|
||||
foreach(var elem;line)
|
||||
s~=elem~' ';
|
||||
s~='\n';
|
||||
}
|
||||
print(s);
|
||||
unix.sleep(1/144);
|
||||
}
|
||||
|
||||
func()
|
||||
{
|
||||
if(os.platform()=="windows")
|
||||
system("chcp 65001");
|
||||
print("\ec");
|
||||
rand(time(0));
|
||||
map=new_map();
|
||||
forindex(var i;map)
|
||||
forindex(var j;map[i])
|
||||
map[i][j]=rand()>0.7?'O':' ';
|
||||
var calc=[[0,1],[1,0],[0,-1],[-1,0],[1,1],[1,-1],[-1,-1],[-1,1]];
|
||||
for(var r=0;r<100;r+=1)
|
||||
{
|
||||
prt(map);
|
||||
var tmp=new_map();
|
||||
for(var i=0;i<15;i+=1)
|
||||
for(var j=0;j<20;j+=1)
|
||||
{
|
||||
var cnt=0;
|
||||
foreach(var k;calc)
|
||||
cnt+=(check(i+k[0],j+k[1])=='O');
|
||||
if(cnt==2) tmp[i][j]=map[i][j];
|
||||
elsif(cnt==3) tmp[i][j]='O';
|
||||
else tmp[i][j]=' ';
|
||||
}
|
||||
map=tmp;
|
||||
}
|
||||
return;
|
||||
}();
|
||||
@@ -6,25 +6,32 @@ for(;;)
|
||||
}
|
||||
for(var i=1;;)break;
|
||||
for(var i=1;;i+=1)break;
|
||||
for(var i=1;i<10;i+=1)print(i);
|
||||
for(var i=1;i<10;i+=1)print(i,'\n');
|
||||
|
||||
while(1)break;
|
||||
var j=0;
|
||||
while(j<10)
|
||||
{
|
||||
print(j);
|
||||
print(j,'\n');
|
||||
j+=1;
|
||||
}
|
||||
|
||||
forindex(var j;[0,1,2,3])print(j);
|
||||
forindex(var j;[0,1,2,3])print(j,'\n');
|
||||
forindex(var j;[0,1,2,3])
|
||||
{
|
||||
var a=j;
|
||||
print(a*a);
|
||||
print(a*a,'\n');
|
||||
}
|
||||
foreach(var j;[0,1,2,3])print([0,1,2,3][j]);
|
||||
foreach(var j;[0,1,2,3])print([0,1,2,3][j],'\n');
|
||||
foreach(var j;[0,1,2,3])
|
||||
{
|
||||
var a=[0,1,2,3][j];
|
||||
print(a*a-1);
|
||||
print(a*a-1,'\n');
|
||||
}
|
||||
|
||||
var f=func(){
|
||||
var x=0;
|
||||
return func(){x+=1;};
|
||||
}();
|
||||
for(var i=0;i<4e6;i+=1)
|
||||
f();
|
||||
382
test/main.nas
382
test/main.nas
@@ -1,382 +0,0 @@
|
||||
# game left in corner by ValKmjolnir
|
||||
# 2020
|
||||
|
||||
# lib function defined here
|
||||
var print=func(elements...)
|
||||
{
|
||||
nasal_call_builtin_std_cout(elements);
|
||||
return nil;
|
||||
};
|
||||
var append=func(vector,elements...)
|
||||
{
|
||||
nasal_call_builtin_push_back(vector,elements);
|
||||
return nil;
|
||||
}
|
||||
var setsize=func(vector,size)
|
||||
{
|
||||
nasal_call_builtin_set_size(vector,size);
|
||||
return nil;
|
||||
}
|
||||
var system=func(str)
|
||||
{
|
||||
nasal_call_builtin_system(str);
|
||||
return;
|
||||
}
|
||||
var sleep=func(duration)
|
||||
{
|
||||
nasal_call_builtin_sleep(duration);
|
||||
return;
|
||||
}
|
||||
var input=func()
|
||||
{
|
||||
return nasal_call_builtin_input();
|
||||
}
|
||||
var io=
|
||||
{
|
||||
fin:func(filename)
|
||||
{
|
||||
return nasal_call_builtin_finput(filename);
|
||||
},
|
||||
fout:func(filename,str)
|
||||
{
|
||||
nasal_call_builtin_foutput(filename,str);
|
||||
return;
|
||||
}
|
||||
};
|
||||
var int=func(str)
|
||||
{
|
||||
return str+0;
|
||||
}
|
||||
var str=func(num)
|
||||
{
|
||||
return num~'';
|
||||
}
|
||||
# string split
|
||||
|
||||
# game elements defined here
|
||||
var role_property=
|
||||
{
|
||||
health:100,
|
||||
mood:100,
|
||||
satiety:100,
|
||||
thirst:100,
|
||||
health_change:func(x)
|
||||
{
|
||||
me.health+=x;
|
||||
if(me.health<0)
|
||||
me.health=0;
|
||||
elsif(me.health>100)
|
||||
me.health=100;
|
||||
return nil;
|
||||
},
|
||||
mood_change:func(x)
|
||||
{
|
||||
me.mood+=x;
|
||||
if(me.mood<0)
|
||||
me.mood=0;
|
||||
elsif(me.mood>100)
|
||||
me.mood=100;
|
||||
return nil;
|
||||
},
|
||||
satiety_change:func(x)
|
||||
{
|
||||
me.satiety+=x;
|
||||
if(me.satiety<0)
|
||||
me.satiety=0;
|
||||
elsif(me.satiety>100)
|
||||
me.satiety=100;
|
||||
return nil;
|
||||
},
|
||||
thirst_change:func(x)
|
||||
{
|
||||
me.thirst+=x;
|
||||
if(me.thirst<0)
|
||||
me.thirst=0;
|
||||
elsif(me.thirst>100)
|
||||
me.thirst=100;
|
||||
return nil;
|
||||
}
|
||||
};
|
||||
var screen=
|
||||
{
|
||||
picture:[],
|
||||
info_below_left:[],
|
||||
info_below_right:[],
|
||||
clear:func()
|
||||
{
|
||||
me.picture=[];
|
||||
me.info_below_left=[];
|
||||
me.info_below_right=[];
|
||||
return;
|
||||
},
|
||||
pic_addline:func(_str)
|
||||
{
|
||||
append(me.picture,_str);
|
||||
return;
|
||||
},
|
||||
left_add:func(_str)
|
||||
{
|
||||
append(me.info_below_left,_str);
|
||||
return;
|
||||
},
|
||||
right_add:func(_str)
|
||||
{
|
||||
append(me.info_below_right,_str);
|
||||
return;
|
||||
},
|
||||
prt_screen:func()
|
||||
{
|
||||
foreach(var i;me.picture)
|
||||
print(i);
|
||||
forindex(var i;me.info_below_left)
|
||||
print(me.info_below_left[i]~me.info_below_right[i]);
|
||||
return;
|
||||
}
|
||||
};
|
||||
var first_shown_info=func()
|
||||
{
|
||||
system("cls");
|
||||
var str_list=[
|
||||
"+-----------------------------------------------+",
|
||||
"| |",
|
||||
"| |",
|
||||
"| Let me tell you a story... |",
|
||||
"| A story that really happened many years ago...|",
|
||||
"| Nearly no one knows and cares about it... |",
|
||||
"| But some children may still suffer from... |",
|
||||
"| This kind of stories... |",
|
||||
"| And this kind of stories never stop hurting...|",
|
||||
"| People that are still alive... |",
|
||||
"| |",
|
||||
"| |",
|
||||
"+-----------------------------------------------+"
|
||||
];
|
||||
foreach(var i;str_list)
|
||||
print(i);
|
||||
return;
|
||||
}
|
||||
var generate_role_property=func()
|
||||
{
|
||||
screen.left_add("+-----------------------+");
|
||||
var str="";
|
||||
for(var i=10;i<=100;i+=10)
|
||||
{
|
||||
if(i<=role_property.health)
|
||||
str~="=";
|
||||
else
|
||||
str~=" ";
|
||||
}
|
||||
screen.left_add("|[health ]:"~str~" |");
|
||||
str="";
|
||||
for(var i=10;i<=100;i+=10)
|
||||
{
|
||||
if(i<=role_property.mood)
|
||||
str~="=";
|
||||
else
|
||||
str~=" ";
|
||||
}
|
||||
screen.left_add("|[mood ]:"~str~" |");
|
||||
str="";
|
||||
for(var i=10;i<=100;i+=10)
|
||||
{
|
||||
if(i<=role_property.satiety)
|
||||
str~="=";
|
||||
else
|
||||
str~=" ";
|
||||
}
|
||||
screen.left_add("|[satiety]:"~str~" |");
|
||||
str="";
|
||||
for(var i=10;i<=100;i+=10)
|
||||
{
|
||||
if(i<=role_property.thirst)
|
||||
str~="=";
|
||||
else
|
||||
str~=" ";
|
||||
}
|
||||
screen.left_add("|[thirst ]:"~str~" |");
|
||||
screen.left_add("+-----------------------+");
|
||||
return;
|
||||
}
|
||||
var generate_choose_list=func()
|
||||
{
|
||||
var str_list=[
|
||||
"-----------------------+",
|
||||
"[1]| next step |",
|
||||
"[2]| restart |",
|
||||
"[3]| store game |",
|
||||
"[4]| exit |",
|
||||
"-----------------------+"
|
||||
];
|
||||
foreach(var i;str_list)
|
||||
screen.right_add(i);
|
||||
return;
|
||||
}
|
||||
var next_step=func()
|
||||
{
|
||||
role_property.health_change(-1);
|
||||
role_property.mood_change(-1);
|
||||
role_property.satiety_change(-1);
|
||||
role_property.thirst_change(-10);
|
||||
var str_list=[
|
||||
"+-----------------------------------------------+",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"+-----------------------------------------------+"
|
||||
];
|
||||
foreach(var i;str_list)
|
||||
screen.pic_addline(i);
|
||||
return;
|
||||
}
|
||||
var restart=func()
|
||||
{
|
||||
role_property.health=100;
|
||||
role_property.mood=100;
|
||||
role_property.satiety=100;
|
||||
role_property.thirst=100;
|
||||
var str_list=[
|
||||
"+-----------------------------------------------+",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"+-----------------------------------------------+"
|
||||
];
|
||||
foreach(var i;str_list)
|
||||
screen.pic_addline(i);
|
||||
return;
|
||||
}
|
||||
var generate_incorrect_choice_screen=func()
|
||||
{
|
||||
var str_list=[
|
||||
"+-----------------------------------------------+",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| make a correct choice. |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"+-----------------------------------------------+"
|
||||
];
|
||||
foreach(var i;str_list)
|
||||
screen.pic_addline(i);
|
||||
}
|
||||
var generate_goodbye_screen=func()
|
||||
{
|
||||
var str_list=[
|
||||
"+-----------------------------------------------+",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| see you next life. |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"+-----------------------------------------------+"
|
||||
];
|
||||
foreach(var i;str_list)
|
||||
screen.pic_addline(i);
|
||||
}
|
||||
var store_file=func()
|
||||
{
|
||||
var str=role_property.health~'\n'~role_property.mood~'\n'~role_property.satiety~'\n'~role_property.thirst~'\n';
|
||||
io.fout("game-left-in-corner.glic",str);
|
||||
var str_list=[
|
||||
"+-----------------------------------------------+",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| data stored. |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"| |",
|
||||
"+-----------------------------------------------+"
|
||||
];
|
||||
foreach(var i;str_list)
|
||||
screen.pic_addline(i);
|
||||
return;
|
||||
}
|
||||
var get_file=func()
|
||||
{
|
||||
var str=io.fin("game-left-in-corner.glic");
|
||||
print(str);
|
||||
return;
|
||||
}
|
||||
var game_main=func()
|
||||
{
|
||||
first_shown_info();
|
||||
screen.clear();
|
||||
generate_role_property();
|
||||
generate_choose_list();
|
||||
screen.prt_screen();
|
||||
while(1)
|
||||
{
|
||||
screen.clear();
|
||||
print("|your choice[1|2|3|4]: |");
|
||||
var choice=input();
|
||||
if((choice!='1') and (choice!='2') and (choice!='3') and (choice!='4'))
|
||||
generate_incorrect_choice_screen();
|
||||
elsif(choice=='1')
|
||||
next_step();
|
||||
elsif(choice=='2')
|
||||
restart();
|
||||
elsif(choice=='3')
|
||||
store_file();
|
||||
elsif(choice=='4')
|
||||
{
|
||||
system("cls");
|
||||
screen.clear();
|
||||
generate_goodbye_screen();
|
||||
generate_role_property();
|
||||
generate_choose_list();
|
||||
screen.prt_screen();
|
||||
break;
|
||||
}
|
||||
system("cls");
|
||||
generate_role_property();
|
||||
generate_choose_list();
|
||||
screen.prt_screen();
|
||||
if(role_property.health==0 or role_property.mood==0 or role_property.satiety==0 or role_property.thirst==0)
|
||||
{
|
||||
print("|you died. |");
|
||||
print("+-----------------------------------------------+");
|
||||
system("pause");
|
||||
screen.clear();
|
||||
restart();
|
||||
system("cls");
|
||||
generate_role_property();
|
||||
generate_choose_list();
|
||||
screen.prt_screen();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
game_main();
|
||||
4808
test/mandel.nas
Normal file
4808
test/mandel.nas
Normal file
File diff suppressed because it is too large
Load Diff
26
test/mandelbrot.nas
Normal file
26
test/mandelbrot.nas
Normal file
@@ -0,0 +1,26 @@
|
||||
var (yMin,yMax,xMin,xMax,line)=(-0.2,0.2,-1.5,-1.0,"");
|
||||
var (yDel,xDel)=(yMax-yMin,xMax-xMin);
|
||||
for(var yPixel=0;yPixel<24;yPixel+=1)
|
||||
{
|
||||
var y=(yPixel/24)*yDel+yMin;
|
||||
for(var xPixel=0;xPixel<80;xPixel+=1)
|
||||
{
|
||||
var x=(xPixel/80)*xDel+xMin;
|
||||
var pixel=" ";
|
||||
var (x0,y0)=(x,y);
|
||||
for(var iter=0;iter<80;iter+=1)
|
||||
{
|
||||
var x1=(x0*x0)-(y0*y0)+x;
|
||||
var y1=2*x0*y0+y;
|
||||
(x0,y0)=(x1,y1);
|
||||
if((x0*x0)+(y0*y0)>4)
|
||||
{
|
||||
pixel=chr(" .:;+=xX$&"[iter/8]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
line~=pixel;
|
||||
}
|
||||
line~='\n';
|
||||
}
|
||||
print(line);
|
||||
247
test/md5.nas
Normal file
247
test/md5.nas
Normal file
@@ -0,0 +1,247 @@
|
||||
var check=func(x){
|
||||
if(x<0x100000000)
|
||||
return x;
|
||||
return x-floor(x/0x100000000)*0x100000000;
|
||||
}
|
||||
var u32_bits_and=func(x,y){
|
||||
(x,y)=(check(x),check(y));
|
||||
var (res,op)=(0,1);
|
||||
for(var i=0;i<32;i+=1){
|
||||
var (tmpx,tmpy)=(x-floor(x/2)*2,y-floor(y/2)*2);
|
||||
res+=op*(tmpx==1 and tmpy==1);
|
||||
(x,y)=(floor(x/2),floor(y/2));
|
||||
op*=2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
var u32_bits_or=func(x,y){
|
||||
(x,y)=(check(x),check(y));
|
||||
var (res,op)=(0,1);
|
||||
for(var i=0;i<32;i+=1){
|
||||
var (tmpx,tmpy)=(x-floor(x/2)*2,y-floor(y/2)*2);
|
||||
res+=op*(tmpx==1 or tmpy==1);
|
||||
(x,y)=(floor(x/2),floor(y/2));
|
||||
op*=2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
var u32_bits_xor=func(x,y){
|
||||
(x,y)=(check(x),check(y));
|
||||
var (res,op)=(0,1);
|
||||
for(var i=0;i<32;i+=1){
|
||||
var (tmpx,tmpy)=(x-floor(x/2)*2,y-floor(y/2)*2);
|
||||
res+=op*(tmpx!=tmpy);
|
||||
(x,y)=(floor(x/2),floor(y/2));
|
||||
op*=2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
var u32_bits_not=func(x){
|
||||
x=check(x);
|
||||
var (res,op)=(0,1);
|
||||
for(var i=0;i<32;i+=1){
|
||||
res+=op*((x-floor(x/2)*2)==1?0:1);
|
||||
x=floor(x/2);
|
||||
op*=2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
var hex32str=func(){
|
||||
var ch=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
|
||||
var tbl=[];
|
||||
setsize(tbl,256);
|
||||
for(var i=0;i<16;i+=1){
|
||||
for(var j=0;j<16;j+=1)
|
||||
tbl[i*16+j]=ch[i]~ch[j];
|
||||
}
|
||||
return func(num){
|
||||
var res="";
|
||||
for(var i=0;i<4;i+=1){
|
||||
res~=tbl[u32_bits_and(num,0xff)];
|
||||
num=floor(num/256);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
}();
|
||||
|
||||
var _md5=func(){
|
||||
var K=[
|
||||
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
||||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
|
||||
];
|
||||
|
||||
var S=[
|
||||
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
|
||||
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
|
||||
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
|
||||
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
|
||||
];
|
||||
var idx=[
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
|
||||
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
|
||||
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
|
||||
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
|
||||
];
|
||||
|
||||
var l=func(num,cx){
|
||||
for(var i=0;i<cx;i+=1){
|
||||
num=check(num*2);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
var r=func(num,cx){
|
||||
num=check(num);
|
||||
for(var i=0;i<cx;i+=1){
|
||||
num=num/2;
|
||||
}
|
||||
return floor(num);
|
||||
}
|
||||
var rol=func(num,cx){
|
||||
return u32_bits_or(l(num,cx),r(num,32-cx));
|
||||
}
|
||||
# round 1
|
||||
var F=func(x,y,z){
|
||||
return u32_bits_or(
|
||||
u32_bits_and(x,y),
|
||||
u32_bits_and(u32_bits_not(x),z)
|
||||
);
|
||||
}
|
||||
# round 2
|
||||
var G=func(x,y,z){
|
||||
return u32_bits_or(
|
||||
u32_bits_and(x,z),
|
||||
u32_bits_and(y,u32_bits_not(z))
|
||||
);
|
||||
}
|
||||
# round 3
|
||||
var H=func(x,y,z){
|
||||
return u32_bits_xor(u32_bits_xor(x,y),z);
|
||||
}
|
||||
# round 4
|
||||
var I=func(x,y,z){
|
||||
return u32_bits_xor(
|
||||
y,
|
||||
u32_bits_or(x,u32_bits_not(z))
|
||||
);
|
||||
}
|
||||
var functions=[
|
||||
F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
|
||||
G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,
|
||||
H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,
|
||||
I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I
|
||||
];
|
||||
|
||||
return func(s){
|
||||
var (s_size,len,res)=(size(s),size(s)*8,[]);
|
||||
setsize(res,s_size);
|
||||
for(var i=0;i<s_size;i+=1){
|
||||
res[i]=s[i];
|
||||
}
|
||||
# +------len------+--1~512--+--64--+
|
||||
# | text | fill | size |
|
||||
# +---------------+---------+------+ N*512 bit
|
||||
var (mod,res_size)=(s_size-floor(s_size/64)*64,0);
|
||||
if(mod==56){
|
||||
res_size=s_size+64;
|
||||
}elsif(mod<56){
|
||||
res_size=floor(s_size/64)*64+56;
|
||||
}elsif(mod>56){
|
||||
res_size=floor(s_size/64)*64+120; # 512+448=960 960/8=120
|
||||
}
|
||||
setsize(res,res_size);
|
||||
res[s_size]=0x80;
|
||||
for(var i=s_size+1;i<res_size;i+=1)
|
||||
res[i]=0;
|
||||
|
||||
# little endian
|
||||
setsize(res,size(res)+8);
|
||||
var (s_size,lower32,higher32)=(size(res),check(len),check(len/math.pow(2,32)));
|
||||
for(var i=4;i>0;i-=1){
|
||||
res[s_size-4-i]=floor(lower32-floor(lower32/256)*256);
|
||||
lower32=floor(lower32/256);
|
||||
}
|
||||
for(var i=4;i>0;i-=1){
|
||||
res[s_size-i]=floor(higher32-floor(higher32/256)*256);
|
||||
higher32=floor(higher32/256);
|
||||
}
|
||||
|
||||
# 1 block=>16 uint32=>64 byte=>512 bit
|
||||
# because using double to discribe number
|
||||
# this may only work when string's length is under 1<<51
|
||||
var tmp=[];
|
||||
setsize(tmp,size(res)/4);
|
||||
for(var i=0;i<size(res);i+=4){
|
||||
tmp[i/4]=res[i+3]*math.pow(2,24)+
|
||||
res[i+2]*math.pow(2,16)+
|
||||
res[i+1]*math.pow(2,8)+
|
||||
res[i];
|
||||
}
|
||||
res=tmp;
|
||||
|
||||
var A=0x67452301;
|
||||
var B=0xefcdab89;
|
||||
var C=0x98badcfe;
|
||||
var D=0x10325476;
|
||||
|
||||
res_size=size(res);
|
||||
for(var i=0;i<res_size;i+=16){
|
||||
var (f,a,b,c,d)=(0,A,B,C,D);
|
||||
for(var j=0;j<64;j+=1){
|
||||
f=functions[j](b,c,d);
|
||||
(a,b,c,d)=(d,check(b+rol(a+f+K[j]+res[i+idx[j]],S[j])),b,c);
|
||||
}
|
||||
(A,B,C,D)=(check(a+A),check(b+B),check(c+C),check(d+D));
|
||||
}
|
||||
return hex32str(A)~hex32str(B)~hex32str(C)~hex32str(D);
|
||||
};
|
||||
}();
|
||||
|
||||
# check if md5 runs correctly
|
||||
var md5check=func(){
|
||||
var test_set=[
|
||||
"md5",
|
||||
"github.com",
|
||||
"helloworld",
|
||||
"abc",
|
||||
"https://www.github.com/ValKmjolnir/Nasal-Interpreter",
|
||||
"https://github.com/andyross/nasal",
|
||||
"var (lower32,higher32)=(check(len),check(len/math.pow(2,32)));",
|
||||
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
"let the bass kick",
|
||||
"f499377c9ae8454c6c8a21ddba7f00de5817fccdc611333ed004d826abb17f4efdacad297f72956e0619002cecffc8e3d18d9b03b082f3cb114bc29173954043",
|
||||
"you are our last hope"
|
||||
];
|
||||
var result=[
|
||||
"1bc29b36f623ba82aaf6724fd3b16718",
|
||||
"99cd2175108d157588c04758296d1cfc",
|
||||
"fc5e038d38a57032085441e7fe7010b0",
|
||||
"900150983cd24fb0d6963f7d28e17f72",
|
||||
"6b3a7bbc2240046c4fb1b0b3a4ed8181",
|
||||
"14a6afca5f3a7b239c56b5a9678c428e",
|
||||
"f499377c9ae8454c6c8a21ddba7f00de",
|
||||
"fdacad297f72956e0619002cecffc8e3",
|
||||
"16eadccb9799dfb4c1ca512f40638bbb",
|
||||
"a7916c5ce54e73b7ddf6a286b36d976d",
|
||||
"ec6d5b197ba019db23c719112f3f70b7"
|
||||
];
|
||||
forindex(var i;test_set){
|
||||
var res=_md5(test_set[i]);
|
||||
if(cmp(res,result[i]))
|
||||
println(
|
||||
"md5 cannot work:\n",
|
||||
" test \""~test_set[i]~"\"\n",
|
||||
" result \""~result[i]~"\"\n",
|
||||
" but get \""~res~"\"\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# check when loading md5.nas
|
||||
md5check();
|
||||
132
test/md5compare.nas
Normal file
132
test/md5compare.nas
Normal file
@@ -0,0 +1,132 @@
|
||||
import("test/md5.nas");
|
||||
|
||||
srand();
|
||||
|
||||
var progress_bar=func(){
|
||||
var res=[];
|
||||
setsize(res,51);
|
||||
var (tmp,sp)=(" |"," | ");
|
||||
res[0]=tmp~sp;
|
||||
for(var i=1;i<=50;i+=1){
|
||||
tmp~="#";
|
||||
res[i]=tmp~substr(sp,i,52-i);
|
||||
}
|
||||
return res;
|
||||
}();
|
||||
|
||||
var compare=func(){
|
||||
var ch=[
|
||||
"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","+",
|
||||
"_","*","/","\'","\"",".",",",";",":","<",">","!","@","#","$","%",
|
||||
"^","&","*","(",")","-","=","\\","|","[","]","{","}","`"," ","\t","?"
|
||||
];
|
||||
return func(begin,end){
|
||||
var (total,prt_cnt,lastpercent,percent)=(end-begin,0,0,0);
|
||||
for(var i=begin;i<end;i+=1){
|
||||
var s="";
|
||||
for(var j=0;j<i;j+=1){
|
||||
s~=ch[rand()*size(ch)];
|
||||
}
|
||||
var res=md5(s);
|
||||
if(cmp(res,_md5(s))){
|
||||
die("error: "~str(i));
|
||||
}
|
||||
percent=int((i-begin+1)/total*100);
|
||||
if(percent-lastpercent>=2){
|
||||
prt_cnt+=1;
|
||||
lastpercent=percent;
|
||||
}
|
||||
print(progress_bar[prt_cnt],percent,"% (",i-begin+1,"/",total,")\t",res," max byte: ",end-1," \r");
|
||||
}
|
||||
print('\n');
|
||||
};
|
||||
}();
|
||||
|
||||
var filechecksum=func(){
|
||||
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 files=[
|
||||
"./stl/file.nas ",
|
||||
"./stl/lib.nas ",
|
||||
"./stl/list.nas ",
|
||||
"./stl/module.nas ",
|
||||
"./stl/queue.nas ",
|
||||
"./stl/result.nas ",
|
||||
"./stl/sort.nas ",
|
||||
"./stl/stack.nas ",
|
||||
"./test/ascii-art.nas ",
|
||||
"./test/auto_crash.nas ",
|
||||
"./test/bf.nas ",
|
||||
"./test/bfcolored.nas ",
|
||||
"./test/bfconvertor.nas ",
|
||||
"./test/bfs.nas ",
|
||||
"./test/bigloop.nas ",
|
||||
"./test/bp.nas ",
|
||||
"./test/calc.nas ",
|
||||
"./test/choice.nas ",
|
||||
"./test/class.nas ",
|
||||
"./test/diff.nas ",
|
||||
"./test/exception.nas ",
|
||||
"./test/fib.nas ",
|
||||
"./test/filesystem.nas ",
|
||||
"./test/hexdump.nas ",
|
||||
"./test/json.nas ",
|
||||
"./test/leetcode1319.nas ",
|
||||
"./test/lexer.nas ",
|
||||
"./test/life.nas ",
|
||||
"./test/loop.nas ",
|
||||
"./test/mandel.nas ",
|
||||
"./test/mandelbrot.nas ",
|
||||
"./test/md5.nas ",
|
||||
"./test/md5compare.nas ",
|
||||
"./test/module_test.nas ",
|
||||
"./test/nasal_test.nas ",
|
||||
"./test/pi.nas ",
|
||||
"./test/prime.nas ",
|
||||
"./test/props_sim.nas ",
|
||||
"./test/props.nas ",
|
||||
"./test/qrcode.nas ",
|
||||
"./test/quick_sort.nas ",
|
||||
"./test/scalar.nas ",
|
||||
"./test/snake.nas ",
|
||||
"./test/tetris.nas ",
|
||||
"./test/trait.nas ",
|
||||
"./test/turingmachine.nas",
|
||||
"./test/utf8chk.nas ",
|
||||
"./test/wavecollapse.nas ",
|
||||
"./test/ycombinator.nas ",
|
||||
"LICENSE ",
|
||||
"main.cpp ",
|
||||
"makefile ",
|
||||
"nasal_ast.h ",
|
||||
"nasal_builtin.h ",
|
||||
"nasal_codegen.h ",
|
||||
"nasal_dbg.h ",
|
||||
"nasal_err.h ",
|
||||
"nasal_gc.h ",
|
||||
"nasal_import.h ",
|
||||
"nasal_lexer.h ",
|
||||
"nasal_opt.h ",
|
||||
"nasal_parse.h ",
|
||||
"nasal_vm.h ",
|
||||
"nasal.ebnf ",
|
||||
"nasal.h ",
|
||||
"README.md "
|
||||
];
|
||||
foreach(var i;files){
|
||||
var f=io.fin(getname(i));
|
||||
var (res0,res1)=(md5(f),_md5(f));
|
||||
println(i,' ',res0,' ',!cmp(res0,res1),' ',size(f),' byte');
|
||||
}
|
||||
}
|
||||
|
||||
var randomchecksum=func(){
|
||||
for(var i=0;i<4096;i+=512)
|
||||
compare(i,i+512);
|
||||
}
|
||||
|
||||
filechecksum();
|
||||
randomchecksum();
|
||||
44
test/module_test.nas
Normal file
44
test/module_test.nas
Normal file
@@ -0,0 +1,44 @@
|
||||
var libfib=func(){
|
||||
var (dd,fib,qfib)=(nil,nil,nil);
|
||||
return {
|
||||
open:func(){
|
||||
if(dd==nil){
|
||||
dd=dylib.dlopen("./module/libfib.so");
|
||||
fib=dylib.dlsym(dd,"fib");
|
||||
qfib=dylib.dlsym(dd,"quick_fib");
|
||||
}else{
|
||||
println("[info ] already loaded.");
|
||||
}
|
||||
},
|
||||
close:func(){
|
||||
if(dd==nil){
|
||||
println("[error ] already closed.");
|
||||
return;
|
||||
}
|
||||
dylib.dlclose(dd);
|
||||
(dd,fib,qfib)=(nil,nil,nil);
|
||||
},
|
||||
fib:func(x){
|
||||
if(fib!=nil)
|
||||
return dylib.dlcall(fib,x);
|
||||
println("[error ] cannot call fib.");
|
||||
return nil;
|
||||
},
|
||||
qfib:func(x){
|
||||
if(qfib!=nil)
|
||||
return dylib.dlcall(qfib,x);
|
||||
println("[error ] cannot call qfib.");
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
println("[keys ] ",keys(libfib));
|
||||
libfib.open();
|
||||
libfib.open();
|
||||
println("[result] ",libfib.fib(40));
|
||||
println("[result] ",libfib.qfib(40));
|
||||
libfib.close();
|
||||
println("[result] ",libfib.fib(40));
|
||||
println("[result] ",libfib.qfib(40));
|
||||
libfib.close();
|
||||
@@ -1,10 +1,9 @@
|
||||
#//This is written for Nasal Intepreter
|
||||
#//Sidi Liang
|
||||
|
||||
# This is written for Nasal Intepreter
|
||||
# Sidi Liang
|
||||
var w = 1;
|
||||
var x = "hello";
|
||||
var f = func(){
|
||||
print("f is called");
|
||||
println("f is called");
|
||||
}
|
||||
var f2 = func(){
|
||||
return 2;
|
||||
@@ -28,71 +27,27 @@ var z1 = {
|
||||
hashh:z
|
||||
};
|
||||
var y2 = [w, x, y, z1];
|
||||
|
||||
var z2 = {
|
||||
hashh: z1,
|
||||
listt2: y2,
|
||||
};
|
||||
|
||||
print(w);#//1
|
||||
print("\n");
|
||||
print(x);#//hello
|
||||
print("\n");
|
||||
print(y);#//Empty
|
||||
print("\n");
|
||||
print(z);#//Empty
|
||||
print("\n");
|
||||
print(z1);#//Empty
|
||||
print("\n");
|
||||
print(y2);#//Empty
|
||||
print("\n");
|
||||
print(y[0]);#//1
|
||||
print("\n");
|
||||
print(y1[2][1]);#//hello
|
||||
print("\n");
|
||||
print(z.numb);#//1
|
||||
print("\n");
|
||||
print(z.listt[2][1]);#//hello
|
||||
print("\n");
|
||||
print(z1.hashh.listt[2][1]);#//hello
|
||||
print("\n");
|
||||
print(y2[3].hashh.listt[2][1]);#//hello
|
||||
print("\n");
|
||||
print(f);#//Empty
|
||||
print("\n");
|
||||
println(w);#//1
|
||||
println(x);#//hello
|
||||
println(y);#//[1,hello]
|
||||
println(z);#//{...}
|
||||
println(z1);#//{...}
|
||||
println(y2);#//[...]
|
||||
println(y[0]);#//1
|
||||
println(y1[2][1]);#//hello
|
||||
println(z.numb);#//1
|
||||
println(z.listt[2][1]);#//hello
|
||||
println(z1.hashh.listt[2][1]);#//hello
|
||||
println(y2[3].hashh.listt[2][1]);#//hello
|
||||
println(f);#//func(...){...}
|
||||
f();#//f is called
|
||||
print("\n");
|
||||
print(z.funcc);#//Empty
|
||||
print("\n");
|
||||
println(z.funcc);#//func(...){...}
|
||||
z.funcc();#//f is called
|
||||
print("\n");
|
||||
print(z.funcccall);#//Empty
|
||||
print("\n");
|
||||
z.funcccall();#//f is called
|
||||
print("\n");
|
||||
println(z.funcccall);#//func(...){...}
|
||||
z2.listt2[3].hashh.funcc();#//f is called
|
||||
print("\n");
|
||||
print(y1[f2()][w]);#//hello
|
||||
print("\n");
|
||||
#//print(z.f3()); Error
|
||||
call(f);#//f is called
|
||||
print("\n");
|
||||
call(z.funcc);#//f is called
|
||||
print("\n");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
println(y1[f2()][w]);#//hello
|
||||
156
test/neo4j.nas
156
test/neo4j.nas
@@ -1,156 +0,0 @@
|
||||
import("lib.nas");
|
||||
|
||||
rand(time(0));
|
||||
var chartable=split('','abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
|
||||
var node=func(type)
|
||||
{
|
||||
var s="";
|
||||
for(var i=0;i<10;i+=1)
|
||||
s~=chartable[rand()*62];
|
||||
return {name:s,type:type,next:[]};
|
||||
}
|
||||
var film_node=[];
|
||||
for(var i=0;i<1000;i+=1)
|
||||
append(film_node,node("film"));
|
||||
var director_node=[];
|
||||
for(var i=0;i<400;i+=1)
|
||||
append(director_node,node("direct"));
|
||||
var actor_node=[];
|
||||
for(var i=0;i<2000;i+=1)
|
||||
append(actor_node,node("actor"));
|
||||
var writer_node=[];
|
||||
for(var i=0;i<300;i+=1)
|
||||
append(writer_node,node("writer"));
|
||||
var type_node=[];
|
||||
for(var i=0;i<20;i+=1)
|
||||
append(type_node,node("type"));
|
||||
var lang_node=[];
|
||||
for(var i=0;i<120;i+=1)
|
||||
append(lang_node,node("lang"));
|
||||
var country_node=[];
|
||||
for(var i=0;i<120;i+=1)
|
||||
append(country_node,node("country"));
|
||||
|
||||
func()
|
||||
{
|
||||
var director_size=size(director_node);
|
||||
var actor_size=size(actor_node);
|
||||
var writer_size=size(writer_node);
|
||||
var type_size=size(type_node);
|
||||
var lang_size=size(lang_node);
|
||||
var country_size=size(country_node);
|
||||
|
||||
var director_link=int(1+rand()*2);
|
||||
var actor_link=int(1+rand()*10);
|
||||
var writer_link=int(1+rand());
|
||||
var type_link=int(1+rand()*3);
|
||||
var lang_link=int(1+rand()*4);
|
||||
var country_link=int(1+rand()*2);
|
||||
foreach(var film;film_node)
|
||||
{
|
||||
for(var i=0;i<director_link;i+=1)
|
||||
{
|
||||
var director=director_node[rand()*director_size];
|
||||
append(film.next,director);
|
||||
append(director.next,film);
|
||||
}
|
||||
for(var i=0;i<actor_link;i+=1)
|
||||
{
|
||||
var actor=actor_node[rand()*actor_size];
|
||||
append(film.next,actor);
|
||||
append(actor.next,film);
|
||||
}
|
||||
for(var i=0;i<writer_link;i+=1)
|
||||
{
|
||||
var writer=writer_node[rand()*writer_size];
|
||||
append(film.next,writer);
|
||||
append(writer.next,film);
|
||||
}
|
||||
for(var i=0;i<type_link;i+=1)
|
||||
{
|
||||
var _type=type_node[rand()*type_size];
|
||||
append(film.next,_type);
|
||||
append(_type.next,film);
|
||||
}
|
||||
for(var i=0;i<lang_link;i+=1)
|
||||
{
|
||||
var lang=lang_node[rand()*lang_size];
|
||||
append(film.next,lang);
|
||||
append(lang.next,film);
|
||||
}
|
||||
for(var i=0;i<country_link;i+=1)
|
||||
{
|
||||
var country=country_node[rand()*country_size];
|
||||
append(film.next,country);
|
||||
append(country.next,film);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}();
|
||||
|
||||
|
||||
var film_list=[];
|
||||
var count_list=[];
|
||||
for(var i=0;i<10;i+=1)
|
||||
{
|
||||
append(film_list,film_node[i]);
|
||||
append(count_list,1);
|
||||
}
|
||||
|
||||
var sort_list=func(begin,end)
|
||||
{
|
||||
for(var i=begin;i<end;i+=1)
|
||||
{
|
||||
var index=i;
|
||||
for(var j=i+1;j<end;j+=1)
|
||||
if(count_list[index]<count_list[j])
|
||||
index=j;
|
||||
if(index!=i)
|
||||
{
|
||||
var tmp=film_list[i];
|
||||
film_list[i]=film_list[index];
|
||||
film_list[index]=tmp;
|
||||
tmp=count_list[i];
|
||||
count_list[i]=count_list[index];
|
||||
count_list[index]=tmp;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
var list_size=size(film_list);
|
||||
list_size=list_size>10?10:list_size;
|
||||
for(var i=0;i<list_size;i+=1)
|
||||
print(i,'\t:',film_list[i].name,'\t',count_list[i]);
|
||||
var choose=input();
|
||||
if(choose=="exit")
|
||||
break;
|
||||
if(num(choose)>=list_size)
|
||||
die("choose a correct index");
|
||||
var label_list=film_node[num(choose)].next;
|
||||
film_list=[];
|
||||
count_list=[];
|
||||
foreach(var label;label_list)
|
||||
foreach(var film;label.next)
|
||||
{
|
||||
var has=0;
|
||||
for(var i=0;i<size(film_list);i+=1)
|
||||
if(film_list[i].name==film.name)
|
||||
{
|
||||
has=1;
|
||||
count_list[i]+=rand();
|
||||
break;
|
||||
}
|
||||
if(has==0)
|
||||
{
|
||||
append(film_list,film);
|
||||
append(count_list,1);
|
||||
}
|
||||
}
|
||||
sort_list(0,size(film_list));
|
||||
}
|
||||
|
||||
foreach(var film;film_node)
|
||||
setsize(film.next,0);
|
||||
7
test/pi.nas
Normal file
7
test/pi.nas
Normal file
@@ -0,0 +1,7 @@
|
||||
var (t,res)=(1,0);
|
||||
for(var m=1;m<4e6;m+=2)
|
||||
{
|
||||
res+=t/m;
|
||||
t=-t;
|
||||
}
|
||||
println(res*4);
|
||||
38
test/prime.nas
Normal file
38
test/prime.nas
Normal file
@@ -0,0 +1,38 @@
|
||||
var is_prime=func(x){
|
||||
for(var i=2;i<x;i+=1)
|
||||
if(x/i==int(x/i))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
var is_prime_sqrt=func(x){
|
||||
for(var i=2;i<=math.sqrt(x);i+=1)
|
||||
if(x/i==int(x/i))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
var primes=[];
|
||||
var filter=func(x){
|
||||
foreach(var i;primes){
|
||||
if(x/i==int(x/i))
|
||||
return 0;
|
||||
if(x>=i){
|
||||
for(var j=i+1;j<=math.sqrt(x);j+=1)
|
||||
if(x/j==int(x/j))
|
||||
return 0;
|
||||
append(primes,x);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
append(primes,x);
|
||||
return 1;
|
||||
}
|
||||
|
||||
func(){
|
||||
var cnt=0;
|
||||
for(var i=2;i<50000;i+=1)
|
||||
if(filter(i))
|
||||
cnt+=1;
|
||||
println(cnt);
|
||||
}();
|
||||
246
test/prop.nas
246
test/prop.nas
@@ -1,246 +0,0 @@
|
||||
import("lib.nas");
|
||||
|
||||
var property_tree=
|
||||
{
|
||||
accelerations:
|
||||
{
|
||||
'n-z-cg-fps_sec':0,
|
||||
ned:
|
||||
{
|
||||
'down-accel-fps_sec':0,
|
||||
'east-accel-fps_sec':0,
|
||||
'north-accel-fps_sec':0,
|
||||
},
|
||||
nlf:0,
|
||||
pilot:
|
||||
{
|
||||
'x-accel-fps_sec':0,
|
||||
'y-accel-fps_sec':0,
|
||||
'z-accel-fps_sec':0,
|
||||
},
|
||||
'pilot-g':1,
|
||||
'pilot-gdamped':1
|
||||
},
|
||||
ai:
|
||||
{
|
||||
models:
|
||||
{
|
||||
carrier:
|
||||
{
|
||||
callsign:'',
|
||||
controls:{},
|
||||
environment:{},
|
||||
id:2,
|
||||
name:'Nimitz',
|
||||
navaids:{},
|
||||
orientation:{},
|
||||
position:{},
|
||||
radar:{},
|
||||
sign:'CVN-68',
|
||||
sim:{},
|
||||
subID:0,
|
||||
submodels:
|
||||
{
|
||||
path:'',
|
||||
serviceable:1
|
||||
},
|
||||
'surface-positions':{},
|
||||
type:'AI',
|
||||
valid:1,
|
||||
velocities:{},
|
||||
waypoint:{}
|
||||
},
|
||||
'carrier[1]':
|
||||
{
|
||||
callsign:'',
|
||||
controls:{},
|
||||
environment:{},
|
||||
id:3,
|
||||
name:'Eisenhower',
|
||||
navaids:{},
|
||||
orientation:{},
|
||||
position:{},
|
||||
radar:{},
|
||||
sign:'CVN-69',
|
||||
sim:{},
|
||||
subID:0,
|
||||
submodels:
|
||||
{
|
||||
path:'',
|
||||
serviceable:0
|
||||
},
|
||||
'surface-positions':{},
|
||||
type:'AI',
|
||||
valid:1,
|
||||
velocities:{},
|
||||
waypoint:{}
|
||||
},
|
||||
count:2,
|
||||
'model-added':'/ai[0]/models[0]/carrier[1]',
|
||||
'model-removed':nil,
|
||||
'num-players':0
|
||||
},
|
||||
submodels:
|
||||
{
|
||||
contrails:0
|
||||
},
|
||||
},
|
||||
aircraft:
|
||||
{
|
||||
icao:
|
||||
{
|
||||
equipment:'SDFGY',
|
||||
surveillance:'S',
|
||||
type:'ZZZZ',
|
||||
'wake-turbulence-category':'L'
|
||||
},
|
||||
performance:
|
||||
{
|
||||
approach:
|
||||
{
|
||||
'airspeed-knots':150,
|
||||
},
|
||||
climb:'\n\t\t\t\n\t\t\t',
|
||||
cruise:
|
||||
{
|
||||
'airspeed-knots':1000,
|
||||
'altitude-ft':4500,
|
||||
},
|
||||
descent:'\n\t\t\t\n\t\t\t',
|
||||
maximum:'\n\t\t\t\n\t\t\t',
|
||||
minimum:'\n\t\t\t\n\t\t\t',
|
||||
},
|
||||
settings:
|
||||
{
|
||||
fuel_persistent:0,
|
||||
ground_services_persistent:0,
|
||||
radio_persistent:0,
|
||||
tooltips:1,
|
||||
weight_persistent:0
|
||||
}
|
||||
},
|
||||
autopilot:
|
||||
{
|
||||
internal:{},
|
||||
locks:{},
|
||||
'route-manager':{},
|
||||
settings:{},
|
||||
'target-tracking':{},
|
||||
},
|
||||
canvas:
|
||||
{
|
||||
'by-index':
|
||||
{
|
||||
texture:
|
||||
{
|
||||
background:'rgba(0,0,0,0)',
|
||||
group:{},
|
||||
name:'Tooltip',
|
||||
placement:{},
|
||||
size:600,
|
||||
'size[1]':200,
|
||||
status:0,
|
||||
'status-msg':'OK',
|
||||
view:300,
|
||||
'view[1]':100
|
||||
},
|
||||
'texture[1]':
|
||||
{
|
||||
background:'rgba(0,0,0,0)',
|
||||
group:{},
|
||||
mipmapping:1,
|
||||
name:'SymbolCache1024x1024',
|
||||
placement:{},
|
||||
size:1024,
|
||||
'size[1]':1024,
|
||||
status:0,
|
||||
'status-msg':'OK',
|
||||
view:1024,
|
||||
'view[1]':1024
|
||||
},
|
||||
'texture[2]':
|
||||
{
|
||||
background:'rgba(0,0,0,0)',
|
||||
group:{},
|
||||
mipmapping:1,
|
||||
name:'SymbolCache1024x1024',
|
||||
placement:{},
|
||||
size:1024,
|
||||
'size[1]':1024,
|
||||
status:0,
|
||||
'status-msg':'OK',
|
||||
view:1024,
|
||||
'view[1]':1024
|
||||
},
|
||||
}
|
||||
},
|
||||
command:{},
|
||||
consumables:{},
|
||||
controls:{},
|
||||
cursor:'Aircraft/ufo/Models/cursor.ac',
|
||||
devices:{},
|
||||
earthview:{},
|
||||
engines:{},
|
||||
environment:{},
|
||||
ephemeris:{},
|
||||
fdm:{},
|
||||
gear:{},
|
||||
hazards:{},
|
||||
input:{},
|
||||
instrumentation:{},
|
||||
'local-weather':{},
|
||||
logging:{},
|
||||
models:{},
|
||||
nasal:{},
|
||||
orientation:{},
|
||||
position:{},
|
||||
rendering:{},
|
||||
scenery:{},
|
||||
sim:{},
|
||||
source:'Models',
|
||||
'surface-positions':{},
|
||||
systems:{},
|
||||
velocities:{},
|
||||
};
|
||||
|
||||
var setprop=func(prop,value)
|
||||
{
|
||||
if(type(prop)!="string")
|
||||
die("setprop: prop is not a string");
|
||||
var path=split('/',prop);
|
||||
var tmp=property_tree;
|
||||
var path_size=size(path);
|
||||
for(var i=0;i<path_size-1;i+=1)
|
||||
tmp=tmp[path[i]];
|
||||
tmp[path[path_size-1]]=value;
|
||||
return;
|
||||
}
|
||||
var getprop=func(prop)
|
||||
{
|
||||
if(type(prop)!="string")
|
||||
die("getprop: prop is not a string");
|
||||
var path=split('/',prop);
|
||||
var tmp=property_tree;
|
||||
foreach(var i;path)
|
||||
tmp=tmp[i];
|
||||
return tmp;
|
||||
}
|
||||
setprop("aircraft/icao/type",'IDG MD-11');
|
||||
|
||||
var print_prop=func(depth,prop)
|
||||
{
|
||||
var s='';
|
||||
for(var i=0;i<depth;i+=1)
|
||||
s~='| ';
|
||||
if(type(prop)!="hash")
|
||||
return;
|
||||
var m=keys(prop);
|
||||
foreach(var elem;m)
|
||||
{
|
||||
print(s,elem,':',prop[elem]);
|
||||
print_prop(depth+1,prop[elem]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
print_prop(0,property_tree);
|
||||
@@ -9,6 +9,24 @@
|
||||
# local node, there is no equivalent of the "relative path" variants
|
||||
# available in C++; just use node.getNode(path).whatever() instead.
|
||||
#
|
||||
|
||||
##
|
||||
# Utility. Turns any ghosts it finds (either solo, or in an
|
||||
# array) into Node objects.
|
||||
#
|
||||
var wrap = func(node) {
|
||||
var argtype = typeof(node);
|
||||
if(argtype == "ghost") {
|
||||
return wrapNode(node);
|
||||
} elsif(argtype == "vector") {
|
||||
var v = node;
|
||||
var n = size(v);
|
||||
for(var i=0; i<n; i+=1) { v[i] = wrapNode(v[i]); }
|
||||
return v;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
var Node = {
|
||||
getNode : func wrap(_getNode(me._g, arg)),
|
||||
getParent : func wrap(_getParent(me._g, arg)),
|
||||
@@ -166,23 +184,6 @@ var copy = func(src, dest, attr = 0) {
|
||||
if(attr) dest.setAttribute(src.getAttribute());
|
||||
}
|
||||
|
||||
##
|
||||
# Utility. Turns any ghosts it finds (either solo, or in an
|
||||
# array) into Node objects.
|
||||
#
|
||||
var wrap = func(node) {
|
||||
var argtype = typeof(node);
|
||||
if(argtype == "ghost") {
|
||||
return wrapNode(node);
|
||||
} elsif(argtype == "vector") {
|
||||
var v = node;
|
||||
var n = size(v);
|
||||
for(var i=0; i<n; i+=1) { v[i] = wrapNode(v[i]); }
|
||||
return v;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
##
|
||||
# Utility. Returns a new object with its superclass/parent set to the
|
||||
# Node object and its _g (ghost) field set to the specified object.
|
||||
|
||||
179
test/props_sim.nas
Normal file
179
test/props_sim.nas
Normal file
@@ -0,0 +1,179 @@
|
||||
var geodinfo=func(lat,lon){
|
||||
return {};
|
||||
}
|
||||
var maketimer=func(interval,function){
|
||||
return {
|
||||
isRunning:0,
|
||||
start:func(){
|
||||
me.isRunning=1;
|
||||
while(1){
|
||||
unix.sleep(interval);
|
||||
function();
|
||||
}
|
||||
},
|
||||
stop:func(){
|
||||
me.isRunning=0;
|
||||
},
|
||||
restart:func(interval){
|
||||
|
||||
},
|
||||
singleShot:0,
|
||||
simulatedTime:0
|
||||
};
|
||||
}
|
||||
|
||||
var props=
|
||||
{
|
||||
globals:nil,
|
||||
Node:nil,
|
||||
getNode:func(path,index)
|
||||
{
|
||||
path=split('/',path);
|
||||
var tmp=me.globals;
|
||||
var path_size=size(path);
|
||||
for(var i=0;i<path_size-1;i+=1)
|
||||
tmp=tmp.val[path[i]];
|
||||
if(path_size>0)
|
||||
{
|
||||
if(contains(tmp.val,path[i]~'['~index~']'))
|
||||
return tmp.val[path[i]~'['~index~']'];
|
||||
else
|
||||
return tmp.val[path[i]];
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
props.Node=
|
||||
{
|
||||
new:func(values=nil)
|
||||
{
|
||||
var result={
|
||||
parents:[props.Node],
|
||||
val:{},
|
||||
type:'GHOST',
|
||||
parent:nil
|
||||
};
|
||||
if(typeof(values)=="hash")
|
||||
result.val=values;
|
||||
return result;
|
||||
},
|
||||
addChild:func(name)
|
||||
{
|
||||
if(!contains(me.val,name))
|
||||
{
|
||||
me.val[name]=props.Node.new();
|
||||
me.val[name].parent=me;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
addChildren:func(name,cnt=0)
|
||||
{
|
||||
for(var i=0;i<cnt;i+=1)
|
||||
{
|
||||
var label=name~'['~i~']';
|
||||
me.val[label]=props.Node.new();
|
||||
me.val[label].parent=me;
|
||||
}
|
||||
return;
|
||||
},
|
||||
setValue:func(path,val)
|
||||
{
|
||||
path=split('/',path);
|
||||
var tmp=me;
|
||||
foreach(var label;path)
|
||||
tmp=tmp.val[label];
|
||||
tmp.val=val;
|
||||
if(typeof(val)=='str')
|
||||
{
|
||||
if(val=='true' or val=='false')
|
||||
tmp.type='BOOL';
|
||||
else
|
||||
tmp.type='STRING';
|
||||
}
|
||||
elsif(typeof(val)=='num')
|
||||
tmp.type='DOUBLE';
|
||||
return;
|
||||
},
|
||||
setIntValue:func(num)
|
||||
{
|
||||
me.val=num;
|
||||
me.type='INT';
|
||||
return;
|
||||
},
|
||||
setBoolValue:func(state)
|
||||
{
|
||||
me.val=state;
|
||||
me.type='BOOL';
|
||||
return;
|
||||
},
|
||||
setDoubleValue:func(num)
|
||||
{
|
||||
me.val=num;
|
||||
me.type='DOUBLE';
|
||||
return;
|
||||
},
|
||||
getValue:func(){return me.val;},
|
||||
getName:func()
|
||||
{
|
||||
var val=me.parent.val;
|
||||
var key=keys(val);
|
||||
foreach(var k;key)
|
||||
if(val[k]==me)
|
||||
return k;
|
||||
return '';
|
||||
},
|
||||
getParent:func()
|
||||
{
|
||||
return me.parent;
|
||||
},
|
||||
getPath:func()
|
||||
{
|
||||
if(me.parent==nil) return '';
|
||||
return me.parent.getPath()~'/'~me.getName();
|
||||
},
|
||||
equals:func(node){return me==node;},
|
||||
debug:func(s='')
|
||||
{
|
||||
if(typeof(me.val)=='hash')
|
||||
{
|
||||
var key=keys(me.val);
|
||||
if(!size(key))
|
||||
{
|
||||
println("{}");
|
||||
return;
|
||||
}
|
||||
println('{');
|
||||
foreach(var k;key)
|
||||
{
|
||||
print(s~' ',k,':');
|
||||
me.val[k].debug(s~' ');
|
||||
}
|
||||
println(s,'}');
|
||||
}
|
||||
else
|
||||
println(me.val,' (',me.type,')');
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
props.globals=props.Node.new();
|
||||
var c=['aircraft','ai','models','position','orientation','controls','sim'];
|
||||
foreach(var i;c)
|
||||
props.getNode('/',1).addChild(i);
|
||||
props.getNode('/ai',1).addChildren('ai',4);
|
||||
props.getNode('/aircraft',1).setValue('/','IDG MD-11');
|
||||
for(var i=0;i<4;i+=1)
|
||||
props.getNode('/ai/ai['~i~']',1).setBoolValue('true');
|
||||
props.getNode('/models',1).addChildren('building',4);
|
||||
for(var i=0;i<4;i+=1)
|
||||
props.getNode('/models/building['~i~']',1).setIntValue(i);
|
||||
props.getNode('/',1).addChild('test');
|
||||
props.getNode('/test',1).addChildren('in',4);
|
||||
props.getNode('/test/in',0).setValue('/','true');
|
||||
props.getNode('/test/in',1).setValue('/','false');
|
||||
props.getNode('/test/in',2).setValue('/','welcome aboard,need help? use help->tutorial');
|
||||
props.getNode('/test/in',3).setValue('/',2147483648);
|
||||
props.globals.debug();
|
||||
println(props.getNode('/test/in',3).getPath());
|
||||
63
test/qrcode.nas
Normal file
63
test/qrcode.nas
Normal file
@@ -0,0 +1,63 @@
|
||||
var code=[
|
||||
[1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1],
|
||||
[1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1],
|
||||
[1,0,1,1,1,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,1],
|
||||
[1,0,1,1,1,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,1],
|
||||
[1,0,1,1,1,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,1],
|
||||
[1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1],
|
||||
[1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1],
|
||||
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
];
|
||||
|
||||
if(os.platform()=="windows")
|
||||
system("chcp 65001");
|
||||
var texture=[" ","██"];
|
||||
for(var i=0;i<size(code);i+=1){
|
||||
for(var j=0;j<size(code[i]);j+=1)
|
||||
print(texture[code[i][j]]);
|
||||
print('\n');
|
||||
}
|
||||
|
||||
var transfer=func(s){
|
||||
var mode=[0,1,0,0];
|
||||
println(mode);
|
||||
|
||||
var len=size(s);
|
||||
var vec=[0,0,0,0,0,0,0,0,0];
|
||||
for(var i=8;i>=0;i-=1){
|
||||
vec[i]=bits.bitand(1,len);
|
||||
len=int(len/2);
|
||||
}
|
||||
println(vec);
|
||||
|
||||
var bitstr=[];
|
||||
for(var i=0;i<size(s);i+=1){
|
||||
var tmp=[0,0,0,0,0,0,0,0];
|
||||
var c=s[i];
|
||||
for(var j=7;j>=0;j-=1){
|
||||
tmp[j]=bits.bitand(1,c);
|
||||
c=int(c/2);
|
||||
}
|
||||
foreach(var j;tmp)
|
||||
append(bitstr,j);
|
||||
}
|
||||
println(bitstr);
|
||||
|
||||
var end=[0,0,0,0];
|
||||
println(end);
|
||||
}
|
||||
|
||||
transfer("github.com/ValKmjolnir");
|
||||
@@ -1,35 +0,0 @@
|
||||
# lib queue.nas
|
||||
var block_alloc=func()
|
||||
{
|
||||
return {elem:nil,next:nil};
|
||||
}
|
||||
var new_queue=func()
|
||||
{
|
||||
return {next:nil};
|
||||
}
|
||||
var queue_push=func(queue,elem)
|
||||
{
|
||||
var tmp=queue;
|
||||
while(tmp.next!=nil)
|
||||
tmp=tmp.next;
|
||||
tmp.next=block_alloc();
|
||||
tmp.next.elem=elem;
|
||||
}
|
||||
var queue_pop=func(queue)
|
||||
{
|
||||
var tmp=queue.next;
|
||||
if(tmp!=nil)
|
||||
queue.next=tmp.next;
|
||||
return;
|
||||
}
|
||||
var queue_front=func(queue)
|
||||
{
|
||||
var tmp=queue.next;
|
||||
if(tmp!=nil)
|
||||
return tmp.elem;
|
||||
return nil;
|
||||
}
|
||||
var queue_empty=func(queue)
|
||||
{
|
||||
return queue.next==nil;
|
||||
}
|
||||
24
test/quick_sort.nas
Normal file
24
test/quick_sort.nas
Normal file
@@ -0,0 +1,24 @@
|
||||
var sort=func(vec,left,right)
|
||||
{
|
||||
if(left>=right) return;
|
||||
var (L,R,tmp)=(left,right,vec[left]);
|
||||
while(left<right)
|
||||
{
|
||||
while(left<right and tmp<=vec[right])
|
||||
right-=1;
|
||||
while(left<right and tmp>=vec[left])
|
||||
left+=1;
|
||||
if(left!=right)
|
||||
(vec[left],vec[right])=(vec[right],vec[left]);
|
||||
}
|
||||
(vec[L],vec[left])=(vec[left],tmp);
|
||||
sort(vec,L,left-1);
|
||||
sort(vec,left+1,R);
|
||||
return;
|
||||
}
|
||||
var vec=[];
|
||||
rand(time(0));
|
||||
for(var i=0;i<1e4;i+=1)
|
||||
append(vec,int(rand()*1e5));
|
||||
sort(vec,0,size(vec)-1);
|
||||
println(vec);
|
||||
103
test/scalar.nas
103
test/scalar.nas
@@ -54,7 +54,7 @@ var hash_4={
|
||||
|
||||
# function
|
||||
var func_1=func(){return 1;}
|
||||
var prt=func(x){print(x);return nil;}
|
||||
var prt=func(x){println(x);return nil;}
|
||||
var func_with_dynamic_id=func(a,b,c,d...){return [a,b,c,d];}
|
||||
var func_with_lack_para=func(a,b,c=1,d=2){return a+b+c+d;}
|
||||
var func_with_func_para=func(a,f){return f(a);}
|
||||
@@ -72,21 +72,21 @@ var source={
|
||||
member_1: func func_1(), # this will get a number
|
||||
member_2: func {return 2.71828;} # this will get a function
|
||||
};
|
||||
print(source['member_2']());
|
||||
print(source.member_2());
|
||||
println(source['member_2']());
|
||||
println(source.member_2());
|
||||
|
||||
var test_func=func{return 1;}
|
||||
print(func test_func()); # 1
|
||||
print(test_func()); # 1
|
||||
print(func test_func); # nothing
|
||||
print(test_func); # nothing
|
||||
print(([0,1,2,3])[1]); # 1
|
||||
print(({str:"what?"})["str"]); # what?
|
||||
print(({str:"what?"}).str); # what?
|
||||
println(func test_func()); # 1
|
||||
println(test_func()); # 1
|
||||
println(func test_func); # nothing
|
||||
println(test_func); # nothing
|
||||
println(([0,1,2,3])[1]); # 1
|
||||
println(({str:"what?"})["str"]); # what?
|
||||
println(({str:"what?"}).str); # what?
|
||||
|
||||
# lambda
|
||||
(func(x){return x>0? x:0;})(12);
|
||||
(func{print("hello world");})();
|
||||
(func{println("hello world");})();
|
||||
(((func(x){return 1.0/math.exp(x);})))(0);
|
||||
|
||||
# flexible definition & assignment
|
||||
@@ -114,7 +114,7 @@ var multi_assign_2=[10,9,8,7];
|
||||
((-1*2+9))/7-1;
|
||||
((({num:2})))["num"]*2*2*2;
|
||||
((((([0,1,2])[0:2]))[0:2]))[1]-1;
|
||||
(((((((((((((((((((1+1+2+3+5)+8))+13)))+21))))+34)))))+55))))*89;
|
||||
println((((((((((((((((((((1+1+2+3+5)+8))+13)))+21))))+34)))))+55))))*89); # 12727
|
||||
number_1*(number_2+number_3)/90-number_4;
|
||||
(func test_func)()-1;
|
||||
hash_3.member_3+(func {return {what:"i don't tell you.",case_small:80,case_large:100}})()["case_large"]/10;
|
||||
@@ -123,4 +123,81 @@ nil and 1+7*8;
|
||||
(number_1 or number_2) and (number_3 or number_4-number_4*1);
|
||||
[0,1,4,3,2][4]*2-4+1*2*2*2*2*2/8;
|
||||
{num:0}.num or {what_is_the_secret_of_universe:42}["what_is_the_secret_of_universe"];
|
||||
"123"~"456"-123456*2/2;
|
||||
"123"~"456"-123456*2/2;
|
||||
|
||||
var hash={str:'hello',f:func{return me.str;}};
|
||||
var tmp_f=hash.f;
|
||||
hash=1;
|
||||
println(tmp_f());
|
||||
# undefined symbol 'me'
|
||||
# this means that
|
||||
# when generating local_scope for function f,
|
||||
# nasal_gc will not count 'me' as one reference of this hash
|
||||
|
||||
var h1={str:'hello',f:func{return me.str;}};
|
||||
var h2={str:'world',f:func{return nil;}};
|
||||
h2.f=h1.f;
|
||||
println(h2.f());
|
||||
# print 'world'
|
||||
# this means that 'me' in hash's functions
|
||||
# only points to the hash this function belongs to
|
||||
|
||||
var f1=func(){println(1);return 1;}
|
||||
var f2=func(){println(2);return 0;}
|
||||
f1() or f2();
|
||||
# print '1'
|
||||
# this means that when using 'or' or 'and',
|
||||
# if the result is clear when calculating,
|
||||
# objects behind will not be calculated
|
||||
|
||||
print(
|
||||
subvec([0,1,2,3],2),'\n',
|
||||
subvec([0,1,2,3],2,1),'\n',
|
||||
abs(1),'\n',
|
||||
abs(-1),'\n',
|
||||
systime(),'\n',
|
||||
isfunc(func{}),' ',isfunc([]),'\n',
|
||||
ishash({}),' ',ishash([]),'\n',
|
||||
isint(114.514),' ',isint(114514),'\n',
|
||||
isnum("0xaa55"),' ',isnum("?"),'\n',
|
||||
isscalar(0.618),' ',isscalar("hello"),' ',isscalar([]),'\n',
|
||||
isstr("hello"),' ',isstr(func{}),'\n',
|
||||
isvec([]),' ',isvec("[]"),'\n',
|
||||
vecindex([0,1,2,3,4],1),'\n',
|
||||
vecindex(["apple","banana"],"apple")!=nil,'\n'
|
||||
);
|
||||
|
||||
println(values({
|
||||
a:1,
|
||||
b:2,
|
||||
c:3
|
||||
}));
|
||||
println(find("cd", "abcdef")); # prints 2
|
||||
println(find("x", "abcdef")); # prints -1
|
||||
println(find("cd", "abcdef")); # prints 2
|
||||
|
||||
var a={
|
||||
new: func(x=0){
|
||||
return {
|
||||
x:x,
|
||||
parents:[a]
|
||||
};
|
||||
},
|
||||
new2: func(x=0){
|
||||
return {
|
||||
x:x,
|
||||
parents:a
|
||||
};
|
||||
}
|
||||
};
|
||||
println(isa(a.new(),a)); # 1
|
||||
println(isa(a.new2(),a));# 0
|
||||
|
||||
var a=[10,-10,0,1,2,3,nil,"string","hello",[],[0,1,2,3],{},{a:0,b:1,c:2},func{}];
|
||||
println("type\tsize\tnum\tsrc");
|
||||
foreach(var i;a){
|
||||
println(typeof(i),'\t',size(i),'\t',num(i),'\t',i);
|
||||
}
|
||||
foreach(i;a){
|
||||
;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
var global_value=0;
|
||||
var global_hash=
|
||||
{
|
||||
var1:1,
|
||||
var2:2,
|
||||
var3:func(){return me.var2;}
|
||||
};
|
||||
print(global_value);
|
||||
print(global_hash.var3());
|
||||
|
||||
var func1=func()
|
||||
{
|
||||
global_value=1;
|
||||
print(global_value);
|
||||
var closure_value=1;
|
||||
var temp_value=1;
|
||||
print(temp_value);
|
||||
return func{return closure_value;};
|
||||
}
|
||||
|
||||
var func2=func()
|
||||
{
|
||||
for(var temp_value=0;temp_value<100;temp_value+=1)
|
||||
{
|
||||
if(temp_value<10)
|
||||
print(temp_value,"< 10");
|
||||
elsif(10<=temp_value and temp_value<50)
|
||||
print(temp_value,"< 50");
|
||||
temp_value=10;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var func3=func()
|
||||
{
|
||||
var fake_closure_value=1;
|
||||
return func()
|
||||
{
|
||||
var fake_closure_value=2;
|
||||
return fake_closure_value;
|
||||
};
|
||||
}
|
||||
|
||||
func1()();
|
||||
func2();
|
||||
func3()();
|
||||
|
||||
if(!global_value)
|
||||
{
|
||||
var temp_value=1;
|
||||
if(temp_value)
|
||||
{
|
||||
var temp_value=2;
|
||||
if(temp_value>=1)
|
||||
{
|
||||
var temp_value=3;
|
||||
print(temp_value);
|
||||
}
|
||||
print(temp_value);
|
||||
}
|
||||
print(temp_value);
|
||||
}
|
||||
216
test/snake.nas
Normal file
216
test/snake.nas
Normal file
@@ -0,0 +1,216 @@
|
||||
import("./module/libkey.nas");
|
||||
var list=func(){
|
||||
var (begin,end,len)=(nil,nil,0);
|
||||
return{
|
||||
push_back:func(elem){
|
||||
var tmp={
|
||||
elem:elem,
|
||||
prev:nil,
|
||||
next:nil
|
||||
};
|
||||
if(end!=nil){
|
||||
end.next=tmp;
|
||||
tmp.prev=end;
|
||||
end=tmp;
|
||||
}else{
|
||||
begin=end=tmp;
|
||||
}
|
||||
len+=1;
|
||||
},
|
||||
push_front:func(elem){
|
||||
var tmp={
|
||||
elem:elem,
|
||||
prev:nil,
|
||||
next:nil
|
||||
};
|
||||
if(begin!=nil){
|
||||
begin.prev=tmp;
|
||||
tmp.next=begin;
|
||||
begin=tmp;
|
||||
}else{
|
||||
begin=end=tmp;
|
||||
}
|
||||
len+=1;
|
||||
},
|
||||
pop_back:func(){
|
||||
if(end!=nil)
|
||||
end=end.prev;
|
||||
if(end==nil)
|
||||
begin=nil;
|
||||
else
|
||||
end.next=nil;
|
||||
if(len)
|
||||
len-=1;
|
||||
},
|
||||
pop_front:func(){
|
||||
if(begin!=nil)
|
||||
begin=begin.next;
|
||||
if(begin==nil)
|
||||
end=nil;
|
||||
else
|
||||
begin.prev=nil;
|
||||
if(len)
|
||||
len-=1;
|
||||
},
|
||||
front:func(){
|
||||
if(begin!=nil)
|
||||
return begin.elem;
|
||||
},
|
||||
back:func(){
|
||||
if(end!=nil)
|
||||
return end.elem;
|
||||
},
|
||||
length:func(){
|
||||
return len;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var game=func(x,y){
|
||||
rand(time(0));
|
||||
var texture=[" ","██","\e[91m██\e[0m"];
|
||||
var edge0="╔";
|
||||
var edge1="╚";
|
||||
for(var i=0;i<x;i+=1){
|
||||
edge0~="══";
|
||||
edge1~="══";
|
||||
}
|
||||
edge0~="╗\n";
|
||||
edge1~="╝\n";
|
||||
|
||||
var vec=[];
|
||||
setsize(vec,x);
|
||||
for(var i=0;i<x;i+=1){
|
||||
vec[i]=[];
|
||||
setsize(vec[i],y);
|
||||
for(var j=0;j<y;j+=1)
|
||||
vec[i][j]=0;
|
||||
}
|
||||
|
||||
var snake=list();
|
||||
snake.push_back([int(x/2),int(y/3)]);
|
||||
snake.push_back([int(x/2),int(y/3)+1]);
|
||||
vec[int(x/2)][int(y/3)]=1;
|
||||
vec[int(x/2)][int(y/3)+1]=1;
|
||||
|
||||
var move='w';
|
||||
var gameover=0;
|
||||
var setapple=func(){
|
||||
var (cord_x,cord_y)=(int(rand()*x),int(rand()*y));
|
||||
while(vec[cord_x][cord_y]!=0)
|
||||
(cord_x,cord_y)=(int(rand()*x),int(rand()*y));
|
||||
vec[cord_x][cord_y]=2;
|
||||
}
|
||||
setapple();
|
||||
|
||||
return {
|
||||
print:func(){
|
||||
var s="";
|
||||
var (fx,fy)=snake.front();
|
||||
for(var i=0;i<y;i+=1){
|
||||
s~="║";
|
||||
for(var j=0;j<x;j+=1){
|
||||
if(fx==j and fy==i)
|
||||
s~="\e[93m"~texture[vec[j][i]]~"\e[0m";
|
||||
else
|
||||
s~=texture[vec[j][i]];
|
||||
}
|
||||
s~='║\n';
|
||||
}
|
||||
print('\e[1;1H'~edge0~s~edge1);
|
||||
},
|
||||
next:func(){
|
||||
var (fx,fy)=snake.front();
|
||||
var eat=0;
|
||||
if(move=="w" and fy-1>=0){
|
||||
snake.push_front([fx,fy-1]);
|
||||
if(vec[fx][fy-1]==1)
|
||||
gameover=1;
|
||||
elsif(vec[fx][fy-1]==2)
|
||||
eat=1;
|
||||
vec[fx][fy-1]=1;
|
||||
}elsif(move=='a' and fx-1>=0){
|
||||
snake.push_front([fx-1,fy]);
|
||||
if(vec[fx-1][fy]==1)
|
||||
gameover=1;
|
||||
elsif(vec[fx-1][fy]==2)
|
||||
eat=1;
|
||||
vec[fx-1][fy]=1;
|
||||
}elsif(move=='s' and fy+1<y){
|
||||
snake.push_front([fx,fy+1]);
|
||||
if(vec[fx][fy+1]==1)
|
||||
gameover=1;
|
||||
elsif(vec[fx][fy+1]==2)
|
||||
eat=1;
|
||||
vec[fx][fy+1]=1;
|
||||
}elsif(move=='d' and fx+1<x){
|
||||
snake.push_front([fx+1,fy]);
|
||||
if(vec[fx+1][fy]==1)
|
||||
gameover=1;
|
||||
elsif(vec[fx+1][fy]==2)
|
||||
eat=1;
|
||||
vec[fx+1][fy]=1;
|
||||
}else{
|
||||
gameover=1;
|
||||
}
|
||||
if(!gameover and !eat){
|
||||
var (bx,by)=snake.back();
|
||||
vec[bx][by]=0;
|
||||
snake.pop_back();
|
||||
}
|
||||
|
||||
if(eat and snake.length()!=x*y)
|
||||
setapple();
|
||||
elsif(snake.length()==x*y)
|
||||
gameover=2;
|
||||
},
|
||||
move:func(c){
|
||||
if(c=='w' or c=='a' or c=='s' or c=='d')
|
||||
move=c;
|
||||
},
|
||||
gameover:func(){
|
||||
return gameover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var main=func(){
|
||||
if(os.platform()=="windows")
|
||||
system("chcp 65001");
|
||||
print("\ec");
|
||||
libkey.init();
|
||||
var g=game(15,10);
|
||||
g.print();
|
||||
print("\rpress any key to start...");
|
||||
libkey.getch();
|
||||
print("\r \r");
|
||||
var counter=12;
|
||||
while(1){
|
||||
var ch=libkey.nonblock();
|
||||
if(ch!=nil){
|
||||
if(ch=='q'[0])
|
||||
break;
|
||||
elsif(ch=='p'[0]){
|
||||
print("\rpress any key to continue...");
|
||||
libkey.getch();
|
||||
print("\r \r");
|
||||
}
|
||||
g.move(chr(ch));
|
||||
}
|
||||
unix.sleep(0.02);
|
||||
counter-=1;
|
||||
if(counter==0){
|
||||
counter=20;
|
||||
g.next();
|
||||
if(g.gameover())
|
||||
break;
|
||||
g.print();
|
||||
}
|
||||
}
|
||||
libkey.close();
|
||||
println(g.gameover()<=1?"game over.":"you win!");
|
||||
println("enter anything to quit.");
|
||||
input();
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,24 +0,0 @@
|
||||
var hash={str:'hello',f:func{return me.str;}};
|
||||
var tmp_f=hash.f;
|
||||
hash=1;
|
||||
print(tmp_f());
|
||||
# undefined symbol 'me'
|
||||
# this means that
|
||||
# when generating local_scope for function f,
|
||||
# nasal_gc will not count 'me' as one reference of this hash
|
||||
|
||||
var h1={str:'hello',f:func{return me.str;}};
|
||||
var h2={str:'world',f:func{return nil;}};
|
||||
h2.f=h1.f;
|
||||
print(h2.f());
|
||||
# print 'world'
|
||||
# this means that 'me' in hash's functions
|
||||
# only points to the hash this function belongs to
|
||||
|
||||
var f1=func(){print(1);return 1;}
|
||||
var f2=func(){print(2);return 0;}
|
||||
f1() or f2();
|
||||
# print '1'
|
||||
# this means that when using 'or' or 'and',
|
||||
# if the result is clear when calculating,
|
||||
# objects behind will not be calculated
|
||||
@@ -1,34 +0,0 @@
|
||||
# lib stack.nas
|
||||
var block_alloc=func()
|
||||
{
|
||||
return {elem:nil,next:nil};
|
||||
}
|
||||
var new_stack=func()
|
||||
{
|
||||
return {next:nil};
|
||||
}
|
||||
var stack_push=func(stack,elem)
|
||||
{
|
||||
var tmp=stack.next;
|
||||
stack.next=block_alloc();
|
||||
stack.next.elem=elem;
|
||||
stack.next.next=tmp;
|
||||
}
|
||||
var stack_pop=func(stack)
|
||||
{
|
||||
var tmp=stack.next;
|
||||
if(tmp!=nil)
|
||||
stack.next=tmp.next;
|
||||
return;
|
||||
}
|
||||
var stack_top=func(stack)
|
||||
{
|
||||
var tmp=stack.next;
|
||||
if(tmp!=nil)
|
||||
return tmp.elem;
|
||||
return nil;
|
||||
}
|
||||
var stack_empty=func(stack)
|
||||
{
|
||||
return stack.next==nil;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import("lib.nas");
|
||||
var filename="";
|
||||
|
||||
filename=input();
|
||||
print(filename[0]);
|
||||
348
test/tetris.nas
Normal file
348
test/tetris.nas
Normal file
@@ -0,0 +1,348 @@
|
||||
import("./module/libkey.nas");
|
||||
var color=[
|
||||
"\e[31m","\e[32m","\e[33m","\e[34m","\e[35m","\e[36m",
|
||||
"\e[91m","\e[92m","\e[93m","\e[94m","\e[95m","\e[96m",
|
||||
];
|
||||
var blocktype=[
|
||||
[0,1,2,3 ],
|
||||
[4,5,6,7 ],
|
||||
[8,9,10,11],
|
||||
[12,13 ],
|
||||
[14 ],
|
||||
[15,16 ],
|
||||
[17,18 ]
|
||||
];
|
||||
var blockshape=[
|
||||
# [][] [] [][][]
|
||||
# [] [] [] []
|
||||
# [] [][][] [][]
|
||||
[[0,0],[1,0],[0,1],[0,2]],
|
||||
[[0,0],[0,1],[1,1],[2,1]],
|
||||
[[0,0],[0,1],[0,2],[-1,2]],
|
||||
[[0,0],[1,0],[2,0],[2,1]],
|
||||
# [][] [][][] []
|
||||
# [] [] [] []
|
||||
# [] [][] [][][]
|
||||
[[0,0],[1,0],[1,1],[1,2]],
|
||||
[[0,0],[1,0],[2,0],[0,1]],
|
||||
[[0,0],[0,1],[0,2],[1,2]],
|
||||
[[0,0],[0,1],[-1,1],[-2,1]],
|
||||
# [] [] [][][] []
|
||||
# [][][] [][] [] [][]
|
||||
# [] []
|
||||
[[0,0],[0,1],[-1,1],[1,1]],
|
||||
[[0,0],[0,1],[-1,1],[0,2]],
|
||||
[[0,0],[-1,0],[1,0],[0,1]],
|
||||
[[0,0],[0,1],[0,2],[1,1]],
|
||||
# [] [][][][]
|
||||
# []
|
||||
# []
|
||||
# []
|
||||
[[0,0],[0,1],[0,2],[0,3]],
|
||||
[[0,0],[1,0],[2,0],[3,0]],
|
||||
# [][]
|
||||
# [][]
|
||||
[[0,0],[1,0],[0,1],[1,1]],
|
||||
# [] [][]
|
||||
# [][] [][]
|
||||
# []
|
||||
[[0,0],[0,1],[-1,1],[-1,2]],
|
||||
[[0,0],[1,0],[1,1],[2,1]],
|
||||
# [] [][]
|
||||
# [][] [][]
|
||||
# []
|
||||
[[0,0],[0,1],[1,1],[1,2]],
|
||||
[[0,0],[1,0],[0,1],[-1,1]]
|
||||
];
|
||||
|
||||
var color_count=0;
|
||||
var counter=0;
|
||||
var package=[0,1,2,3,4,5,6];
|
||||
var exchange=func(){
|
||||
for(var i=6;i>=0;i-=1){
|
||||
var index=int(i*rand());
|
||||
(package[i],package[index])=(package[index],package[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var block={
|
||||
x:0,
|
||||
y:0,
|
||||
rotate:0,
|
||||
type:nil,
|
||||
shape:nil,
|
||||
color:nil,
|
||||
new:func(x=0,y=0){
|
||||
(me.x,me.y)=(x,y);
|
||||
me.rotate=0;
|
||||
me.type=blocktype[package[counter]];
|
||||
counter+=1;
|
||||
if(counter==7){
|
||||
exchange();
|
||||
counter=0;
|
||||
}
|
||||
|
||||
me.shape=blockshape[me.type[me.rotate]];
|
||||
|
||||
me.color=color_count;
|
||||
color_count+=1;
|
||||
if(color_count>=size(color))
|
||||
color_count=0;
|
||||
|
||||
return {parents:[block]};
|
||||
}
|
||||
};
|
||||
|
||||
var mapgen=func(mapx,mapy){
|
||||
var (score,gameover)=(0,0);
|
||||
var (empty,unset,full)=(0,1,2);
|
||||
|
||||
if(mapx<1 or mapy<1)
|
||||
die("map_x or map_y must be greater than 1");
|
||||
|
||||
# use in print
|
||||
var line="";
|
||||
for(var i=0;i<mapx;i+=1)
|
||||
line~="══";
|
||||
var head="\e[32m╔"~line~"╗\e[0m\n";
|
||||
var tail="\e[32m╚"~line~"╝\e[0m\n";
|
||||
|
||||
# generate new map
|
||||
var map=[];
|
||||
for(var y=0;y<mapy;y+=1){
|
||||
var tmp=[];
|
||||
for(var x=0;x<mapx;x+=1)
|
||||
append(tmp,empty);
|
||||
append(map,tmp);
|
||||
}
|
||||
|
||||
var blk=nil;
|
||||
var new_block=func(){
|
||||
blk=block.new(int(mapx/2),0);
|
||||
|
||||
# check if has enough place to place a new block
|
||||
foreach(var i;blk.shape)
|
||||
if(map[blk.y+i[1]][blk.x+i[0]]>=full){
|
||||
gameover=1;
|
||||
return;
|
||||
}
|
||||
# update map
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=unset;
|
||||
}
|
||||
new_block(); # initialize the first block
|
||||
|
||||
# color print
|
||||
var map_print=func(){
|
||||
var s="\e[1;1H"~head;
|
||||
for(var y=0;y<mapy;y+=1){
|
||||
s~="\e[32m║\e[0m";
|
||||
for(var x=0;x<mapx;x+=1){
|
||||
var c=map[y][x];
|
||||
if(c==empty)
|
||||
s~=" ";
|
||||
elsif(c==unset)
|
||||
s~=color[blk.color]~"██\e[0m";
|
||||
elsif(c>=full)
|
||||
s~=color[c-full]~"██\e[0m";
|
||||
}
|
||||
s~="\e[32m║\e[0m\n";
|
||||
}
|
||||
s~=tail;
|
||||
print(s,"\e[31ms\e[32mc\e[33mo\e[34mr\e[35me\e[36m: \e[0m",score,'\n');
|
||||
}
|
||||
|
||||
var moveleft=func(){
|
||||
var (x,y)=(blk.x-1,blk.y);
|
||||
foreach(var i;blk.shape){
|
||||
if(x+i[0]<0)
|
||||
return;
|
||||
if(map[y+i[1]][x+i[0]]>=full)
|
||||
return;
|
||||
}
|
||||
# update block state and map
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=empty;
|
||||
blk.x=x;
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=unset;
|
||||
map_print();
|
||||
}
|
||||
|
||||
var moveright=func(){
|
||||
var (x,y)=(blk.x+1,blk.y);
|
||||
foreach(var i;blk.shape){
|
||||
if(x+i[0]>=mapx)
|
||||
return;
|
||||
if(map[y+i[1]][x+i[0]]>=full)
|
||||
return;
|
||||
}
|
||||
# update block state and map
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=empty;
|
||||
blk.x=x;
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=unset;
|
||||
map_print();
|
||||
}
|
||||
|
||||
var rotate=func(){
|
||||
var (r,x,y)=(blk.rotate,blk.x,blk.y);
|
||||
r=(r+1>=size(blk.type))?0:r+1;
|
||||
var shape=blockshape[blk.type[r]];
|
||||
foreach(var i;shape){
|
||||
if(x+i[0]>=mapx or x+i[0]<0 or y+i[1]>=mapy or y+i[1]<0)
|
||||
return;
|
||||
if(map[y+i[1]][x+i[0]]>=full)
|
||||
return;
|
||||
}
|
||||
|
||||
# update block state and map
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=empty;
|
||||
blk.rotate=r;
|
||||
blk.shape=shape;
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=unset;
|
||||
map_print();
|
||||
}
|
||||
|
||||
var fall=func(){
|
||||
var (x,y)=(blk.x,blk.y+1);
|
||||
# check if falls to the edge of other blocks or map
|
||||
var sethere=0;
|
||||
foreach(var i;blk.shape)
|
||||
if(y+i[1]>=mapy or map[y+i[1]][x+i[0]]>=full){
|
||||
sethere=1;
|
||||
break;
|
||||
}
|
||||
# set block here and generate a new block
|
||||
if(sethere){
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=blk.color+full;
|
||||
checkmap();
|
||||
new_block();
|
||||
map_print();
|
||||
return;
|
||||
}
|
||||
# update block state and map
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=empty;
|
||||
blk.y=y;
|
||||
foreach(var i;blk.shape)
|
||||
map[blk.y+i[1]][blk.x+i[0]]=unset;
|
||||
map_print();
|
||||
}
|
||||
|
||||
var checkmap=func(){
|
||||
var lines=1;
|
||||
for(var y=mapy-1;y>=0;y-=1){
|
||||
# check if this line is full of blocks
|
||||
var tmp=0;
|
||||
for(var x=0;x<mapx;x+=1){
|
||||
if(map[y][x]<full)
|
||||
break;
|
||||
tmp+=map[y][x];
|
||||
}
|
||||
# if is full, clear this line and
|
||||
# all the lines above fall one block
|
||||
if(x==mapx){
|
||||
score+=lines*tmp;
|
||||
lines*=2;
|
||||
for(var t=y;t>=1;t-=1)
|
||||
for(var x=0;x<mapx;x+=1)
|
||||
map[t][x]=map[t-1][x];
|
||||
for(var x=0;x<mapx;x+=1)
|
||||
map[0][x]=empty;
|
||||
y+=1;
|
||||
}
|
||||
}
|
||||
map_print();
|
||||
}
|
||||
return {
|
||||
print:map_print,
|
||||
moveleft:moveleft,
|
||||
moveright:moveright,
|
||||
rotate:rotate,
|
||||
fall:fall,
|
||||
checkmap:checkmap,
|
||||
gameover:func(){return gameover;}
|
||||
};
|
||||
}
|
||||
|
||||
var main=func(){
|
||||
# windows use chcp 65001 to output unicode
|
||||
if(os.platform()=="windows")
|
||||
system("chcp 65001");
|
||||
|
||||
libkey.init();
|
||||
print(
|
||||
"\ec\e[1:1H",
|
||||
"╔═════════════════════════╗\n",
|
||||
"║ TETRIS ║\n",
|
||||
"╠═════════════════════════╣\n",
|
||||
"║ w:rotate, a:move left ║\n",
|
||||
"║ s:fall, d:move right ║\n",
|
||||
"║ p:pause, q:quit ║\n",
|
||||
"╠═════════════════════════╣\n",
|
||||
"║ press any key to start ║\n",
|
||||
"╚═════════════════════════╝\n"
|
||||
);
|
||||
|
||||
rand(time(0));
|
||||
exchange();
|
||||
var map=mapgen(mapx:12,mapy:18);
|
||||
|
||||
libkey.getch();
|
||||
print("\ec");
|
||||
|
||||
var counter=30;
|
||||
while(1){
|
||||
# nonblock input one character
|
||||
var ch=libkey.nonblock();
|
||||
if(ch){
|
||||
if(ch=='a'[0]) # move left
|
||||
map.moveleft();
|
||||
elsif(ch=='d'[0]) # move right
|
||||
map.moveright();
|
||||
elsif(ch=='w'[0]) # rotate
|
||||
map.rotate();
|
||||
elsif(ch=='s'[0]) # move down
|
||||
map.fall();
|
||||
elsif(ch=='q'[0]) # quit the game
|
||||
break;
|
||||
if(ch=='p'[0]){ # pause the game
|
||||
print("\rpress any key to continue...");
|
||||
libkey.getch();
|
||||
print("\r ");
|
||||
}
|
||||
map.checkmap();
|
||||
if(map.gameover())
|
||||
break;
|
||||
}
|
||||
if(!counter){
|
||||
# automatically fall one block and check
|
||||
map.fall();
|
||||
map.checkmap();
|
||||
if(map.gameover())
|
||||
break;
|
||||
counter=30;
|
||||
}
|
||||
unix.sleep(0.02);
|
||||
counter-=1;
|
||||
}
|
||||
libkey.close();
|
||||
print(
|
||||
map.gameover()?
|
||||
"\e[31mg\e[32ma\e[33mm\e[34me \e[35mo\e[36mv\e[94me\e[31mr \e[32m~\e[0m\n":
|
||||
"\e[31ms\e[32me\e[33me \e[34my\e[35mo\e[36mu \e[94m~\e[0m\n"
|
||||
);
|
||||
print(
|
||||
"\e[31me\e[32mn\e[33mt\e[34me\e[35mr ",
|
||||
"\e[36ma\e[94mn\e[95my\e[96mt\e[31mh\e[32mi\e[33mn\e[34mg ",
|
||||
"\e[35mt\e[36mo \e[94mq\e[95mu\e[91mi\e[92mt\e[0m\n"
|
||||
);
|
||||
input();
|
||||
};
|
||||
|
||||
main();
|
||||
38
test/trait.nas
Normal file
38
test/trait.nas
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
var trait={
|
||||
get:func{return me.val;},
|
||||
set:func(x){me.val=x;}
|
||||
};
|
||||
|
||||
var class={
|
||||
new:func(){
|
||||
return {
|
||||
val:nil,
|
||||
parents:[trait]
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
var class2={
|
||||
new:func(){
|
||||
return {
|
||||
val:nil,
|
||||
parents:[trait],
|
||||
set:func(x){me.val=typeof(x);}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
var class_obj=[];
|
||||
for(var i=0;i<10;i+=1){
|
||||
append(class_obj,class.new());
|
||||
class_obj[i].set(i);
|
||||
}
|
||||
for(var i=0;i<10;i+=1){
|
||||
append(class_obj,class2.new());
|
||||
class_obj[10+i].set(i);
|
||||
}
|
||||
|
||||
foreach(var object;class_obj){
|
||||
println(object.get(),' ',keys(object));
|
||||
}
|
||||
100
test/turingmachine.nas
Normal file
100
test/turingmachine.nas
Normal file
@@ -0,0 +1,100 @@
|
||||
|
||||
var table=[
|
||||
['q0','0','1','R','q1'],
|
||||
['q1','1','1','R','q1'],
|
||||
['q1','0','0','S','q2'],
|
||||
['q2','0','1','R','q3'],
|
||||
['q3',nil,nil,'S','q3']
|
||||
];
|
||||
|
||||
var operand={
|
||||
new:func(symbol,changed_symbol,move,next_state){
|
||||
if(move!='L' and move!='R' and move!='S')
|
||||
die("invalid move type:"+move);
|
||||
return {
|
||||
symbol:symbol,
|
||||
changed_symbol:changed_symbol,
|
||||
move:move,
|
||||
next_state:next_state
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
var machine={
|
||||
states:{},
|
||||
add:func(state,operand){
|
||||
if(!contains(me.states,state))
|
||||
me.states[state]=[operand];
|
||||
else{
|
||||
foreach(var i;me.states[state])
|
||||
if(i.symbol==operand.symbol or i.symbol==nil){
|
||||
println(i);
|
||||
die("conflict operand");
|
||||
}
|
||||
append(me.states[state],operand);
|
||||
}
|
||||
},
|
||||
load:func(data){
|
||||
foreach(var opr;data){
|
||||
var (nstat,sym,csym,move,nextstat)=opr;
|
||||
me.add(nstat,operand.new(sym,csym,move,nextstat));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var prt=func(state,pointer,paper,act=nil){
|
||||
print(act!=nil?act:'','\n\t');
|
||||
var s='';
|
||||
foreach(var i;paper)
|
||||
s~=i;
|
||||
s~='\n\t';
|
||||
for(var i=0;i<pointer;i+=1)
|
||||
for(var j=0;j<size(paper[i]);j+=1)
|
||||
s~=' ';
|
||||
print(s,'^\n',state," ");
|
||||
}
|
||||
var run=func(table,start,stop){
|
||||
var paper=['0','1','1','1','0','1','0','a'];
|
||||
var pointer=0;
|
||||
|
||||
machine.load(table);
|
||||
|
||||
print("states: ",keys(machine.states),'\n');
|
||||
if(!contains(machine.states,start))
|
||||
die(start~" is not a valid node");
|
||||
if(!contains(machine.states,stop))
|
||||
die(stop~" is not a valid node");
|
||||
|
||||
var (state,pointer)=(start,0);
|
||||
|
||||
prt(state,pointer,paper);
|
||||
while(state!=stop){
|
||||
if(!contains(machine.states,state))
|
||||
die("no matching function for state:"~state);
|
||||
var found=0;
|
||||
foreach(var action;machine.states[state]){
|
||||
var (sym,csym,move,next)=(
|
||||
action.symbol,
|
||||
action.changed_symbol,
|
||||
action.move,
|
||||
action.next_state
|
||||
);
|
||||
if(sym==paper[pointer] or sym==nil){
|
||||
if(sym!=nil)
|
||||
paper[pointer]=csym;
|
||||
if(move=='L') pointer-=1;
|
||||
elsif(move=='R') pointer+=1;
|
||||
(state,found)=(next,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
die("no matching function for state:"~state);
|
||||
|
||||
prt(state,pointer,paper,[sym,csym,move,next]);
|
||||
}
|
||||
}
|
||||
|
||||
run(table,'q0','q3');
|
||||
print('\n');
|
||||
32
test/utf8chk.nas
Normal file
32
test/utf8chk.nas
Normal file
@@ -0,0 +1,32 @@
|
||||
var unicode测试=func(){
|
||||
var 输出=print;
|
||||
var 测试成功=[
|
||||
"unicode: utf-8支持测试成功",
|
||||
"目前仅支持utf-8以及ascii格式文件",
|
||||
"注意: windows系统请开启chcp 65001代码页"
|
||||
];
|
||||
foreach(var 内容;测试成功)
|
||||
输出(内容~"\n");
|
||||
}
|
||||
var emoji测试=func(){
|
||||
var 💻=print;
|
||||
var 🎤="\n";
|
||||
var 🤣="🤣笑嘻了";
|
||||
var 😅="😅差不多得了";
|
||||
var 🤤="🤤收收味";
|
||||
var 🥵="🥵太烧啦";
|
||||
var 🥶="🥶捏麻麻滴冷死了";
|
||||
var 🤢="🤢老八秘制小汉堡🍔";
|
||||
var 🤓="🤓我是傻逼";
|
||||
var 😭="😭你带我走吧😭😭😭";
|
||||
var 👿="👿密麻麻石蜡";
|
||||
var 🤡="🤡居然就是你";
|
||||
var 💩="💩奥利给干了兄弟们";
|
||||
var 🍾="🍾好似,开🍾咯";
|
||||
var 🐘="🐘太🚬🐘了兄弟们";
|
||||
var 📁=[🤣,😅,🤤,🥵,🥶,🤢,🤓,😭,👿,🤡,💩,🍾,🐘];
|
||||
foreach(var 📄;📁)
|
||||
💻(📄,🎤);
|
||||
}
|
||||
unicode测试();
|
||||
emoji测试();
|
||||
104
test/wavecollapse.nas
Normal file
104
test/wavecollapse.nas
Normal file
@@ -0,0 +1,104 @@
|
||||
# wave collapse function 2022/4/10
|
||||
# by ValKmjolnir
|
||||
srand();
|
||||
var interval=1/60;
|
||||
var table=[
|
||||
# c ,w,a,s,d
|
||||
["═",0,1,0,1],
|
||||
["═",0,1,0,1],
|
||||
["═",0,1,0,1],
|
||||
["║",1,0,1,0],
|
||||
|
||||
["╔",0,0,1,1],
|
||||
["╗",0,1,1,0],
|
||||
["╚",1,0,0,1],
|
||||
["╝",1,1,0,0],
|
||||
|
||||
# ["╠",1,0,1,1],
|
||||
# ["╣",1,1,1,0],
|
||||
# ["╦",0,1,1,1],
|
||||
# ["╩",1,1,0,1],
|
||||
# ["╬",1,1,1,1],
|
||||
|
||||
[" ",0,0,0,0],
|
||||
[" ",0,0,0,0],
|
||||
[" ",0,0,0,0],
|
||||
[" ",0,0,0,0],
|
||||
[" ",0,0,0,0],
|
||||
[" ",0,0,0,0]
|
||||
];
|
||||
|
||||
var map=func(){
|
||||
var (vec,x,s)=(nil,nil,size(table));
|
||||
var generator=func(){
|
||||
var tmp=[];
|
||||
foreach(var elem;table)
|
||||
if(elem[1]==vec[0][0][3] and elem[2]==0)
|
||||
append(tmp,elem);
|
||||
vec[1][0]=tmp[rand()*size(tmp)];
|
||||
|
||||
for(var j=1;j<x;j+=1){
|
||||
if(vec[0][j][3]==0 and vec[1][j-1][4]==0 and rand()>0.5){
|
||||
vec[1][j]=table[-1];
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp=[];
|
||||
foreach(var elem;table)
|
||||
if(elem[2]==vec[1][j-1][4] and elem[1]==vec[0][j][3]){
|
||||
if((j==x-1 and elem[4]==0) or j<x-1)
|
||||
append(tmp,elem);
|
||||
}
|
||||
vec[1][j]=tmp[rand()*size(tmp)];
|
||||
}
|
||||
}
|
||||
return {
|
||||
new:func(_x=10){
|
||||
x=_x;
|
||||
vec=[[],[]];
|
||||
for(var i=0;i<2;i+=1){
|
||||
setsize(vec[i],x);
|
||||
for(var j=0;j<x;j+=1)
|
||||
vec[i][j]=table[-1];
|
||||
}
|
||||
|
||||
var tmp=[];
|
||||
foreach(var elem;table)
|
||||
if(elem[1]==0 and elem[2]==0)
|
||||
append(tmp,elem);
|
||||
vec[0][0]=tmp[rand()*size(tmp)];
|
||||
|
||||
for(var i=1;i<x;i+=1){
|
||||
tmp=[];
|
||||
foreach(var elem;table)
|
||||
if(elem[2]==vec[0][i-1][4] and elem[1]==0){
|
||||
if((i==x-1 and elem[4]==0) or i<x-1)
|
||||
append(tmp,elem);
|
||||
}
|
||||
vec[0][i]=tmp[rand()*size(tmp)];
|
||||
}
|
||||
me.print(0);
|
||||
generator();
|
||||
},
|
||||
print:func(index){
|
||||
var str="";
|
||||
foreach(var _x;vec[index])
|
||||
str~=_x[0];
|
||||
str~="\n";
|
||||
print(str);
|
||||
},
|
||||
next:func(){
|
||||
(vec[0],vec[1])=(vec[1],vec[0]);
|
||||
generator();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
if(os.platform()=="windows")
|
||||
system("chcp 65001");
|
||||
map.new(80);
|
||||
for(var iter=0;iter<100;iter+=1){
|
||||
map.print(1);
|
||||
map.next();
|
||||
unix.sleep(interval);
|
||||
}
|
||||
15
test/ycombinator.nas
Normal file
15
test/ycombinator.nas
Normal file
@@ -0,0 +1,15 @@
|
||||
# Y combinator by ValKmjolnir
|
||||
var fib=func(f){
|
||||
return f(f);
|
||||
}(
|
||||
func(f){
|
||||
return func(x){
|
||||
if(x<2) return x;
|
||||
var tmp=f(f);
|
||||
return tmp(x-1)+tmp(x-2);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
for(var i=1;i<31;i+=1)
|
||||
println(fib(i));
|
||||
Reference in New Issue
Block a user