编程界的“二向箔”——Dart元编程

已阅读《三体》的学生必须知道“向下维度打击”,从更高维度查看问题,然后直接瞄准对手KO。今天,我们聊了编程世界中的“双向箔纸”元编程。

我们听到了太多的名词,而且耳朵似乎有一些名词。例如,为了安装x的某些名词(例如作者的文章标题.)或其本身的含义难以定义,它将添加一些看似闪烁的前缀,例如meta。计算机软件行业具有元数据,元模型,元编程。

今天,我们x加载的主角是元编程元编程。

实际上,可以在Internet上找到许多相关文章。有关单词的定义,请参阅Wikipedia句子:

这意味着可以将程序设计为读取,生成,分析或转换其他程序,甚至在运行时对其进行修改。在某些情况下,这使程序员可以最大程度地减少表达解决方案的代码行数,从而减少开发时间。它还使程序具有更大的灵活性,可以有效地处理新情况而无需重新编译。

简而言之,该程序用作数据,可用于操纵程序或程序本身,并实现某些功能,例如将运行时工作移至编译时。

根据编译器的开发过程,元编程可以实现为代码替换(通过宏),泛型编程(从宏,远离类型,高度抽象的逻辑,减小代码大小)或以更高级的语言实现。运行时通过自省/反射机制来操作代码逻辑,或者通过解耦和打开编译过程来运行,它可以在中间语言阶段(AST,IL),操作语法树和中间语言中实现,以实现更多功能可扩展性。能力。

元编程的几个阶段

作为一种现代的高级语言,Dart除了具有模板功能之外,还可以基于中间语言来操作代码。本文重点介绍如何通过AST树的操作,基于中间语言(莳萝)执行元编程,以及实现一些现有的dart语法本身无法实现的语法。而且此实现对编译时运行时的程序性能几乎没有影响。

2.1背景知识

我们知道,几乎任何一种语言的代码都会在“编译”过程中生成树状的中间状态(解释的语言在运行时也具有已编译的过程),这就是AST(抽象语法树)。 AST在每个表达式/语句中描述了子语句的执行顺序和执行逻辑,以便可以轻松地将其转换为目标代码。基于此抽象,编译器可以合理地分为三个阶段:FrontEnd,Optimizer和Backend,以便可以实现与各种语法形式兼容的语言,并且更容易迁移并与不同架构的CPU兼容。参见下图:

三阶段编译

这三个阶段围绕此IL(中间语言)执行。 IL语言可以隔离语法(可以轻松适应各种新语言),平台体系结构等。

三阶段编译架构

2.2 Dart编译过程

Dart的设计相似,中间语言是Dill。区别在于,此处的Dill不如Java IL或DotNet IL开放,而是可以由程序直接编写。

Dart编译器

此方法实际上基于AST库,用于计算Dill。

莳萝操纵

该库中的组件包含定义和对AST树中涉及的所有节点的访问,将编程的基本概念(例如类型,函数,语句,声明和表达式)抽象为对象。基于这些对象,我们可以遍历整个AST树,或生成新的类型和函数,插入代码语句并实现新的逻辑。

2.3几个栗子

入门实际上非常简单。只看示例代码。

2.3.1。例如,以下语句定义一个新的Map变量并调用其构造函数:

2.3.2。创建功能主体

该函数的主体实际上是一个块。

2.3.3创建函数

本示例将参考函数的声明形式创建一个新函数。长度受到限制,某些参数被省略。

2.3.4其他

基于AST,您还可以创建复杂的表达式和语句,例如ForInStatement(for . in循环)等。语句和表达式也可以通过ExpressionStatement和BlockExpression相互转换。在AST定义中可以找到更多提示。

2.4如何调试

编辑过的莳萝似乎是个黑匣子。除了查看日志或异常堆栈之外,不可能进行单步调试,这给开发带来了一些困难。但是dart提供了一些工具,可以将内核dill转换成可读的文本,以便于调试:

打开的文本文件类似于此:

基于dill的操作,我们可以在代码中实现新的逻辑。例如,在idle fish技术出现之前,开源aop库asped的原理是通过加载dill文件,然后遍历ast,寻找已被注释的函数或语句,并生成dill以参与后续过程来生成ast。编译后的dill级别的操作。aop的最终实现。

同样,我们知道dart对于json解析操作也不是很方便。jsondecode不能直接生成业务对象,但可以生成map或list等集合。它还要求用户手动遍历这些集合并加载对象。虽然官方开源的一个基于源代码的解决方案,但使用起来并不友好(还有dason等其他程序,但依赖镜像,请看这里的比较)。事实上,遍历map或list并组合对象的逻辑非常简单。我们也可以通过操纵莳萝来做到这一点。

它很容易使用,例如:

为了更深入地思考,到目前为止还没有推荐DART现有的镜像功能(出于分析的原因,请参阅本文),那么我们是否可以实现一个基于DILL操作的简单而轻量级的LiteMirror库呢?并基于这个litemirror库来实现更高层次的json解析和aop甚至hook功能?

当然,您可能已经发现Dill Manipulation不可避免地必须自定义编译过程。例如,这需要在Flutter环境中,您需要自定义Flutter工具以加入Dill,然后进行编辑。惯用鱼技术Spoiler现在已经实现了Json解析器,正在为开源做准备,敬请期待!

作者:忙鱼技术-于杰

阅读原文

本文是云栖社区的原始内容,未经允许不得复制。

阿里云云栖社区

4.8

2019.08.29 16: 10

字数1775

已阅读《三体》的学生必须知道“向下维度打击”,从更高维度查看问题,然后直接瞄准对手KO。今天,我们聊了编程世界中的“双向箔纸”元编程。

我们听到了太多的名词,而且耳朵似乎有一些名词。例如,为了安装x的某些名词(例如作者的文章标题.)或其本身的含义难以定义,它将添加一些看似闪烁的前缀,例如meta。计算机软件行业具有元数据,元模型,元编程。

今天,我们x加载的主角是元编程元编程。

实际上,可以在Internet上找到许多相关文章。有关单词的定义,请参阅Wikipedia句子:

这意味着可以将程序设计为读取,生成,分析或转换其他程序,甚至在运行时对其进行修改。在某些情况下,这使程序员可以最大程度地减少表达解决方案的代码行数,从而减少开发时间。它还使程序具有更大的灵活性,可以有效地处理新情况而无需重新编译。

简而言之,该程序用作数据,可用于操纵程序或程序本身,并实现某些功能,例如将运行时工作移至编译时。

根据编译器的开发过程,元编程可以实现为代码替换(通过宏),泛型编程(从宏,远离类型,高度抽象的逻辑,减小代码大小)或以更高级的语言实现。运行时通过自省/反射机制来操作代码逻辑,或者通过解耦和打开编译过程来运行,它可以在中间语言阶段(AST,IL),操作语法树和中间语言中实现,以实现更多功能可扩展性。能力。

元编程的几个阶段

作为一种现代的高级语言,Dart除了具有模板功能之外,还可以基于中间语言来操作代码。本文重点介绍如何通过AST树的操作,基于中间语言(莳萝)执行元编程,以及实现一些现有的dart语法本身无法实现的语法。而且此实现对编译时运行时的程序性能几乎没有影响。

2.1背景知识

我们知道,几乎任何一种语言的代码都会在“编译”过程中生成树状的中间状态(解释的语言在运行时也具有已编译的过程),这就是AST(抽象语法树)。 AST在每个表达式/语句中描述了子语句的执行顺序和执行逻辑,以便可以轻松地将其转换为目标代码。基于此抽象,编译器可以合理地分为三个阶段:FrontEnd,Optimizer和Backend,以便可以实现与各种语法形式兼容的语言,并且更容易迁移并与不同架构的CPU兼容。参见下图:

三阶段编译

这三个阶段围绕此IL(中间语言)执行。 IL语言可以隔离语法(可以轻松适应各种新语言),平台体系结构等。

三阶段编译架构

2.2 Dart编译过程

dart的设计是相似的,中间语言是dill。不同之处在于,DIL在DOTNET中不像IL或IL那样开放,可以直接编写,而是通过程序操作的方式编写。

DART编译器

这种方法是基于ast库操作dill。

dill操作

这个库中的组件包含ast树中所有节点的定义和访问,将类型、函数、语句、语句、表达式等基本编程概念抽象为对象。基于这些对象,我们可以遍历整个ast树,或者生成新的类型和函数,插入代码语句,实现新的逻辑。

2.3几个栗子

介绍实际上非常简单,只需看一下示例代码。

2.3.1例如,下面的语句定义了一个新的映射变量并调用其构造函数:

2.3.2.创建函数体

函数体实际上是一个块。

2.3.3创建函数

这个例子引用一个函数的声明形式来创建一个新函数,这个函数的长度是有限的,并且省略了一些参数。

2.3.4其他

ast还可以创建复杂的表达式和语句,例如forinstatement(for…在循环中),语句和表达式也可以通过表达式statement和块表达式进行转换。有关更多提示,请参阅ast的定义。

2.4如何调试

编辑过的莳萝似乎是个黑匣子。除了查看日志或异常堆栈之外,不可能进行单步调试,这给开发带来了一些困难。但是dart提供了一些工具,可以将内核dill转换成可读的文本,以便于调试:

打开的文本文件类似于此:

基于dill的操作,我们可以在代码中实现新的逻辑。例如,在idle fish技术出现之前,开源aop库asped的原理是通过加载dill文件,然后遍历ast,寻找已被注释的函数或语句,并生成dill以参与后续过程来生成ast。编译后的dill级别的操作。aop的最终实现。

同样,我们知道dart对于json解析操作也不是很方便。jsondecode不能直接生成业务对象,但可以生成map或list等集合。它还要求用户手动遍历这些集合并加载对象。虽然官方开源的一个基于源代码的解决方案,但使用起来并不友好(还有dason等其他程序,但依赖镜像,请看这里的比较)。事实上,遍历map或list并组合对象的逻辑非常简单。我们也可以通过操纵莳萝来做到这一点。

它很容易使用,例如:

为了更深入地思考,到目前为止还没有推荐DART现有的镜像功能(出于分析的原因,请参阅本文),那么我们是否可以实现一个基于DILL操作的简单而轻量级的LiteMirror库呢?并基于这个litemirror库来实现更高层次的json解析和aop甚至hook功能?

当然,您可能已经发现Dill Manipulation不可避免地必须自定义编译过程。例如,这需要在Flutter环境中,您需要自定义Flutter工具以加入Dill,然后进行编辑。惯用鱼技术Spoiler现在已经实现了Json解析器,正在为开源做准备,敬请期待!

作者:忙鱼技术-于杰

阅读原文

本文是云栖社区的原始内容,未经允许不得复制。

已阅读《三体》的学生必须知道“向下维度打击”,从更高维度查看问题,然后直接瞄准对手KO。今天,我们聊了编程世界中的“双向箔纸”元编程。

我们听到了太多的名词,而且耳朵似乎有一些名词。例如,为了安装x的某些名词(例如作者的文章标题.)或其本身的含义难以定义,它将添加一些看似闪烁的前缀,例如meta。计算机软件行业具有元数据,元模型,元编程。

今天,我们x加载的主角是元编程元编程。

实际上,可以在Internet上找到许多相关文章。有关单词的定义,请参阅Wikipedia句子:

这意味着可以将程序设计为读取,生成,分析或转换其他程序,甚至在运行时对其进行修改。在某些情况下,这使程序员可以最大程度地减少表达解决方案的代码行数,从而减少开发时间。它还使程序具有更大的灵活性,可以有效地处理新情况而无需重新编译。

简而言之,该程序用作数据,可用于操纵程序或程序本身,并实现某些功能,例如将运行时工作移至编译时。

根据编译器的开发过程,元编程可以实现为代码替换(通过宏)、通用编程(从宏、远离类型、高度抽象逻辑、减小代码大小)或更高级的语言。运行时通过内省/反射机制来操作代码逻辑,或者随着编译过程的分离和开放,可以在中间语言阶段(ast、il)、操作语法树和中间语言中实现,以获得更大的可伸缩性。能力。

元编程的几个阶段

作为一种现代高级语言,dart除了具有模板化功能外,还可以操作基于中间语言的代码。本文主要研究如何基于中间语言(dill)执行元编程,通过对ast树的操作,实现一些现有的dart语法本身无法实现的功能。而且这种实现对程序在编译时运行时的性能影响很小。

2.1背景知识

我们知道,几乎在任何语言中,代码都会在“编译”过程中生成类似树的中间状态(解释语言在运行时也有编译过程),即ast(抽象语法树)。ast描述了每个表达式/语句中的子语句的执行顺序和执行逻辑,以便可以很容易地将其转换为目标代码。基于这种抽象,编译器可以合理地分为前端、优化器和后端三个阶段,从而实现与各种语法形式兼容的语言,更容易移植和兼容不同架构的CPU。见下图:

三阶段编译

这三个阶段是围绕着这个中间语言进行的。il语言将语法(可以很容易地适应各种新语言)、平台架构等隔离开来。

三阶段编译架构

2.2 DART编译过程

Dart的设计相似,中间语言是Dill。区别在于,此处的Dill不如Java IL或DotNet IL开放,而是可以由程序直接编写。

Dart编译器

此方法实际上基于AST库,用于计算Dill。

莳萝操纵

该库中的组件包含定义和对AST树中涉及的所有节点的访问,将编程的基本概念(例如类型,函数,语句,声明和表达式)抽象为对象。基于这些对象,我们可以遍历整个AST树,或生成新的类型和函数,插入代码语句并实现新的逻辑。

2.3几个栗子

入门实际上非常简单。只看示例代码。

2.3.1。例如,以下语句定义一个新的Map变量并调用其构造函数:

2.3.2。创建功能主体

该函数的主体实际上是一个块。

2.3.3创建函数

本示例将参考函数的声明形式创建一个新函数。长度受到限制,某些参数被省略。

2.3.4其他

基于AST,您还可以创建复杂的表达式和语句,例如ForInStatement(for . in循环)等。语句和表达式也可以通过ExpressionStatement和BlockExpression相互转换。在AST定义中可以找到更多提示。

2.4如何调试

编辑的莳萝似乎是一个黑匣子。除了查看日志或查看异常堆栈之外,还无法单步调试,这给开发带来了一些困难。但是Dart提供了将内核莳萝转换为可读文本的工具,以便于调试:

打开的文本文件类似于此:

基于Dill的操作,我们可以在代码中实现新的逻辑。例如,闲置鱼技术之前的开源AOP库AspectD的原理是通过加载莳萝文件,然后遍历AST,查找已注释的函数或语句,并生成参与的莳萝来生成AST。在后续的莳萝级编译过程中进行操作。 AOP的最终实现。

同样,我们知道Dart对于Json解析操作不是很方便。 jsonDecode无法直接生成业务对象,但是可以生成Map或List之类的集合。它还要求用户手动遍历这些集合并加载对象。虽然是基于source_gen的解决方案的官方开源软件,但使用起来并不友好(还有其他程序,例如Dason,但依赖Mirror,请参阅此处的比较)。实际上,遍历Map或List以及组装对象的逻辑非常简单。我们也可以通过Dill Manipulation进行操作。

例如,它易于使用:

为了进行更深入的思考,到目前为止,尚未建议使用Dart的现有镜像功能(出于分析的原因,请参阅本文),那么我们是否可以基于Dill Manipulation实现一个简单轻巧的LiteMirror库?并基于此LiteMirror库实现更高级别的Json解析和AOP甚至Hook功能?

当然,您可能已经发现dill操作不可避免地要定制编译过程。这需要,例如,在颤振环境中,您需要自定义颤振工具以加入dill,然后进行编辑。spoiler,idle fish技术现在已经实现了json解析器,正在为开源做准备,请继续关注!

作者:忙鱼科技-于杰

阅读原文

本文为云起社区原创内容,未经许可不得转载。