2016年9月12日 星期一

compiler [5] eval printf

以忍制己情,以恕制人情。

已經可以 eval 運算式了, 再來還得要有一個 output function, 在 c 上頭還有比 printf 更好的選擇嗎? 我決定要實作 printf。

ec.c
 1 
 2 int a;
 3 
 4 int f2(int i)
 5 {
 6   1+2;
 7   return 2+5+i;
 8 }
 9 
10 int main()
11 {
12   int x,y;
13   int a;
14   char *p;
15 
16   p="point strint";
17 
18   a=99;
19   printf("a: %d\n", a);
20 
21   y=2;
22   x = f2(y+1);
23 
24   printf("f2(): %d, %s, y=%d, p=%s\n", x, "test_string", y, p);
25 }

L24 可以正常 eval 的話, 就可以有輸出功能了, 這樣會讓這個 c interpreter 更好用, 可以把輸出結果印出來。

我一開始遇到的困難是不定個數參數怎麼傳給 printf?

ex.cpp
1 vector<string> args;
2 if (args.size() == 2)
3   printf(args[0].c_str(), args[1].c_str());
4 else if (args.size() == 3)
5        printf(args[0].c_str(), stoi(args[1]), args[2].c_str());

這樣我怎麼窮舉的完呢?

後來用了一個不太高明的方法解決了。呼叫 unix tool printf 來解決這問題。將 args 產生成 printf 的指令, 透過 system 執行。

p.cpp
 1 
 2 int main(int argc, char *argv[])
 3 {
 4   vector<string> args;
 5 
 6   string fmt = R"("test %d %s\n")";
 7   string p_str = tree_string(fmt);
 8 
 9   args.push_back(fmt);
10   args.push_back("123");
11   args.push_back("string_test");
12 
13   string cmd=R"(printf "My name is \"%s\".\nIt's a pleasure to meet you
14 %d.\n" "John" )";
15   string cmd_s{"printf "};
16   for (auto &i : args)
17   {
18     cmd_s += i;
19     cmd_s += " ";
20   }
21   cout << "cmd_s: " << cmd_s << endl;
22 
23   cmd+="25";
24   system(cmd.c_str());
25   system(cmd_s.c_str());
26   return 0;
27 }

可攜性如何呢? mac osX 沒問題, unix like 嘛! windows 呢? 別怕, printf 指令有 win32 版本, 所以還是有相當的可攜性。

這是很大的一個進步, 依靠語言本身自己印出結果, 不需要透過 interpreter 的程式印出運算結果。

再來是指標的問題, 我要怎麼印出指標呢? 在我實作出指標後 (雖然是 interpreter, 我還是想實作指標, 沒有指標, 就不能算是 c 了), 我想印出指標, printf 沒有支援 %p, 我耍了一點小心機, 將 %p 轉成 %x, 把指標的值順利印出。

雖然我在開始寫這個程式後, 陸續又買進不少編譯器的書, 但通過 lexer, parser, AST 的試鍊後, 幾乎都可以靠著自己的想法實作出目前的成果, 不在需要閱讀書籍中的知識。似乎只要建立起 AST 後, 再來的事情就沒有那麼難了。目前最新的成果 (20160909) 已經可以產生 gas 的組合語言, 雖然只有很小很小的一部份, 但已經沒有我開始寫的那種困難感了, 難度從一開始的 100 降低到 20 左右, 已經是可以靠著我自己的想法來實踐。自己土炮的作法也許和理論/專業的作法不同, 依然是玩具等級, 但最重要的是「這是我自己想出來的哦!」, 這比從書上獲得作法還更有意義。

interpreter 暫時告個段落, 我要向產生 machine code 邁進, 這是另外一個門檻, 我沒有做語意分析, 比起語意分析, 我更想先產生 machine code, 能把 c 程式碼轉成 machine code 的功能, 酷到讓我忍不住要先實作她。

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。