手写编程语言教程,手写代码编程
前言首先带来每日GScript更新:增加了可变参数特性,语法如下:
int add(字符串s,int.num){
println(s);
int sum=0;
for(int I=0;I len(num);i ){
int v=num[I];
sum=sum v;
}
返回总和;
}
int x=add(abc ,1,2,3,4);
println(x);
assertEqual(x,10);由于可变参数,增加了一个新的用于格式化字符串的内置函数:
//根据格式说明符格式化,并写入标准输出。
printf(字符串格式,任何.a){}
//根据格式说明符格式化,并返回结果字符串。
string printf(string format,any.a) {}下面看看GScript支持的运算符重载是如何实现的。
使用运算符重载实际上是多态的一种形式。我们可以重写运算符的重载函数来改变它们的计算规则。
println(100 2 * 2);以这段代码的运算符为例,输出结果自然是:104。
但是,如果我们正在计算两个对象,例如:
类别人员{
int age
人员(内部){
年龄=a;
}
}
人p1=人(10);
人p2=人(20);
人p3=p1 p2这种写法在Java/Go中会报错,因为两者都不支持运算符重载;
但是,Python/C#是受支持的。相比之下,我觉得C#的实现更符合GScript语法,所以我参考C#实现了以下语法规则。
人员操作员(人员p1,人员p2){
人pp=人(P1 . age p2 . age);
返回PP;
}
人p3=p1 p2
println( P3 . age= P3 . age);
assertEqual(p3 .年龄,30);有几个硬性条件:
operator目前支持的运算符有:-*/==!===
之前在实现Python操作符重载的时候,我考虑过是怎么实现的。但我没有深究。这次是自己实现相关功能,需要深入了解。
重点是两个步骤:
编译时:记录所有重载函数和运算符之间的关系。运行:根据当前操作找到声明的函数,直接运行。第一步,扫描所有重载函数,存储重载函数和运算符,注意函数的返回值和运算符类型。
//oporload重载
o过载结构类型{
函数*Func
tokenType int
}
//运算符重载自定义函数
Opoverloads [] *符号。Opoverload与一个片一起存储在编译器中。
在运行时,当两个参数属于同一类型时,需要找到重载的函数。
//GetOpFunction获取运算符重载函数
//通过返回值和操作符号(-*/)匹配重载函数
func(a * AnnotatedTree)getop function(returnType符号。Type,token type int)*符号。功能
对于_,过载:=range a.opOverloads {
isType :=重载。GetFunc()。GetReturnType()。IsType(returnType)
如果是类型重载。GetTokenType()==tokenType {
返回过载。GetFunc()
}
}
返回零
}查找方法是匹配编译时存储的数据,自动调用重载函数实现重载。
重载汇总运算符不是一个常见的函数;因为它会改变运算符的语义,比如在重载函数中加但写减。
这将使代码难以阅读,但在某些情况下,我们真的希望语言本身能够支持运算符重载。
比如第三方精度库,decimal。围棋常用的小数,只能用d1这样的函数。执行操作时添加(d2)。当操作复杂时:
a5=(a1。添加(a2)。添加(a3))。mul(a4);a5=(a1 a2 a3)* a4;版权归作者所有:原创作品来自博主小二上九8,转载请联系作者取得转载授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。