博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

计划开发的语言及一些细节求吐槽

Posted on 2013-10-31 16:56  xuld  阅读(812)  评论(11编辑  收藏  举报

我做了一个决定:开发一门语言。

这是很多coder的梦想,但只有很少人才能真正做出来,做出来后只有很少人能真正使用这门语言。

请不要在这里说语言已经很多了,做了也是白做之类的话,反正浪费的不是你的时间。

~~~~~~~~~~~~~~~~~

我已经确认在技术水平上这个语言是完全可以做出来的。语言最后一定会做出来的。

发表此文的目的,是为了在语言设计完成前参考下各位coder的意见,

作为一个coder,你一定想过自己做一个语言,只是你可能不会做,不敢做,或者没时间,或者觉得做这个零回报。

但是你可以在这里把你关于语言(特别是语法)的想法说出来,如果真的是不错的想法我会采纳你的意见。

当然你不会在你的工作中使用这门语言,不过纯吐槽吐槽不也是挺好的么。

~~~~~~~~~~~~~~~~~~

先说我要做的语言的大致特点:1. C风格,更符合C++用户的习惯。2. 强类型、需要编译执行。3. 可以编译为原生机器码,当然GC之类的也是会有的。

语言的设计目标不是高运行效率,也不是简单稳定完美。而是:做业务需求更方便。

~~~~~~~~~~~~~~~~~~

接下来就是目前已经设计好的语法和吐槽点了。欢迎提供建议和批评。

一、基本结构

1. 全局下只能有:全局函数、全局变量、名字空间和类。程序入口函数默认是 main 函数。 hello world 代码如下:

void main(){
      System.Console.writeLine("hello world");
}

其中,System 是系统包。对于代码中的所有点都可以省略,代码如下:

using System;
void
main(){ Console.writeLine("hello world"); }

更甚至是:

using System.Console;
void
main(){ writeLine("hello world"); }

2. 代码中支持C中经典的预处理符,但是不允许 #define a b 的形式,因为这东西会让代码非常难读懂。所以同时 #ifdef 之类的也改成了 #if 。也没有#include ,因为这东西让编译速度急速下降。其实这些情况和C#完全一样。

二、语句和表达式

1. 代码允许缺少分号,只要不出现歧义。还有 if for 等语句的小括号也可以省略,只要不出现歧义。

2. switch 语句case之间不贯穿,这意味着不需要break。相同处理情况的case可以使用一个case,然后后面表达式逗号隔开。

3. 使用和JavaScript相同的 for in 语句(内部使用 yield 语句)。同时还支持下面语法:

for(object value, int i in arr){}
for(int i = 0 to 100){} until(a){} // 即 while(!a) do {} until(a) // 即 while(!a)
loop {} // 死循环 loop(100){} // 循环100次

4. 自动识别类型。

auto i = 1; // 自动识别 auto 到 int
dynamic j = 1; // 动态类型

// 注意以上两者是本质区别的,前者是静态类型,编译时就已知类型了,后者动态

var k = 1; // 智能的类型判断,如果 k 在生命周期内只有一个类型,那么它是静态类型,相当于 auto 了。否则,k有多个类型可能的话,即 dynamic  。

5. 使用 dispose 来释放外部资源

var s = new FileStream("C:\\a.txt");
s.dispose(); // 释放s所占的资源(但s对象本身肯能是受GC管理而没有释放的)

// 也可以使用语法糖写成:


let(var s = new FileStream("C:\\a.txt")){}

6. 类型转换问题

int a = 1 as long // 即C的 int a = 1L;
int b = a as long // 即C的 int a = (long)b;
int c = "111" as int
string d = 1 as string;
// 可见不存在 .toString() 函数。(as 操作同样可以使用参数)
// 对于明确类型的变量定义。可以直接省略 as 调用
string s = 1; // 省略一个 as string

// 但是其它地方是不允许省略的。
// 类型转换也可以使用这个语法糖:
int("111") // 等效于 "111" as int

// 类型转换也存在和C一样的隐式方式。

7. 指针问题

语法上不直接提供指针功能,同时使用类似API的方式使用:

int i = 0;
Ptr<int> pi = i as Ptr<int>;
int j = pi++.value;

8. 变量约束

int i : i > 5 ;
i = 4;  // 运行时错误: i 必须大于 5  

使用变量约束可以大幅增加代码的稳定性。变量约束同样可以应用在参数和字段。

9. 衍生类型

int[] p = [1, 2, 3];

int? p = null // 可空类型
string! p = null // 不可空类型(此代码运行时报错)

//  ? 和 ! 是两种相反的特殊类型, ?适于值类型, !适于引用类型。

10. 使用类名来获取类型本身并用来反射

Type s = String;  // 直接获取此类型本身
Method d =String.replace;   // 直接返回此函数本身
string ns = d.call("", "a", "b");

11. 模板字符串

int i = 1;
string s = `v is $i` // 最后 v is 1 

12. 支持 goto

三、类

1. class 都是引用类型。 struct 都是结构类型。

2. 默认 public, 名字以 _ 前缀的默认 private

3.  interface 可以包含默认的实现。

4. 允许动态扩展类成员。

5. 没有析构函数。(提升 GC 的效率)

 

请不要说这些东西不符合面向对象。我压根没打算做面向对象,我做的是原创的面向接口。

6. 支持函数动态重载。

class A{}
class B:A{}
class C:A{}

// 定义动态重载
void fn(case B i){}
void fn(case C i){}


A a = getA();
fn(a); // 调用动态重载

// 如果没有 case ,那么是静态重载。此时因为不存在  fn(A i) 所以报错。
// 但是有 case证明动态重载,那么fn在运行时选择真正函数  。

7. 使用 base 表示基类。内部类不能直接访问外部类非静态成员。

 

 

 

 

附 Object 类源码:

class Object {

    protected Object memberwiseClone(){
        return Native.memberwiseClone(this);
    }
    
    protected virtual void finalize(){
    
    }
    
    Type getType() {
        return Native.getType(this);
    }

    virtual int getHashCode() {
        return Native.getHashCode(this);
    }
    
    virtual as String {
        return this.type as String;
    }

as void* { return Native.getPtr(this); } virtual bool == (Object value) { return Object.referenceEquals(this, value); } virtual >> { >> this as String; } static bool referenceEquals(Object objA, Object objB) { return Native.referenceEquals(objA, objB); } }

 

 

 

欢迎补充。

string