# 元神语言 **Repository Path**: xydhw/Meta-language ## Basic Information - **Project Name**: 元神语言 - **Description**: 元神语言是一个通用编程语言代码生成语言,旨在提高工作效率,降低程序员学习成本,提高程序稳定性. - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-02-06 - **Last Updated**: 2024-02-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MetaLang 元神语言 元神语言是一个通用代码生成语言,旨在提高工作效率,降低程序员学习成本,提高程序稳定性. 元神语言语法简洁,表达能力强大,信息密度高. - 它像lisp一样灵活,可以快速编写自身的语法以及开发新的框架。 - 它能让你触到业务最本质的复杂度,消灭一切重复代码。 - 它可以轻松地编译成其他的编程语言,充分利用其他语言的特性和生态,降低换语言的学习成本。 - 它可以让你快速扩展编辑器的语法分析,以减少人为的代码规范不符和潜在漏洞。 # 教程 ## 前提 元神语言是一种代码生成语言,所以默认你已经掌握了一门主流编程语言.本教程以C#为例子. ### 语法 元神语言的语法非常简洁,能很直观地转换为抽象语法树.足够抽象的语法才能转换为其他语言. ### 0.类型 元神语言所有的代码只有两种类型:symbol和list,符号和列表. list内可以容纳list或者symbol ```MetaLang There are 7 words in the list ``` 上文的'Threre','are','words','in','the','list'都是symbol. 而['Threre','are','words','in','the','list']这个整体是list 下面是一个list嵌套了一个list ```MetaLang There are 7 (words in) the list ``` 对应的json是:['Threre','are',['words','in'],'the','list'] 元神语言的核心关键字非常少,三个语法符号:分隔符",",左括号:"(",右括号")" 一些关键字符和主流语言一致: 一些运算符号:+-*/&|$!=.? 字符串的开始结尾"" 转义字符\ symbol不包含以上符号,其他的都是symbol,symbol之间用空格隔开.系统预先定义了一组symbol. ### 1.层级 元神语法借鉴了lisp的s表达式和python的缩进式层级语法.避免了像lisp一样括号太多 你还可以这样写:(与前一段是等价的) ```MetaLang There are 7 words in the list ``` 只要词所在的行缩进次数一致,他们的层级就是一样的,下面的写法也合法: ```MetaLang There are 7 words in the list ``` 下面是两个list ```MetaLang (There are 7)(words in the list) ``` 用符号","对同级的词进行分割,这也是两个list.下面几个写法等价 ```MetaLang There are 7,words in the list ``` ```MetaLang There are 7, words in the list ``` ```MetaLang There are 7 ,words in the list ``` 下面两种写法等价,这段代码根节点是一个list ``` a b c d ``` ``` a(b)c(d) ``` 下面的写法等价,代码根节点是两个list ``` a b ,c d ``` ``` (a(b))(c(d)) ``` ``` a(b),c(d) ``` ``` a(b), c(d) ``` 注意,下面两种写法不等价,"b,"是和b同层级的分割符号",c"是和c同层级的分隔符,前者等价a(b)c(d),后者等价(a(b))(c(d)) ``` a b, c d ``` ``` a b ,c d ``` 多层嵌套的情况,下面的代码等价(比较复杂,可先跳过本段) ``` (((a b))) (((a))((b))) ``` ``` , ((a b)) (((a,,b))) ``` ``` , (a b) (((a ,,b))) ``` ``` , a b (((a(, (b))) ``` ``` , a b (((a(, (b))) ``` 总结一下,你可以把分割符","理解为")(",但","形成的空列表()在编译时去掉.如果需要空列表(),直接写就好了 ### 2.代码映射 下文的元神代码和C#代码是可以互相转换的: MetaLang: ```MetaLang csharp using System class Program static void Main Console.WriteLine "Hellow, World!" ``` csharp: ```cs using System; class Program { static void Main() { Console.WriteLine("Hello, World!"); } } ``` 同样的,元神语言转换为其他语言也一样的简洁。 你 可以用 # 这个 symbol 使得 同层级 后面的 symbol 内嵌 一层 . 注意 # 的解析 是在 "," 和 小括号 解析 之后 才进行. 下面的 写法 是 同样的 效果: ```MetaLang csharp using System class Program static void Main Console.WriteLine "Hellow, World!" ``` ```MetaLang csharp using System class Program # static void Main Console.WriteLine "Hellow, World!" ``` ```MetaLang csharp using System class Program # static void Main # Console.WriteLine "Hellow, World!" ``` ```MetaLang csharp using System class Program # static void Main # Console.WriteLine "Hellow, World!" ``` 如果 你 习惯了 这种 语法 , 你 会 发现 写代码 就像 写文章 一样. XAML一样可以进行映射,下面是一段比较复杂的xaml ```xaml Default Light Dark ``` 映射为元神语言: ``` xaml UserControl xmlns "https://github.com/avaloniaui" xmlns:mc "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm "clr-namespace:ComConfigUI.ViewModels" mc:Ignorable "d" d:DesignWidth "800" d:DesignHeight "450" xmlns:pgc "using:Avalonia.PropertyGrid.Controls" x:DataType"vm:MainViewModel", Design.DataContext () # (// This only sets the DataContext for the previewer in an IDE ,vm:MainViewModel), Grid (RowDefinitions "*, Auto") StackPanel Margin "4" Orientation "Horizontal" Grid.Row "1" HorizontalAlignment "Right", TextBlock (Text "Theme" HorizontalAlignment "Center" VerticalAlignment "Center" Padding "2"), ComboBox x:Name "ThemeVariantsBox" Width "125" Padding "4" DisplayMemberBinding "{Binding Key, x:DataType=ThemeVariant}" SelectedIndex "0", ComboBox.Items () # ThemeVariant () Default, ThemeVariant () Light, ThemeVariant () Dark ``` 不仅字符数少很多,行数也变少了.多用 # symbol还可以更短,但可读性会变差.这下代码更加紧凑了.总长度从1240降到了876 ``` xaml UserControl xmlns "https://github.com/avaloniaui" xmlns:mc "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm "clr-namespace:ComConfigUI.ViewModels" mc:Ignorable "d" d:DesignWidth "800" d:DesignHeight "450" xmlns:pgc "using:Avalonia.PropertyGrid.Controls" x:DataType"vm:MainViewModel", Design.DataContext () ( // This only sets the DataContext for the previewer in an IDE ,vm:MainViewModel), Grid # RowDefinitions "*, Auto", StackPanel # Margin "4" Orientation "Horizontal" Grid.Row "1" HorizontalAlignment "Right", TextBlock # Text "Theme" HorizontalAlignment "Center" VerticalAlignment "Center" Padding "2", ComboBox # x:Name="ThemeVariantsBox" Width "125" Padding "4" DisplayMemberBinding "{Binding Key, x:DataType ThemeVariant}" SelectedIndex "0", ComboBox.Items () # ThemeVariant () Default,ThemeVariant () Light,ThemeVariant () Dark ``` 为了更容易看清楚分段的位置,可以把","放在行首 . 如果再加上各种各样的高亮.熟悉后代码也是一目了然的. ``` xaml UserControl xmlns "https://github.com/avaloniaui" xmlns:mc "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm "clr-namespace:ComConfigUI.ViewModels" mc:Ignorable "d" d:DesignWidth "800" d:DesignHeight "450" xmlns:pgc "using:Avalonia.PropertyGrid.Controls" x:DataType"vm:MainViewModel" ,Design.DataContext () ( // This only sets the DataContext for the previewer in an IDE ,vm:MainViewModel) ,Grid # RowDefinitions "*, Auto" ,StackPanel # Margin "4" Orientation "Horizontal" Grid.Row "1" HorizontalAlignment "Right" ,TextBlock # Text "Theme" HorizontalAlignment "Center" VerticalAlignment "Center" Padding "2" ,ComboBox # x:Name="ThemeVariantsBox" Width "125" Padding "4" DisplayMemberBinding "{Binding Key, x:DataType ThemeVariant}" SelectedIndex "0" ,ComboBox.Items () # ThemeVariant () Default,ThemeVariant () Light,ThemeVariant () Dark ``` 更为提倡的是不要使用"#",只使用缩进,括号和分隔符"," ``` xaml UserControl xmlns "https://github.com/avaloniaui" xmlns:mc "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm "clr-namespace:ComConfigUI.ViewModels" mc:Ignorable "d" d:DesignWidth "800" d:DesignHeight "450" xmlns:pgc "using:Avalonia.PropertyGrid.Controls" x:DataType"vm:MainViewModel" ,Design.DataContext () (// This only sets the DataContext for the previewer in an IDE , vm:MainViewModel) ,Grid # RowDefinitions "*, Auto" ,StackPanel Margin "4" Orientation "Horizontal" Grid.Row "1" HorizontalAlignment "Right" ,TextBlock Text "Theme" HorizontalAlignment "Center" VerticalAlignment "Center" Padding "2" ,ComboBox x:Name="ThemeVariantsBox" Width "125" Padding "4" DisplayMemberBinding "{Binding Key, x:DataType ThemeVariant}" SelectedIndex "0" ,ComboBox.Items () # ThemeVariant () Default,ThemeVariant () Light,ThemeVariant () Dark ``` ### 3.编译扩展 元神语言能在不同的时期执行代码。 1. 编辑时:类似于代码智能补全和vs的灯泡提示。 1. 编译时:可以对代码的不同阶段进行扩展,甚至管理阶段。 编译时可以详细分为以下阶段: 1. 字符串阶段:原始的代码字符串。 1. token阶段:词法分析后,代码被解析为一个个的词。 1. Meta ast阶段:元神语言的抽象语法树。 1. 目标语言阶段:编译为目标语言后的字符串。 1. tagert ast阶段:目标语言的抽象语法树。 下面示范一个C#自动给MVVM添加属性通知的ast阶段的扩展。 使用metalang在meta编译阶段扩展功能: ``` On MetaAst Asts where x (x.IsCsharpPropertyDeclaration and x.HasTag AutoNotify) ForEach x if (x.CsharpAst.AccessorList.Accessors.Count==2) //判定是否是自动属性 var priname #intern ("_"+x.(-2).Name) ,x.Parent.InsertChild #ListAst (x.SkipLast 2) priname ,x.ReplaceNode x.Last #ListAst (ListAst 'get priname) #ListAst #'set #'RaiseIfChange priname 'value else csharp public class ViewModel : ViewModelBase private int _age=0, private string _name="peter", AutoNotify public int Age (get _age,set _age=value), public string Name (get _age,set _age=value), public bool Enable (get set), ```