每一位热爱编程的软件工程师都有一个终极梦想:创造一门自己的计算机语言。
zlang
是一门C/Java语系的、追求简洁但又高阶的、基于对象克隆的的解释性编程语言。
import stdtypes stdio ;
function int main( array args )
{
stdout.Println( "hello world" );
return 0;
}
创造zlang
的一部分初衷是觉得手头的语言总存在这样那样的不方便之处,C
在处理字符串时不够高阶简单,Java
的Get
/Set
太八股,这些通过扩展很难彻底解决,但如果拥有一门自己的语言,就能打造成自己想要的样子,岂不爽哉。
import stdtypes stdio ;
function int main( array args )
{
string fruit = "pear" ;
string guess ;
stdin.Scan( guess );
if( guess == fruit )
stdout.Println( "Yes" );
else
stdout.Println( "No" );
return 0;
}
首先是如何设计zlang
的语法,程序员在学习一门新的编程语言时最烦的就是新语言的语法完全特立独行、奇形怪状、满眼都是符号,自己得重新培养新的语感,其实C/Java
的语法已经设计的相当完美了,新语言根本没必要完全设计一套新的语法,新语言的重点应该放在如何解决老语言的问题上,以及基于既有语法做扩展,zlang
语法继承自C/Java
,能让最广大的同学们快速学习掌握,把有限的时间精力放在差异化部分。
import stdtypes stdio ;
function int factorial( int n )
{
if( n == 1 )
return 1;
else
return factorial(n-1) * n ;
}
function int main( array args )
{
n = factorial( 6 ) ;
stdout.Println( n );
return 0;
}
UNIX/Linux
的伟大之一是所有进程都是从根进程克隆出来的,这和Windows
笨重的从头创建一个新进程形成鲜明的对比,克隆体现出一种简单而又不失强大的UNIX哲学,zlang
尝试通过克隆根对象来创造整个应用程序来实践一门语言哲学,希望这是正确的。
import stdtypes stdio ;
function int main( array args )
{
string sheep1 = "Dolly" ;
sheep1 sheep2 ;
stdout.Println( sheep2 );
return 0;
}
性能方面,zlang
虽然是解释性语言,但还未做大规模的优化就拥有不俗的性能了,在我的老爷机上短连接、串行请求一个WEB动态页面(模板实例化),RT在1ms左右(TPS 1000)。
<html>
<head>
<title>((HEADER_TITLE))</title>
</head>
<body>
({UNLOGIN))
<p>Please login first</p>
(/UNLOGIN})
({LOGIN))
<p>USER : ((USER))</p>
<table border="1">
<tr>
<td>ID</td>
<td>NAME</td>
<td>AMOUNT</td>
</tr>
([DETAIL))
<tr>
<td>((ID))</td>
<td>((NAME))</td>
<td>((AMOUNT:%.1lf))</td>
</tr>
(/DETAIL])
</table>
<p> TOTAL : ((TOTAL))</p>
<p>TOTAL_AMOUNT : ((TOTAL_AMOUNT))</p>
<p> DATETIME : ((DATETIME))</p>
(/LOGIN})
</body>
</html>
$ ab -c 1 -n 10000 'http://192.168.11.79:9527/test_httpserver_htmlsection_1_1'
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.11.79 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software:
Server Hostname: 192.168.11.79
Server Port: 9527
Document Path: /test_httpserver_htmlsection_1_1
Document Length: 466 bytes
Concurrency Level: 1
Time taken for tests: 10.448 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 5060000 bytes
HTML transferred: 4660000 bytes
Requests per second: 957.13 [#/sec] (mean)
Time per request: 1.045 [ms] (mean)
Time per request: 1.045 [ms] (mean, across all concurrent requests)
Transfer rate: 472.96 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 1 1 0.1 1 3
Waiting: 1 1 0.1 1 3
Total: 1 1 0.1 1 3
Percentage of the requests served within a certain time (ms)
50% 1
66% 1
75% 1
80% 1
90% 1
95% 1
98% 1
99% 1
100% 3 (longest request)
除此之外,zlang
还拥有如下特性:
同时支持面向过程和面向对象,语言设计者根本不用考虑面向过程和面向对象哪个好,都支持好了,看用户怎么喜欢怎么用。
import stdtypes stdio ;
interface animal
{
string name ;
function void SetWarriorName( string name )
{
this.name = name + " warrior" ;
}
function void Cry();
function void Eat( string food );
}
object cat implements animal
{
function void Cry()
{
stdout.Println( "miaomiaomiao~" );
}
function void Eat( string food )
{
if( food == "fish" )
stdout.Println( ":)" );
else
stdout.Println( ":(" );
}
}
object dog implements animal
{
function void Cry()
{
stdout.Println( "wangwangwang~" );
}
function void Eat( string food )
{
if( food == "bone" )
stdout.Println( ":>" );
else
stdout.Println( ":<" );
}
}
function int main( array args )
{
cat my_cat ;
my_cat.SetWarriorName( "ahua" );
stdout.Println( my_cat.name );
my_cat.Cry();
my_cat.Eat( "fish" );
my_cat.Eat( "bone" );
dog my_dog ;
my_dog.SetWarriorName( "black" );
stdout.Println( my_dog.name );
my_dog.Cry();
my_dog.Eat( "bone" );
my_dog.Eat( "fish" );
return 0;
}
自动推导类型,声明变量时,明显可自动推导出来类型,则不用写出来。
import stdtypes stdio ;
function int main( array args )
{
str2 = "hello2" ;
stdout.Println( str2 );
return 0;
}
对象动态增删方法和属性,既然是解释语言,就要把运行时这个优势发挥好,语言只管提供这种能力,天知道会被神一般的用户玩出什么花来,比如我对实体类就很感冒。
import stdtypes stdio ;
function int main( array args )
{
zobject o ;
string str ;
o.AddProperty( <object>string , "name" );
o.name = "cal" ;
stdout.Println( o.name );
str = o.ReferProperty( "name" ) ;
str =* "vin" ;
stdout.Println( o.name );
o.RemoveProperty( "name" );
return 0;
}
提供完整、必要的集合对象:数组、链表、映射、队列、栈,管理数据基本无忧。
import stdtypes stdio ;
function int main( array args )
{
list<string> my_list ;
my_list.AddTail( "111" );
my_list.AddTail( ”222“ );
my_list.AddTail( "333" );
stdout.Println( my_list.Length() );
foreach( string s in my_list )
{
stdout.Println( s );
}
return 0;
}
人必云Get
、Set
能做到封装性、提供扩展能力,我觉得封装性不一定非要用方法,对象中的一些属性为什么就不能作为接口暴露出来,不要人云己云,至于扩展性,那是Java
语言的设计问题了,zlang
提供了属性拦截器解决扩展性问题,没必要为将来极小概率的扩展性而要求每个属性都用繁琐的存取写法,大胆的直接赋值好了,直接的、简单的就是最好的,将来碰到需要扩展性时写一个属性拦截器就解决了,真没必要为了将来1%的扩展性导致99%都遵循繁琐的写法。比如以下表达,你更喜欢哪一种?
赋值
Java
tortoise.setName( msg.getName() );
zlang
falcon.name = msg.name ;
字符串比较
Java
if( name.equals(name2) )
zlang
if( name == name2 )
自创的属性拦截器
zlang
import stdtypes stdio ;
object greasy_man
{
public string name ;
public int age ;
intercept get name( object name )
{
if( name == null || name == "" )
name = "" ;
else
name += "@Hangzhou" ;
return;
}
intercept set age( object age )
{
if( age < 0 )
age = 0 ;
else if( age > 200 )
age = 200 ;
return;
}
}
function int main( array args )
{
greasy_man i ;
i.name = "calvin" ;
stdout.FormatPrintln( "i.name[%s]" , i.name );
i.age = 296 ;
stdout.FormatPrintln( "i.age[%d]" , i.age );
return 0;
}
zlang
的迭代器支持前后移动。
关键字、函数名、变量名都可以使用中文。还是那句话,我提供功能,喜欢的人就用,不喜欢的人可以不碰。
charset "zh_CN.gb18030"
导入 stdtypes stdio ;
函数 整型 主函数( 数组 命令行参数集 )
{
字符串 招呼 = "你好,世界" ;
字符串 A前中后B有字母C = "A前中后B有字母C" ;
整型 数 = 3 ;
整型 序号 , 总数 ;
如果(招呼!="你好,世界")
{
标准输出.显示并换行( "不对" );
}
否则
{
标准输出.显示并换行( A前中后B有字母C );
}
分支判断(数)
{
分支匹配 1 :
标准输出.显示并换行( "击中1" );
分支匹配 2 :
标准输出.显示并换行( "击中1" );
分支缺省:
标准输出.显示并换行( "击中缺省" );
}
总数 = 3 ;
循环( 序号=0 ; 序号<总数 ; 序号++ )
{
标准输出.格式化显示并换行( "序号[%d]" , 序号 );
}
循环每一个( 字符串 参数 在里面 命令行参数集 )
{
标准输出.格式化显示并换行( "命令行参数[%s]" , 参数 );
}
返回 0;
}
zlang
加入了很多各种编程语言精华的特性,比如延迟执行等。
import stdtypes stdio ;
function int main( array args )
{
stdfile f ;
nret = f.Open( "test_defer_1.out" , "w" ) ;
if( nret == -1 )
{
stdout.Println( "open file failed[%d]" , nret );
return 1;
}
defer f.Close();
f.FormatPrintln( "hello" );
return 0;
}
zlang
的输出对象支持格式化串中不给定参数对应的类型而通过自动推导、支持直接在格式化串给定变量名而不用在后面苦哈哈的一个又一个加对应的参数。
stdout.FormatPrintln( "s[%?] i[%?] l[%?] f[%?] d[%?]" , s , i , l , f , d );
stdout.FormatPrintln( "s[%{s:2hd}] i[%{i:-4d}] l[%{l:ld}] f[%{f:4f}] d[%{d:10.2lf}]" );
zlang
是我几乎完全自研的编程语言,连词法分析器都手工编写,以下是仅有的依赖:
rbtree_tpl
(zlang
源代码中已包含其源码)aodatapage
(zlang
源代码中已包含其源码)byteorder
(zlang
源代码中已包含其源码)cdbc
(zlang
源代码中已包含其源码)libgus
(zlang
源代码中已包含其源码)fasterjson
(zlang
源代码中已包含其源码)fasterxml
(zlang
源代码中已包含其源码)fasterhttp
(zlang
源代码中已包含其源码)fastertpl
(zlang
源代码中已包含其源码)hetao
(zlang
源代码中已包含其源码)iLOG3
(zlang
源代码中已包含其源码)list
、rbtree
(zlang
源代码中已包含其源码)hiredis
(链接时外部依赖)libmysqlclient.so
、libpq.so
、libsqlite3.so
(链接时外部依赖)此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型