TGDZcalc by Ada (43th)
今日再研究了一下Ada,这个语言有不少Pascal的特点,让我见面就有不少好感.但安装过程中走了点误区,装了最新的gnat pro,但它没有带Ada编译器.后来还是用2021年的版本(500M)安装,效果还是理想的.
这个IDE有比较好的功能提示,也有一些调试功能(不过没学会).
它比较强调软件工程,因此即使是简单的代码,也要有一个包文件(ads),一个源码文件(adb)
写出来的代码是这样的.
点击查看代码
--File0: 项目文件,注意下面引用了具体的实现包.
with Ada.Text_IO; with Ada.Integer_Text_IO;
with TGDZpackage; use TGDZpackage;
procedure Main is
akey:Character;
begin
Test(1900);
Test(1924);
Test(1976);
Test(-361);
Ada.Text_IO.Get_Immediate(aKey); --pause
null;
end Main;
---------------------------------------------
--File1:TGDZpackage.ads
--有点像C++的头文件,定义基本的结构
package TGDZpackage is
function CalcBaseYear(year:integer) return Integer;
function YearToTGDZ(year:integer) return Wide_String;
function TGDZtoYear(tgdz:Wide_String; baseYear:Integer) return Integer;
procedure Test(y:integer);
end TGDZpackage;
------------------------------------------------
--File2: TGDZPackage.adb,主要过程定义在此中
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;
with Ada.Strings.Wide_Fixed;
with Ada.Text_IO;
package body TGDZpackage is
function CalcBaseYear(year:integer) return Integer is
b:integer;
begin
if year>0 then
b:=4;
else
b:= -57;
end if;
while b>year loop
b:=b-60;
end loop;
while b+60<=year loop
b:=b+60;
end loop;
return b;
end CalcBaseYear;
function YearToTGDZ(year:integer) return Wide_String is
strTG:constant Wide_String(1..30):="甲乙丙丁戊已庚辛壬癸"; --注意这个长度设置.
strDZ:constant Wide_String(1..36) :="子丑寅卯辰巳午未申酉戌亥";
tmpY:Integer; ti,di:integer;
t:Wide_String(1..3):=" ";
d:Wide_String(1..3):=" ";
Restgdz:wide_string(1..6);
begin
if year=0 then
return "";
end if;
tmpY:=year;
if tmpY>0 then
tmpY:=tmpY-4;
else
tmpY:=tmpY-3;
end if;
while tmpY<0 loop
tmpY:=tmpY+60;
end loop;
ti:=tmpY mod 10;
di:=tmpY mod 12;
ti:=ti*3+1; di:=di*3+1; --配合宽字符的特点调整,上面已经限定了序数从1开始.
t:=strTG(ti..ti+2);
d:=strDZ(di..di+2);
Restgdz:=t & d;
-- Restgdz:="甲子";
return Restgdz ;
end YearToTGDZ;
function TGDZtoYear(tgdz:Wide_String; baseYear:Integer) return Integer is
strLen:Natural :=tgdz'Length;
strTG:constant Wide_String:="甲乙丙丁戊已庚辛壬癸";
strDZ:constant Wide_String:="子丑寅卯辰巳午未申酉戌亥";
charTG:Wide_String(1..3);
charDZ:Wide_String(1..3);
ti:Natural; di:Natural;
m:Integer; Result:Integer;
firstIndexOfTGDZ:Integer:=tgdz'First;
lastIndexofTGDZ:Integer:=tgdz'Last;
begin
if (strLen/=6) then --在Ada中,汉字是每个字符三个字节
return 0;
end if;
charTG:=tgdz(firstIndexOfTGDZ..firstIndexOfTGDZ+2); --第一个索引用First,实际是第一个字节而非第一个 字符(=3字节 inUTF8)
charDZ:=tgdz(lastIndexofTGDZ-2..lastIndexofTGDZ); --由于Ada中第一个字节的系数可自定义,此处用变量较为安全.
ti:=Ada.Strings.Wide_Fixed.Index(strTG,charTG);
di:=Ada.Strings.Wide_Fixed.Index(strDZ,charDZ);
ti:=(ti-1)/3; --wide_string的搜索,其结果要减1除3,才是汉字序的顺序.
di:=(di-1)/3;
if ti >= di then
m:=ti-di;
else
m:=12+ti-di;
end if;
Result:= baseYear + m*5 + ti;
return Result;
end TGDZtoYear;
procedure Test(y:integer) is
by:Integer;
tgdz:Wide_string(1..6);
recalY:Integer;
begin
Ada.Text_IO.Put("Year: "); Put(y);
by:=CalcBaseYear(y);
Ada.Text_IO.Put("-> BaseYear ");Put(by);
Put(", TGDZ ");
tgdz:=YeartoTGDZ(y);
put(tgdz);
Ada.Text_IO.Put(", RecalBack to Year: ");
recalY:=TGDZtoYear(tgdz,by);
Put(recalY);
New_Line;
end Test;
end TGDZpackage;
代码在这个IDE显示的效果相当不错,值得截个图记录一下.



IDE gnat pro的控制台对中文支持不好,汉字显示出来变成了⬜⬜.
编译好的文件在cmd下运行,且运行之前把代码页修改为65001以应对UTF8格式的字串输出,效果就正常了.见下图


浙公网安备 33010602011771号