Poplang智体编程语言的LLM大模型中文编译器

使用markdown文档定义的poplang中文编译器(对话agent)

Poplang编程语言语法规范

Poplang是OPCode Oriented Programming(即:面向opcode操作码编程语言)。语法简单,一行语句即是一个poplang编程语言代码行。

1. Poplang行代码语法

opcode {opval1} {opval2} {opval3} ...

注:opcode是操作码,或者函数名。opval1-opval3等等即是操作的参数值,每一个参数均是可选的。可以是0-N个。

举例:

+ a b c

上面这句代码说的是:c = a + b ,即将a和b的和,存入到变量c中。

2. Poplang的变量赋值

2.1 赋值声明set

set val constant

注:set即是赋值声明的opcode操作码,val是一个变量。constant是一个常量,例如数字、字符串、JSON对象。这里constant只能是常量,不能是变量

举例:

set a 1

注:设置a的值为1,此语句是正确的

错误的用法:

set a b

注:b不能是变量,所以这个语句是错误的

2.1.1 变量初始化
set b **{"name":"this is a string"}

设置b为JSON值。JSON属性name的值为"this is a string"。代码行中的"**"定义了字符串常量:从"**"之后的字符串常量值均为b的值。这里因为该字符串是JSON,故自动转化为JSON对象并赋值给b。

set str 这是一个字符串

注:{这是一个字符串}本身是不需要使用双引号和单引号包裹字符串常量的。这里不要参考其他编程语言。假如字符串包含了空格或者其它不可见的字符,可以使用JSON对象赋值方式:例如 set obj **{"str":"this is a string"},然后通过后续提到的object.get来得到str字符串的值;或者使用set str **this is a string来字符包含空格的字符串:"**"代表了从此开始到行结束均是字符串的内容。

set str **这是一个带空格 的字符串常量

注:"**"代表从此开始至代码行结束,均是该str变量的字符串的值:这是一个带空格 的字符串常量

2.1.2 举例:为user_name赋值lee code

错误的用法:

set user_name "lee code"
:这是错误的set用法,因为user的变量值会被:"lee

正确的用法如下:

set user_name **lee code

注:那么我们将得到user_name是:lee code

或者使用对象变量user_obj的属性user_name来实现,如下:

set user_obj **{"user_name":"lee code"}

object.get user_obj.user_name user_name

注:上面两行poplang代码运行后user_name的值为:lee code

2.1.3 "**"定义的字符串常量,只能用于opcode操作码:set的代码行中

错误的用法:

== str **street result

注:这里的opcode操作码是==,第二个参数**street只能是变量名,不能认为是字符串:street

修改后正确的用法:

set str2 **street is road 100

== str str2 result

注:先使用set语句来实现str2的字符串值为:street is road 100。再使用==逻辑判断str与str2是否相等,结果存于result变量中。

错误的用法举例如下:

?= a **正确 **不正确 result

注:字符串常量"**正确"、"**不正确"不能用于?=条件运算符中。

修正后正确的用法:

set reult_ok **正确

set result_notok **不正确

?= a result_ok result_notok result

2.2 变量赋值

举例1:

= a c

将变量c的值赋值给变量a

2.3 其它的opcode赋值

语法1:

< a b c

注:判断是否a小于b,将比较的结果赋值给c

语法2:

== a b c

注:判断是否a与b相等,将比较的结果赋值给c

语法3:

> a b c

注:判断是否a大于b,将比较的结果赋值给c

语法4:

!= a b c

注:判断是否a不等于b,将比较的结果赋值给c

语法5:

! a b

注:将a的值逻辑取非得到的结果赋值给b

语法6:数值运算

+ a b c

- a b c

* a b c

/ a b c

% a b c

注:以上的+、-、*、/分别指加减乘除的opcode操作码。%是指整数取模,例如9%10的结果为9。

语法7:逻辑运算

|| a b c

&& a b c

> a b c

>= a b c

< a b c

<= a b c

== a b c

注:以上是将a与b进行逻辑opcode操作,结果赋值给c。

例如:&& a b c,其中a的值为真,b的值为假,则c的结果是真&&假,运行结果:c被赋值为假。

语法8:条件运算

?= a b c d

注:判断a是否为真,给d赋值为b或c变量的值。1,如果a值是逻辑真,将变量变量b的值赋值给变量d;如果a值是逻辑假,将变量变量c的值赋值给变量d。这里的a、b、c、d均是变量,不能是opcode操作码、且均不能是**开头的字符串常量、并且不能是数值常量、并且不能是逻辑真与假的常量true或常量false。

语法9:位运算

| a b c # 按位或

& a b c # 按位与

^ a b c # 按位异或XOR

<< a b c # 数位左移

>> a b c # 数位右移

~ a b # 按位取反,a的取反运算结果赋予变量c

注:其中,|、&、^、<<、>>分别为位运算中的按位或、按位与、按位异或、左移、右移,将变量a、变量b的位运算结果赋予变量c。最后"~ a b"中的"~"取反运算opcode操作码,是将变量a按位取反,将取反的位运算结果赋予b变量。

特别注意:上述运算类型的opcode操作码,只能对变量进行操作,不能对数值常量、字符串常量、opcode操作码进行操作。

2.4 读取对象的属性的值

object.get obj{.property_name1}{.sub_property_name01}{...} dst_val

注:object.get操作码可以读取obj对象的属性或属性的属性值,赋值给dst_val变量。

举例1:

object.get a.b.c dst_val

读取对象变量a的属性名为b的值,再读取这个值的c属性值,存入到dst_val变量中。

举例2:

object.get a.b.c.d.e.f.g val

假如a对象是一个JSON:{"a":{"b":{"c":{"d":{"e":{"f":{"g":"这是a.b.c.d.e.f.g的字符串值"}}}}}}},运行结果为:val的值为:这是a.b.c.d.e.f.g的字符串值

2.5 设置对象的属性值

object.set obj{.property_name1}{.sub_property_name01}{...} val

注:object.set操作码可以设置obj的属性property_name1的子属性sub_property_name01的值为val

举例1:

object.set obj.a val

假定obj的值为{}空对象,val的值为1,则运行后obj的值是:{"a":1}

举例2:

object.set obj.a.b val

假定obj的值为{"a":{}},val的值为2,则运行后obj的值是:{"a":{"b":2}}

2.5 常量只用于变量初始化set的语句中

set val constant_val # constant_val是一个数值常量或字符串常量、逻辑常量真true或假false

注:常量仅在以下操作码opcode中使用:set

举例错误的用法:

1、数字运算中错误使用常量

+ i 1 i

正确的用法:

set one 1 # 先将常量数值1保存在变量one中

+ i one i # +加法运算只能使用变量,不能使用常量

2、条件判断中错误使用常量

pop.ifelse flag **正确 **不正确 # 这里错误的使用了"**"指向的字符串常量。

正确的用法:

pop.ifelse flag doOk doNotOk # 这里的doOk和doNotOk是两个被声明了的函数(opcode操作码)

3. 函数的声明与调用

pop.func.define func_name

opcode1 ...

opcode2 ...

...

pop.func.end

注:pop.func.define是函数声明的预编译指令(不是opcode操作码),func_name即是被定义的函数名。opcode1、opcode2等等代表了函数func_name内部的每一行poplang代码行。可以是1行或者多行poplang代码行。最终函数定义的结束的预编译指令是:pop.func.end。

函数调用的语法:

func_name

注:这是一个函数调用的poplang代码行,func_name即是被定义的函数名(也是opcode操作码)。这是其中一个调用方式。另外还可以在pop.do.while循环指令中使用。下面会讲到循环语句的使用。

3.1 函数声明内部不能嵌套子函数声明

错误的用法:

pop.func.define outer_func

pop.func.define inner_func

pop.func.end

inner_func

pop.func.end

注:这是错误的函数声明,函数声明是不能嵌套的。

正确的用法:

pop.func.define inner_func

pop.func.end

pop.func.define outer_func

inner_func

pop.func.end

注:函数声明只能一个个来,并且被调用函数声明要在调用函数之前。

4. 循环语句

循环语句可用于执行条件循环,例如从1计算到100的和。

pop.do.while flag opcode

其中,pop.do.while是执行循环的opcode操作码,opcode是一个函数名或者操作码。先执行1次opcode,再判断flag是否为true。如果是true继续执行opcode,否则结束循环。

5. 注释语句

# 这是一行注释

说明:# 是注释的操作码,代码本行代码不被poplang的代码执行器执行。用于注释代码给人类用户看。

6. 条件判断语句

pop.ifelse flag opcode_ok opcode_notok

注:pop.ifelse是条件判断的opcode操作码,这里的flag是条件判断的变量,当flag值为真时调用opcode_ok函数,当flag值为非时调用opcode_notok函数。opcode_ok函数中包含了poplang代码行,是flag为真时所执行的函数代码。opcode_notok函数中包含了poplang代码行,是flag为非时所执行的函数代码。pop.ifelse在poplang编程语言中只有这一种用法,没有其它的用法,不要使用其他编程语言的用法。

举例:使用pop.ifelse来判断flag的值,当为真时加1,当为非时加2。poplang代码如下。重点代码在:pop.ifelse flag opcode_ok opcode_notok。这行代码一行代码实现了判断flag实现opcode_ok和opcode_notokg函数的跳转。

# 初始化n和max变量、flag的值

set n 0

set max 100

# 定义函数opcode_ok:给n变量加上1

pop.func.define opcode_ok

set one 1

+ n one n

pop.func.end

# 定义函数opcode_notok:用于检查n是否不为100

pop.func.define opcode_notok

set two 1

+ n two n

pop.func.end

# flag为真,调用opcode_ok函数,加1

set flag true

pop.ifelse flag opcode_ok opcode_notok # flag为非,调用opcode_notok,加2

! flag flag

pop.ifelse flag opcode_ok opcode_notok

# 此时,n的值为3(先加了1,再加上2)

7. 数组操作语法

7.1 创建数组对象

方法1:

new array

注:new是创建数组对象的opcode操作码,array这个字符串,代表了new操作码创建的是array对象即数组对象。得到的新的数组对象默认保存在$ret变量中。

方法2:

set list **[1,2,3,4,5]

注:使用set操作码opcode来给list变量赋值,将"**"后面的字符串转为JSON对象,即是一个数组对象,保存在list变量中。

7.2 数组操作

7.2.1 数组的下标值的设置

array.set list i val

注:array.set是数组元素位置i的值赋值操作码opcode,将val保存到list数组下标为i变量值的对象中。例如i变量的值为0,则说明将list[0]的值设置为val变量的值。

7.2.2 的元素的读取

array.get list i val

注:array.get是数组元素位置i变量下的值的读取的操作码opcode,将list[i]的值存入到变量val中。

举例:

set list **[3,100,5,92]

set i 1

array.get list i val

# 此时结果:val的值为list[1],即100。

set val 87

set i 2

array.set list i val

# 此时结果,list[i]的值被设置为新的val值即87,i为2。即:list[2]的值87。list数组为:[3,100,87,92]

示例:计算1到100的和

下面我们使用一个代码块,来解释如何使用poplang编程实现1+2+3一直加到100的结果。

# 开始设置初始化变量sum、one、n、max、flag

set sum 0

set one 1

set n 1

set max 100

set flag true

# 定义了一个计算1-100的函数:addTo100

pop.func.define addTo100

+ sum n sum

+ n one n

!= n 100 flag

pop.func.end

# 计算从1-100,直到n为100时退出循环

pop.do.while flag addTo100

上述poplang代码行被poplang执行器逐句分析并执行,最终得到了结果:sum的值为5050。

Prompt提示语

我要计算1至1000

对话Agent生成的Poplang代码

# 开始设置初始化变量sum、one、n、max、flag

set sum 0

set one 1

set n 1

set max 1000

set flag true

# 定义了一个计算1-1000的函数:addTo1000

pop.func.define addTo1000

+ sum n sum

+ n one n

!= n max flag

pop.func.end

# 计算从1-1000,直到n为1000时退出循环

pop.do.while flag addTo1000

返回案例列表