原件存檔 Original files吳哲宇 Che-Yu Wu

高一上(2010 年 9 月到 10 月)Grade 10, first term (September to October 2010)

Chinese Script:用中文句子寫程式,轉成 C++ 再編譯Chinese Script: write a program in Chinese sentences, convert it to C++ and compile it

專案叫 Chinese Script,視窗標題是 Majer Script。視窗上方有選單(檔案、教學、關於),右上有「編譯」和「美化」兩顆按鈕,下面是一個大文字框,在裡面用中文句子寫程式,每一句用全形逗號「,」結尾,最後一句用句號。按「編譯」,VB 把每一句換成 C++,存成 .cpp,叫隨附的 Dev-C++ 裡的 g++ 編譯成 .exe,再把 exe 執行起來。「關於」視窗寫著「此程式由 建國中學 吳哲宇 設計」。

最短的範例是 Hello MajerScript,5 句。

The project is called Chinese Script and the window title is Majer Script. The window has a menu (檔案 file, 教學 tutorial, 關於 about), two buttons at the upper right, 編譯 (compile) and 美化 (beautify), and a large text box below that takes the program, written in Chinese sentences that each end with a full-width comma ",", the last one with a full stop. The compile button makes VB replace every sentence with C++, save it as a .cpp, have the g++ in the bundled Dev-C++ compile it to an .exe, and run the exe. The About window reads "此程式由 建國中學 吳哲宇 設計" (this program was designed by Wu Che-Yu of Jianguo High School).

The shortest example is Hello MajerScript, 5 sentences.

程式開始,
設s是字串,
將s變"Hello MajerScript!!",
輸出s和換行,
暫停。
Hello MajerScript.mjs(2010-09-25)。Hello MajerScript.mjs (25 September 2010).

再一個例子是判斷正負數:讀入一個整數,說它是正數、0 還是負數。上面是他寫的中文,下面是轉譯器當時存下來的 C++。「當輸入 i」變成 while (cin>>i),每個「結束」變成一個右大括號,縮排由轉譯器用括號層數算出來。

Another example tells whether a number is positive, zero or negative. The Chinese above is what he wrote, and the C++ below is what the translator saved at the time. "當輸入 i" (while there is input i) becomes while (cin>>i), every "結束" (end) becomes a closing brace, and the indentation is worked out by the translator from the brace depth.

程式開始,
設i是整數,
當輸入i,
如果i>0,輸出i和"是個正數!!"和換行,結束,
如果i是0,輸出i和"是0!!"和換行,結束,
如果i<0,輸出i和"是個負數!!"和換行,結束,
就這樣,
程式結束。
判斷正負數.mjs(2010-09-26)。判斷正負數.mjs, the positive/zero/negative example (26 September 2010).
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include <iostream>
using namespace std;
int main(){
    int i;
    while (cin>>i) {
        if (i>0) {
            cout<<i<<"是個正數!!"<< endl;
        }
        if (i==0) {
            cout<<i<<"是0!!"<< endl;
        }
        if (i<0) {
            cout<<i<<"是個負數!!"<< endl;
        }
    }
}
同一支程式轉出的 C++(判斷正負數的 cpp 檔)。The 判斷正負數.cpp the translator produced from it.

轉譯器的做法很直接:把整段程式照「,」切成句子,每一句用 Contains 找關鍵字,找到就換成對應的 C++。認得的包括程式開始、設…是…(整數、長整數、超長整數、短整數、小數、字元、字串、布林)、如果、當輸入、輸入、輸出、將…變…、重複…次、結束、就這樣、到此、終止、暫停。「重複 n 次」會轉成 for 迴圈,計數變數自動取名 randomdecidenum0、randomdecidenum1……,所以巢狀的重複不會撞名。

The translator is direct: it cuts the program into sentences at each ",", looks for keywords in every sentence with Contains, and swaps each one for its C++. Among others it recognises 程式開始 (program start), 設…是… (let … be …, with integer, long integer, very long integer, short integer, decimal, character, string and boolean), 如果 (if), 當輸入 (while input), 輸入 (input), 輸出 (output), 將…變… (set … to …), 重複…次 (repeat … times), 結束 (end), 就這樣, 到此, 終止 (stop) and 暫停 (pause). "重複 n 次" becomes a for loop whose counter is named randomdecidenum0, randomdecidenum1 and so on, so nested repeats do not collide.

            If consen.Contains("程式開始") Then
                deone = "int main(){" & vbNewLine
                mainstart = True
                now &= "main"
            End If
            …
            If consen.Contains("設") Then
                dtext1 = Split(sen, "設")(1)
                dtext1 = Split(dtext1, "是")(0)
                dtext1 = dtext1.Replace("和", ",")
                dtext2 = Split(sen, "是")(1)
                Select Case dtext2
                    Case "整數"
                        deone += "int "
                    Case "長整數"
                        deone += "long int "
                    Case "超長整數"
                        deone += "long long int "
                    Case "短整數"
                        deone += "short "
                    Case "小數"
                        deone += "double "
                    Case "字元"
                        deone += "char "
                    Case "字串"
                        deone += "string "
                    Case "布林"
                        deone += "bool "
                End Select
                deone &= dtext1 & ";" & vbNewLine
            End If
            …
            If consen.Contains("如果") Then
                deone = "if (" & Split(sen, "果")(1).Replace("或", " or ").Replace("是", "==").Replace("和", " && ") & ") {" & vbNewLine
                ifbol = True
                now &= ",if"
                ifnum += 1
            End If
Majer Script.vb 轉譯的一部分:程式開始、設…是…、如果。Part of the translation in Majer Script.vb: program start, let … be …, if.

bin/Debug/save 資料夾裡有 24 個 .mjs 原始檔和 17 個轉出的 .cpp。其中 19 個 .mjs 的日期在 2010 年 9 月 25 日到 10 月 30 日,另外 5 個日期是 2013 年和 2016 年。檔名有 a001 到 a006、d063、b077 這樣的編號,也有平均成績、畢氏定理、1乘到n 這樣的中文名字。

The bin/Debug/save folder holds 24 .mjs sources and 17 converted .cpp files. 19 of the .mjs files are dated 25 September to 30 October 2010 and the other 5 carry dates in 2013 and 2016. The names include codes such as a001 to a006, d063 and b077, and Chinese names such as 平均成績 (average score), 畢氏定理 (Pythagorean theorem) and 1乘到n (1 times up to n).

程式開始,
設a和b和c是整數,
將a變0,將b變0,將c變0,
輸出"請輸入人數:"和換行,
輸入a,
輸出"請輸入這"和a和"人的分數:"和換行,
重複a次,輸入b,將c變c+b,結束,
輸出"這"和a和"人的平均分數是:"和c/a和換行,
暫停。
平均成績.mjs(2010-09-25):用「重複 a 次」讀入 a 個分數再求平均。平均成績.mjs (25 September 2010): read a scores with "重複 a 次" (repeat a times) and average them.