Board logo

标题: [其他] 两个脚本语言解释器(仅提供编译方法,不提供下载) [打印本页]

作者: Pchief    时间: 2020-5-4 01:38     标题: 两个脚本语言解释器(仅提供编译方法,不提供下载)

本帖最后由 Pchief 于 2020-5-4 01:42 编辑

0. 准备编译环境
首先安装MinGW-w64,推荐采用TDM-GCC版本 ( https://github.com/jmeubank/tdm-gcc/releases/download/v9.2.0-tdm64-1/tdm64-gcc-9.2.0.exe ),可以同时生成32位和64位代码,而不用分开装两套编译器。
当然喽,理论上用VC++也能编译,但我没试过(我不喜欢VC++,体积大,不开源,而且编译出的东东莫名其妙各种依赖)

安装组件要选C和C++,装完之后,把编译器添加到系统搜索路径中。

1. Squirrel语言解释器:sq.exe

Squirrel语言是一种嵌入宿主程序中执行的脚本语言,类似于lua,但比lua功能丰富,而且语法更接近C/C++。

官方网站:http://www.squirrel-lang.org/
GitHub主页:https://github.com/albertodemichelis/squirrel
在线文档:http://www.squirrel-lang.org/squirreldoc/

编译方法:下载源代码解压缩(或者Git克隆)之后,在源代码的顶层目录中建立一个批处理 build.bat ,内容如下:
  1. :: build.bat
  2. :: put this script in the top level directory of the SQ source tree
  3. :: Usage: build.bat [sq64 | sqprof]
  4. @echo off
  5. pushd %~dp0
  6. setlocal
  7. if not exist lib\NUL mkdir lib
  8. if not exist bin\NUL mkdir bin
  9. set "lib_dir=%~dp0lib"
  10. set "bin_dir=%~dp0bin"
  11. set "includeflag=-I../include -I. -Iinclude"
  12. if /i "%1"=="sq64" (
  13. set "gccflag_for_libs=-O2 -m64 -D_SQ64 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing"
  14. set "gccflag_for_sq=-O2 -m64 -D_SQ64 -fno-exceptions -fno-rtti"
  15. goto action
  16. )
  17. if /i "%1"=="sqprof" (
  18. set "gccflag_for_libs=-O2 -m32 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing"
  19. set "gccflag_for_sq=-O2 -m32 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3"
  20. goto action
  21. )
  22. set "gccflag_for_libs=-O2 -m32 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing"
  23. set "gccflag_for_sq=-O2 -m32 -fno-exceptions -fno-rtti"
  24. :action
  25. chdir squirrel
  26. for %%i in (*.cpp) do (g++ %gccflag_for_libs% -c %%~nxi %includeflag%)
  27. ar rc "%lib_dir%\libsquirrel.a" *.o
  28. del /q *.o
  29. chdir ..\sqstdlib
  30. for %%i in (*.cpp) do (g++ %gccflag_for_libs% -c %%~nxi %includeflag%)
  31. ar rc "%lib_dir%\libsqstdlib.a" *.o
  32. del /q *.o
  33. chdir ..\sq
  34. g++ %gccflag_for_sq% -o "%bin_dir%\sq" sq.c %includeflag% -I../sqlibs -L../lib -lsquirrel -lsqstdlib
  35. chdir ..
  36. endlocal
  37. popd
  38. echo on
复制代码
然后在命令行输入 build.bat sq64 来编译(直接双击,不带参数的话,生成的是32位代码)。编译完成之后,打开 bin 子目录,里面就有 sq.exe 了。

测试脚本:把下列内容保存为 hello.nut (是的,这种语言脚本后缀名默认为.nut,松鼠爱吃坚果嘛)
  1. function print_hello()
  2. {
  3. local i;  // 使用变量前必须声明(虽然它没有类型)
  4. for (i=1; i<=3; ++i)
  5. {
  6. print("Hello Nut" + i + "\n");
  7. }
  8. }
  9. print_hello();
复制代码
然后在命令行输入 sq.exe hello.nut ,应该会输出:
  1. Hello Nut1
  2. Hello Nut2
  3. Hello Nut3
复制代码
2. JavaScript语言解释器:mujs.exe

JavaScript不用多说了吧。

官方网站:https://mujs.com/
下载页面:https://mujs.com/download.html

下载页面只有源代码,需要自己编译。
编译方法:源代码解包后,在顶层目录建立一个文件 build.bat,内容如下:
  1. :: build.bat
  2. :: put this script in the top level directory of the mujs source tree
  3. @echo off
  4. pushd %~dp0
  5. gcc -std=c99 -pedantic -Wall -Wextra -Wno-unused-parameter -O3 -o build/release/libmujs.o -c one.c
  6. gcc -std=c99 -pedantic -Wall -Wextra -Wno-unused-parameter -O3 -o build/release/main.o -c main.c
  7. gcc -Wl,-s -o build/release/mujs build/release/libmujs.o build/release/main.o  -lm
  8. gcc -std=c99 -pedantic -Wall -Wextra -Wno-unused-parameter -O3 -o build/release/pp.o -c pp.c
  9. gcc -Wl,-s -o build/release/mujs-pp build/release/libmujs.o build/release/pp.o -lm
  10. popd
  11. echo on
复制代码
双击 build.bat 完成编译,打开 build/release 子目录,里面有两个 exe 文件,其中mujs.exe就是我们要的解释器,另一个文件mujs-pp.exe是什么东东我不清楚(看源码说明,可能是个代码美化工具)。

测试脚本:把如下内容保存为hello.js:
  1. for(var i=1; i<=3; ++i) write("Hello\n");
复制代码
然后命令行输入 mujs.exe hello.js ,应该会输出:
  1. Hello
  2. Hello
  3. Hello
复制代码
当然喽,write()并不是JavaScript标准的函数,而是mujs解释器所提供的函数。JavaScript本身能做的事有限,如果没有相关库的支持,它连写文件这样的基本操作都做不到(不像C语言,起码有个标准库干这事)。所以mujs.exe里内置了一些简单的函数供命令行操作使用,它们是:

gc(report)    资源回收(GC)
load(fileName)  加载并运行脚本文件<fileName>
quit()          退出解释器(主要用于从交互模式中退出)
read(fileName)  返回文件<fileName>的内容
readline()      从标准输入(STDIN)中读取一个行
require(module) 加入一个模块module(类似于C语言的#include命令)
write(...)      将各参数用空格分隔后,写到标准输出(STDOUT)
print(...)      同write(),但末尾添加一个换行符(所以print("Hello","World")等同于write("Hello","World\n"))

这些函数能做的事仍然不多,所以mujs基本上也就只能作为一个JavaScript代码测试器,用于测试某段代码是否正常工作。

既然提到mujs.exe就顺便安利他家的mutool.exe,这是一个多功能的PDF文档处理工具,跟mupdf.exe(PDF阅读器)打包在一起下载,下载页面为:
https://mupdf.com/downloads/index.html
把windows的包下载下来,打开里面就有mutool.exe了。
mutool.exe可以干的事包括:从pdf中提取页面,图像,字体,合并pdf,创建pdf等等,比如我要删除文件in.pdf的第二页,可以用如下命令实现:
  1. mutool.exe clean in.pdf out.pdf 1,3-N
复制代码
就是说,只把in.pdf的第1页和第3页以后的内容写到out.pdf中。

更重要的是,mutool.exe内嵌了mujs引擎,如果对它自带的功能不满意,你可以自己写JavaScript脚本来操纵它处理pdf。只需通过命令
  1. mutool.exe run <script.js>
复制代码
就可以让它运行脚本script.js。从这一点说,mutool.exe本身已经可以当一个JavaScript解释器来使用了。更详细的文档,参见 https://mupdf.com/docs/index.html
作者: netdzb    时间: 2020-5-4 06:00

学习了,谢谢。




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2