Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

LogicStep 语言规范 v1.0(Basic)

LogicStep 是一种面向无编程基础用户的极简单脚本语言。它的设计灵感来自 Scratch 积木式编程,采用顺序步骤、明确结尾、自然语言风格的语法,适用于任何需要“一步步说明”的场景——游戏逻辑、自动化流程、数据处理、交互式问答、教学演示等等。本规范定义了 LogicStep 的核心语法、语义和标准通用指令集。

脚本文件扩展名为 .lgs
本规范仅定义语言本身,不绑定任何特定应用领域。具体宿主程序(如游戏服务器、自动化工具)可通过指令扩展多语言包定制自己的 LogicStep 环境。
类比:如果 LogicStep 是一套乐高积木的连接协议,那么每个宿主程序就是提供不同主题积木包的套装。学会本规范,你就可以在任何兼容 LogicStep 的环境里编写脚本。


一、核心设计原则

  1. 步骤即积木
    脚本由多个**步骤(Step)模块(Module)**组成,每个步骤/模块内部是一条条按顺序执行的指令,就像拼积木一样。

  2. 对缩进不敏感
    代码块使用明确的结束标记(end ifend whileend step 等),缩进仅用于提高可读性,不影响解析。推荐每条语句独占一行,但也可用分号分隔。

  3. 接近自然语言的简单单词
    所有关键字均使用最常见的英文单词(如 ifrepeatfor),并内置多语言翻译支持。宿主程序可提供语言映射表,将母语关键字(如中文“如果”、“那么”)映射到标准英文关键字,使非英语用户能够用母语编写脚本。

  4. 通过点号调用模块和跳转

    • mod.模块名(参数) – 调用一个可复用的模块(相当于函数),执行完毕后返回调用处继续执行。
    • jump.步骤名(参数) – 跳转到另一个步骤并传递参数,当前步骤不再返回
  5. 动态类型,极简表达式
    变量无需声明类型,支持数字、字符串、布尔值、列表。表达式采用中缀数学形式,支持常见运算符。字符串拼接使用 +,数字与字符串相加自动转换数字。


二、程序结构

一个 LogicStep 脚本是纯文本文件(扩展名 .lgs),由一个或多个步骤定义模块定义组成。可指定一个起始步骤,默认为第一个被定义的步骤,或显式指定名为 main 的步骤。

2.1 步骤定义

step 步骤名(参数1, 参数2, ...)
    语句
    ...
end step
  • 标识符规则:字母、数字、下划线、中文(由语言包决定),不能以数字开头,不能与关键字冲突。
  • 参数在步骤内部作为局部变量直接使用。
  • 步骤可由宿主程序直接调用作为入口,也可通过 jump.步骤名(...) 跳转。

2.2 模块定义

module 模块名(参数1, 参数2, ...)
    语句
    ...
    return 表达式
end module
  • 模块必须有 return 语句返回一个值。调用方式为 mod.模块名(参数...),执行后返回原处继续执行。
  • 模块内部定义局部变量,不会污染调用者作用域。

2.3 注释

  • 单行注释:// 开头,到行尾结束。
  • 多行注释:/* ... */,可跨行。

2.4 语句形式

每条语句占一行。可以是:

  • 指令调用(有/无输出)
  • 变量赋值
  • 控制流结构
  • 模块调用或跳转

三、数据类型与变量

3.1 基本类型

  • 数字:整数或小数,如 5, 3.14, -2.5
  • 字符串:用双引号包围,如 "Hello",支持转义 \"\\
  • 布尔值truefalse
  • 列表:用方括号,元素逗号分隔,如 ["a", "b", 3],可为空列表 []
  • 空值null

3.2 变量赋值

set 变量名 = 表达式

变量名允许字母、数字、下划线和中文,不能以数字开头。变量无需声明类型,可随时重新赋值为不同类型。

3.3 变量作用域

  • 步骤和模块均创建独立的作用域,内部定义的变量仅在该作用域内可见。
  • 参数也是局部变量,由调用者传入值。
  • 不能跨作用域访问其他步骤/模块的局部变量,数据传递必须通过参数和返回值。
  • 宿主程序可提供全局只读变量(如 playerworld),在所有作用域可直接访问。

3.4 获取指令或模块的输出

使用 -> 箭头语法将结果存入变量:

指令名 参数... -> 变量名
mod.模块名(参数...) -> 变量名

箭头右侧的变量可以是已存在或新的局部变量。不写 -> 变量 则丢弃输出。


四、表达式

表达式支持以下运算符,按优先级从高到低排列:

优先级 运算符 含义
1 () 括号分组
2 ! - 逻辑非、负号
3 * / 乘、除
4 + - 加、减
5 < > <= >= 大小比较
6 == != 等值比较
7 and 逻辑与
8 or 逻辑或
  • 字符串可用 + 拼接。数字与字符串相加时,数字自动转为字符串。
  • 比较运算符可用于数字(按数值)或字符串(按字典序)。
  • 条件判断中可省略 == true,直接写变量名:if has_perm then
  • 列表索引访问请使用 list_get 指令,表达式中不直接支持 [] 索引。

五、通用标准指令集

每条指令由指令名和参数组成,部分指令有输出。宿主程序应至少提供以下通用指令,以构成 LogicStep 的基础能力。宿主可根据需要添加更多领域专用指令。

5.1 指令调用形式

  • 无输出指令名 参数1, 参数2, ...
  • 有输出指令名 参数1, 参数2 -> 输出变量
  • 跳转jump.步骤名(参数1, 参数2)
  • 模块调用mod.模块名(参数1, 参数2)mod.模块名(参数1, 参数2) -> 变量

5.2 标准内置指令

以下指令为 LogicStep 核心通用指令集,任何兼容实现都应支持。

输入输出

指令 参数 输出 描述
print 向用户输出信息(显示在控制台、聊天框或界面)
input 提示字符串 字符串 向用户显示提示并等待输入,返回输入的字符串

数学与随机

指令 参数 输出 描述
random_int 最小值, 最大值 数字 生成区间内随机整数(含两端)
random_chance 百分比数字 布尔值 有指定概率返回 true
floor 数字 数字 向下取整
ceil 数字 数字 向上取整
round 数字 数字 四舍五入
abs 数字 数字 绝对值

列表操作

指令 参数 输出 描述
list_create 列表 创建一个空列表
list_add 列表变量, 值 向列表尾部添加元素
list_get 列表变量, 索引 元素值 获取列表指定位置的值(索引从0开始)
list_set 列表变量, 索引, 新值 修改列表指定位置的值
list_remove 列表变量, 索引 移除列表指定位置的元素
list_size 列表变量 数字 返回列表长度
list_contains 列表变量, 值 布尔值 检查列表是否包含指定值

字符串处理

指令 参数 输出 描述
split 字符串, 分隔符 列表 将字符串按分隔符拆分为列表

类型判断与转换

指令 参数 输出 描述
to_number 字符串 数字 将字符串转为数字,失败返回 null
to_string 任意值 字符串 将值转为字符串
typeof 字符串 返回值的类型名称("number","string","boolean","list","null")

5.3 自定义指令扩展

宿主程序可通过注册新指令扩展 LogicStep 的能力。新指令名不应与标准指令或关键字冲突。领域专用指令的详细说明由宿主程序提供。


六、控制流

所有控制结构都有明确的结束标记。

6.1 条件判断

if 条件 then
    语句
    ...
else if 条件 then
    语句
    ...
else
    语句
    ...
end if
  • else ifelse 块可选,可有多条 else if

6.2 循环

while 循环

while 条件 do
    语句
    ...
end while

repeat-until 循环

repeat
    语句
    ...
until 条件
  • 循环体至少执行一次。

for 遍历循环

for 元素变量 in 列表表达式 do
    语句
    ...
end for
  • 元素变量 依次取列表中的每个元素;不可直接修改原列表(修改请用 list_set)。
  • 列表表达式可以是变量、列表字面量或返回列表的调用。

6.3 跳出循环

  • exit while 跳出当前最内层 while 循环。
  • exit for 跳出当前最内层 for 循环。
  • exit repeat 跳出 repeat-until 循环。

七、步骤与跳转

7.1 步骤调用与跳转

  • 宿主程序可调用入口步骤(如 main)并传入参数。
  • 脚本内部使用 jump.步骤名(参数...) 跳转,当前步骤终止,不返回。

7.2 模块调用与返回

  • 调用:mod.模块名(参数...) -> 输出变量。模块执行完毕后返回 return 的值。
  • 模块内部可 return 表达式 提前退出;若未遇到 return,隐式返回 null

7.3 递归

模块支持递归,但宿主程序应限制最大调用栈深度。


八、错误处理

8.1 编译时错误

语法错误、未闭合的块等在加载时报错,指出行号与原因。

8.2 运行时错误

除零、索引越界、未定义变量等会终止脚本,并将错误信息返回宿主。宿主可选择捕获并降级处理。

8.3 try-catch(可选)

try
    语句
catch
    语句
end try

如果 try 块内发生运行时错误,跳转至 catch 块,错误信息可通过 _error 变量获取。此特性为可选。


九、多语言翻译机制

LogicStep 的关键字和内置指令名均可通过语言映射表进行本地化。宿主程序在加载脚本时,先将本地化关键字替换为标准英文关键字,再交给解析器。

映射表示例(中文 -> 英文):

如果      -> if
那么      -> then
否则      -> else
否则如果  -> else if
结束如果  -> end if
当        -> while
重复      -> repeat
直到      -> until
步骤      -> step
模块      -> module
跳转      -> jump
设置      -> set
返回      -> return
遍历      -> for
在...里   -> in
结束遍历  -> end for
退出循环  -> exit while / exit for / exit repeat

内置指令名同样可映射,例如:

输出      -> print
输入      -> input
随机整数  -> random_int
取整      -> floor
列表添加  -> list_add

宿主程序提供语言包后,用户即可用母语编写 LogicStep 脚本。


十、与宿主程序的接口

LogicStep 脚本运行在宿主程序提供的环境中。

10.1 入口

宿主程序调用指定步骤(如 main)并传入参数启动脚本。脚本执行完毕或遇到未捕获错误时返回宿主。

10.2 内置变量

宿主程序可预定义全局只读变量供脚本使用,例如:

  • player:当前用户标识
  • world:当前场景名称
  • 任何其他上下文信息

10.3 指令绑定

宿主程序必须将自身功能包装为指令并注册到 LogicStep 运行时。指令应尽量遵循本规范的标准语义,领域专用指令由宿主自行定义。

10.4 安全性

  • 脚本在沙箱中运行,默认无文件系统/网络访问,除非宿主提供相关指令。
  • 可限制最大执行步数、最大内存、最大递归深度等。

十一、完整语法参考(EBNF 风格)

程序        ::= { 步骤定义 | 模块定义 }

步骤定义    ::= "step" 标识符 ["(" 参数列表 ")"] 语句序列 "end" "step"
模块定义    ::= "module" 标识符 ["(" 参数列表 ")"] 语句序列 "end" "module"

语句序列    ::= { 语句 }
语句        ::= 简单语句 | 控制流结构
简单语句    ::= 赋值语句
              | 指令调用
              | 跳转语句
              | "return" 表达式
              | "exit" ("while"|"for"|"repeat")
              | 空

赋值语句    ::= "set" 标识符 "=" 表达式
指令调用    ::= 标识符 [ 实际参数 ] ["->" 标识符]
跳转语句    ::= "jump." 标识符 "(" [ 实际参数 ] ")"
模块调用    ::= "mod." 标识符 "(" [ 实际参数 ] ")" ["->" 标识符]

控制流结构  ::= if结构 | while结构 | repeat结构 | for结构 | try结构
if结构      ::= "if" 表达式 "then" 语句序列
                { "else" "if" 表达式 "then" 语句序列 }
                [ "else" 语句序列 ]
                "end" "if"
while结构   ::= "while" 表达式 "do" 语句序列 "end" "while"
repeat结构  ::= "repeat" 语句序列 "until" 表达式
for结构     ::= "for" 标识符 "in" 表达式 "do" 语句序列 "end" "for"
try结构     ::= "try" 语句序列 "catch" 语句序列 "end" "try"

参数列表    ::= 标识符 { "," 标识符 }
实际参数    ::= 表达式 { "," 表达式 }

表达式      ::= 逻辑或表达式
逻辑或表达式::= 逻辑与表达式 { "or" 逻辑与表达式 }
逻辑与表达式::= 比较表达式 { "and" 比较表达式 }
比较表达式  ::= 加减表达式 [ (">"|"<"|">="|"<="|"=="|"!=") 加减表达式 ]
加减表达式  ::= 乘除表达式 { ("+"|"-") 乘除表达式 }
乘除表达式  ::= 一元表达式 { ("*"|"/") 一元表达式 }
一元表达式  ::= [ "!" | "-" ] 主要表达式
主要表达式  ::= 字面量 | 标识符 | "(" 表达式 ")" | 列表字面量 | 指令调用 | 模块调用
列表字面量  ::= "[" [ 表达式 { "," 表达式 } ] "]"
字面量      ::= 数字 | 字符串 | "true" | "false" | "null"

十二、迁移与兼容性

LogicStep 可以作为现有 YAML/JSON 逻辑配置的前端语言。通过编译器可将 LogicStep 脚本转换为后端可执行的步骤序列;反之也可将旧配置转换为 LogicStep 脚本。

任何通过 LogicStep 核心语法测试套件的实现,均可称为 LogicStep 兼容实现


十三、完整示例

示例 1:计算折扣(中文关键字)

step main
    input "请输入原价:" -> 原价_str
    to_number 原价_str -> 原价
    
    if 原价 == null then
        print "输入的不是有效数字"
        return
    end if
    
    mod.计算折扣后价格(原价) -> 折后价
    print "折后价格:" + 折后价
end step

module 计算折扣后价格(原价)
    if 原价 >= 500 then
        set 折扣 = 0.7
    else if 原价 >= 200 then
        set 折扣 = 0.8
    else
        set 折扣 = 0.9
    end if
    
    return floor(原价 * 折扣)
end module

示例 2:随机点名与列表操作(中文关键字)

module 随机点名(学生列表)
    list_size 学生列表 -> 人数
    if 人数 == 0 then
        return "无学生"
    end if
    
    random_int 0, 人数 - 1 -> 索引
    list_get 学生列表, 索引 -> 被点名学生
    return 被点名学生
end module

// 使用示例
set 班级 = ["小明", "小红", "小刚"]
mod.随机点名(班级) -> 结果
print "今天回答问题的同学是:" + 结果

示例 3:遍历与统计(中文关键字)

module 统计及格人数(分数列表)
    set 及格数 = 0
    for 分数 in 分数列表 do
        if 分数 >= 60 then
            set 及格数 = 及格数 + 1
        end if
    end for
    return 及格数
end module

附录:关键字速查表(英文)

以下为 LogicStep 保留关键字,不可用作变量名/步骤名/模块名:

关键字 用途
step 步骤定义
module 模块定义
end 块结束
if 条件判断
then 条件后接
else 否则分支
while while 循环
do while 条件后接
repeat repeat-until 循环
until repeat 结束条件
for for 遍历循环
in for 变量与列表之间
return 返回值
exit 跳出循环
set 变量赋值
try 错误捕获
catch 错误处理块
and 逻辑与
or 逻辑或
true / false 布尔字面量
null 空值
mod 模块调用前缀
jump 步骤跳转前缀

About

LogicStep 是一种 “面向无编程基础用户” 的极简单脚本语言。它的设计灵感来自 Scratch 积木式编程,采用 “顺序步骤、明确结尾、自然语言风格” 的语法,适用于任何需要“一步步说明”的场景——游戏逻辑、自动化流程、数据处理、交互式问答、教学演示等等。本规范定义了 LogicStep 的核心语法、语义和标准通用指令集。

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors