你一定有过这种困惑,一直想要找到一个完全适合自己编码风格,开发习惯的语言。却发现每一个语言各有优略,没有哪个能完全适合你的…
或者你看到现在层出不穷的各种编程语言,难道就没有想装个逼,自己搞一个玩玩的冲动?
爱装逼的人都拥有同样的气质,所以,我就尝试自己创建了一个编程语言------------Menthol
所以,你也不用想了,自己开发一个吧。
下面我将以我创建Menthol语言过程为例子,一步步说明,如何创建一个基于虚拟机的编程语言。
在你实际编码前,需要有3点,做在编码前,很重要
1.确定你理想中个的编码风格
可能你无数次想过理想中的一个语言,但从来没有实际去写过类似风格的demo。所以,如果只通过思考去架构出一个完整的代码风格,可能比较困难,一个语言不仅要完成功能,还要保证书写的简便性、代码格式的优雅性
所以,用你最常用的语言,开发一个程序,这个程序,最好能稍微复杂一点,能最多的体现出语言的各种逻辑,比如可以写一个,从网页中获取img地址的功能,用C#写一个
private string[] GetHtmlImageUrlList(string sHtmlText)
{
Regex regImg = new Regex(@"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<imgUrl>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>", RegexOptions.IgnoreCase);
MatchCollection matches = regImg.Matches(sHtmlText);
int i = 0;
string[] sUrlList = new string[matches.Count];
foreach (Match match in matches)
sUrlList[i++] = match.Groups["imgUrl"].Value;
return sUrlList;
}
public static string DownloadHtml(string url)
{
string html = string.Empty;
try
{
var request = WebRequest.Create(url) as HttpWebRequest;
request.Timeout = RequestModels.Timeout * 1000;
request.UserAgent = RequestModels.UserAgent;
request.ContentType = RequestModels.ContentType;
request.Headers.Add("Cookie", @RequestModels.Cookie);
using (var response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
{
return url;
}
try
{
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);//Encoding.GetEncoding("GB2312"));//
html = sr.ReadToEnd();
sr.Close();
}
catch (Exception ex)
{
html = null;
}
}
}
catch (System.Net.WebException ex)
{
if (ex.Message.Equals("远程服务器返回错误: (306)。"))
{
return null;
}
}
catch (Exception ex)
{
html = null;
}
return html;
}
然后把这个段代码,修改成为你理想中的代码风格。至于代码风格是怎样的,随便写,只要你写的顺手就可以。在这个过程中,你要确认,你的类型是静态的,还是动态的。
我们来把他翻译成Menthol语言的编码
def GetHtmlImageUrlList(var $str)
{
var $sUrlList = [];
var $a = Regex.Exec($str,"<img.*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png]))[\'|\"].*?[\/]?>");
for(var $s in $a){
Array.Push($sUrlList,$s[1]);
}
}
def DownloadHtml(var $url)
{
var $curl = CurlSystem.init();
CurlSetOpt.url($curl, $url);
CurlCallback.writefunction($curl,test.getsource);
var $res = CurlSystem.perform($curl);
CurlSystem.cleanup($curl);
}
应为Menthol是无类型语言,所以,所有的变量声明不需要指定类型,在编译或运行时会自动判断,我将局部变量用 开头,因为是函数式语言,没有类的概念,只有模块的概念,所有调用模块方法的是时候,要用模块名 . 函数名调用,例如 C u r l S e t O p t . u r l ( 开头,因为是函数式语言,没有类的概念,只有模块的概念,所有调用模块方法的是时候,要用模块名.函数名调用,例如 CurlSetOpt.url( 开头,因为是函数式语言,没有类的概念,只有模块的概念,所有调用模块方法的是时候,要用模块名.函数名调用,例如CurlSetOpt.url(curl, $url); 还定义了类似C#的foreach的工能:for in。
目前通过上述只能看到这么多,当然,如果你写的程序够复杂的话,那么一次性定义出语法风格的机会就大很多,这个过程可能需要多次执行,才能最终把你需要的代码风格定义出来
应为C#与Menthol在类库上的不同,所以,上述翻译不可能完全一样,只作为参考就可以了
2.定义关键字
如果你打算做成静态的话,那么所有的变量,对于编程人员来说,都要有一种类型,比如int,string,double等。如果是动态的话,就没有类型了。所有的类型就一种。我在开发Menthol时,以我的需求,定义了以下关键字
if else for break true false try except throw continue return while null import _mmain def var in typeof module use。
3.定义运算符
一个语言,不能只有关键字,那样逻辑运算无法进行,所以还要定义运算符,比如1中的"=“,”!=“,”[]"等。都可以算是运算符,Menthol,依目前开发需求定义如下运算符
/ () ; , | & ? [] ! % ^ : :: … = < > != <> || && >= <= == += -= /= = %= &= |= ^= << >> *
以上,定义一个语言的基本要素,已经完成.下面开始进行实际的编码操作