2016年9月29日 星期四

拜訪 bjd/dd 實體店家 - 神樂坊、放課後 Tea Time

[神樂坊]

店地址:高雄市新興區林森一路178號B1 (美麗島站6號出口, 茶湯會後面)

fig 1 fig 2
搭乘高雄捷運到「美麗島站」從六號出口出來, 過個馬路, 大約 3 分鐘即可抵達。從茶湯會那條巷子走了進去, 左邊看到了一個門, 往下走進入這地下室之後, 勇敢的打開門, 就會看到這間娃店以及友善的九夜 (老闆)。

這家是以 bjd 為主, 很多國家都有在製作 bjd, 中日韓, 中是指中國, 這家店以是中國的 bjd 買賣為主, 配件走的是比較平價的路線, bjd 本身當然不便宜, 展示的大多是 bjd。

而在店長親切的解說下, 我終於更加知道 bjd 的相關知識, 並為我展示了bjd 的可動性 (fig 1)。也介紹了不少相關的書籍給我, 最後我購買了兩本 dollsky - 玩偶天空, 每本 150nt, 中國簡體中文。店長還送了我 3 本娃展的型錄, 真是感謝, 我很喜歡蒐集這些東西。還有一張圓形板凳 (120nt)。

bjd 是以橡皮筋來固定整個身體, dd/smart doll 是以骨架來支撐整個身體, 而 bjd 表面較硬, 整體重量也比 dd 重上不少。

而 bjd 的大小實在太混亂了, 以3分來說, 頭圍, 腳長可能都有點不同, 沒有親自試過的配件, 有可能會不合自己的娃, 到實體店面試穿還是比較好。





20180923 到神樂坊酒吧團拍, 神樂坊在 201809 佈置了一個酒吧, 相當寫實, 是個非常好的拍娃景點, 和幾位娃友一起熱鬧喝個酒。



這次帶上在日本買的 dollce 娃頭, 是個蘿莉臉, 不太適合來酒吧這地方才是, 不過有反差才有趣, 下次再帶大姊姊去喝酒, 這次只能喝咖啡。




[放課後 Tea Time]
他們都在同一個地址 - 店地址:高雄市新興區林森一路178號B1 (美麗島站6號出口, 茶湯會後面, 與神樂坊同址)

地點不好找, 我從茶湯會那條巷子走了進去, 左邊看到了一個門, 該不是就是這裡往下走吧! 很懷疑的想著, 後來壯著膽子進入這地下室, 勇敢的打開門, 怎麼沒人, 問問看有沒有人在。第一次來的時候還以為誤闖民宅, 實在是太像一般住宅了。這邊也是走平價路線, 店員也是很親切, 也讓我看到了 DD2 的素體, 終於知道如何判斷 DD2 和 DD3 的差別, 看肩膀有露出關節球就是 DD2 了。

還有 mdd 和 ob50 素體的差異我也知道了, 之前看到牧瀨紅莉栖:


【商品名】ハイブリッドアクティブフィギュア Steins;Gate(シュタインズゲート) 牧瀬紅莉栖
【發賣元】ハイブリッドアクティブフィギュア
【スケール】 1/3(全高:約 50 cm)
【素 体】 オビツ 50 cm ボディ M バスト
【頭 部】 新規造形ソフビヘッド、ウィッグ
【衣 装】 私服衣装一式・ブーツ
【付属品】 白衣
【ヘッド原型製作】鬼山尚丈(ハイパースペース)
【價格】¥52,500(税込)
【 発売日】2012年9月末以降順次発送予定


覺得好看, 有心動, 後來知道她是 azone 娃, 雖然寫 1/3, 但其實只有 50 cm, 和主流的 1/3 娃稍微有點不同, 被歸類在 4 分娃。我儘量買比較流行的產品, 4 分娃的衣服、鞋子太難買, 不熟的娃友可能會買到不合適的配件, 所以我還是以主流 dd 3 分為主。

DD 2 白肌素體
最後帶了一件 HTT t-shirt 和幾件褲襪, 由於褲襪是打樣品, 一件只要 30nt。

黑色褲襪 t-shirt - 290 or 390 忘了, 圓形板凳 120nt

2016年9月27日 星期二

20160927 梅姬颱風

這些放半天的首長都該受到譴責, 上次只罵一個, 這次要罵五個。這樣的首長說會照顧人民、為市民著想, 是沒有人會相信的。

20160927 0810 騎著機車出門後, 大概騎了 15 分鐘後, 我就後悔了, 馬上回頭向公司請假, 其實我是有壓力的, 因為今天有個會要開, 大概只有我請假, 在公司打考績的時候我是不是有可能會放在最後呢?

這些長官是怎麼回事, 腦袋真的有在替人民思考嗎?

20160928 (這天勞工放假, 軍公教沒放假) 倒是很乾脆就宣佈放了, 一樣是這 5 個, 原來沒有資方壓力就可以這麼乾脆阿! 你有沒注意到六日的颱風假也是很乾脆就放了。

一個颱風讓這些首長漏出馬腳。

而其中某個醫生背景的還很嘴硬, 最後有沒道歉我也不清楚, 但那個人的回應方式讓我想到馬英九, 就稱他為台南馬英九吧!

這是第三次南九這麼做了:

1. 20150929 杜鵑
2. 20160914 莫蘭蒂
3. 20160927 梅姬

會有第四次嗎? 一定會的, 因為他沒有得到懲罰, 所以是不會改變的。one outs 裡頭有一句話, 污染水源的人應該就要去喝那裡的水; 污染土地的人應該要住在那裡。沒有得到處罰, 是不會改變現狀的。

放半天假挨轟 賴清德:亂放假會影響競爭力

不放假會死人的, 你知道嗎? 還是醫生勒? 該有的醫德去哪了? 哪間公司競爭力這麼差? 放個假就不行了, 我就不信政府放個一天假, 整個台灣就倒了。

國民黨可能也高興不起來, 因為對這些人的討厭, 也沒有轉成對你們的支持度。

希望能有機會讓第三勢力壯大。

行政院人事行政總處 全球資訊網
105年9月27日 天然災害停止上班及上課情形
更新時間: 2016/09/27 08:42:07
資料來源:各縣市政府民眾洽詢天然災害停止上班及上課各地方政府連絡一覽表
區域
縣市名稱
是否停止上班上課情形
北部地區
基隆市今天停止上班、停止上課。
臺北市今天停止上班、停止上課。
新北市今天停止上班、停止上課。
桃園市今天停止上班、停止上課。
新竹市今天停止上班、停止上課。
新竹縣今天停止上班、停止上課。
中部地區
苗栗縣今天停止上班、停止上課。
臺中市今天停止上班、停止上課。
彰化縣今天停止上班、停止上課。
雲林縣今天下午停止上班、停止上課。
南投縣今天停止上班、停止上課。
南部地區
嘉義市今天下午停止上班、停止上課。
嘉義縣今天下午停止上班、停止上課。 
阿里山鄉: 今天停止上班、停止上課。
臺南市今天下午停止上班、停止上課。
高雄市今天下午停止上班、停止上課。 
那瑪夏國中、桃源區樟山國小、桃源區寶山國小、桃源國中: 今天停止上班、停止上課。
屏東縣今天停止上班、停止上課。
東部地區
宜蘭縣今天停止上班、停止上課。
花蓮縣今天停止上班、停止上課。
臺東縣今天停止上班、停止上課。
外島地區澎湖縣今天停止上班、停止上課。
連江縣今天上午照常上班、照常上課。
金門縣今天照常上班、照常上課。
備註:
  1. 若欲進入本總處網站首頁版面,請按 人事行政總處全球資訊網、 事求人機關徵才系統 。
  2. 語音查詢電話: 020300166 
  3. 適用範圍為各級政府機關及公、私立學校;至交通運輸、警察、消防、海岸巡防、醫療、關務等業務性質特殊機關(構),為全年無休服務民眾,且應實施輪班、輪休制度,如遇天然災害發生時,其尚無停止上班之適用。
  4. 民間事業單位及勞工應依勞動部『天然災害發生事業單位勞工出勤管理及工資給付要點』處理, 如有疑義,請按 「勞動部網頁」 查詢,或電洽該部免付費電話專線:0800-085-151。

2016年9月25日 星期日

gitbook 指令安裝

為了看這《C语言编程透视》, 我想辦法把 gitbook 指令安裝起來。最好都用 root 安裝, 避免遇到權限問題。



ref:
https://github.com/GitbookIO/gitbook-cli
https://huhu8.gitbooks.io/learnpython0/content/source/part2/installdisqus.html

安裝 npm
apt-get install npm
npm install -g gitbook-cli

如果以下這問題, 到 /usr/bin/ 做個 link
run npm command gives error "/usr/bin/env: node: No such file or directory

ln -s /usr/bin/nodejs /usr/bin/node
lrwxrwxrwx 1 root root        6 Sep 12 15:44 node -> nodejs
-rwxr-xr-x 1 root root 11187096 May 21 07:40 nodejs

cd ~/open-c-book
gitbook pdf # 產生 pdf 版本
gitbook epub # 產生 epub 版本 

能產生 epub 版本才是 gitbook 最大的功能, 這樣才可以在 e-ink 電子閱讀器上觀看。

2016年9月20日 星期二

20160820 ~ 0821 coscup

對於南部的參加者要怎麼到台北是個問題, 我最後選擇搭早上的高鐵, 20160820 凌晨 1:00 ~ 6:00 的客運都客滿了。6:00 出門還真有點早, 騎著廢鐵往車站前進。

沒多久抵達台北後, 下了車, 哇! 真多人, 完全不習慣遇到這麼多人, 搭了捷運趕緊往南港展覽館去, 人數少多了。遇到認識的朋友, 一起搭計程車到中研院人文館, 花了 20nt, 少走一大段路, 拍謝, 佔了朋友一點小便宜。

這次報到用 app, 還真的有尊覺不凡的感覺, 好像再用麥當勞的優惠 app, 按下按鈕後就完成報到手續, 領文件、便當都是靠這個 app。

第一場是 LLVM 議程, 很棒, 雖然是入門的介紹, 但這時的我需要的就是這樣的介紹, 太深入反而可能聽不懂, 剛好最近在寫 compiler, 有了一點體會。llvm 原來可以拿來這麼用阿! fig 1 的書來的正是時候。

這陣子買了不少編譯器的書, 這幾本書都是實作型的, 有具體程式碼, 理論方面比較弱, 這真是一個弔詭的地方, 沒有深入理論, 還是可以寫出編譯器的, 而讀《松崗 - 編譯器compiler 編譯程式原理技巧與工具》, 理論到位, 但我很確定是寫不出編譯器的, 那是有實作經驗後再去讀才會有感覺的書。

另外一場在 stm32f4discovery 開發版上的 http server 議程也很有趣, 和我用同樣的開發版自然吸引我的注意, 講者提到了 nsapi, 這是好久不見的技術, 這是 netscape 的 web 技術, ms 提供的則是 isapi, 是 ms 在 asp 之前的技術, 這兩個技術應該沒什麼人再用了, ebay 之前用的就是 nsapi 的技術。

簡報: Micro HTTP Server Implemented in C

在 BOF 上, 我遇到了講者, 他很親切的回答我在 stm32f4discovery 開發版的疑惑, 真是感謝。

也遇到了之前送蛋糕給那些努力做專題的同學, 原來還記得送蛋糕的是我, 應該不是難吃到印象深刻吧。

BOF 結束後, 到後山裨站下車, 走了不少路, 終於在松山火車站附近找到住宿點, 1100nt, 還可接受。
fig 1
fig 2

fig 3

fig 4

fig 5
fig 6
早上到松山搭火車到南港火車站, 沒昨天的運氣, 得需要搭公車, 台北的公車系統真是方便, 為什麼其他地方做不到這麼方便呢? 不過只到大門口, 這次得用走的去人文館了。

第二天我參加工作坊的議程 - COSCUP 2016 Workshop: 靠北IoT OS, 我是第三位講者, 有 40 分鐘, 本來怕時間太長, 不確定能不能講那麼久。一進入會議室剛好遇到 Ben 在簡介 iot, 隨後便是接續的三個議程, 三個主題分別是:
  1. RTOS on ARM cortex-M platform -draft
  2. Get started with hyperC OS
    Get started
  3. 為樹莓派寫個 lisp bootloader (用 c++)
1 議程的 Neo, 不是駭客任務那個 Neo, 介紹了 realtek 開發版, 並詳細說明了 st-link 這端的作業方式, 原來還有個 cortex-m0 在操作這個除錯功能, 之前只會用, 不知道裡頭還有這麼多學問。

2 的議程介紹 hyperCOS, hyperCOS 實作了 tickless, Buddy system 記憶體管理, Trust zone hypervisor 實作, Loadable kernel module, 這幾個特性都是我有興趣的, 現在我只要看看 hyperCOS 怎麼做的就好, 不用去看 linux 那大怪物的實作, 輕鬆多了。

HyperCOS 開始, 這是評估的版本, 完整版本要另外申請。

再來我上場了, 介紹了 scheme 和樹莓派上的 bare-metal 開發方式, 超過 40 分鐘一點點, 安全下莊。

下午的議程遇到 irc 上的朋友, 在 irc 上互動很好, 聊的很開心, 現在終於見到本人, 都是很厲害的高手, 帥叔叔和集貨達人。

這次的活動遇到一些熟人, 有的已經從學校畢業, 到新竹、台北工作了, 每個人都在不錯的公司上班, 讓我很羨慕, 學歷的差距會影響自己可以去上班的公司, 得用好幾倍的實力才能彌補, 我也曾經有過仁寶面試的機會, 人資聲音很好聽, 可惜我那時不懂事, 因為剛找到新工作, 竟然推掉了, 應該還是要去參加面試的, 畢竟以我的狀況來說, 很難得有大公司面試的機會。

最後聽翟博士的議程, 翟博士的聲音很溫暖, 是那種可以讓人心平氣和的聲音, 我也想要能有那樣的聲音, 不過後來想了想, 一位朋友說, 自己有自己的特色就好了, 沒有必要成為別人, 這句話喚回我的信心, 是的, 我有自己的特色, 別人的優點去欣賞就好, 不一樣要成為那樣。

閃電秀用 git 畫捷運圖很有趣, 真的有人這麼無聊阿 XD, 還不只一個人這麼做過, 真是有創意。

後來我急著去可汀敗家, 那又是另外的事了。敗家的東西收錄於「[敗家] dd 娃娃配件 (3) - 單車與女孩

結束可汀一行, 和老同學到了西門町吃牛肉麵, 感謝招待, 每年都來打擾他, 感激不盡。

2016年9月17日 星期六

[敗家] dd 娃娃配件 (3) - 單車與女孩

fig 1
fig 2
fig 3
fig 4, 20160918 高雄神樂坊入手的圓形板凳, 120 nt
fig 1 的衣服 20160821 購於可汀, 2400nt, 店長說這是棉花糖女孩系, 不過我後來查了一下, 應該是森林系的服飾風格。

ref:
森林系女孩【森ガール】森女,完全攻略

第一次在可汀看到這種風格的服飾時, 就有一種療癒、簡約自然、讓人覺得很安心、寧靜的感覺, 不過那套要價 4200nt, 我沒出手, 這次再去已經售出, 娃友的消費能力實在太強大, 而我也在玩娃這期間知道, 看到喜歡的衣服就趕緊出手, 一旦售完, 是不一定會在製作的。如果像我這樣覺得太貴沒出手, 就只好抱著遺憾了。這種風格還有一個好處, 很容易就換上了, 沒有其他衣服的煩雜, 好看又容易上手。

這次看到這套, 價格是一樣是之前那件的數字, 只不過前後順序掉換了一下, 雖然還是很貴, 但勉強可以出手。可汀店長還是一樣親切, 應我要求先把這套衣服放在人體模型上讓我看看, 看過之後還算滿意, 就這套了, 聽說來可汀的沒有不躺著出去的, 我是說「錢包」。

另外一個吸引我目光的是 fig 2 的登山背包, 1280 nt, 我喜歡的東西怎麼都這麼貴, 喜歡上了沒辦法, 掏錢吧! 在這期間購買, 可汀還送現在最潮的神奇寶貝球, 讓你的娃也可以跟上潮流, 去抓怪。

這個登山背包製作的十分精細, 該有的背帶都很真人使用的版本一致, 扣環也真的可以拉開、扣上, 只是太小了不太好按。

fig 1 的頭髮我很喜歡, 68 rmb, 初音未來的雙馬尾實在是太長了, 雖然很有特色, 但整理起來實在累人, 這個直髮長度剛好, 整隻娃拿起來非常有操控性 (又不是耍布袋戲), 不用再被那長髮搞得有點卡卡。

fig 2 的牛仔吊帶裙 78 rmb, 一開始沒有搭配的衣服, 感覺很可惜, 牛仔吊帶裙很好看, 但總不能沒穿上衣吧? 購入 fig 2 的 t-shirt (48 rmb) 後, 整體造型相當不錯, 很生活化, 也需要搭配的鞋子, 有跟的鞋不太合適, 購入了 fig 2 的帆布鞋 (40 rmb), 本來想再找個運動鞋, 不過不是很好找, 只找到一款, 不急著購買, 帆布鞋穿上後果然很合適, 我還蠻會搭衣服的嘛!

fig 2 的褲襪也相當酷, 個人也很喜歡, 32 rmb, 和上述的配件合體之後, 真的不錯看, 不過我比較想要的是咖啡色, 可惜沒這顏色可以挑, 這個顏色也不錯。

fig 3 的單車是個好道具, 從掏寶購入, 讓娃娃不在那麼單調, 多了交通工具, 整體感加分不少。

不過不便宜, 100 + 535 + 45 = 680 rmb, 100 是定金, 45 是包裝和運費。我知道還有些包包、mac book 的配件, 都可讓娃娃看起來更添豐富性。fig 4 是在高雄神樂坊入手的圓形板凳, 120 nt, dd 3 分坐起來剛剛好, 總算有椅子坐了, 雖然不是華麗的沙發之類的精巧的椅子, 但我實在喜愛這個原型木頭板凳, 作工不算好, 有些粗糙, 邊緣我想再用砂紙磨一下, 但我很喜歡。

2016-05-20 訂購, 2016-07-18 賣家通知製作完畢, 補上餘款, 2016-07-20 到集貨商。2016-08-21 才到我手上。整整歷經了三個月。單車模型零件是分開, 收到後要自己組裝, 照片看起來好看, 不過實際上散散的, 我沒用特別的方式將這些零件固定, 鏈條部份比較讓我失望, 沒真能和大盤齒和飛輪掛上同步轉動, 甚是可惜。

我個人很喜歡單車, 不管是模型還是照片, 只要有單車就能吸引我的目光, 其實我比較想買淑女車造型的模型, 女孩和淑女車比較搭, 但找不到, 登山車雖然和女孩不太適合, 但效果也還不錯。

fig 5 是後來又購買的另外一台單車, 老實說, 作工非常的差, 我收到的時候龍頭斷了, 賣家不管, 然後腳架也沒有做好, 和平地有一個高度的落差, 所以無法單車站立, 我得墊一片 CD 空盒才能站立, 賣家也不管, 叫我自己凹, 喵的勒!

fig 5 的自行車服則是之後購入, 剛好用來搭配單車, 配上鴨舌帽, 還真的蠻合適。

fig 5 20170829 拍下, 199+18 = 217 rmb, SD13/3分用 娃用自行车, 自行車服 236.06 rmb, 20171111 拍下。

2016年9月14日 星期三

20160914 莫蘭蒂侵台台風

20160914 莫蘭蒂侵台風
賴醫生應該是以救人救命為處世方針, 但在 20160914 莫蘭蒂侵台風卻做了一個令人難以想像的決策 - 早上上班, 下午放假。

單純只看氣象數據來決定, 而沒有去思考背後帶來的一切不便, 學校的營運、學生的回家通勤問題, 台鐵還要特地配合台南的這決定, 整個中午下班的塞車與不便, 在風雨中塞車的感覺我想沒人願意, 但就是因為這決定, 讓台南市民浸淫在一個非常危險、不變得處境。

而只要不上那半天班就可以避免這樣的事情, 之前台中已經有因為上半天班而一家3口死亡的例子, 難道當了市長就忘記醫生的德行了嗎?

又, 為什麼一定要上半天班呢? 真的是這個理由嗎?

為了 ?? 你可以不進議會, 有人為你鼓掌, 為了人民, 你不能說放個假嗎? 原來你也是這種等級而已。被罵也是剛好, 希望不要在理由伯, 把這次人們的聲音聽進去, 還是有機會更上層樓。現在已經從賴神變成賴半天了。

我們人民想得到的原因你想不到嗎?

我是不是看起來像笨蛋, 要不然你怎麼會說出這樣的回應?

颱風來襲,台南市做出上午上班上課、下午停班停課的決定,引發不少民眾抱怨,對此台南市長賴清德今(14)日到海邊視察防颱整備時指出,目前看來決策無誤,但颱風假決策很難贏得全體市民支持,只能根據客觀數據並依法行政,希望市民能諒解。
氣象局預報,南部濱海地區風勢最強,且適逢滿潮,可能會造成淹水,高雄港更出現貨櫃被強風掀翻的畫面。而目前除國軍已動員協助堆沙包等防治工作,賴清德上午也前往濱海地區了解防颱準備情形。

對於南市府昨晚10點才宣布「上午上班上課、下午停班停課」,賴清德解釋,因為昨晚7時預報未達停班停課標準,只能等到晚間10點預報才能決策;而預報也指出,台南雨量全天未達標準,風力則待下午才符合放假標準,經討論後作出上半天班的決定,「造成一些家長不便,但希望大家能理解」。

賴清德也說,中央氣象局預報將軍區有有嚴重暴漲及強烈風勢,但上午風雨都不嚴重,證明昨晚決策應該沒有偏差,賴清德也強調,法律並沒有給他說放假就放假的權力,只能依照中央氣象局數據與法律做決策。

你沒說出口的原因大家心知肚明, 準備後承受這後果吧, 人民給的壓力似乎輸給另外一方了呢?

之前台風已經一次了, 這次又這樣, 我實在無法相信這是會把人民身家安全放在第一位的首長作法。

實在氣不過, 要不然我才不那麼閒, 好好假期不過, 打這篇文章。

人心就是這樣一點一點失去的, 莫忘國民黨怎麼失去政權的, 怎麼打敗仗逃到台灣的。我講這個不是恐嚇, 因為這些政治人物聽不下去人們的聲音, 只怕掉了選票, 人民也只有選票這個武器而已, 只有選票可以教訓這些人。

我本來可以請假, 但為什麼要我花自己的假來彌補這個爛決策呢?

忍無可忍, 無需再忍。

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 的功能, 酷到讓我忍不住要先實作她。

2016年9月4日 星期日

compiler [4] 環境與變數 => 環境變數

日拱一卒,功不唐捐
20161219 重要: 本篇文章有個錯誤, 感謝 fb Jensen Holder 指出, 我放在最後補充。

變數就是字面上的意思, 寫程式的都知道, 但知道 interpreter 怎麼把這功能做出來的程式員可能就不多了。

list 1
 1 x=1;
 2 x+5;

list 1 L2 怎麼把 x, 1 做個對應的呢? 就是靠《環境》, 他不是什麼神祕的東西, 用 c++ 來說明什麼是環境的話就是:

std::map<std::string, ASTNode *> env;

然後把 env["x"]=1 就完成 x=1 這個運算式。

不管你用什麼資料結構, 反正就是把 x 和 1 的關係存起來就對了。感覺很簡單, 但真實世界上可沒這麼簡單, 不過教學就是要化繁為簡, 先知道這樣就夠了。

再來的 list 1 L2 在 x+5 要做 eval 時, eval 5 就回傳 5 ASTNode 本身, x 就到 env 去把他對應的數字找出來, 也就是 1, 所以傳回 1 的 ASTNode, 然後 + 就可以把 1, 5 作相加的運算, 6 就這麼算出來了。

那《環境》困難在哪裡呢? 在 function call。

p1
 1 int x;
 2 int f1()
 3 {
 4   2*3;
 5   12+13;
 6 }
 7
 8 int f2(int i)
 9 {
 9.5 int cc;
10   5*i;
11 }
12 int main()
13 {
14   int z;
15   61+2;
16   z=5;
17   f1();
18   f2(z);
19 }

如果像 p1 這樣, 掃描到 L1 時, 把 x 加入 global_env (table 1), 在 call main 時, 要產生 main_env (table 2), main_env 的上層 up_env 要指到 global_env, 當掃描到 L 14 時, 把 x:0 加入到 main_env, 而掃描到 L 16 時, 把 5 的值至換到 z (table 3), 在 call f2(z) 時 (L 18), 又要產生 f2_env (table 4), 再把 up_env 指到 main_env, 並把 z/i 的對應存到 f2_env, cc 的對應也要存到 f2_env, 疑, cc 沒對應的值阿, 隨便塞一個就好了, 這不就是 c 語言 auto 變數的行為嗎? 而上層 env 要指到 main_env, 這樣層層下去, 讓整個環境建立起所有的變數名稱/變數值的對應關係。大概像 env class 那樣。


table 1. global_env
up_env 0
x 0

table 2. main_env
up_env global_env
z 0

table 3 main_env
up_env global_env
z 5

table 4. f2_env
up_env main_env
i z
cc 0

所以在 f2() 裡頭用到 cc, i 時, 就去查 f2_env, 把對應的值找出來, 就可以知道這個變數的值, 而在這層找不到, 就要去 up_env 找, 都找不到就發出錯誤訊息。

env class
14 class Environment
15 {
16   public:
17     Environment(Environment *outer=0, const char *name=0): outer_(outer)
18     {
21     }
22     Environment *outer_;
31     int free_frame_index_;
32   private:
33     std::map<std::string, ASTNode *> frame_;
34 };

觀念很簡單, 但實作還是會困難一點, 可參考以下範例程式碼。以下程式碼只有實作最簡單的環境, 我還沒完成 function call 那複雜的環境。目前的版本我已經完成了 function call 和 return, 真是有種覺得自己很不簡單的感覺呢! 你一定也很想要有這種成就感吧! 加油。

source code:
https://github.com/descent/simple_compiler
commit: 0452c23b770dad99b1d503e0f417cae45879ce72

除了加入變數, 函式的定義也一樣要加入環境, 當呼叫一個函式時, 就到環境來找這個函式, 找到後把 parameter, argument 配對後, 就去執行該函式了。

至於函式的傳回值, 那又是另外一件事情了。

因為使用了「環境」來處理「變數」, 這便是「環境變數」名稱的由來。

打通整個 interpreter 流程並不容易, 當我滿懷好奇心將所有疑問抽絲剝繭, 最後接觸到本質的那一刻, 我知道這些努力與堅持是值得的, 縱使我無法因為這樣而在工作上有立即的幫助, 但滿足自己的好奇心就是驅使我這麼做的最大動力。

html table from:
http://htmleditor.i2yes.com/




fb Jensen Holder
所以是 interpreter 還是 compiler 啊?
interpreter 的話通常是用 denoted value, 不是 AST Node
compiler 的話這應該是靜態決定的不是動態的東西吧
而常說的 symbol table 是另外一個東西

你的 env 處理有點奇怪, 這個行為看起來比較像 call stack

f2 查看 cc, i 的行為應該是在 f2_env 裡面查詢, 查不到去 global 找, 而不是從 call stack 找上去

fb Jensen Holder
這有點難避開數學或程式用純文字解釋, 但是大概有兩個部分 (1) 程式提到的變數到底是哪一個變數 (2) 程式提到的變數在 runtime 中到底放在記憶體的哪裡. (1) 的話, 若我們是 lexical scoping, 哪些 variable references 是指同一個 variable 是看他們寫在哪就知道, 這個不用執行程式也可以事先算出來. (2) 就是我們平常看到的即使同一個函式被呼叫兩次, 不同次的呼叫對應的是不同實體, 所以變數的值不會互相干涉

https://gist.github.com/shhyou/1b7afff0b8b470d9a531f56480165a51#file-variable-md

以這個程式為例, L06 跟 L13 的 x 指的是 L01 的 x, L05 L06 的 i 是 L03 的 i, 而 L10 L11 的 x 是 L09 的 x; L14 是錯誤的, scope 當中沒有 argc. 這是 "(1)" 的 "哪個變數到底是指哪個變數?".

執行時, 實作可以是這樣: 每次呼叫 f, 我們都會配個嶄新的記憶體給 i 跟 cc 跟 cc 跟 x. 而後面 reference 到 i, cc, x 時, 依照上一段所述已知哪個 variable reference 指哪個變數, 再去操作該變數對應的記憶體.

https://gist.github.com/shhyou/1b7afff0b8b470d9a531f56480165a51#file-intc-cpp

這是一個範例的轉換程式, 把 prog 轉成 prog2. prog2 當中, 變數都是 local_id 或 global_id, 執行時, 每次呼叫函數就直接建立新的 stack frame 就好, local 就存取該 stack frame, global 就存取 heap

事先計算哪個變數是哪個變數只是一種寫法, 直接邊跑邊更新 environment 也是可以, 不過比較複雜. 至於函數式語言直譯器範例的那種 environment 一個 linked-list 往上搜尋其實是另外一回事. 那是實作 lexical scoping 語意的一個方便寫法. 如果仔細觀察, 可以發現那種寫法在函數呼叫時, 實際上是 extend 函數建立時就保存起來的 environment (也就是 closure). 乍看之下雖然是一個鏈, 但實際上是一棵樹. 此外, 這種 environment 是不支援 mutation 的. 如果要 mutation 就是要有另外一個 global store, environment 中紀錄 address, 再到 store[address] 中去存取或修改值.