背景
本文适合有c语言基础的朋友,且了解make编译。elk是cesanta开源社区mongoose同类产品中的javascript库。目前支持的特性如下:
- Operations: all standard JS operations except:
!=
,==
. Use strict comparison!==
,===
- No computed member access
a[b]
- Typeof:
typeof('a') === 'string'
- While:
while (...) { ... }
- Conditional:
if (...) ... else ...
- Ternary operator
a ? b : c
- Simple types:
let a, b, c = 12.3, d = 'a', e = null, f = true, g = false;
- Functions:
let f = function(x, y) { return x + y; };
- Objects:
let obj = {f: function(x) { return x * 2}}; obj.f(3);
- Every statement must end with a semicolon
;
- Strings are binary data chunks, not Unicode strings:
'Київ'.length === 8
不支持的特性如下:
- No
var
, noconst
. Uselet
(strict mode only) - No
do
,switch
,for
. Usewhile
- No
=>
functions. Uselet f = function(...) {...};
- No arrays, closures, prototypes,
this
,new
,delete
- No standard library: no
Date
,Regexp
,Function
,String
,Number
笔者在freebsd 11编译测试过程如下,仅供参考
project@freebsd:~ % git clone https://github.com/cesanta/elk.git Cloning into 'elk'... remote: Enumerating objects: 778, done. remote: Counting objects: 100% (50/50), done. remote: Compressing objects: 100% (33/33), done. remote: Total 778 (delta 17), reused 17 (delta 17), pack-reused 728 Receiving objects: 100% (778/778), 4.27 MiB | 2.29 MiB/s, done. Resolving deltas: 100% (364/364), done.
测试
cd elk/test #查看Makefile vim Makefile CFLAGS ?= -W -Wall -Werror -Wno-deprecated -I.. -g -fsanitize=address,undefined -coverage -lm $(EXTRA) CWD ?= $(realpath $(CURDIR)) ROOT ?= $(realpath $(CURDIR)/..) DOCKER = docker run $(DA) --rm -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CWD) DESTDIR ?= . define clean rm -rf *.o *.dSYM ut* elk fuzzer* *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* a.out tmp endef # %(call build,ENVIRONMENT,COMPILE,FLAGS,OUTPUT,RUN) define build $(call clean) $1 $2 unit_test.c $3 $1 $4 endef all: test test++ vc2017 linux mingw elk test: $(call build,,$(CC),$(CFLAGS) -o ut,$(RUN) ./ut) test++: $(call build,,$(CXX),$(CFLAGS) -Wno-deprecated -o ut,./ut) vc2017: $(call build,$(DOCKER) mdashnet/vc2017 wine64,cl,/nologo /W3 /O2 /I. $(EXTRA) /Feut.exe,ut.exe) linux: $(call build,$(DOCKER) mdashnet/cc2,$(CC), $(CFLAGS) -o ut,./ut) mingw: $(call build,$(DOCKER) mdashnet/mingw,i686-w64-mingw32-gcc,-W -Wall $(EXTRA) -o ut,wine ut) arduino: curl -s http://downloads.arduino.cc/arduino-1.8.13-linux64.tar.xz -o /tmp/a.tgz tar -xf /tmp/a.tgz mv arduino-* $@ uno: arduino rm -rf tmp; mkdir tmp; cp ../examples/BlinkyJS/BlinkyJS.ino tmp/tmp.ino cp ../elk.c ../elk.h tmp/ $(DOCKER) mdashnet/cc2 ./arduino/arduino --verify --board arduino:avr:nano tmp/tmp.ino elk: $(CC) ../elk.c ../examples/cmdline/main.c -I.. -W -Wall -O2 -lm -o $(DESTDIR)/$@ coverage: test gcov -l -n *.gcno | sed '/^$$/d' | sed 'N;s/\n/ /' @gcov test.gcno >/dev/null upload-coverage: coverage curl -s https://codecov.io/bash | /bin/bash clean: $(call clean)
测试
gmake elk project@freebsd:~/elk/test % ./elk -e "print('Hello World from ELk')" Hello World from ELkundefined
project@freebsd:~/elk/test % gmake test rm -rf *.o *.dSYM ut* elk fuzzer* *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* a.out tmp cc unit_test.c -W -Wall -Werror -Wno-deprecated -I.. -g -fsanitize=address,undefined -coverage -lm -o ut ./ut FUNC: 14 [(n){return n<2?1:n*f(n-1);}] FUNC: 14 [(){let n=0; while (n++ < 100){prnt(str(0,n)+'\n');} return n;}] FUNC: 8 [(){}] FUNC: 14 [(){}] FUNC: 8 [(a,b){}] FUNC: 12 [(a){return 17;}] FUNC: 9 [(){}] FUNC: 9 [(){}] FUNC: 9 [(){1}] FUNC: 9 [(){1;}] FUNC: 9 [(){return 1;}] FUNC: 9 [(){return 1;}] FUNC: 9 [(){return 1;}] FUNC: 9 [(){return 1;2;}] FUNC: 9 [(){return 1;2;return 3;}] FUNC: 9 [(a,b){return a + b;}] FUNC: 9 [(a,b){return a + b;}] FUNC: 9 [(a,b){return a + b;}] FUNC: 9 [(a,b){return a + b;}] FUNC: 12 [(a,b){return a + b;}] FUNC: 20 [(){a++;}] FUNC: 14 [(){ a++; }] FUNC: 14 [(x){a=x;}] FUNC: 14 [(x){a=x;}] FUNC: 13 [(x){let z=x;a=typeof z}] FUNC: 9 [(x){return x;}] FUNC: 9 [(x){return {a:x};null;}] FUNC: 9 [(x){let m= {a:7}; return m;}] FUNC: 9 [(x){let m=7;return m;}] FUNC: 9 [(x){let m='hi';return m;}] FUNC: 9 [(x){let m={a:2};return m;}] FUNC: 9 [(x){let m={a:x};return m;}] FUNC: 16 [(x,y){return x*y;}] FUNC: 10 [(){return 1;}] FUNC: 11 [(x){return x+1;}] FUNC: 14 [(x){return x;}] FUNC: 8 [(x){return x;}] FUNC: 14 [(x){return x*x;}] FUNC: 8 [(x){return x*x;}] FUNC: 16 [(){return 1;}] FUNC: 14 [(x){return os.sum1(x,1);}] FUNC: 8 [(x){return os.sum1(x,1);}] FUNC: 14 [(x){return os.sum1(x,os.sum1(1,2));}] FUNC: 8 [(x){return os.sum1(x,os.sum1(1,2));}] FUNC: 10 [(x){return eval(null,x,x.length);}] FUNC: 15 [(x){ let g = 'axds', h= 'sadlkasd', foo = {f:x}; a = foo.f; }] FUNC: 8 [(x){ let g = 'axds', h= 'sadlkasd', foo = {f:x}; a = foo.f; }] SUCCESS. All tests passed in 1078.12 ms