2 Star 1 Fork 0

funnyos / study

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
泛语言参考规范.txt 16.80 KB
AI 代码解读
一键复制 编辑 原始数据 按行查看 历史
1. 泛语言概论
1.1 概要
泛语言是一种文法相对自由的语言,可根据需要翻译或解释成类scheme语言。
泛语言的发明是受到各种通用语言的启发,尤其是scheme,其语法很scheme很像,但不限制词素的顺序,因而更自然,更符合人类思维。
1.2 术语
词法:又称字法,是文法层面的类型之一,是特定文本内语词的构成和使用的法则。
语法:包含词的构词、构形的规则和组词成句的规则等。
AST(Abstract Syntax Tree):抽象语法树
DFA(Deterministic Finite Automaton):确定的有穷自动机
NFA(Nondeterministic Finite Automata):非确定的有穷自动机
PDFA(Parametric Deterministic Finite Automaton):带参数的确定有穷自动机,泛语言特有的编译技术
lex:LEXical compiler的缩写
常量:程序运行中始终不变的量
变量:程序运行中可动态改变的量
过程:对命令的顺序执行
函数:对通用过程的封装,泛语言要求函数都具有返回值,默认返回true
纯函数:对同样的参数输入只对应一种输出的函数
类/类型:表示对对象的分类,是具有共同特征的事物的抽象
对象:类的一个具体实例
属性:隶属于某个对象的变量
方法:隶属于某个对象的函数
继承:子类继承父类,则子类拥有父类的属性和行为(方法)
消息传递:对象之间通过消息传递进行函数调用
宏:能够对代码进行转换展开的代码
模式匹配:对数据以一定规则进行解析,并匹配到相应的参数
多分派:函数或者方法的分派取决于运行时参数的对象类型
1.3 约定和标准
常量名:以*开头和结尾,词以小写字母表示,词之间以-分隔。例如:*this-is-a-constant*
变量/函数名:词以小写字母表示,词之间以-分隔。例如:this-is-a-variable
类名:词以大写字母开头,词之间直接连接。例如:ThisIsAClass
原语函数:均以大写字母表示。例如:EXTRACT
宏变量:宏中定义的临时变量,以$开头。例如:$temp
特殊变量:特殊变量是指具有某种特定含义的变量,以%开头。例如:%self,%target,%target-name
1.4 词法
泛语言的词法是能够自定义的,词法的定义采用正则表达式,例如复数的词法定义:
{define lex rule {complex} -> {"<real> :: (make-complex $1 0)"
or "<real>\\+<ureal>i :: (make-complex $1 $2)"
or "<real>-<ureal>i :: (make-complex $1 (- $2))"
or "<real>\\+i :: (make-complex $1 1)"
or "<real>-i :: (make-complex $1 -1)"
or "\\+<ureal>i :: (make-complex 0 $1)"
or "-<ureal>i :: (make-complex 0 (- $1))"
or "\\+i :: (make-complex 0 1)"
or "-i :: (make-complex 0 -1)"}}
这里,complex表示规则的名称,由""包围的句法是规则的定义。由于定义是递归的,则由<>包围的单词,如real, ureal,表示另一个规则的名称。
由::符号隔开的两边,左边表示待匹配单词的正则表达式,右边表示翻译后的目标语言,其中$n表示第n个<>包围的单词,$则表示自身。
lex-rule的概念类似于词法分析里的非终结符,在未碰到终结符时它是能够不断展开的。
与此相对,lex-token则类似于终结符的概念。例如:
{define lex token {digit} -> {"[[:digit:]]"}}
{define lex token {letter} -> {"[a-zA-Z]"}}
此外,还有lex-group也类似于非终结符,它的句法中包含的都是lex-token,在进行正则表达式匹配时使用分组(group)匹配。
{define lex group {integer} -> {"(<sign><digit>+) :: (lex \"Integer\" \"$\")"}}
{define lex group {uinteger} -> {"(<digit>+) :: (lex \"Integer\" \"$\")"}}
1.5 语法
泛语言的语法可直接解析成抽象语法树AST,其语法的关键字即界符为:{},例如:
{define function {qsum}: {the sum of squares {a} and {b}} as {{{a}*{a}}+{{b}*{b}}}}
当{}包含的模块为可选模式时,以符号..结尾,例如:
{if {if_clause} then {then_clause} {, else {else_clause} ..}}
该语句既可匹配:{if {if_clause} then {then_clause}},又可匹配:{if {if_clause} then {then_clause}, else {else_clause}}
当{}包含的模块为重复模式时,以符号...结尾,例如:
{case {when {when_clause} then {then_clause}, ...}}
该语句可以匹配:
{case}
{case when {when_clause} then {then_clause}}
{case when {when_clause1} then {then_clause1}, {when_clause2} then {then_clause2}}
{case when {when_clause1} then {then_clause1}, {when_clause2} then {then_clause2}, {when_clause3} then {then_clause3}}
......
【注】在泛语言中,不对,进行匹配
当{}包含的模块为询问时,以符号answer:开头并且以?结尾,例如:
{answer: who is {U} when {{a} is {U}'s uncle} ?}
询问之后会对U进行设值
1.6 语义
泛语言的语义是通过宏原语描述的,通过解析匹配宏原语,能够精确地将泛语言翻译为scheme语言
宏原语的一个例子如下:
$$ example: {define function {qsum}: {the sum of squares {a} and {b}} as {{{a}*{a}}+{{b}*{b}}}}
statement: {define function {name}: {function} as {statement}}
name: defun
function: EXTRACT[{name}]
mapping: {function} > \{(EXTRACT[{name}] TARGET[{function}])\}
run: NIL
eval: (define (EXTRACT[{name}] ARGLIST[{function}]) MATCH[{statement}])
其中:
statement表示匹配的模板;
name表示模板的名称;
function表示函数名称;
mapping表示泛语言中对语句做转换的映射(以>分隔,>左边是源语句,>右边是目标语句)
run表示要执行的逻辑;
eval表示该statement翻译后的字符串
1.7 注释
注释有两种方式:
一是以;开头的字符串且;不包含于泛语言中定义的字符串
二是形如 {COMMENT "comment string"} 这样的形式
2 编程范式
泛语言支持常见的几种编程范式:
2.1 过程式
泛语言执行的时候是一条条由{}包起来的语句执行的,所以整体上是过程式。局部如果想要实现过程式,可以使用语句{begin {{statement} ...}}
2.2 函数式
由于{}组成的表达式可以嵌套,所以语句也可以是函数式的,这里的函数不一定是纯函数,如果出现set之类的语句会破坏函数的单纯性。
所以是否实现为纯函数需要在编写函数时由自己保证。
2.3 面向对象
泛语言支持面向对象的编程方式,但是要遵循一些约定:
泛语言目前仅支持单继承,在打包项目时,需要提供继承树的元数据。
泛语言翻译后的scheme语言,采用函数来模拟对象,虽然机制不一样,但是达到的效果是一样的。
泛语言的类名符合之前定义的标准,并且一个文件只允许定义一个类,且文件名与类名相同,包命名与文件夹路径相同。
普通对象,即只包含属性,不包含行为的对象,其类的定义采用define struct,否则采用define class
普通对象可以同模式匹配器关联,例如:
{define struct {BinaryTreeNode}: {data left right} with pattern matcher {left<-[data]->right}}
对象的属性和方法是在泛语言里是能够动态添加,删除和修改的,只要获取了系统级别的权限,这使得泛语言关于面向对象的代码是能够动态重构的。
2.4 面向切面
泛语言支持面向切面的编程。
首先需要定义切面:
{define aspect {log-aspect} as {"function:funciton-match-string || method:method-match-string || multimethod:multimethod-match-string"}}
然后定义织入语句:
{execute advice {print log {"log before "} {%target-name}} before aspect {log-aspect}}
{execute advice {print log {"log after "} {%target-name}} after aspect {log-aspect}}
{execute advice {print log {"log before "} {%target} {" and after"}} around aspect {log-aspect}}
2.5 逻辑式
泛语言支持逻辑式的编程:
事实
{define fact {is-female} that {{jane} is female}}
{define fact {is-father} that {{john} is {mary}'s father}}
{define fact {gives} that {{john} gives {book} to {mary}}
{define fact {likes} that {{john} likes {flowers}}}
{define fact {likes} that {{john} likes {mary}}}
{define fact {likes} that {{paul} likes {mary}}}
规则
{define rule {friends} that {{X} and {Y} are friends} when {{{X} likes {Y}} and {{Y} likes {X}}}}
询问
{answer: who is {X} when {{john} likes {X}} ?}
{answer: who is {X} when {{{mary} likes {X}} and {{john} likes {X}}} ?}
例子:
{define fact {is-father} that {{a} is {b}'s father}}
{define fact {is-father} that {{c} is {d}'s father}}
{define fact {is-brother} that {{a} is {c}'s brother}}
{define rule {is-uncle} that {{X} is {Y}'s uncle} when {{{X} is {Z}'s brother} and {{Z} is {Y}'s father}}}
{answer: who is {U} when {{a} is {U}'s uncle} ?}
3. 表达式
3.1 抽象语法树
对语句
{define function {qsum}: {the sum of squares {a} and {b}} as {{{a}*{a}}+{{b}*{b}}}}
的解析将形成抽象语法树
3.2 基本表达式
泛语言支持scheme语言的表达式,将表达式以{}括起来就可以解释成对表达式的求值,例如:
{(+ 2 3)}
翻译后的scheme语句为(+ 2 3),其求值的结果为5。
即便如此,由于泛语言采用了自定义的词法,所以对于list结构的数据的构造与scheme稍有不同,例如:
在scheme中,构建一个list的语句形如:(list 4 5 6);而在泛语言中,构建list的语句为:
{list {1+2i} {3+4i}}
{list lex {(({1} {2}) {3.1} ({3/4} {5/6}) {9+4i})}}
由于泛语言中表达式{9+4i}翻译后的表达式并非数值,而是形如(make-complex 9 4)的语句,使用list lex语法弥合了scheme句法和泛语言句法不统一的矛盾
3.3 宏
泛语言的宏并非完全卫生的(hygienic),它会对宏变量替换成gensym-XXXXXX这样的符号,其中XXXXXX是系统中的唯一序列
这么做的目的之一是为了使宏便于理解,另一个目的是使宏能够正确展开而不具有副作用
泛语言的设计将可读性放在首位,泛语言的任何模块都应遵循易读的原则
3.4 模式匹配
模式匹配的几个要点:
3.4.1 模式
模式是指对简单的数据结构进行表达的字符串,例如:
模式[x|xs]可以用于表示一个数组,其中x表示头部,xs表示剩余部分;
模式[h|...|t]则表示以h开头和以t结尾的数组;
模式left<-%self->right则表示一个二叉树节点,其中left表示左子树,right表示右子树
3.4.2 模式匹配器的定义:
通过define pattern matcher将模式与对象关联,例如:
{define pattern matcher {list-matcher1}: {[x|xs]} for {list}:{List} as {
{x} => {first of {list}}
{xs} => {rest of {list}}}
{define pattern matcher {list-matcher2}: {[h|...|t]} for {list}:{List} as {
{h} => {first of {list}}
{t} => {last of {list}}}
或者,在定义struct时,直接指定模式匹配器,如:
{define struct {AvlTreeNode}: {data height left right} with pattern matchers {{left<-[data:height]->right} {left<-%self->right}}}
3.4.3 应用模式:
通过match statement或match with statement对模式进行匹配,例如对于二叉树的一些方法:
{define method {height-of-branch} as {match {node}:
{} => {0},
{left<-[_]->right} => {{max of {height of branch {left}} and {height of branch {right}}} + {1}}}}
{define method {size} as {match {node}:
{} => {0},
{left<-[_]->right} => {{size of {left}} + {size of {right}} + {1}}
}}
{define method {traverse-pre-order} as {match {node} with {function}:
{} => {},
{left<-[data]->right} => {begin
{eval {function} {data}}
{traverse tree {left} pre order with function {function}}
{traverse tree {right} pre order with function {function}}}}}
{define method {traverse-in-order} as {match {node} with {function}:
{} => {},
{left<-[data]->right} => {begin
{traverse tree {left} in order with function {function}}
{eval {function} {data}}
{traverse tree {right} in order with function {function}}}}}
{define method {traverse-post-order} as {match {node} with {function}:
{} => {},
{left<-[data]->right} => {begin
{traverse tree {left} post order with function {function}}
{traverse tree {right} post order with function {function}}
{eval {function} {data}}}}}
例如,对于AVL树的方法:
{define method {left-left-rotate} as {match {node}:
{{x<-k1->y}<-k2->z} {COMMENT "
k2
/\
k1 z
/\
x y
"} => {begin
{set {k2.left} as {y} {COMMENT "
k2 k1 k2
/\ / /\
k1 z => x y z
/\
x y
"}}
{set {k1.right} as {k2} {COMMENT "
k1 k2 k1
/ /\ /\
x y z => x k2
/\
y z
"}}
{k1}
}
}}
4. 过程与函数
泛语言函数定义的语法是:{define function {name}: {function} as {statement}}
泛语言模板定义的语法则为:{define template {name}: {template} as {statement}}
两者的区别在于
泛语言模板会最终将句法转换为scheme语言的句法,而函数则将句法转换为泛语言的本身的句法
另外,定义宏的语法是:{define macro {template} as {statement}}
宏与函数的区别在于宏不需要名称,直接展开成目标语句,而函数需要名称,翻译的顺序为先展开宏后翻译函数
5. 面向对象
5.1 继承
在项目元数据中取得继承信息,继承为单向继承,继承后类将获得所有祖辈的属性和方法
继承后,子孙类应避免添加和祖辈一致的属性名称,虽然项目中不强制,但是不保证程序会出现怪异行为
所有类至少继承Object类,改变继承使用语句:
{change inheritance {ChildClass}: {ParentClass}}
5.2 多态和消息传递
以下是多态的一个例子:
; Animal.fn
{define class {Animal}}
{add method {how-to-eat}:{eat}}
; Chicken.fn
{define class {Chicken}}
{change inheritance {Chicken}: {Animal}}
{define method {how-to-eat} as {print line {"Chicken eat."}}}
; Duck.fn
{define class {Duck}}
{change inheritance {Duck}: {Animal}}
{define method {how-to-eat} as {print line {"Duck eat."}}}
; poly-demo.fn
{define {animal} as {new instance of {Chicken}}}
{send message {how-to-eat}:{eat} to {animal}} ;will print "Chicken eat."
{set {animal} as {new instance of {Duck}}}
{send message {how-to-eat}:{eat} to {animal}} ;will print "Duck eat."
5.3 自省或反射
{get properties of class {Circle}}
{get methods of class {Rectangle}}
{get class name of object {an-object}}
{get super class of {Circle}}
{get super classes list of {Rectangle}}
{get sub classes of {Shape}}
{get all arguments of method {draw} of class {Shape}}
{get all arguments of function {a-function}}
......
5.4 异常处理
泛语言的异常默认抛到最外层,并由指定的处理函数进行处理,例如:
{define function {exception-demo}: {run demo} as {if {error occur} then
{throw new exception {AnException} with message {"There is an error."} and handler {default-exception-handler}}}}
如果要在抛到最外层前处理异常,可以使用try catch的方式,例如:
{try {run demo} catch exception {
{ExceptionA} => {handle code A},
{ExceptionB} => {handle code B}}}
6. 多分派函数
多分派函数的例子如下,其中generic function是函数原型,instance function是函数实例:
{define generic function {collide-with}:{{a} collide with {b}}}
{define instance function {collide-with}:{{@ a Asteroid} collide with {@ b Asteroid}} as {...}}
{define instance function {collide-with}:{{@ a Asteroid} collide with {@ b Spaceship}} as {...}}
{define instance function {collide-with}:{{@ a Spaceship} collide with {@ b Asteroid}} as {...}}
{define instance function {collide-with}:{{@ a Spaceship} collide with {@ b Spaceship}} as {...}}
{define {x} as {new instance of {Asteroid}}}
{define {y} as {new instance of {Spaceship}}}
{{x} collide with {y}}
【注】{@ object Class}表示指定object的类型为Class
7. 其它
泛语言将有许多特性在后续版本实现
7.1 并发
并发支持协程,STM,Actor模型等,例如Actor模型可以通过面向对象进行编程扩展:
{define class {DemoActor}}
{change inheritance {DemoActor}:{Actor}}
{define immutable {message} as {new instance of {Message} with witch {...}}}
{send message {method-name}:{send actor {message}} to {demoActor}}
7.2 组件
项目的可组件化是泛语言发展的一个目标,它实施的关键在于接口之间的定义和组装以及可以进行远程调用
7.3 动态重构
动态重构是指通过编写额外的重构代码对项目的源代码及目标代码进行修改,动态重构仅超级管理员有权限执行
7.4 与C语言交互
指泛语言调用C的函数及C语言调用泛语言的函数
8. 版权声明
本文版权所有,不得任意篡改,在引用、修改完善词条或用于商业计划前请征得原作者同意。
就目前为止,泛语言仍在不断发展完善中,该规范并未定型,仍可能会修改,作者会不定期地更新标准,以契合软件开发的最佳实践。
另外,该规范是开放的,您可以据此开发自己的泛语言实现而不需要支付任何费用,但是请注明规范来源与此。
1
https://gitee.com/funnyos/study.git
git@gitee.com:funnyos/study.git
funnyos
study
study
master

搜索帮助