# BxScript **Repository Path**: javaup/BxScript ## Basic Information - **Project Name**: BxScript - **Description**: 本项目主要处于学习目的而开发,灵感来源主要是otto开源项目,语法主要是JavaScript语法,但是有部分特色(见下方), JavaScript的prototype等没有支持;未来支持桌面应用开发 - **Primary Language**: Go - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-09-13 - **Last Updated**: 2025-01-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: 桌面应用, 解释器, JavaScript ## README # BxScript ## 前言 `本项目主要处于学习目的而开发,灵感来源主要是otto开源项目,语法主要是JavaScript语法.但未完全支持,例如: prototype.` `本项目仅供学习参考,切勿用于非法用途` ## 特性   可以用脚本的方式编写GUI项目【Window平台】,并不需要像其他语言那么麻烦,通过拖拽即可实现,而且不需要安装类似于.net这种语言环境,直接调用系统的API, 理论上可以支持到windows7 x64以上的系统上运行, 并且可以将脚本打包成exe文件, 直接运行即可【!!!!并非自解压】 ## 项目结构 - [Ast](Ast) 此处定义了AST语法树结构等,这里基本上就是OTTO的代码,删减了部分 - [Cache](Cache) 缓存模块,可以理解为全局变量,主要是主窗口句柄和定时器的标记 - [Evaluator](Evaluator) 执行器,定义了基本类型、运行时、值封装和运行器等 - [Kit](Kit) 工具模块 - [Lexer](Lexer) 词法分析器,关键字、符号等此处定义 - [Main](Main) 项目入口,定义了代码运行方式,获取代码资源并执行等 - [Parser](Parser) 语法分析器,可以修改语法 - [Windows](Windows) 封装了windows相关api,比如GUI相关、消息相关等,来源是一个github上的winc包,做了部分删减和修改 ## 项目环境 - go 1.19.6 以上 - windows 7 x64及以上 - goland 2022.3.2 ## 快速上手 - 下载项目并在goland中打开,如果下载了编译好的解释器则跳到[ 1 ] - 编译解释器,在CMD终端或者Goland的Terminal中切到Main目录 - 编译解释器:go build -ldflags="-s -w -H=windowsgui" - 在Main目录下生成的Main.exe文件就是解释器 - [ 1 ]编写脚本文件,Main目录下[Script.bx](Main%2FScript.bx)是一个测试脚本文件,可以使用 - 运行解释器:在CMD下输入`Main.exe Script.bx`即可查看效果 ## 关于语法与API说明 - 部分语法说明和API放在IDE上,[传送门](https://gitee.com/javaup/bx-script-ide) - 后期将增加一个api.md文件,存放所有语法说明和API说明 ## 打包解释器和脚本文件 - 第一种: 使用ResourceHacker将Script.bx作为资源打包到解释器中,ID可以在中Main.go查看 - 第二种: 下载[BxScriptIDE](https://gitee.com/javaup/bx-script-ide),本人练手编写的一个开发环境,附带语法说明、API说明、GUI助手等,可一键打包资源并设置图标等 ## (引用/参考)包说明 - [otto](https://github.com/robertkrimen/otto),主要参考语法解析和运行时资料 - [winc](https://github.com/lxn/win),主要参考GUI和与Win底层交互相关 - [oleautil](https://github.com/go-ole/go-ole),主要用于处理部分Win组件调用: Excel, Voice等 ## 未完善说明 - 可能存在部分语法未完善,需要测试中发现。 - 部分代码不够规范,onKeyDown响应来自app.go没有通过wndproc来分发,后续优化 - 部分api未完善 ## 增加自己需要的特性向导 `第一种:GlobalObject.go中定义的是全局对象,可以自己增加需要的特性。例如:` ```go // 表示在全局上定义一个World对象 globalObject.DefineProperty("World", Value{Kind: ValNativeObject, Value: &Object{ Class: "World", Property: map[string]Value{ // 这是World对象的属性, 后面为返回值 "diameter": {Kind: ValNumber, Value: 12742}, }, // 这是World对象的方法, 这儿调用windows的MsgBox方法 弹出提示消息 Inline: map[string]func(call FunctionCall) Value{ "hello": func(call FunctionCall) Value { Windows.MsgBox(nil, "消息提示", "Hello World", 0) return UndefinedValue }, }, }}) // 这样解释器就可以执行这样的代码了: World.hello();` // 解释器这样也可以获取World对象的diameter属性: World.diameter;` ``` `第二种:增加自己的语法或者关键字等,由于需要的工作量较大,此处不做详细说明,仅提供相关思路.` ```javascript // 0、可能还需要在Lexer中定义自己的关键字 // 1、在Ast中定义自己的语法结构 // 2、在Parser中解析自己刚刚定义的语法解析结构 // 3、在Evaluator中定义的运行器` ``` ## 接口列表 - Crypt - aesEncrypt("text", "key"); 返回加密后的Base64字符串 - aesDecrypt("text", "key"); 返回解密后的字符串 - toBase64("text"); 返回Base64字符串 - otBase64("text"); 返回原始字符串 - Voice - wts(); 创建一个语音对象 - speak("string"); 播放文字 - setRate(number); 设置语速 - setVolume(number); 设置音量 - close(); 关闭语音对象 - open(path); 打开指定音频文件 - stop(); 停止播放 - close(); 关闭音频文件 - play(); 播放音频文件 - Excel - open(path); 打开指定excel文件 - save(); 保存文件 - saveAs(path); 保存文件到指定路径 - close(); 关闭文件 - getSheet(index); 获取指定sheet - addSheet(name); 添加sheet - rowCount(); 获取当前sheet行数 - colCount(); 获取当前sheet列数 - cell(rowIndex, colIndex); 获取指定单元格 - value(value); 设置单元格值 - value(); 获取单元格值 - new(); 创建一个excel对象 - save(); 保存文件 - saveAs(path); 保存文件到指定路径 - close(); 关闭文件 - getSheet(index); 获取指定sheet - addSheet(name); 添加sheet - rowCount(); 获取当前sheet行数 - colCount(); 获取当前sheet列数 - cell(rowIndex, colIndex); 获取指定单元格 - value(value); 设置单元格值 - value(); 获取单元格值 - JSON - stringify(jsonObject); 将对象转为JSON字符串 - parse(jsonString); 将JSON字符串转为对象 - Date - now(); 返回当前时间对象 - new(timestamp); 返回指定时间对象 - parseDate(dateString); 解析日期字符串 - parseDateTime(dateString); 解析日期时间字符串 - format(formatString); 格式化日期字符串 - getTime(); 返回时间戳 - getYear(); 返回年份 - getMonth(); 返回月份 - getDate(); 返回日期 - getHour(); 返回小时 - getMinutes(); 返回分钟 - getSeconds(); 返回秒 - getWeek(); 返回星期几 - Number - parseInt(string); 将字符串转为整数 - parseFloat(string); 将字符串转为浮点数 - isNaN(string); 判断是否为NaN - Http - download(url, func); 下载文件 - request(method, url, header, data, func); 发起请求 - get(url, header, callback); get请求 - post(url, header, data, callback); post请求 - Math - PI; 圆周率(属性) - E; E(属性) - LN2; 以2为底数对数(属性) - LN10; 以10为底数对数(属性) - LOG2E; 以E为底数对数(属性) - LOG10E; 以E为底数对数(属性) - SQRT2; 2的平方根(属性) - abs(num); 返回绝对值 - acos(num); 返回反余弦 - asin(num); 返回反正弦 - atan(num); 返回反正切 - ceil(num); 返回向上取整 - cos(num); 返回余弦 - exp(num); 返回指数 - fool(num); 返回向下取整 - log(num); 返回对数 - max(num1, num2,...); 返回最大值 - min(num1, num2,...); 返回最小值 - pow(num, num); 返回指数 - random(); 返回随机数 - round(num); 返回四舍五入值 - sin(num); 返回正弦 - sqrt(num); 返回平方根 - tan(num); 返回正切 - tanh(num); 返回双曲正切 - trunc(num); 返回截断值 - Thread - setTimeout(func, time); 循环执行 - setInterval(func, time); 延迟执行 - clear(id); 清除定时器 - invoke(func); 调用函数 - Win - create(title, width, height, IsCenter, showMax, showMin); 创建窗口 - saveFile(path); 打开文件选择框 - chooseFile(); 打开文件选择框 - chooseFolder(); 打开文件夹选择框 - add({}); 添加控件 - loop(); 消息循环 - alert(string, title); 弹出提示框 - confirm(string, title); 弹出确认框 - close(); 关闭程序 - show(); 显示窗口 - showTop(); 显示窗口到顶层 - isShow(); 判断窗口是否显示 - hide(); 隐藏窗口 - toMin(); 最小化窗口 - toMax(); 最大化窗口 - toMove(); 移动窗口 #### 【input, button, textarea, label】 - getText(); 获取文字,例: Win.[控件ID].getText() - setText(val); 设置文字,例: Win.[控件ID].setText("Hello World") - setEnable(bool); 设置控件是否可用,例: Win.[控件ID].setEnable(true) #### 【select】 - add(str); 添加选项,例: Win.[控件ID].add("选项1"); - getValue(); 获取当前选项值,例: Win.[控件ID].getValue() - remove(index); 删除选项,例: Win.[控件ID].remove(0); - clear(); 清空选项,例: Win.[控件ID].clear() #### 【listBox】 - add(str); 添加数据,例: Win.[控件ID].add("1"); - addHeader([{text: str, width: wid}]); 添加表头,例: Win.[控件ID].addHeader([{text: "序号", width: 50}]); #### 【checkbox】 - getValue(); 获取当前值,例: Win.[控件ID].getValue() - setValue(bool); 设置当前值,例: Win.[控件ID].setValue(true) #### 【process】 - setValue(int, [0-100]); 设置当前值,例: Win.[控件ID].setValue(50) #### 【image】 - src(url); 设置图片路径,例: Win.[控件ID].src("./image.png"),本地路径 - File - create(path); 创建文件对象 - mkdir(path); 创建文件夹 - delete(path); 删除文件 - deleteFolder(path); 删除文件夹 - readAll(path); 读取文件所有内容 - write(path, content, append); 写入文件 - list(path); 列出文件夹内容 - copy(path, target); 复制文件 - exist(path); 判断文件是否存在 - move(path, target); 移动文件 ## 基础语法 ```javascript //特殊说明 //1、swtich case语法不支持 //2、do while,while不支持 //3、new表达式不支持 //变量声明 var int = 1; var array = []; var object = {}; var string = "你好"; var bool = true; var date = Date.now(); let ele = array[0] //一元表达式 delete object.name console.log(typeof object) var i = int++ i = ++int i = int-- i = --int //条件表达式 bool = 3 > 2 bool = 3 == 2 bool = 3 <= 2 bool = 3 != 2 bool = bool && 3 != 2 bool = bool || 3 != 2 bool = !bool //运算表达式 var x = 1 + 2 * 3 / 5 % 3 - 1 var z = 1 + " hello " + 33 var intx = int << 2 intx = int >> 1 var func = function(x){ console.log(this) } for(var i = 0 ; i < 10 ; i++){ console.log(i) } for(var i = false; i == true ; ){ //跳出循环 i = true } //条件判断 if(1 > 2){ } else if (2 == 3){ } else { } //try catch try{ throw "错误" }catch (e){ }finally { } ```