├── source ├── people.md ├── video.md ├── article.md ├── discuss.md ├── message.md ├── preface.md ├── pdffooter.htm ├── md0.js ├── Makefile ├── convert.exe ├── mimetex.exe ├── tex2img.bat ├── metadata.xml ├── header.htm ├── footer.htm ├── license.md ├── reflink.md9 ├── editor.md ├── netconstitution.md ├── message3.md ├── video1.md ├── message1.md ├── home.md ├── message2.md ├── netsong.md ├── info.md ├── people1.md ├── discuss1.md ├── netcountry.md ├── discuss1long.md ├── article1.md ├── people1long.md ├── message1long.md └── article2.md ├── code.zip ├── book ├── A4.pdf ├── A4.epub ├── ipad.epub └── ipad.pdf ├── img ├── mux.png ├── adder4.png ├── cover.jpg ├── follow.png ├── 01_hello.png ├── coverA4.png ├── ex-app1.png ├── ex-app2.png ├── ex-app3.png ├── ex-app4.png ├── ex-app5.png ├── ex-app6.png ├── input_01.png ├── input_02.png ├── input_03.png ├── mux4to1.png ├── SilverCross.jpg ├── addsub4-mux.png ├── addsub4-xor.png ├── output_01.png ├── output_02.png ├── output_03.png ├── output_04.png ├── Constitution.jpg ├── textToSpeech1.png ├── textToSpeech2.png ├── textToSpeech3.png ├── clkao_code_sick.jpg ├── Arduino_LCD_board1.png ├── Arduino_LCD_circuit1.png ├── Arduino_LCD_device1.png └── Arduino_LCD_device2.png ├── code ├── oc │ ├── ccc.js │ ├── code.js │ ├── cpu0i.v │ ├── cpu0m.v │ ├── cpu0mb.v │ ├── cpu0p.v │ ├── mcu0i.v │ ├── os0t.as0 │ ├── sum.ob0 │ ├── sum.ob1 │ ├── sum.obj0 │ ├── test.obj │ ├── cpu0mb0.1.v │ ├── cpu0mb0.2.v │ ├── cpu0mb0.3.v │ ├── cpu0mb0.4.v │ ├── cpu0mb0.5.v │ ├── cpu0mb0.6.v │ ├── cpu0mb0.7.v │ ├── cpu0mb0.9.v │ ├── cpu0mb1.0.v │ ├── inherit2.js │ ├── memory.js │ ├── memory32.v │ ├── memory8.v │ ├── os0ts.as0 │ ├── regbank.v │ ├── test.c0 │ ├── test.j1 │ ├── cpu0m_block.v │ ├── cpu0mb0.81.v │ ├── cpu0mb0.82.v │ ├── cpu0mb0.95.v │ ├── cpu0mb_bug1.v │ ├── test2.j1 │ ├── cpu0pidecode.v │ ├── pctick_block.v │ ├── while.j │ ├── while.j0 │ ├── cpu0pidecode0.1.v │ ├── cpu0pidecode0.2.v │ ├── mcu0i.hex │ ├── mcu0i1.hex │ ├── sum.as1 │ ├── mult4.v │ ├── scan.js │ ├── shift_mult.v │ ├── test.j │ ├── test.j0 │ ├── cpu1.js │ ├── counter.v │ ├── xor3.v │ ├── latch.v │ ├── mux.v │ ├── fastadder.v │ ├── optable.js │ ├── counter_block.v │ ├── cpu0.js │ ├── inherit.js │ ├── pctick.v │ ├── sum.as0 │ ├── PipeReg.v │ ├── as1.js │ ├── cpu0i.hex │ ├── expc.js │ ├── ifetch.v │ ├── vm1.js │ ├── as.js │ ├── jc1.js │ ├── jexpc.js │ ├── cc1.js │ ├── jc1parser.js │ ├── jparser.js │ ├── as0.js │ ├── as1_bak.js │ └── vm0.js ├── textToSpeech2.html ├── textToSpeech1.html ├── mux.v ├── textToSpeech3.html ├── adder4.v └── addsub4.v ├── submit ├── R-shiny.zip └── R-shiny │ ├── ex-app1.png │ ├── ex-app2.png │ ├── ex-app3.png │ ├── ex-app4.png │ ├── ex-app5.png │ ├── ex-app6.png │ ├── follow.png │ ├── 01_hello.png │ ├── input_01.png │ ├── input_02.png │ ├── input_03.png │ ├── output_01.png │ ├── output_02.png │ ├── output_03.png │ ├── output_04.png │ └── Makefile ├── htm ├── article.html ├── message.html ├── preface.html ├── people.html ├── video.html ├── discuss.html ├── editor.html ├── license.html ├── netconstitution.html ├── netsong.html ├── video1.html ├── message3.html ├── message2.html ├── message1.html ├── discuss1.html ├── people1.html ├── home.html ├── netcountry.html ├── info.html └── discuss1long.html └── css └── pmag.css /source/people.md: -------------------------------------------------------------------------------- 1 | # 程式人介紹 2 | -------------------------------------------------------------------------------- /source/video.md: -------------------------------------------------------------------------------- 1 | # 程式人頻道 2 | -------------------------------------------------------------------------------- /source/article.md: -------------------------------------------------------------------------------- 1 | 2 | # 程式人文集 3 | -------------------------------------------------------------------------------- /source/discuss.md: -------------------------------------------------------------------------------- 1 | # 程式人討論區 2 | 3 | -------------------------------------------------------------------------------- /source/message.md: -------------------------------------------------------------------------------- 1 | 2 | # 程式人短訊 3 | -------------------------------------------------------------------------------- /source/preface.md: -------------------------------------------------------------------------------- 1 | # 前言 2 | 3 | 4 | -------------------------------------------------------------------------------- /source/pdffooter.htm: -------------------------------------------------------------------------------- 1 |
_PAGENUM_
2 | -------------------------------------------------------------------------------- /code.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code.zip -------------------------------------------------------------------------------- /book/A4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/book/A4.pdf -------------------------------------------------------------------------------- /img/mux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/mux.png -------------------------------------------------------------------------------- /book/A4.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/book/A4.epub -------------------------------------------------------------------------------- /book/ipad.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/book/ipad.epub -------------------------------------------------------------------------------- /book/ipad.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/book/ipad.pdf -------------------------------------------------------------------------------- /code/oc/ccc.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/ccc.js -------------------------------------------------------------------------------- /img/adder4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/adder4.png -------------------------------------------------------------------------------- /img/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/cover.jpg -------------------------------------------------------------------------------- /img/follow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/follow.png -------------------------------------------------------------------------------- /source/md0.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/source/md0.js -------------------------------------------------------------------------------- /code/oc/code.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/code.js -------------------------------------------------------------------------------- /code/oc/cpu0i.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0i.v -------------------------------------------------------------------------------- /code/oc/cpu0m.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0m.v -------------------------------------------------------------------------------- /code/oc/cpu0mb.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb.v -------------------------------------------------------------------------------- /code/oc/cpu0p.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0p.v -------------------------------------------------------------------------------- /code/oc/mcu0i.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/mcu0i.v -------------------------------------------------------------------------------- /code/oc/os0t.as0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/os0t.as0 -------------------------------------------------------------------------------- /code/oc/sum.ob0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/sum.ob0 -------------------------------------------------------------------------------- /code/oc/sum.ob1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/sum.ob1 -------------------------------------------------------------------------------- /code/oc/sum.obj0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/sum.obj0 -------------------------------------------------------------------------------- /code/oc/test.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/test.obj -------------------------------------------------------------------------------- /img/01_hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/01_hello.png -------------------------------------------------------------------------------- /img/coverA4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/coverA4.png -------------------------------------------------------------------------------- /img/ex-app1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/ex-app1.png -------------------------------------------------------------------------------- /img/ex-app2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/ex-app2.png -------------------------------------------------------------------------------- /img/ex-app3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/ex-app3.png -------------------------------------------------------------------------------- /img/ex-app4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/ex-app4.png -------------------------------------------------------------------------------- /img/ex-app5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/ex-app5.png -------------------------------------------------------------------------------- /img/ex-app6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/ex-app6.png -------------------------------------------------------------------------------- /img/input_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/input_01.png -------------------------------------------------------------------------------- /img/input_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/input_02.png -------------------------------------------------------------------------------- /img/input_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/input_03.png -------------------------------------------------------------------------------- /img/mux4to1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/mux4to1.png -------------------------------------------------------------------------------- /source/Makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/source/Makefile -------------------------------------------------------------------------------- /code/oc/cpu0mb0.1.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.1.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.2.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.2.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.3.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.3.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.4.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.4.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.5.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.5.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.6.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.6.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.7.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.7.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.9.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.9.v -------------------------------------------------------------------------------- /code/oc/cpu0mb1.0.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb1.0.v -------------------------------------------------------------------------------- /code/oc/inherit2.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/inherit2.js -------------------------------------------------------------------------------- /code/oc/memory.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/memory.js -------------------------------------------------------------------------------- /code/oc/memory32.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/memory32.v -------------------------------------------------------------------------------- /code/oc/memory8.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/memory8.v -------------------------------------------------------------------------------- /code/oc/os0ts.as0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/os0ts.as0 -------------------------------------------------------------------------------- /code/oc/regbank.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/regbank.v -------------------------------------------------------------------------------- /code/oc/test.c0: -------------------------------------------------------------------------------- 1 | sum = 0; 2 | for (i=0; i<=10; i++) 3 | { 4 | sum = sum + i; 5 | } 6 | return sum; 7 | -------------------------------------------------------------------------------- /code/oc/test.j1: -------------------------------------------------------------------------------- 1 | sum = 0; 2 | for (i=0; i<=10; i++) 3 | { 4 | sum = sum + i; 5 | } 6 | return sum; 7 | -------------------------------------------------------------------------------- /img/SilverCross.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/SilverCross.jpg -------------------------------------------------------------------------------- /img/addsub4-mux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/addsub4-mux.png -------------------------------------------------------------------------------- /img/addsub4-xor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/addsub4-xor.png -------------------------------------------------------------------------------- /img/output_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/output_01.png -------------------------------------------------------------------------------- /img/output_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/output_02.png -------------------------------------------------------------------------------- /img/output_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/output_03.png -------------------------------------------------------------------------------- /img/output_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/output_04.png -------------------------------------------------------------------------------- /source/convert.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/source/convert.exe -------------------------------------------------------------------------------- /source/mimetex.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/source/mimetex.exe -------------------------------------------------------------------------------- /submit/R-shiny.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny.zip -------------------------------------------------------------------------------- /code/oc/cpu0m_block.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0m_block.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.81.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.81.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.82.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.82.v -------------------------------------------------------------------------------- /code/oc/cpu0mb0.95.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb0.95.v -------------------------------------------------------------------------------- /code/oc/cpu0mb_bug1.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0mb_bug1.v -------------------------------------------------------------------------------- /code/oc/test2.j1: -------------------------------------------------------------------------------- 1 | sum = 0; 2 | for (i=0; i<=10; i++) 3 | { 4 | sum = sum + i; 5 | } 6 | return sum; 7 | -------------------------------------------------------------------------------- /img/Constitution.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/Constitution.jpg -------------------------------------------------------------------------------- /img/textToSpeech1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/textToSpeech1.png -------------------------------------------------------------------------------- /img/textToSpeech2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/textToSpeech2.png -------------------------------------------------------------------------------- /img/textToSpeech3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/textToSpeech3.png -------------------------------------------------------------------------------- /code/oc/cpu0pidecode.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0pidecode.v -------------------------------------------------------------------------------- /code/oc/pctick_block.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/pctick_block.v -------------------------------------------------------------------------------- /code/oc/while.j: -------------------------------------------------------------------------------- 1 | sum = 0; 2 | i=1; 3 | while (i<=10) { 4 | sum = sum + i; 5 | i++; 6 | } 7 | return sum; 8 | -------------------------------------------------------------------------------- /code/oc/while.j0: -------------------------------------------------------------------------------- 1 | sum = 0; 2 | i=1; 3 | while (i<=10) { 4 | sum = sum + i; 5 | i++; 6 | } 7 | return sum; 8 | -------------------------------------------------------------------------------- /img/clkao_code_sick.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/clkao_code_sick.jpg -------------------------------------------------------------------------------- /code/oc/cpu0pidecode0.1.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0pidecode0.1.v -------------------------------------------------------------------------------- /code/oc/cpu0pidecode0.2.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/code/oc/cpu0pidecode0.2.v -------------------------------------------------------------------------------- /img/Arduino_LCD_board1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/Arduino_LCD_board1.png -------------------------------------------------------------------------------- /submit/R-shiny/ex-app1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/ex-app1.png -------------------------------------------------------------------------------- /submit/R-shiny/ex-app2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/ex-app2.png -------------------------------------------------------------------------------- /submit/R-shiny/ex-app3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/ex-app3.png -------------------------------------------------------------------------------- /submit/R-shiny/ex-app4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/ex-app4.png -------------------------------------------------------------------------------- /submit/R-shiny/ex-app5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/ex-app5.png -------------------------------------------------------------------------------- /submit/R-shiny/ex-app6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/ex-app6.png -------------------------------------------------------------------------------- /submit/R-shiny/follow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/follow.png -------------------------------------------------------------------------------- /img/Arduino_LCD_circuit1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/Arduino_LCD_circuit1.png -------------------------------------------------------------------------------- /img/Arduino_LCD_device1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/Arduino_LCD_device1.png -------------------------------------------------------------------------------- /img/Arduino_LCD_device2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/img/Arduino_LCD_device2.png -------------------------------------------------------------------------------- /submit/R-shiny/01_hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/01_hello.png -------------------------------------------------------------------------------- /submit/R-shiny/input_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/input_01.png -------------------------------------------------------------------------------- /submit/R-shiny/input_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/input_02.png -------------------------------------------------------------------------------- /submit/R-shiny/input_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/input_03.png -------------------------------------------------------------------------------- /submit/R-shiny/output_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/output_01.png -------------------------------------------------------------------------------- /submit/R-shiny/output_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/output_02.png -------------------------------------------------------------------------------- /submit/R-shiny/output_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/output_03.png -------------------------------------------------------------------------------- /submit/R-shiny/output_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programmermagazine/201309/gh-pages/submit/R-shiny/output_04.png -------------------------------------------------------------------------------- /source/tex2img.bat: -------------------------------------------------------------------------------- 1 | if not exist {%2.jpg} ( 2 | mimetex -d %1 -e %2.gif 3 | convert %2.gif %2.jpg 4 | rm %2.gif 5 | ) 6 | -------------------------------------------------------------------------------- /source/metadata.xml: -------------------------------------------------------------------------------- 1 | Creative Commons Non-Commercial Share Alike 3.0 2 | en-US 3 | -------------------------------------------------------------------------------- /code/oc/mcu0i.hex: -------------------------------------------------------------------------------- 1 | 00 04 // 0 LD A 2 | 10 04 // 2 ST B 3 | E3 00 // 4 RET 4 | 00 03 // 6 A: 3 5 | 00 05 // 8 B: 5 6 | -------------------------------------------------------------------------------- /code/oc/mcu0i1.hex: -------------------------------------------------------------------------------- 1 | 00 08 // 0 LD A 2 | 10 08 // 4 ST B 3 | E3 00 // 8 RET 4 | 00 03 // c A: 3 5 | 00 05 // 10 B: 5 6 | -------------------------------------------------------------------------------- /source/header.htm: -------------------------------------------------------------------------------- 1 |
2 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

3 |
4 |
5 | -------------------------------------------------------------------------------- /source/footer.htm: -------------------------------------------------------------------------------- 1 |
2 | 5 | -------------------------------------------------------------------------------- /code/oc/sum.as1: -------------------------------------------------------------------------------- 1 | LD R1, sum 2 | LD R2, i 3 | ADDI R3, R0, 10 4 | ADDI R4, R0, 10 5 | FOR: ADDI R5, R2,-11 6 | JZ R5, EXIT 7 | ADD R1, i 8 | ADDI R2, R2, 1 9 | ST R2, i 10 | JZ R0, FOR 11 | EXIT: RET 12 | x: BYTE 3,18,2 13 | i: WORD 1 14 | sum: WORD 0 15 | back: WORD 0 -------------------------------------------------------------------------------- /code/textToSpeech2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 中文 (zh): 你好、這是谷歌的語音合成測試! 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /code/oc/mult4.v: -------------------------------------------------------------------------------- 1 | module multiplier(a,b, ab); 2 | input [3:0] a,b; 3 | output [7:0] ab; 4 | 5 | wire [3:0] t0,t1,t2,t3; 6 | 7 | assign t0 = (b[0]==1) ? a : 4'h0; 8 | assign t1 = (b[1]==1) ? a : 4'h0; 9 | assign t2 = (b[2]==1) ? a : 4'h0; 10 | assign t3 = (b[3]==1) ? a : 4'h0; 11 | 12 | assign ab=t0+(t1<<1)+(t2<<2)+(t3<<3); 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /code/oc/scan.js: -------------------------------------------------------------------------------- 1 | // 本來應該用 .*? 來比對 /*...*/ 註解的,但 javascript 的 . 並不包含 \n, 因此用 \s\S 代替 . 就可以了。 2 | var re = /(\/\*[\s\S]*?\*\/)|(\/\/[^\r\n])|(\d+)|([a-zA-Z]\w*)|(\r?\n)|(.)/gm; // *?, +? non greedy, m for multiline 3 | text = "a=3+x-num*99; // comment\r\n y=5; /* block \r\n comment 1 */ z=3; /* block comment 2 */"; 4 | var tokens = text.match(re); 5 | console.log(tokens); 6 | -------------------------------------------------------------------------------- /code/oc/shift_mult.v: -------------------------------------------------------------------------------- 1 | module mult8(p,x,y); 2 | output [15:0]p; 3 | input [7:0]x,y; 4 | reg [15:0]p; 5 | reg [15:0]a; 6 | integer i; 7 | 8 | always @(x , y) 9 | begin 10 | a=x; 11 | p=0; // needs to zeroed 12 | for(i=0;i<8;i=i+1) 13 | begin 14 | if(y[i]) 15 | p=p+a; // must be a blocking assignment 16 | a=a<<1; 17 | end 18 | end 19 | endmodule 20 | -------------------------------------------------------------------------------- /source/license.md: -------------------------------------------------------------------------------- 1 | ## 授權聲明 2 | 3 | 本雜誌採用 創作共用:[姓名標示、相同方式分享] 授權,若您想要修改本書產生衍生著作時,至少應該遵守下列授權條件: 4 | 5 | 1. 標示原作者姓名 6 | 3. 採用 創作共用:[姓名標示、相同方式分享] 的方式公開衍生著作。 7 | 8 | 另外、當本雜誌中有文章或素材並非採用 [姓名標示、相同方式分享] 時,將會在該文章或素材後面標示其授權,此時該文章將以該標示的方式授權釋出,請修改者注意這些授權標示,以避免產生侵權糾紛。 9 | 10 | 例如有些文章可能不希望被作為「商業性使用」,此時就可能會採用創作共用:[姓名標示、非商業性、相同方式分享] 的授權,此時您就不應當將該文章用於商業用途上。 11 | 12 | 最後、懇請勿移除公益捐贈的相關描述,以便讓愛心得以持續散播! 13 | 14 | -------------------------------------------------------------------------------- /source/reflink.md9: -------------------------------------------------------------------------------- 1 | [程式人雜誌社團]: https://www.facebook.com/groups/programmerMagazine/ 2 | [姓名標示、相同方式分享]: http://creativecommons.org/licenses/by-sa/3.0/tw/ 3 | [姓名標示、非商業性、相同方式分享]: http://creativecommons.org/licenses/by-nc-sa/3.0/tw/ 4 | [馬萬圳]: http://coopermaa2nd.blogspot.tw/ 5 | [陳鍾誠]: http://ccckmit.wikidot.com/ 6 | [雜誌訂閱]: https://docs.google.com/spreadsheet/viewform?fromEmail=true&formkey=dG1TcER6Q3h1ZkpacFpDeEVFTDBLeVE6MQ 7 | -------------------------------------------------------------------------------- /submit/R-shiny/Makefile: -------------------------------------------------------------------------------- 1 | RMD = $(wildcard *.Rmd) 2 | MD = $(RMD:.Rmd=.md) 3 | HTML = $(RMD:.Rmd=.html) 4 | XCF = $(wildcard *.xcf) 5 | PNG = $(XCF:.xcf=.png) 6 | 7 | all: $(MD) $(HTML) 8 | 9 | %.md: %.Rmd 10 | Rscript -e "require(knitr);knit('$<','$@')" 11 | 12 | %.html: %.md 13 | ~/.cabal/bin/pandoc -s --self-contained $< -o $@ 14 | 15 | %.png: %.xcf 16 | mogrify -format png $< 17 | 18 | clean: 19 | -rm *.md *.html 20 | -------------------------------------------------------------------------------- /code/textToSpeech1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 中文 (zh): 你好、這是谷歌的語音合成測試!
7 | 9 | 英文 (en): Hi! This is the text to speech function of Google.
10 | 11 | 12 | -------------------------------------------------------------------------------- /code/oc/test.j: -------------------------------------------------------------------------------- 1 | s = sum(10); 2 | m = max(3,5); 3 | 4 | function sum(n) { 5 | s = 0; 6 | i=1; 7 | while (i<=10) { 8 | s = s + i; 9 | i++; 10 | } 11 | return s; 12 | } 13 | 14 | function max(a, b) { 15 | if (a > b) 16 | return a; 17 | else 18 | return b; 19 | } 20 | 21 | function total(a) { 22 | s = 0; 23 | for (i in a) { 24 | s = s + a[i]; 25 | } 26 | return s; 27 | } 28 | 29 | a = [ 1, 3, 7, 2, 6]; 30 | t = total(a); 31 | word = { e:"dog", c:"狗" }; 32 | -------------------------------------------------------------------------------- /code/oc/test.j0: -------------------------------------------------------------------------------- 1 | s = sum(10); 2 | m = max(3,5); 3 | 4 | function sum(n) { 5 | s = 0; 6 | i=1; 7 | while (i<=10) { 8 | s = s + i; 9 | i++; 10 | } 11 | return s; 12 | } 13 | 14 | function max(a, b) { 15 | if (a > b) 16 | return a; 17 | else 18 | return b; 19 | } 20 | 21 | function total(a) { 22 | s = 0; 23 | for (i in a) { 24 | s = s + a[i]; 25 | } 26 | return s; 27 | } 28 | 29 | a = [ 1, 3, 7, 2, 6]; 30 | t = total(a); 31 | word = { e:"dog", c:"狗" }; 32 | -------------------------------------------------------------------------------- /source/editor.md: -------------------------------------------------------------------------------- 1 | ## 編輯小語 2 | 3 | 在本期的「程式人雜誌」中,我們引入了一個比較奇怪的主題:「鍵盤革命」,這個主題有點「政治性」。 4 | 5 | 雖然可能有些「程式人」的朋友們會不喜歡,不過由於 2013/08/03 凱達格蘭大道的 25 萬人集會,讓我們決定要引入這樣一個 6 | 與「程式」距離較遠的主題。 7 | 8 | 如果讀者對這個主題比較不喜歡的話,可以選擇從「程式人文集」的技術類文章開始閱讀,跳過前半部的「鍵盤革命」主題。 9 | 10 | 但是、「鍵盤革命」的主題其實也有一些與程式人的關連,像是今年在 COSCUP 開源人年會的 g0v 組織,開源之父 Richard Stallman 等, 11 | 都是這個主題的相關人物,不排斥政治主題的程式人,可能會有興趣也說不定。 12 | 13 | 另外、由於小編已經從「中斷」(Interrupted) 的度假狀態,回復到「可工作」的 Ready 狀態,因此中斷一期的 「R、Verilog、開放電腦計畫」 14 | 等主題,都將回到正常狀態,繼續刊登了。 15 | 16 | ---- (程式人雜誌編輯 - 陳鍾誠) 17 | -------------------------------------------------------------------------------- /code/oc/cpu1.js: -------------------------------------------------------------------------------- 1 | var opTable = require("./optable"); 2 | var opList = ["LD 00 L", "ST 01 L", "LDB 02 L", "STB 03 L", 3 | "ADDI 12 C", "ADD 13 L", "SUB 14 L", "MUL 15 L", "DIV 16 L", "AND 18 L", 4 | "OR 19 L", "XOR 1A L", "ROL 1C L", "ROR 1D L", "SHL 1E L", "SHR 1F L", 5 | "JZ 20 L", "RET 2C N", "PUSH 30 L", "POP 31 L", "PUSHB 32 L", "POPB 33 L", 6 | "RESW F0 D", "RESB F1 D", "WORD F2 D", "BYTE F3 D"]; 7 | 8 | var cpu = { "opTable" : new opTable(opList) }; 9 | // cpu.opTable.dump(); 10 | module.exports = cpu; 11 | -------------------------------------------------------------------------------- /code/oc/counter.v: -------------------------------------------------------------------------------- 1 | module counter(input clk, rst, output reg [2:0] q); 2 | always @(posedge clk) begin 3 | if (rst) 4 | q = 3'b000; 5 | else 6 | q = q+1; 7 | end 8 | endmodule 9 | 10 | module main; 11 | reg clk; 12 | reg rst; 13 | wire [2:0] q; 14 | 15 | counter DUT (.clk(clk), .rst(rst), .q(q)); 16 | 17 | initial 18 | begin 19 | $monitor("%4dns monitor: q=%d", $stime, q); 20 | clk = 0; 21 | rst = 1; 22 | #100 rst = 0; 23 | #1000 $finish; 24 | end 25 | 26 | always #50 begin 27 | clk=clk+1; 28 | end 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /code/oc/xor3.v: -------------------------------------------------------------------------------- 1 | module xor3(input a, b, c, output abc); 2 | wire ab; 3 | xor g1(ab, a, b); 4 | xor g2(abc, c, ab); 5 | endmodule 6 | 7 | module xor3test; 8 | reg a, b, c; 9 | wire abc; 10 | 11 | xor3 g(a,b,c, abc); 12 | 13 | initial 14 | begin 15 | a = 0; 16 | b = 0; 17 | c = 0; 18 | end 19 | 20 | always #50 begin 21 | a = a+1; 22 | $monitor("%4dns monitor: a=%d b=%d c=%d a^b^c=%d", $stime, a, b, c, abc); 23 | end 24 | 25 | always #100 begin 26 | b = b+1; 27 | end 28 | 29 | always #200 begin 30 | c = c+1; 31 | end 32 | 33 | initial #2000 $finish; 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /code/oc/latch.v: -------------------------------------------------------------------------------- 1 | module latch(input Sbar, Rbar, output Q, Qbar); 2 | 3 | nand g1(Q, Sbar, Qbar); 4 | nand g2(Qbar, Rbar, Q); 5 | 6 | endmodule 7 | 8 | module main; 9 | reg Sbar, Rbar; 10 | wire Q, Qbar; 11 | 12 | latch DUT(Sbar, Rbar, Q, Qbar); 13 | 14 | initial 15 | begin 16 | Sbar = 0; 17 | Rbar = 0; 18 | end 19 | 20 | always #50 begin 21 | Sbar = Sbar+1; 22 | $monitor("%4dns monitor: Sbar=%d Rbar=%d Q=%d Qbar=%d", 23 | $stime, Sbar, Rbar, Q, Qbar); 24 | end 25 | 26 | always #100 begin 27 | Rbar = Rbar + 1; 28 | end 29 | 30 | initial #1000 $finish; 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /code/mux.v: -------------------------------------------------------------------------------- 1 | module mux4(input[1:0] select, input[3:0] d, output reg q ); 2 | always @( select or d ) 3 | begin 4 | case( select ) 5 | 0 : q = d[0]; 6 | 1 : q = d[1]; 7 | 2 : q = d[2]; 8 | 3 : q = d[3]; 9 | endcase 10 | end 11 | endmodule 12 | 13 | module main; 14 | reg [3:0] d; 15 | reg [1:0] s; 16 | wire q; 17 | 18 | mux4 DUT (s, d, q); 19 | 20 | initial 21 | begin 22 | s = 0; 23 | d = 4'b0110; 24 | end 25 | 26 | always #50 begin 27 | s=s+1; 28 | $monitor("%4dns monitor: s=%d d=%d q=%d", $stime, s, d, q); 29 | end 30 | 31 | initial #1000 $finish; 32 | 33 | endmodule -------------------------------------------------------------------------------- /code/oc/mux.v: -------------------------------------------------------------------------------- 1 | module mux4(input[1:0] select, input[3:0] d, output reg q ); 2 | always @( select or d ) 3 | begin 4 | case( select ) 5 | 0 : q = d[0]; 6 | 1 : q = d[1]; 7 | 2 : q = d[2]; 8 | 3 : q = d[3]; 9 | endcase 10 | end 11 | endmodule 12 | 13 | module main; 14 | reg [3:0] d; 15 | reg [1:0] s; 16 | wire q; 17 | 18 | mux4 DUT (s, d, q); 19 | 20 | initial 21 | begin 22 | s = 0; 23 | d = 4'b0110; 24 | end 25 | 26 | always #50 begin 27 | s=s+1; 28 | $monitor("%4dns monitor: s=%d d=%d q=%d", $stime, s, d, q); 29 | end 30 | 31 | initial #1000 $finish; 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /code/oc/fastadder.v: -------------------------------------------------------------------------------- 1 | module CLA_4bit(output [3:0] S, output Cout,PG,GG, input [3:0] A,B, input Cin); 2 | wire [3:0] G,P,C; 3 | 4 | assign G = A & B; //Generate 5 | assign P = A ^ B; //Propagate 6 | assign C[0] = Cin; 7 | assign C[1] = G[0] | (P[0]&C[0]); 8 | assign C[2] = G[1] | (P[1]&G[0]) | (P[1]&P[0]&C[0]); 9 | assign C[3] = G[2] | (P[2]&G[1]) | (P[2]&P[1]&G[0]) | (P[2]&P[1]&P[0]&C[0]); 10 | assign Cout = G[3] | (P[3]&G[2]) | (P[3]&P[2]&G[1]) | (P[3]&P[2]&P[1]&G[0]) 11 | |(P[3]&P[2]&P[1]&P[0]&C[0]); 12 | assign S = P ^ C; 13 | assign PG = P[3] & P[2] & P[1] & P[0]; 14 | assign GG = G[3] | (P[3]&G[2]) | (P[3]&P[2]&G[1]) | (P[3]&P[2]&P[1]&G[0]); 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /code/oc/optable.js: -------------------------------------------------------------------------------- 1 | var c = require("./ccc"); 2 | 3 | var Op = function(line) { 4 | var tokens = line.split(/\s+/); 5 | this.name = tokens[0]; 6 | this.id = parseInt(tokens[1], 16); 7 | this.type = tokens[2]; 8 | } 9 | 10 | var opTable = function(opList) { 11 | for (i in opList) { 12 | var op = new Op(opList[i]); 13 | this[op.name] = op; 14 | } 15 | } 16 | 17 | opTable.prototype.ID = function(op) { 18 | return this[op].id; 19 | } 20 | 21 | opTable.prototype.dump=function() { 22 | for (key in this) { 23 | var op = this[key]; 24 | if (typeof(op)!="function") 25 | c.log("%s %s %s", c.fill(' ', op.name, 8), c.hex(op.id, 2), op.type); 26 | } 27 | } 28 | 29 | module.exports = opTable; 30 | -------------------------------------------------------------------------------- /code/oc/counter_block.v: -------------------------------------------------------------------------------- 1 | module inc(input [2:0] i, output [2:0] o); 2 | assign o = i + 1; 3 | endmodule 4 | 5 | module register(input clk, rst, input [2:0] r_in, output [2:0] r_out); 6 | reg [2:0] r; 7 | always @(posedge clk) begin 8 | if (rst) 9 | r = 3'b000; 10 | else 11 | r = r_in; 12 | end 13 | assign r_out = r; 14 | endmodule 15 | 16 | module counter; 17 | reg clk; 18 | reg rst; 19 | wire [2:0] c_in, c_out; 20 | 21 | register c(clk, rst, c_in, c_out); 22 | inc inc1(c_out, c_in); 23 | 24 | initial 25 | begin 26 | $monitor("%4dns monitor: c.r=%d", $stime, c.r); 27 | clk = 0; 28 | rst = 1; 29 | #100 rst = 0; 30 | #1000 $finish; 31 | end 32 | 33 | always #50 begin 34 | clk=clk+1; 35 | end 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /code/oc/cpu0.js: -------------------------------------------------------------------------------- 1 | var opTable = require("./optable"); 2 | var opList = [ "LD 00 L", "ST 01 L", "LDB 02 L", "STB 03 L", "LDR 04 L", 3 | "STR 05 L", "LBR 06 L", "SBR 07 L", "LDI 08 L", "CMP 10 A", "MOV 12 A", 4 | "ADD 13 A", "SUB 14 A", "MUL 15 A", "DIV 16 A", "AND 18 A", "OR 19 A", "XOR 1A A", 5 | "ADDI 1B A", "ROL 1C A", "ROR 1D A", "SHL 1E A", "SHR 1F A", 6 | "JEQ 20 J", "JNE 21 J", "JLT 22 J", "JGT 23 J", "JLE 24 J", "JGE 25 J", "JMP 26 J", 7 | "SWI 2A J", "JSUB 2B J","RET 2C J", "PUSH 30 J", "POP 31 J", "PUSHB 32 J", 8 | "POPB 33 J", "RESW F0 D", "RESB F1 D", "WORD F2 D", "BYTE F3 D"]; 9 | 10 | var cpu = { "opTable" : new opTable(opList) }; 11 | 12 | if (process.argv[2] == "-d") 13 | cpu.opTable.dump(); 14 | 15 | module.exports = cpu; 16 | -------------------------------------------------------------------------------- /code/textToSpeech3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /code/oc/inherit.js: -------------------------------------------------------------------------------- 1 | var util = require("util"); 2 | 3 | function Parent() { 4 | this.age = 40; 5 | } 6 | 7 | Parent.prototype.toStr = function() { 8 | return "Parent:toStr age="+this.age; 9 | } 10 | 11 | Parent.prototype.callf = function() { 12 | console.log("Parent:callf"); 13 | return this.f(); 14 | } 15 | 16 | function Child() { 17 | this.age = 10; 18 | } 19 | 20 | util.inherits(Child, Parent); 21 | 22 | Child.prototype.toStr = function() { 23 | return "Child:toStr age="+this.age; 24 | } 25 | 26 | Child.prototype.f = function() { 27 | console.log("Child:f"); 28 | } 29 | 30 | Child.prototype.print = function() { 31 | return console.log(this.toStr()); 32 | } 33 | 34 | parent = new Parent(); 35 | console.log(parent.toStr()); 36 | // parent.print(); 37 | child = new Child(); 38 | console.log(child.toStr()); 39 | child.print(); 40 | child.callf(); 41 | -------------------------------------------------------------------------------- /code/oc/pctick.v: -------------------------------------------------------------------------------- 1 | module pcTick(input clock, reset, output reg [31:0] pc, 2 | output reg [2:0] tick); 3 | always @(posedge clock) begin 4 | if (reset) 5 | begin 6 | pc = 0; 7 | tick = 0; 8 | end 9 | else begin 10 | tick = tick+1; 11 | if (tick == 6) begin 12 | tick = 0; 13 | pc = pc+4; 14 | end 15 | $monitor("%4dns %8x %1x", $stime, pc, tick); 16 | end 17 | end 18 | endmodule 19 | 20 | module main; 21 | reg clock; 22 | reg reset; 23 | wire [2:0] tick; 24 | wire [31:0] pc; 25 | 26 | pcTick DUT (.clock(clock), .reset(reset), .pc(pc), .tick(tick)); 27 | 28 | initial 29 | begin 30 | clock = 0; 31 | reset = 1; 32 | #100 reset=0; 33 | #2000 $finish; 34 | end 35 | 36 | always #50 clock=clock+1; 37 | endmodule 38 | -------------------------------------------------------------------------------- /code/oc/sum.as0: -------------------------------------------------------------------------------- 1 | LD R1, sum ; R1 = sum = 0 2 | LD R2, i ; R2 = i = 1 3 | LDI R3, 10 ; R3 = 10 4 | FOR: CMP R2, R3 ; if (R2 > R3) 5 | JGT EXIT ; goto EXIT 6 | ADD R1, R1, R2 ; R1 = R1 + R2 (sum = sum + i) 7 | ADDI R2, R2, 1 ; R2 = R2 + 1 ( i = i + 1) 8 | JMP FOR ; goto FOR 9 | EXIT: ST R1, sum ; sum = R1 10 | ST R2, i ; i = R2 11 | LD R9, msgptr ; R9= pointer(msg) = &msg 12 | SWI 3 ; SWI 3 : 印出 R9 (=&msg) 中的字串 13 | MOV R9, R1 ; R9 = R1 = sum 14 | SWI 4 ; SWI 2 : 印出 R9 (=R1=sum) 中的整數 15 | RET ; return 返回上一層呼叫函數 16 | i: RESW 1 ; int i 17 | sum: WORD 0 ; int sum=0 18 | msg: BYTE "1+...+10=", 0 ; char *msg = "sum=" 19 | msgptr: WORD msg ; char &msgptr = &msg -------------------------------------------------------------------------------- /code/adder4.v: -------------------------------------------------------------------------------- 1 | module fulladder (input a, b, c_in, output sum, c_out); 2 | wire s1, c1, c2; 3 | 4 | xor g1(s1, a, b); 5 | xor g2(sum, s1, c_in); 6 | and g3(c1, a,b); 7 | and g4(c2, s1, c_in) ; 8 | xor g5(c_out, c2, c1) ; 9 | 10 | endmodule 11 | 12 | module adder4(input signed [3:0] a, input signed [3:0] b, input c_in, output signed [3:0] sum, output c_out); 13 | wire [3:0] c; 14 | 15 | fulladder fa1(a[0],b[0], c_in, sum[0], c[1]) ; 16 | fulladder fa2(a[1],b[1], c[1], sum[1], c[2]) ; 17 | fulladder fa3(a[2],b[2], c[2], sum[2], c[3]) ; 18 | fulladder fa4(a[3],b[3], c[3], sum[3], c_out) ; 19 | 20 | endmodule 21 | 22 | module main; 23 | reg signed [3:0] a; 24 | reg signed [3:0] b; 25 | wire signed [3:0] sum; 26 | wire c_out; 27 | 28 | adder4 DUT (a, b, 1'b0, sum, c_out); 29 | 30 | initial 31 | begin 32 | a = 4'b0101; 33 | b = 4'b0000; 34 | end 35 | 36 | always #50 begin 37 | b=b+1; 38 | $monitor("%dns monitor: a=%d b=%d sum=%d", $stime, a, b, sum); 39 | end 40 | 41 | initial #2000 $finish; 42 | 43 | endmodule 44 | -------------------------------------------------------------------------------- /code/oc/PipeReg.v: -------------------------------------------------------------------------------- 1 | module pipeReg(input clock, reset, zero, stall, input [size-1:0] data_i, output reg [size-1:0] data_o); 2 | parameter size = 0; 3 | always @(posedge clk_i) begin 4 | if(~reset) data_o<=0; 5 | else if(zero==1) data_o<=0; 6 | else if(stall==1) data_o<=data_o; 7 | else data_o <= data_i; 8 | end 9 | endmodule 10 | 11 | Pipe_Reg #(.size(64)) IF_ID( //N is the total length of input/output 12 | clk_i,rst_i,IF_ID_i,IF_ID_o,isBranch,stall 13 | ); 14 | module main; 15 | reg clock; 16 | reg reset; 17 | wire isBranch, stall; 18 | 19 | pipeReg #(.size(64)) IF_ID(clock, reset, isBranch, stall, IF_ID_i, IF_ID_o); 20 | pipeReg #(.size(153)) ID_EX(clock, reset, isBranch, stall, ID_EX_i, ID_EX_o); 21 | pipeReg #(.size(107)) EX_MEM(clock, reset, isBranch, stall, EX_MEM_i, EX_MEM_o); 22 | pipeReg #(.size(71)) MEM_WB(clock, reset, 0, 0, MEM_WB_i, MEM_WB_o); 23 | // Hazerd hazard(pcsrc,rs,rt,Mux2_o,MemRead_EX,isBranch,stall); 24 | 25 | initial 26 | begin 27 | clock = 0; 28 | reset = 1; 29 | end 30 | 31 | initial #20 reset = 0; 32 | 33 | always #10 clock=clock+1; 34 | 35 | initial #5000 $finish; 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /htm/article.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |

# 程式人文集

17 |
18 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /htm/message.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |

# 程式人短訊

17 |
18 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /htm/preface.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |
17 | 20 |
21 |

前言

22 |
23 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /htm/people.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |
17 | 20 |
21 |

程式人介紹

22 |
23 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /htm/video.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |
17 | 20 |
21 |

程式人頻道

22 |
23 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /htm/discuss.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |
17 | 20 |
21 |

程式人討論區

22 |
23 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /source/netconstitution.md: -------------------------------------------------------------------------------- 1 | ## 網路公民國 -- 一個虛擬國家的憲法,需要您一起來制定 2 | 3 | ![圖、網路公民國憲法制定之邀請函,圖片作者為網友「中陳」](../img/Constitution.jpg) 4 | 5 | ### 網友們、鄉民們、讓我們建立一個國家吧! 6 | 7 | 2013年8月7日 12:39 8 | 9 | 當五月花號從英國的普利茅斯港前往美洲新大陸時,船上的人應該沒有想過他們會建立一個偉大的國家。因為、他們只是一群在英國受到社會排斥的魯蛇 (Loser) 而已。 10 | 11 | 同樣的,當那些在現實世界中被排斥的魯蛇,為了逃避現實而躲入網路世界的時候,他們可能也沒有想到,自己將成為一個新世界的開拓者,甚至成為數十年後那個世界的領袖人物。因為、現在他們只是一群三餐不繼的失敗者而已。 12 | 13 | * 14 | 15 | 2013 年 8/3 上街頭的網民們,或許你們將會建立一個偉大的國家,而且、這個國家沒有領土! 16 | 17 | 我是陳鍾誠,是金門大學資工系的教師! 18 | 19 | 我很喜歡「黃仁宇」所說的「大歷史」觀點! 20 | 21 | 如果從長遠的角度來看,法國大革命時期的人們,絕對不會想到自己身處在一個偉大的歷史轉捩點上,在他們看來,自己生活的世界是如此的悲慘,如此的不堪! 22 | 23 | 同樣的,如果 50 年後再回頭看,很可能「逃離大學論文評鑑」這件事情,將會是我生命中的一個重要轉捩點。 24 | 25 | 一個永遠無法升等的助理教授,從現實的教育環境逃到網路上,逃到一個沒有任何學校長官會在意的地方,然後、在那裏建立自己的家,一個虛擬空間中的安身之處。 26 | 27 | 我不知道凱達格蘭大道的 25 萬人有著甚麼樣的故事,或許、他們與我一樣,也只是現實世界中的魯蛇。但是我相信,這群魯蛇將會建立一個新的國家,一個沒有領土的新世界,而且這些人,將會創造出新世界的第一部「憲法」。 28 | 29 | 感謝 8/3 站出來的 25 萬網友們,你們的行動讓我們非常感動,也讓我們看到了「政治上的一種全新可能性」。 30 | 31 | 如果您認為「聯合網民的力量」,是有可能改善這個世界的,那麼非常歡迎您加入以下這個社團,一起來創建一個「虛擬的國家」。 32 | 33 | * 網路公民國: 34 | 35 | 虛擬國家這個概念,目前仍然在動態改變,這個國家的概念不是只有一個社團,而且有「憲法、虛擬領土、主權」、也可以宣戰,媾和。當然、虛擬國家運作的方法,應該還是會取決於類似公民投票的方式,即使要宣戰,也必須要網民們投票決定啊! 36 | 37 | 更重要的是,我們網民們在實體世界的國家裏,還是有投票權的,我們可以影響國家的政策,讓未來走得更好。 38 | 39 | 如果我們聯合起來,我們可以左右藍綠兩黨的政策,讓這個虛擬國家成為「國中之國」,而且無處不在。 40 | 41 | 我們有一個非常卑微的願望,就是希望透過這樣的行動,讓政治有那麼一點點變好的可能性,期待您加入我們的行列! 42 | 43 | 44 | 【本文由陳鍾誠撰寫】 45 | -------------------------------------------------------------------------------- /source/message3.md: -------------------------------------------------------------------------------- 1 | ## 資訊政治:g0v 政府零時差組織 2 | 3 | 高嘉良所發起的 g0v 組織,是一個企圖用程式改變政治的組織,有興趣的人可以參考一下他們的網站。 4 | 5 | * 零時政府 -- 6 | 7 | g0v 做了很多有趣的「政治性」程式,以下是 g0v 的專案列表: 8 | 9 | * g0v 專案列表 -- 10 | 11 | 您可以看到其中有琳瑯滿目的專案,大部分是與資訊揭露有關的,像是: 12 | 13 | * 社會運動資訊平台 -- 14 | * 公務員出國考察追蹤網 -- 15 | * 中央政府總預算 -- 16 | * 律師幫幫我 -- 17 | * 鄉民關心你 -- 18 | * 台灣法規的API -- 19 | * 福利請聽 -- 20 | * 新聞小幫手 -- 21 | * 政誌 -- 22 | * 政府公開通訊錄 -- 23 | 24 | 最近我與 g0v 創辦人高嘉良連絡時,發現他們正在關注「柏林海盜黨」所釋出的一個實驗性開放原始碼軟體 liquidfeedback,網址如下: 25 | 26 | * 27 | 28 | 而且他們正在進行一個工作,就是將 liquidfeedback 修改為中文版,並且嘗試用這種方式改變台灣的政治環境,您可以從 github 29 | 上下載這個專案。 30 | 31 | * 32 | 33 | 當然、並不是只有 g0v 在進行「用程式改造社會」的活動,另外像 Code for Tomorrow 也是一個具有類似想法的台灣程式團體。 34 | 35 | * Code for Tomorrow -- 36 | 37 | 而在美國也有像 Code for America 這樣的組織,企圖用程式讓美國社會變得更好。 38 | 39 | * Code for America -- 40 | 41 | 筆者覺得、如果真的能用「程式讓世界變得更美好」,那真的是一件非常有意義的事情啊!希望 g0v 能夠有更多好的想法, 42 | 並發展出更多改善社會的程式,讓我們的社會能夠變得更美好啊! 43 | 44 | 【本文由陳鍾誠取材撰寫】 45 | 46 | -------------------------------------------------------------------------------- /code/addsub4.v: -------------------------------------------------------------------------------- 1 | module fulladder (input a, b, c_in, output sum, c_out); 2 | wire s1, c1, c2; 3 | 4 | xor g1(s1, a, b); 5 | xor g2(sum, s1, c_in); 6 | and g3(c1, a,b); 7 | and g4(c2, s1, c_in) ; 8 | xor g5(c_out, c2, c1) ; 9 | 10 | endmodule 11 | 12 | module adder4(input signed [3:0] a, input signed [3:0] b, input c_in, 13 | output signed [3:0] sum, output c_out); 14 | wire [3:0] c; 15 | 16 | fulladder fa1(a[0],b[0], c_in, sum[0], c[1]) ; 17 | fulladder fa2(a[1],b[1], c[1], sum[1], c[2]) ; 18 | fulladder fa3(a[2],b[2], c[2], sum[2], c[3]) ; 19 | fulladder fa4(a[3],b[3], c[3], sum[3], c_out) ; 20 | 21 | endmodule 22 | 23 | module xor4(input [3:0] a, input [3:0] b, output [3:0] y); 24 | assign y = a ^ b; 25 | endmodule 26 | 27 | module addSub4(input op, input signed [3:0] a, input signed [3:0] b, 28 | output signed [3:0] sum, output c_out); 29 | 30 | wire [3:0] bop; 31 | 32 | xor4 x1(b, {op,op,op,op}, bop); 33 | adder4 a1(a, bop, op, sum, c_out); 34 | 35 | endmodule 36 | 37 | module main; 38 | reg signed [3:0] a; 39 | reg signed [3:0] b; 40 | wire signed [3:0] sum; 41 | reg op; 42 | wire c_out; 43 | 44 | addSub4 DUT (op, a, b, sum, c_out); 45 | 46 | initial 47 | begin 48 | a = 4'b0101; 49 | b = 4'b0000; 50 | op = 1'b0; 51 | end 52 | 53 | always #50 begin 54 | op=op+1; 55 | $monitor("%dns monitor: op=%d a=%d b=%d sum=%d", $stime, op, a, b, sum); 56 | end 57 | 58 | always #100 begin 59 | b=b+1; 60 | end 61 | 62 | initial #2000 $finish; 63 | 64 | endmodule 65 | -------------------------------------------------------------------------------- /source/video1.md: -------------------------------------------------------------------------------- 1 | ## 看影片瞭解「鍵盤革命」的「資訊政治學」 2 | 3 | 現在、讓我們透過影片來看看,台灣與國際上對鍵盤革命的一些看法與想法,以便讓大家能夠進一步的思考:「資訊技術對政治領域,會產生甚麼樣的影響呢」? 4 | 5 | 國際上的鍵盤革命 6 | 7 | * [TED 影片 - Clay Shirky:網際網路(將來)如何改變政府](http://www.ted.com/talks/clay_shirky_how_the_internet_will_one_day_transform_government.html) 8 | * 從 git 版本管理系統看政治文化改變的可能性。 9 | * [TED 影片 - Lessig 談法律如何箝制創造力](http://www.ted.com/talks/larry_lessig_says_the_law_is_strangling_creativity.html) 10 | * Lessig 是 Creative Commons 創作共用的創造者。 11 | * [TED 影片 - Julian Assange:維基解密存在的必要性](http://www.ted.com/talks/julian_assange_why_the_world_needs_wikileaks.html) 12 | * Julian Assange 是維基解密的主要人物。 13 | * [TED 影片 - Rick Falkvinge: I am a pirate](http://www.ted.com/talks/rick_falkvinge_i_am_a_pirate.html) 14 | * Rick Falkvinge 是海盜黨的核心人物。 15 | * [YouTube - Aaron Swartz: The Documentary - Teaser](https://www.youtube.com/watch?v=3izOJ7zX5I0) 16 | * 紀念為鍵盤革命而死的 -- Aaron Swartz (RSS 與 Markdown 的創造者) 17 | 18 | 台灣的鍵盤革命 19 | 20 | * [YouTube -- 2013/08/03 公民1985 公民覺醒 最後演說(完整)](https://www.youtube.com/watch?v=Wmgqc4oiFZI) 21 | * 2013 年 8 月 3 日因為洪仲秋被軍方虐死一案,引發 25 萬人上凱達格蘭大道抗議,會場中令人動容的演說。 22 | * [YouTube -- g0v 黑客松 - 寫程式改造社會 / clkao (Taiwan WebConf)](http://www.youtube.com/watch?v=CCxQzSatN-w) 23 | * 高嘉良創立政府零時差組織 g0v 的原因,可以參考這個影片。 24 | * [YouTube -- Hack Everything, Including Society - 雨蒼](http://www.youtube.com/watch?v=rRrMDkCZeMo) 25 | * 雨蒼在 COSCUP 2013 對於如何用網路改變社會的演講。 26 | * [YouTube -- 蒐證雲/evi.tw - 翟本喬 和沛科技總經](http://www.youtube.com/watch?v=7NDM6kDVPl4) 27 | * 翟本喬在 COSCUP 2013 的演講,因洪仲秋案讓他們想到要用 APP 錄音蒐證。 28 | 29 | ### 參考文獻 30 | * 工程師的鍵盤革命:拆政府,原地重建 31 | 32 | 33 | 【本文由陳鍾誠撰寫】 34 | 35 | -------------------------------------------------------------------------------- /htm/editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |
17 | 20 |
21 |

編輯小語

22 |

在本期的「程式人雜誌」中,我們引入了一個比較奇怪的主題:「鍵盤革命」,這個主題有點「政治性」。

23 |

雖然可能有些「程式人」的朋友們會不喜歡,不過由於 2013/08/03 凱達格蘭大道的 25 萬人集會,讓我們決定要引入這樣一個 與「程式」距離較遠的主題。

24 |

如果讀者對這個主題比較不喜歡的話,可以選擇從「程式人文集」的技術類文章開始閱讀,跳過前半部的「鍵盤革命」主題。

25 |

但是、「鍵盤革命」的主題其實也有一些與程式人的關連,像是今年在 COSCUP 開源人年會的 g0v 組織,開源之父 Richard Stallman 等, 都是這個主題的相關人物,不排斥政治主題的程式人,可能會有興趣也說不定。

26 |

另外、由於小編已經從「中斷」(Interrupted) 的度假狀態,回復到「可工作」的 Ready 狀態,因此中斷一期的 「R、Verilog、開放電腦計畫」 等主題,都將回到正常狀態,繼續刊登了。

27 |

---- (程式人雜誌編輯 - 陳鍾誠)

28 |
29 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /source/message1.md: -------------------------------------------------------------------------------- 1 | ## 資訊政治:台灣「鍵盤革命」的歷史與近況 2 | 3 | ### 前言 4 | 5 | 最近台灣的「程式人」很多都投入了政治運動,企圖用程式改變政治,因此今年的開源人年會 COSCUP 上也出現了好幾場的「政治相關」演講。 6 | 7 | 這個現象或許可以用「鍵盤革命」、「網路政治」、「程式政治學」等詞彙描述。 8 | 9 | ### 莫拉克風災 10 | 11 | 從 2009 年的莫拉克風災開始,台灣的程式人就開始運用專業發揮了不小的影響力,以下是當年的一則 PTT 報導: 12 | 13 | * PTT 精華區 - 閱讀文章 (Emergency) -- 14 | 15 | 莫拉克風災是我第一次看到「網友們」展現政治力量的事件,雖然這件事情很不政治,但是基於孫中山的名言:「管理眾人之事便是政治」, 16 | 我們看到當政府失能的時候,網友們透過網路進行救災,彌補掉政府的無能,讓資訊得以快速流通的的「政治事件」。 17 | 18 | ### 洪仲秋被虐死引發 25 萬人上凱達格蘭大道 19 | 20 | 然後,在 2013 年,我們看到了一次「重要的網路政治事件」,那就是最近因「[洪仲秋被虐死一案]」,透過 [公民 1985 行動聯盟] 這個網路組織的協調,引發了 2013/8/3 日 25 萬人上凱達格蘭大道包圍總統府,卻又盡可能排除政黨介入的情況下,仍然表現出高度的組織能力,以及保持了良好秩序的事件。 21 | 22 | 以下的空拍圖片為這個事件留下了一個重要的見證,這是「鍵盤革命」的重要里程碑,也是台灣「網路世代」開始參與政治運動的一個明證。 23 | 24 | ![圖、photo by Jack0000](../img/SilverCross.jpg) 25 | 26 | * 圖片來源:親愛的芭樂人類學家專欄, 25萬人上街抗議真的有用嗎?, 2013/08/05 公民運動 政治 洪仲丘 社會運動 27 | * 28 | 29 | ### 結語 30 | 31 | 雖然政治令人覺得很黑暗,也讓很多人討厭,但是如果透過「程式專業」與「網路社群」,有機會能讓這個世界變得更好的話, 32 | 我相信還是有許多程式人願意付出時間來讓世界變得更美好的! 33 | 34 | ### 參考文獻 35 | * [工程師的鍵盤革命:拆政府,原地重建](http://www.inside.com.tw/2013/08/05/coscup-2013-coders-keyboard-revolution), inside 網站。 36 | * [PTT 精華區 - 閱讀文章 (Emergency)](http://www.ptt.cc/man/Emergency/D8B1/M.1252037298.A.654.html) 37 | * 維基百科:[中度颱風莫拉克] 38 | * 維基百科:[八八水災] 39 | 40 | [中度颱風莫拉克]:http://zh.wikipedia.org/zh-tw/%E9%A2%B1%E9%A2%A8%E8%8E%AB%E6%8B%89%E5%85%8B_(2009%E5%B9%B4) 41 | [八八水災]:http://zh.wikipedia.org/wiki/%E5%85%AB%E5%85%AB%E6%B0%B4%E7%81%BD 42 | [洪仲秋被虐死一案]:http://zh.wikipedia.org/zh-tw/%E6%B4%AA%E4%BB%B2%E4%B8%98%E6%9E%89%E6%AD%BB%E4%BA%8B%E4%BB%B6 43 | [公民 1985 行動聯盟]:http://zh.wikipedia.org/wiki/%E5%85%AC%E6%B0%911985%E8%A1%8C%E5%8B%95%E8%81%AF%E7%9B%9F 44 | 45 | 【本文由陳鍾誠取材並修改自維基百科,原本寫得很長,但是後來決定簡化,若您想看那個長的版本,我們也有留著,請點選 [這裏](https://dl.dropboxusercontent.com/u/101584453/pmag/201309/htm/message1long.html)】 46 | 47 | -------------------------------------------------------------------------------- /source/home.md: -------------------------------------------------------------------------------- 1 | ### 關於程式人雜誌 2 | 程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌。 3 | 4 | ### 雜誌下載 5 | 6 | 出刊年月 epub ipad:PDF A4:PDF 單頁 HTM 原始碼 全部下載 7 | ------------ ---------- ----------- -------- ----------- ---------- ------------- 8 | 2013年9月 [epub] [ipad.pdf] [A4.pdf] [pmag.html] [code.zip] [all.zip] 9 | 10 | 說明:本期取材比較特殊,前半部分討論「網路與政治」這個與程式距離較遠的主題,不喜歡政治主題的讀者請直接從「程式人文集」開始閱讀,謝謝! 11 | 12 | ### 本期內容 13 | * 前言 14 | * [編輯小語](editor.html) 15 | * [授權聲明](license.html) 16 | * 程式人介紹 17 | * [資訊政治人:Stallman, Lessig, Swartz 與 Assange](people1.html) 18 | * 程式人短訊 19 | * [資訊政治:台灣「鍵盤革命」的歷史與近況](message1.html) 20 | * [資訊政治:海盜黨簡介](message2.html) 21 | * [資訊政治:g0v 政府零時差組織](message3.html) 22 | * 程式人頻道 23 | * [看影片瞭解「鍵盤革命」的「資訊政治學」](video1.html) 24 | * 程式人討論區 25 | * [網路與政治:網友們可以形成一個「虛擬國家」嗎?](discuss1.html) 26 | * 程式人文集 27 | * [Arduino入門教學(9) – 在 2x16 LCD 上顯示 "Hello World" 訊息 (作者:Cooper Maa)](article1.html) 28 | * [JavaScript (9) – Google 的語音合成 API 之使用 (作者:陳鍾誠)](article2.html) 29 | * [R 統計軟體(6) – 迴歸分析 (作者:陳鍾誠)](article3.html) 30 | * [Verilog (3) – 組合邏輯電路 (作者:陳鍾誠)](article4.html) 31 | * [開放電腦計畫 (3) – VM0 虛擬機:使用 JavaScript+Node.js 實作 (作者:陳鍾誠)](article5.html) 32 | * [R 講題分享 – 利用 R 和 Shiny 製作網頁應用 (作者:Taiwan R User Group)](article6.html) 33 | * [雜誌訊息](info.html) 34 | 35 | ### 雜誌取得 36 | 37 | 程式人雜誌預定於每個月 1 日出刊,您可以從下列網址取得程式人雜誌的所有內容 (包含當月最新出刊的雜誌)。 38 | 39 | * 40 | 41 | ### 連絡我們 42 | 43 | 竭誠歡迎程式人投稿,或者成為本雜誌的專欄作家,現在就可以加入 [程式人雜誌社團] 一同共襄盛舉。 44 | 45 | 本雜誌編輯為「陳鍾誠 (@ccckmit)」,若要聯絡編輯,請寄信到 。 46 | 47 | [epub]: ../book/A4.epub 48 | [ipad.pdf]: ../book/ipad.pdf 49 | [A4.pdf]: ../book/A4.pdf 50 | [code.zip]: ../code.zip 51 | [pmag.html]: ../book/pmag.html 52 | [all.zip]: https://github.com/programmermagazine/201309/archive/gh-pages.zip 53 | 54 | -------------------------------------------------------------------------------- /htm/license.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |
17 | 20 |
21 |

授權聲明

22 |

本雜誌採用 創作共用:姓名標示、相同方式分享 授權,若您想要修改本書產生衍生著作時,至少應該遵守下列授權條件:

23 |
    24 |
  1. 標示原作者姓名
  2. 25 |
  3. 採用 創作共用:姓名標示、相同方式分享 的方式公開衍生著作。
  4. 26 |
27 |

另外、當本雜誌中有文章或素材並非採用 姓名標示、相同方式分享 時,將會在該文章或素材後面標示其授權,此時該文章將以該標示的方式授權釋出,請修改者注意這些授權標示,以避免產生侵權糾紛。

28 |

例如有些文章可能不希望被作為「商業性使用」,此時就可能會採用創作共用:姓名標示、非商業性、相同方式分享 的授權,此時您就不應當將該文章用於商業用途上。

29 |

最後、懇請勿移除公益捐贈的相關描述,以便讓愛心得以持續散播!

30 |
31 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /source/message2.md: -------------------------------------------------------------------------------- 1 | ## 資訊政治:海盜黨簡介 2 | 3 | 海盜黨是近年來在政治領域上異軍突起的一個政治團體,而德國海盜黨則是各國海盜黨當中發展得最好的一個,以下是海盜黨的一些相關資料,請讀者參考: 4 | 5 | * 維基百科, [海盜黨國際](http://zh.wikipedia.org/zh-tw/%E6%B5%B7%E7%9B%9C%E9%BB%A8%E5%9C%8B%E9%9A%9B) 6 | * 維基百科, [德國海盜黨](http://zh.wikipedia.org/zh-tw/%E5%BE%B7%E5%9C%8B%E6%B5%B7%E7%9B%9C%E9%BB%A8) 7 | * Wikipedia:[Pirate_Party_Germany](http://en.wikipedia.org/wiki/Pirate_Party_Germany) 8 | * [「遙控民主」新實驗,讓百年大黨取經的七歲駭客政黨 - 專訪海盜黨主席(上)](http://hatetyping.blogspot.de/2013/08/blog-post_24.html) 9 | 10 | 第一個海盜黨是由 李卡德·法克明炎於2006年1月1日成立於瑞典的組織,稱為 Piratpartiet。該組織認為現時的版權制度已經過時,危害到人們傳播知識的權力。 11 | 2006年海盜黨成為了瑞典無議會席位政黨之中最大的一個,後來奧地利、丹麥、芬蘭、德國、愛爾蘭、荷蘭、波蘭和西班牙也先後成立了海盜黨。 12 | 13 | 海盜黨的主張主要有三個:一是改革版權法,二是廢除專利,三是尊重私隱。他們認為現在的版權制度已經過時,很多企業利用版權限制知識發放, 14 | 侷限了很多創造性工作。所以於網路上分享電影、音樂等等行為不應該被視為違法。 15 | 16 | 2009年 4月 17 日,4名 海盜灣經營者被瑞典法庭判處 1 年有期徒刑之後,盜版黨黨員人數暴增到 2萬8千多人,躍身為瑞典第三大黨,並於2009年歐洲議會 17 | 選舉中在瑞典獲得了 7.1% 的選票,在歐洲議會中將擁有1個席位。 18 | 19 | 2011 年,德國海盜黨針對柏林州議會選舉推出 15 位候選人,全上。其後幾次其他的州議會選舉,德國海盜黨也獲得 7-8% 的得票率,取得席次。 20 | 21 | 海盜黨的一些網路民主的實施方法可以參考以下的文章: 22 | 23 | * [德國海盜黨的流動式民主](http://charlesc.ilovemeow.net/blog/20130110/1202) 24 | 25 | 我們將上述文章的重點摘要如下: 26 | 27 | * 海盜黨的多數的決策都是先在網路上經過許多人的討論,例如用 [PiratePad]、聊天室、wiki 和郵件論壇來協作。 28 | * 投票時,每人一票。但是,因為並非大家都能夠詳閱政策內容,所以系統允許成員可以委託他人代為投票。委託範圍可以是所有提案、某個主題的提案、或是某特定提案。而被委派投票的成員,還可以把這些票、包括自己的一票,再度委託給他人投票! 29 | * Liquid Feedback 這種以信任為基礎的模式,類似信譽系統(reputation system),只不過成員的參與所換到的不是點數,而是選票。理論上,這種投票鏈可能會把票集中到人緣好的菁英或獨裁者身上,但好在有個防錯機制,可以在任何時候取消委託投票,有野心的海盜也得認真才能成事。Bormuth 說,我們讓有戰鬥力的人可以成事,但也讓大家有權控制這些人。 30 | 31 | 雖然海盜黨在很多國家都成立了,但是在台灣卻被政府禁止成立,請參考以下新聞。 32 | 33 | * [學者籌組海盜黨 內政部不准中央社中央社](http://tw.news.yahoo.com/%E5%AD%B8%E8%80%85%E7%B1%8C%E7%B5%84%E6%B5%B7%E7%9B%9C%E9%BB%A8-%E5%85%A7%E6%94%BF%E9%83%A8%E4%B8%8D%E5%87%86-033713002.html) – 2012年2月26日 上午11:37 34 | 35 | 不過還是有人在網路上成立了這樣的社團,像是 Google Plus 上就有下列社團: 36 | 37 | * [台灣海盜黨(推廣處)] -- 38 | 39 | ### 結語 40 | 41 | 雖然德國的國情與台灣不同,不過在網路時代,各國的做法都可以很透明的被大家所參考模仿,然後經過嘗試後找到一個比較適合自己國家的實施方式, 42 | 運用網路來改變政治結構啊! 43 | 44 | 【本文由陳鍾誠取材並修改自維基百科】 45 | 46 | 47 | [PiratePad]:http://www.piratenpad.de/ 48 | 49 | -------------------------------------------------------------------------------- /code/oc/as1.js: -------------------------------------------------------------------------------- 1 | var c = require("./ccc"); 2 | var as = require("./as"); 3 | var code = require("./code"); 4 | var cpu1 = require("./cpu1"); 5 | 6 | var as1 = new as(cpu1.opTable); 7 | 8 | as1.parse = function(line) { 9 | return new code(line, this.opTable); 10 | } 11 | 12 | as1.translate = function(code) { // 指令的編碼函數 13 | var ra=0, rb=0, rc=0, cx=0; 14 | var pc = code.address + 4; // 提取後PC為位址+4 15 | var args = code.args, parseR = code.parseR; 16 | var labelCode = null; 17 | switch (code.op.type) { 18 | case "N": 19 | code.obj = c.hex(code.op.id, 2) + c.hex(0, 6); 20 | break; 21 | case "C": 22 | ra = parseR(args[0]); 23 | rb = parseR(args[1]); 24 | cx = parseInt(args[2]); 25 | code.obj = c.hex(code.op.id, 2)+c.hex(ra, 1)+c.hex(rb, 1)+c.hex(cx, 4); 26 | break; 27 | case "L": 28 | ra = parseR(args[0]); 29 | rb = 15; 30 | labelCode = this.symTable[args[1]]; 31 | cx = labelCode.address - pc; 32 | code.obj = c.hex(code.op.id, 2)+c.hex(ra, 1)+c.hex(rb, 1)+c.hex(cx, 4); 33 | break; 34 | case "D": 35 | var unitSize = 1; 36 | switch (code.op.name) { 37 | case "RESW": // 如果是 RESW 38 | case "RESB": // 或 RESB 39 | code.obj = c.dup('0', code.size()*2); 40 | break; 41 | case "WORD": // 如果是 WORD: 42 | unitSize = 4; 43 | case "BYTE": { // 如果是 BYTE : 輸出格式為 %2x 44 | code.obj = ""; 45 | for (var i in args) { 46 | if (args[i].match(/\d+/)) // 常數 47 | code.obj += c.hex(parseInt(args[i]), unitSize*2); 48 | else { // 標記 49 | labelCode = symTable[args[i]]; 50 | code.obj += c.hex(labelCode.address, unitSize*2); 51 | } 52 | } 53 | break; 54 | } // case BYTE: 55 | } // switch 56 | } // case "D" 57 | } 58 | 59 | as1.assemble(process.argv[2], process.argv[3]); 60 | -------------------------------------------------------------------------------- /source/netsong.md: -------------------------------------------------------------------------------- 1 | ### 網路公民國之歌 (1) : 你若是對政府生氣 2 | 3 | ``` 4 | Do you hear the people sing? Singing a song of angry men. 5 | 你若是對政府生氣 不免用生命拼下去 6 | 7 | It is the music of a people who will not be slaves again! 8 | 只要用你的手指 點點滑鼠 然後按下去 9 | 10 | When the beating of your heart echoes the beating of the drums 11 | 然後回去看電視 冷氣開好來吹下去 12 | 13 | There is a life about to start when tomorrow comes! 14 | 他就會自動辦好 回來給我們請示 15 | ``` 16 | 17 | 18 | ### 網路公民國之歌 (2) :你咁有聽著阮唱歌 19 | 20 | ``` 21 | 第 1 段 22 | 23 | Do you hear the people sing? Singing a song of angry men. 24 | 你咁有聽著阮唱歌 唱出得眾人的心聲 25 | 26 | It is the music of a people who will not be slaves again! 27 | 議會的制度實在問題很多 國家攏害了了 28 | 29 | When the beating of your heart echoes the beating of the drums 30 | 咱ㄟ厝給拆去來 咱ㄟ子給人抵虐待 31 | 32 | There is a life about to start when tomorrow comes! 33 | 才隔來給阮騙說 全是為好將來 34 | 35 | 第 2 段 36 | 37 | Will you join in our crusade who will be strong and stand with me? 38 | 政客嘛實在厲害 騙咱民眾憨大呆 39 | 40 | Beyond the barricade is there a world you long to see? 41 | 幾十年憨憨轉 給他格騙來又騙去 42 | 43 | Then join in the fight that will give you the right to be free! 44 | 團結起來 非常厲害 給一死 45 | 46 | 第 3 段 47 | 48 | Do you hear the people sing? Singing a song of angry men. 49 | 你哪是整天怨嘆這 完全是浪費沒採工 50 | 51 | It is the music of a people who will not be slaves again! 52 | 嘎阮做陣來參加網路國家 麥格浪費時間 53 | 54 | When the beating of your heart echoes the beating of the drums 55 | 咱用投票定憲法 咱用網路團結起來 56 | 57 | There is a life about to start when tomorrow comes! 58 | 只要你動動手指 他就未甲你害 59 | 60 | 第 4 段 61 | 62 | Will you give all you can give so that our banner may advance 63 | 你一定會想貢 這是瘋子 才會這麼做 64 | 65 | Some will fall and some will live will you stand up and take your chance? 66 | 網路甘有可能 會凍改變 政治的問題 67 | 68 | The blood of the martyrs will water the meadows of France! 69 | 不願相信 只好給他 繼續害 70 | 71 | 第 5 段 72 | 73 | Do you hear the people sing? Singing a song of angry men. 74 | 你咁有聽著阮唱歌 唱出得未來的希望 75 | 76 | It is the music of a people who will not be slaves again! 77 | 你若是相信 就來甲阮做陣建立網路國家 78 | 79 | When the beating of your heart echoes the beating of the drums 80 | 咱ㄟ心頭抓得定 最夥來建立新國家 81 | 82 | There is a life about to start when tomorrow comes! 83 | 為這咱下一代 來創造出好將來 84 | ``` 85 | 86 | 87 | 【本文歌曲來自悲慘世界歌劇,作詞與編輯者為陳鍾誠】 88 | 89 | 90 | -------------------------------------------------------------------------------- /source/info.md: -------------------------------------------------------------------------------- 1 | # 雜誌訊息 2 | 3 | ## 讀者訂閱 4 | 程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌,如果您願意成為本雜誌的專欄作家,請加入 [程式人雜誌社團] 一同共襄盛舉。 5 | 6 | 我們透過發行這本雜誌,希望讓大家可以讀到想讀的書,學到想學的技術,同時也讓寫作的朋友的作品能產生良好價值 – 那就是讓讀者根據雜誌的價值捐款給慈善團體。 7 | 讀雜誌做公益也不需要有壓力,您不需要每讀一本就急著去捐款,您可以讀了十本再捐,或者使用固定的月捐款方式,當成是雜誌訂閱費,或者是季捐款、一年捐一次等都 OK ! 甚至是單純當個讀者我們也都很歡迎! 8 | 本雜誌每期參考價:NT 50 元,如果您喜歡本雜誌,請將書款捐贈公益團體。例如可捐贈給「羅慧夫顱顏基金會 彰化銀行(009) 帳號:5234-01-41778-800」。(若匯款要加註可用「程式人雜誌」五個字) 9 | 10 | 想訂閱本雜誌的讀者,請按 [雜誌訂閱] 連結並填寫表單,我們會在每一期雜誌出刊時寄送通知與下載網址到您的信箱。 11 | 12 | ## 投稿須知 13 | 14 | *給專欄寫作者:* 做公益不需要有壓力。如果您願意撰寫專欄,您可以輕鬆的寫,如果當月的稿件出不來,我們會安排其他稿件上場。 15 | 16 | *給網誌捐贈者:* 如果您沒時間寫專欄或投稿,沒關係,只要將您的網誌以 [創作共用的「姓名標示、非商業性、相同方式分享」授權] 並通知我們,我們會自動從中選取需要的文章進行編輯,放入適當的雜誌當中出刊。 17 | 18 | *給文章投稿者:* 程式人雜誌非常歡迎您加入作者的行列,如果您想撰寫任何文章或投稿,請用 markdown 或 LibreOffice 編輯好您的稿件,並於每個月 25 日前投稿到[程式人雜誌社團] 的檔案區,我們會盡可能將稿件編入隔月1號出版程式人雜誌當中,也歡迎您到社團中與我們一同討論。 19 | 20 | 如果您要投稿給程式人雜誌,我們最希望的格式是採用 markdown 的格式撰寫,然後將所有檔按壓縮為 zip 上傳到社團檔案區給我們, 21 | 如您想學習 markdown 的撰寫出版方式,可以參考 [程式人雜誌的出版方法] 一文。 22 | 23 | 如果您無法採用 markdown 的方式撰寫,也可以直接給我們您的稿件,像是 MS. Word 的 doc 檔或 LibreOffice 的 odt 檔都可以,我們 24 | 會將這些稿件改寫為 markdown 之後編入雜誌當中。 25 | 26 | ## 參與編輯 27 | 您也可以擔任程式人雜誌的編輯,甚至創造一個全新的公益雜誌,我們誠摯的邀請您加入「開放公益出版」的行列,如果您想擔任編輯或創造新雜誌,也歡迎到 [程式人雜誌社團] 來與我們討論相關事宜。 28 | 29 | ## 公益資訊 30 | 31 | ------------------------------------------------------------------------------------------------------------------------------------------------------------ 32 | 公益團體 聯絡資訊 服務對象 捐款帳號 33 | ------------------------------- ----------------------------- ----------------------------------------- ------------------------------------------- 34 | 財團法人羅慧夫顱顏基金會
顱顏患者 銀行:009彰化銀行民生分行
35 |
(如唇顎裂、小耳症或其他罕見顱顏缺陷) 帳號:5234-01-41778-800 36 | 02-27190408分機 232 37 | 38 | 社團法人台灣省兒童少年成長協會
單親、隔代教養.弱勢及一般家庭之兒童青少年 銀行:新光銀行
39 |
戶名:台灣省兒童少年成長協會
40 | 04-23058005 帳號:103-0912-10-000212-0 41 | ------------------------------- ----------------------------- ----------------------------------------- ------------------------------------------- 42 | 43 | 44 | -------------------------------------------------------------------------------- /code/oc/cpu0i.hex: -------------------------------------------------------------------------------- 1 | 26 00 00 24 // 0 JMP RESET 2 | 26 00 00 04 // 4 JMP ERROR 3 | 26 00 00 04 // 8 JMP IRQ 4 | 26 FF FF FA // c ERROR: JMP ERROR 5 | 00 90 00 24 // 10 IRQ: LD R9, TIMER 6 | 08 A0 00 01 // 14 LDI R10,1 7 | 13 99 A0 00 // 18 ADD R9, R9, R10 8 | 01 90 00 24 // 1C ST R9, TIMER 9 | 2D 00 00 00 // 20 IRET 10 | 00 00 00 00 // 24 TIMER: WORD 0 11 | 00 D0 00 BA // 28 RESET: LD R13, StackEnd 12 | 30 E0 00 00 // 2c PUSH R14 13 | 08 40 00 04 // 30 LDI R4, 4 14 | 08 50 00 08 // 34 LDI R5, 8 15 | 19 85 40 00 // 38 OR R8, R5, R4 16 | 1A 85 40 00 // 3c XOR R8, R5, R4 17 | 1E 85 00 03 // 40 SHL R8, R5, 3 18 | 1F 85 00 02 // 44 SHR R8, R5, 2 19 | 10 45 00 00 // 48 CMP R4, R5 20 | 20 00 00 18 // 4c JEQ L1 21 | 23 00 00 14 // 50 JGT L1 22 | 25 00 00 10 // 54 JGE L1 23 | 22 00 00 0C // 58 JLT L1 24 | 24 00 00 08 // 5c JLE L1 25 | 21 00 00 04 // 60 JNE L1 26 | 26 00 00 00 // 64 JMP L1 27 | 08 10 00 0A // 68 L1: LDI R1, 10 28 | 2B 00 00 08 // 6c CALL SUM 29 | 31 E0 00 00 // 70 POP R14 30 | 2C 00 00 00 // 74 RET 31 | 30 E0 00 00 // 78 SUM: PUSH R14 32 | 12 30 00 00 // 7c MOV R3, R0 // R3 = i = 0 33 | 02 4F 00 24 // 80 LDB R4, k1 // R4 = 1 34 | 08 20 00 00 // 84 LDI R2, 0 // SUM = R2 = 0 35 | 13 22 30 00 // 88 LOOP: ADD R2, R2, R3 // SUM = SUM + i 36 | 13 33 40 00 // 8c ADD R3, R3, R4 // i = i + 1 37 | 10 31 00 00 // 90 CMP R3, R1 // if (i < R1) 38 | 24 FF FF F0 // 94 JLE LOOP // goto LOOP 39 | 01 2F 00 0D // 98 ST R2, s 40 | 03 3F 00 0D // 9c STB R3, i 41 | 31 E0 00 00 // a0 POP R14 42 | 2C 00 00 00 // a4 RET // return 43 | 01 // a8 k1: BYTE 1 // char K1=1 44 | 00 00 00 00 // a9 s: WORD 0 // int s 45 | 00 // ad i: BYTE 0 // char i=1 46 | 00 01 02 03 // ae Stack: BYTE 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 10, 11 47 | 04 05 06 07 // b2 48 | 08 09 0A 0B // b6 49 | 00 00 00 BA // ba StackEnd: WORD StackEnd 50 | 01 02 03 04 // be Data: BYTE 0, 1, 2, 3, 4, 5, 6, 7, 8 51 | 05 06 07 08 // c2 -------------------------------------------------------------------------------- /source/people1.md: -------------------------------------------------------------------------------- 1 | ## 資訊政治人:Stallman, Lessig, Swartz 與 Assange 2 | 3 | 看到上述的人名,很多讀者勢必心中會產生一大堆問號?他們是誰?這些人之間有甚麼關連呢? 4 | 5 | 程式人雜誌曾經介紹過這四位當中的兩位,也就是 Stallman 與 Swartz,甚至也曾經談到過 Lessig , 6 | 但是還沒有介紹過 Assange,讓我們稍微介紹一下這些人的重要事蹟。 7 | 8 | * Stallman : [開放原始碼之父–Richard Stallman], 是著名的程式人, GNU 組織的創建者,GPL 授權的制定者。 9 | * Lessig : [勞倫斯·雷席格], 哈佛大學憲法學教授,創作共用 (Creative Commons) 授權的創造者。 10 | * Swartz : [Markdown 與 RSS 的創造者-Aaron Swartz], 2010 年從 MIT 校園內大量論文後被起訴,然後不堪檢察官威脅,在 2013 年 1 月 11 日時自殺身亡。 11 | * Assange : 維基解密組織的創建者與核心人物。 12 | 13 | 筆者之所以將這些人寫在一起,原因在於這些人是「鍵盤革命」這一個概念當中的重要人物,他們都利用「電腦、程式、網路」等工具,與當權者進行對抗。 14 | 15 | Stallman 因為不滿程式碼被商業公司封閉起來,而創造了 GNU 組織與 GPL 這個開放原始碼的程式授權,以便強制商業公司開放原始碼。 16 | Lessig 延續 Stallman 的想法,將開放原始碼的概念引入一般著作與網頁,創造出了 Creative Commons 授權。而 Swartz 則為了讓資訊的流通更容易, 17 | 創造出 Markdown 格式與 RSS 訂閱技術,並且因為想把學術論文開放而遭到起訴,最後更因此而自殺。 18 | 19 | 至於 Assange,則因為將那些政府機密大量上網,成為各國政府的頭號公敵,並因「性犯罪」的罪名而被瑞典通輯,因此後來向厄瓜多駐倫敦大使館尋求政治庇護,目前英國還企圖與「厄瓜多」談判將 Assange 引渡到瑞典受審當中。 20 | 21 | 以上這些人與事件,都涉及到「資訊揭露」的政治學,有些人用合法的方式企圖揭露資訊 (像是 Stallman, Lessig),而有些人則用目前法律不允許的手段去揭露資訊 (像是 Swartz 與 Assange)。 22 | 23 | 18 世紀工業革命 (第二波) 的結果,造成工業取代農業,因此政治上從封建莊園制度轉向了議會政治,權力的核心從封建領主轉向了資本家。 24 | 25 | 在今日 21 世紀的資訊革命 (第三波) 當中,權力又將如何移轉,這個世界會如何變化呢? 26 | 27 | 未來、網路與資訊科技會帶領我們建立怎麼樣的一個「政治結構」呢?這是筆者很想知道,但卻也還在探索當中的一個重要關注項目啊! 28 | 29 | ### 參考文獻 30 | * [開放原始碼之父–Richard Stallman], 程式人雜誌 2013 年 3 月號 31 | * [Markdown 與 RSS 的創造者-Aaron Swartz], 程式人雜誌 2013 年 4 月號 32 | * 33 | * 維基百科:[勞倫斯·雷席格] 34 | * 35 | * 維基百科:[朱利安·阿桑奇] 36 | * [英國厄瓜多爾或商談阿桑奇去留問題](http://www.apdnews.com/news/27457.html), 作者:亞太日報綜合報導 發稿地:香港 時間:2013-6-03 37 | * 38 | * [第三波 (The Third Wave)], 作者:艾文‧托佛勒 (Alvin Toffler), 譯者:黃明堅, 時報出版社, 1994年06月20日. 39 | * [第三波 - 農業、工業與資訊文明](http://ccckmit.wikidot.com/thethirdwave), 陳鍾誠的網站。 40 | 41 | 42 | [開放原始碼之父–Richard Stallman]:https://dl.dropboxusercontent.com/u/101584453/pmag/201303/htm/people1.html 43 | [Markdown 與 RSS 的創造者-Aaron Swartz]:https://dl.dropboxusercontent.com/u/101584453/pmag/201304/htm/people2.html 44 | [勞倫斯·雷席格]:http://zh.wikipedia.org/wiki/%E5%8B%9E%E5%80%AB%E6%96%AF%C2%B7%E9%9B%B7%E5%B8%AD%E6%A0%BC 45 | [朱利安·阿桑奇]:http://zh.wikipedia.org/wiki/Julian_Assange 46 | [第三波 (The Third Wave)]:http://www.books.com.tw/exep/prod/booksfile.php?item=0010069728 47 | 48 | 【本文由陳鍾誠取材並修改自維基百科,原本寫得很長,但是後來決定簡化,若您想看那個長的版本,我們也有留著,請點選 [這裏](https://dl.dropboxusercontent.com/u/101584453/pmag/201309/htm/people1long.html)】 49 | 50 | 51 | -------------------------------------------------------------------------------- /source/discuss1.md: -------------------------------------------------------------------------------- 1 | ## 網路與政治:網友們可以形成一個「虛擬國家」嗎? 2 | 3 | 受到 2013/8/3 時 25 萬人上凱達格蘭大道這件事的激勵,讓我想到能否號召網友們,形成一個沒有實體領土,只有虛擬領土的「網路國家」呢? 4 | 5 | 透過這個國家,我們可以制定法律、提出政策、甚至發動資訊戰。 6 | 7 | 而且、這些網民仍然是某些實體國家(例如台灣)的國民,因此仍然具有該國的投票權,所以就可以透過「網路公投」決定政策後, 8 | 要求政黨或立委認養這些政策並簽下契約,以換取將這些網民的票投給他們的「交易」。 9 | 10 | 我認為這種方式或許能讓網民可以有效的影響政府,並且跨過「公投法門檻過高」的問題。 11 | 12 | 於是我發了以下的訊息在「程式人雜誌的討論區」以及自己的 facebook 上,並引發了一些討論: 13 | 14 | * 問題:我想我又瘋了,今年初我辦了一本新的雜誌,現在居然想成立一個新的國家 15 | * 網址: 16 | 17 | 我之所以會認為應該用「虛擬國家」的概念,而非採用像「海盜黨」這樣的「黨」的慨念,或許原因之一是「黨」這個中文字 18 | 其實隱含了非常糟糕的負面意義,但是在英文中的 Party 卻沒有這種意思。 19 | 20 | 還有一個原因是,我想法中的這種網路組織,其實更像是一個國家,因為這個組織可以擁有「人民、土地、政府、主權」這四種形成國家的要素,只不過其領土 21 | 乃是在網路上的虛擬領土,而非真實世界的領土而已,有興趣的讀者可以參考以下兩篇文章。 22 | 23 | * [網路世代所需要的制度與法律 -- 虛擬國家的慨念](https://dl.dropboxusercontent.com/u/101584453/pmag/201309/htm/netcountry.html) 24 | * [網路公民國 -- 一個虛擬國家的憲法,需要您一起來制定](https://dl.dropboxusercontent.com/u/101584453/pmag/201309/htm/netconstitution.html) 25 | 26 | 那麼、虛擬國家的憲法應該是什麼樣的呢?以下是一個我構思中的範例: 27 | 28 | 1. 任何人都可以經由明文宣誓的方式,成為網路公民國 (以下簡稱本國) 的公民 (以下簡稱網民)。 29 | 2. 網民除了本國之外,還可以自由參加任何組織或實體國家,本國並無任何禁止「雙重國籍」的規定。 30 | 3. 網民有上網之自由,任何組礙或限制網民上網的行為,都違反本憲法之精神。 31 | 4. 網民有集會結社之基本權利,任何損害此一權利的組織,都將視為本國之敵人,本國有封鎖該組織的權利。 32 | 5. 網民的任何作品,只要不附加「著作權宣告」,就被預設視為「公共領域」之作品,任何網民都擁有合法修改、複製、散布之權利。 33 | 6. 網民可以下載任何未被身分認證機制所保護的內容,而不被控以侵犯著作權之自由。 34 | .... 35 | 36 | 這樣的法律其實意在保障網民們的自由,並且同時尊重創作者的權力,但是將著作權的預設值反轉過來,從 CopyRight 「版權所有」的 37 | All Rights Reserved 轉化為「版權所無」的 No Rights Reserved 的情況,這讓網路自由可以得到法律基礎。 38 | 39 | 這種手法與 GNU 的 GPL 有些不同,GPL 是透過法律來挑戰法律,但「網路虛擬國家」則直接透過「建國」與「制憲」挑戰傳統的政治結構。 40 | 41 | 「虛擬國家」或許不會擁有土地,但是卻擁有「網路空間上的領土」,可以透過「封鎖」、「不提供資訊」與實體國家進行對抗,網民們 42 | 也有可能透過像「鍵盤戰」的方式,進行某種形式的「虛擬戰爭」。 43 | 44 | 更重要的是,「虛擬國家」沒有禁止「雙重國籍」的規定,網民們在實體世界的國家裏,還是有投票權的。因此、「虛擬國家」可以透過 45 | 「公投」制定政策,試圖影響某個實體國家的政策,讓這些國家的政治可以更好。 46 | 47 | 舉例而言,如果台灣的「網民」們聯合起來,形成一個「虛擬國家」,例如叫做「網路公民國」(簡稱網國),就可以先在網路上制定政策 48 | 並且透過「公投」表決,決定建議國民將選票投給「認養」這個政策的「立委」或「政黨」,然後告訴「國民黨」與「民進黨」這個遊戲規則, 49 | 用「虛擬國家」的政策影響甚至左右「實體國家」的政策。 50 | 51 | 於是、這個虛擬國家成了一個「國中之國」,而且可以發揮強大的政治影響力,這就是我對「虛擬國家」運作方式的初步想法。 52 | 53 | 後記:我們甚至連國歌都寫好了,直接採用悲慘世界的革命之歌,配上自己填的歌詞,有興趣的朋友可以點選下列網址。 54 | 55 | * [網路公民國之歌](https://dl.dropboxusercontent.com/u/101584453/pmag/201309/htm/netsong.html) 56 | 57 | 不過可惜的是,由於這個理想尚未得到真實國家的認同,筆者怕因為將自己唱國歌的錄音上網而被告,所以現在這首國歌只能私下唱, 58 | 因為這首歌的商業權還在華納公司的手上啊!請參考下列文章。 59 | 60 | * [《你敢有聽著咱的歌》是誰的(江雅綺)](http://www.appledaily.com.tw/appledaily/article/headline/20130817/35226971) 61 | 62 | 這也正是我們為何在上述憲法中要加入那些 CopyLeft 版權條款的原因啊! 63 | 64 | 當然、您也可以直接宣誓加入這個虛擬國家,只要在 facebook 上按一下加入就行了。 65 | 66 | * 「網路公民國」 -- 67 | 68 | 【本文由陳鍾誠撰寫】 69 | 70 | -------------------------------------------------------------------------------- /code/oc/expc.js: -------------------------------------------------------------------------------- 1 | require("./ccc"); 2 | 3 | var symTable = {}; 4 | 5 | var tempIdx = 0; 6 | var nextTemp=function() { return "T"+tempIdx++; } 7 | 8 | var stack = []; 9 | var push=function(o) { stack.push(o); } 10 | var pop=function() { return stack.pop(); } 11 | 12 | var tokens = []; 13 | var tokenIdx = 0; 14 | // 本來應該用 .*? 來比對 /*...*/ 註解的,但 javascript 的 . 並不包含 \n, 因此用 \s\S 代替 . 就可以了。 15 | var retok = /(\/\*[\s\S]*?\*\/)|(\/\/[^\r\n])|(\d+)|([a-zA-Z]\w*)|(\r?\n)|(.)/gm; // *?, +? non greedy, m for multiline 16 | 17 | var source = ""; 18 | var scan=function(text) { 19 | tokenIdx = 0; 20 | tokens = text.match(retok); 21 | return tokens; 22 | } 23 | 24 | var error=function(o) { printf("Error: %j\n", o); } 25 | var pcode = function(op, t, t1, t2) { printf("%s %s %s %s\n", op, t, t1, t2); } 26 | 27 | var next=function(o) { 28 | if (isNext(o)) 29 | return tokens[tokenIdx++]; 30 | error(token); 31 | } 32 | 33 | var isNext=function(o) { 34 | if (tokenIdx >= tokens.length) 35 | return false; 36 | var token = tokens[tokenIdx]; 37 | if (o instanceof RegExp) { 38 | return token.match(o); 39 | } else { 40 | return (token == o); 41 | } 42 | } 43 | 44 | var compile=function(text) { 45 | scan(text); 46 | printf("text=%s\n", text); 47 | printf("tokens=%j\n", tokens); 48 | E(); 49 | printf("symTable=%j\n", symTable); 50 | } 51 | 52 | var E=function() { // E=T ([+-] T)* 53 | push('E'); 54 | t1 = T(); 55 | while (isNext(/[\+\-]/)) { 56 | op = next(/[\+\-]/); 57 | t = nextTemp(); 58 | t2 = T(); 59 | pcode(op, t, t1, t2); 60 | t1 = t; 61 | } 62 | pop('E'); 63 | return t1; 64 | } 65 | 66 | var T=function() { // T=F ([*/] F)* 67 | push('T'); 68 | f1 = F(); 69 | while (isNext(/[\*\/]/)) { 70 | op = next(/[*\/]/); 71 | f2 = F(); 72 | f = nextTemp(); 73 | pcode(op, f, f1, f2); 74 | f1 = f; 75 | } 76 | pop('T'); 77 | return f1; 78 | } 79 | 80 | var reNumber = /\d+/; 81 | var reId = /[a-zA-Z]\w*/; 82 | 83 | var F=function() { // F=NUMBER | ID | ( E ) 84 | push('F'); 85 | if (isNext("(")) { 86 | next("("); 87 | f = E(); 88 | next(")"); 89 | } else if (isNext(reNumber)) { 90 | number = next(reNumber); 91 | f = nextTemp(); 92 | pcode("=", f, number, ""); 93 | } else if (isNext(reId)) { 94 | f = id = next(reId); 95 | symTable[id] = "ID"; 96 | } 97 | pop('F'); 98 | return f; 99 | } 100 | 101 | printf("=== EBNF Grammar =====\n"); 102 | printf("E=T ([+-] T)*\n"); 103 | printf("T=F ([*/] F)*\n"); 104 | printf("F=NUMBER | ID | '(' E ')'\n"); 105 | compile("32+5*(182+degree*4-20)"); 106 | // printf("typeof(/\w+/)=%s /\w+/ instanceof RegExp=%s\n", typeof(/\w+/), /\w+/ instanceof RegExp); 107 | // printf("typeof(str)=%s\n", typeof("str")); 108 | -------------------------------------------------------------------------------- /code/oc/ifetch.v: -------------------------------------------------------------------------------- 1 | module computer(input clock, reset); 2 | wire [2:0] tick; 3 | wire [31:0] mar, mdr; 4 | wire m_en, m_rw; 5 | 6 | cpu cpu0(clock, reset, mar, mdr, m_en, m_rw); 7 | memory m(clock, reset, m_en, m_rw, mar, mdr); 8 | 9 | endmodule 10 | 11 | module memory(input clock, reset, en, rw, input [31:0] abus, inout [31:0] dbus); 12 | reg [7:0] m [0:128]; 13 | reg [31:0] data; 14 | always @(clock or reset or abus or en or rw or dbus) 15 | begin 16 | if (reset == 1) begin 17 | {m[0],m[1],m[2],m[3]} = 32'h001F0018; // 0000 LD R1, K1 18 | {m[4],m[5],m[6],m[7]} = 32'h002F0010; // 0004 LD R2, K0 19 | {m[8],m[9],m[10],m[11]} = 32'h003F0014; // 0008 LD R3, SUM 20 | {m[12],m[13],m[14],m[15]}= 32'h13221000; // 000C LOOP: ADD R2, R2, R1 21 | {m[16],m[17],m[18],m[19]}= 32'h13332000; // 0010 ADD R3, R3, R2 22 | {m[20],m[21],m[22],m[23]}= 32'h26FFFFF4; // 0014 JMP LOOP 23 | {m[24],m[25],m[26],m[27]}= 32'h00000000; // 0018 K0: WORD 0 24 | {m[28],m[29],m[30],m[31]}= 32'h00000001; // 001C K1: WORD 1 25 | {m[32],m[33],m[34],m[35]}= 32'h00000000; // 0020 SUM: WORD 0 26 | data = 32'hZZZZZZZZ; 27 | end else if (abus >=0 && abus < 125) begin 28 | if (en == 1 && rw == 0) begin // r_w==0:write 29 | {m[abus], m[abus+1], m[abus+2], m[abus+3]} = dbus; 30 | end 31 | else if (en == 1 && rw == 1) // r_w==1:read 32 | data = {m[abus], m[abus+1], m[abus+2], m[abus+3]}; 33 | else 34 | data = 32'hZZZZZZZZ; 35 | end else 36 | data = 32'hZZZZZZZZ; 37 | end 38 | assign dbus = data; 39 | endmodule 40 | 41 | module cpu(input clock, reset, output [31:0] abus, input [31:0] dbus, output m_en, m_rw); 42 | wire [31:0] pc_i, pc_o, pcadd4; 43 | reg [31:0] ir, mar, mdr; 44 | 45 | Reg PC(clock, reset, 1, pcadd4, pc_o); 46 | Adder pcadder(pc_o, 4, pcadd4); 47 | 48 | assign abus = mar; 49 | always @(negedge clock) begin 50 | ir = dbus; 51 | mar = pc_o; 52 | end 53 | assign m_en = 1; 54 | assign m_rw = 1; // read 55 | endmodule 56 | 57 | 58 | module Adder(input [31:0] i1, i2, output [31:0] o); 59 | assign o = i1 + i2; 60 | endmodule 61 | 62 | module Reg(input clock, reset, w_en, input [31:0] ri, output reg[31:0] ro); 63 | always @(posedge clock) begin 64 | if(reset==1) ro<=0; 65 | else if (w_en==1) ro<=ri; 66 | else ro<=ro; 67 | end 68 | endmodule 69 | 70 | module main; 71 | reg clock, reset; 72 | 73 | computer computer0(clock, reset); 74 | 75 | initial 76 | begin 77 | clock = 0; 78 | reset = 1; 79 | $monitor("%4dns PC=%8x IR=%8x", $stime, computer0.cpu0.PC.ro, computer0.cpu0.ir); 80 | end 81 | 82 | initial #20 reset = 0; 83 | 84 | always #10 clock=clock+1; 85 | 86 | initial #500 $finish; 87 | 88 | endmodule 89 | -------------------------------------------------------------------------------- /htm/netconstitution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 | 21 |

網路公民國 -- 一個虛擬國家的憲法,需要您一起來制定

22 |
23 | 圖、網路公民國憲法制定之邀請函,圖片作者為網友「中陳」

圖、網路公民國憲法制定之邀請函,圖片作者為網友「中陳」

24 |
25 |

網友們、鄉民們、讓我們建立一個國家吧!

26 |

2013年8月7日 12:39

27 |

當五月花號從英國的普利茅斯港前往美洲新大陸時,船上的人應該沒有想過他們會建立一個偉大的國家。因為、他們只是一群在英國受到社會排斥的魯蛇 (Loser) 而已。

28 |

同樣的,當那些在現實世界中被排斥的魯蛇,為了逃避現實而躲入網路世界的時候,他們可能也沒有想到,自己將成為一個新世界的開拓者,甚至成為數十年後那個世界的領袖人物。因為、現在他們只是一群三餐不繼的失敗者而已。

29 | 32 |

2013 年 8/3 上街頭的網民們,或許你們將會建立一個偉大的國家,而且、這個國家沒有領土!

33 |

我是陳鍾誠,是金門大學資工系的教師!

34 |

我很喜歡「黃仁宇」所說的「大歷史」觀點!

35 |

如果從長遠的角度來看,法國大革命時期的人們,絕對不會想到自己身處在一個偉大的歷史轉捩點上,在他們看來,自己生活的世界是如此的悲慘,如此的不堪!

36 |

同樣的,如果 50 年後再回頭看,很可能「逃離大學論文評鑑」這件事情,將會是我生命中的一個重要轉捩點。

37 |

一個永遠無法升等的助理教授,從現實的教育環境逃到網路上,逃到一個沒有任何學校長官會在意的地方,然後、在那裏建立自己的家,一個虛擬空間中的安身之處。

38 |

我不知道凱達格蘭大道的 25 萬人有著甚麼樣的故事,或許、他們與我一樣,也只是現實世界中的魯蛇。但是我相信,這群魯蛇將會建立一個新的國家,一個沒有領土的新世界,而且這些人,將會創造出新世界的第一部「憲法」。

39 |

感謝 8/3 站出來的 25 萬網友們,你們的行動讓我們非常感動,也讓我們看到了「政治上的一種全新可能性」。

40 |

如果您認為「聯合網民的力量」,是有可能改善這個世界的,那麼非常歡迎您加入以下這個社團,一起來創建一個「虛擬的國家」。

41 | 44 |

虛擬國家這個概念,目前仍然在動態改變,這個國家的概念不是只有一個社團,而且有「憲法、虛擬領土、主權」、也可以宣戰,媾和。當然、虛擬國家運作的方法,應該還是會取決於類似公民投票的方式,即使要宣戰,也必須要網民們投票決定啊!

45 |

更重要的是,我們網民們在實體世界的國家裏,還是有投票權的,我們可以影響國家的政策,讓未來走得更好。

46 |

如果我們聯合起來,我們可以左右藍綠兩黨的政策,讓這個虛擬國家成為「國中之國」,而且無處不在。

47 |

我們有一個非常卑微的願望,就是希望透過這樣的行動,讓政治有那麼一點點變好的可能性,期待您加入我們的行列!

48 |

【本文由陳鍾誠撰寫】

49 |
50 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /code/oc/vm1.js: -------------------------------------------------------------------------------- 1 | var c = require("./ccc"); 2 | var cpu1 = require("./cpu1"); 3 | var Memory = require("./memory"); 4 | 5 | var IR = 16, PC = 15, LR = 14, SP = 13, SW = 12; 6 | var ID = function(op) { return cpu1.opTable[op].id; } 7 | 8 | var run = function(objFile) { 9 | R = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 13, 14, 0, 16]; 10 | m = new Memory(1); 11 | m.load(objFile); 12 | var stop = false; 13 | while (!stop) { // 如果尚未結束 14 | var tpc = R[PC]; 15 | R[0] = 0; // R[0] 永遠為 0 16 | R[IR] = m.geti(R[PC]); // 指令擷取,IR=[PC..PC+3] 17 | R[PC] += 4; // 擷取完將 PC 加 4,指向下一個指令 18 | var op = c.bits(R[IR], 24, 31); // 取得 op 欄位,IR[24..31] 19 | var ra = c.bits(R[IR], 20, 23); // 取得 ra 欄位,IR[20..23] 20 | var rb = c.bits(R[IR], 16, 19); // 取得 rb 欄位,IR[16..19] 21 | var c16= c.signbits(R[IR], 0, 15); // 取得 16 位元的 cx 22 | var c5 = c.bits(R[IR], 0, 4); 23 | var addr = R[rb]+c16; 24 | switch (op) { // 根據op執行動作 25 | case ID("LD") : R[ra] = m.geti(addr); break; // 處理 LD 指令 26 | case ID("ST") : m.seti(addr, R[ra]); c.log("m[%s]=%s", c.hex(addr,4), m.geti(addr)); break; // 處理 ST 指令 27 | case ID("LDB"): R[ra] = m.getb(addr); break; // 處理 LDB 指令 28 | case ID("STB"): m.setb(addr, R[ra]); break; // 處理 STB 指令 29 | case ID("ADDI"):R[ra] = R[rb] + c16; break; // 處理 ADDI 指令 30 | case ID("ADD"): R[ra] += m.geti(addr); break; // 處理ADD指令 31 | case ID("SUB"): R[ra] -= m.geti(addr); break; // 處理SUB指令 32 | case ID("MUL"): R[ra] *= m.geti(addr); break; // 處理MUL指令 33 | case ID("DIV"): R[ra] /= m.geti(addr); break; // 處理DIV指令 34 | case ID("AND"): R[ra] &= m.geti(addr); break; // 處理AND指令 35 | case ID("OR") : R[ra] |= m.geti(addr); ; break; // 處理OR指令 36 | case ID("XOR"): R[ra] ^= m.geti(addr); ; break; // 處理XOR指令 37 | case ID("SHL"): R[ra] = R[rb]<>c5; break; // 處理SHR指令 39 | case ID("JZ") : if (R[ra]==0) R[PC] = R[rb]+c16; break; // 處理JZ指令 40 | case ID("PUSH"):R[SP]-=4; R[ra]=m.geti(addr); m.seti(R[SP], R[ra]); break; // 處理PUSH指令 41 | case ID("POP"): R[ra] = m.geti(R[SP]); R[SP]+=4; break; // 處理POP指令 42 | case ID("PUSHB"):R[SP]--; R[ra]=m.getb(addr); m.setb(R[SP], R[ra]); break; // 處理PUSH指令 43 | case ID("POPB"):R[ra] = m.getb(R[SP]); R[SP]++; break; // 處理POPB指令 44 | case ID("RET"): stop=true; R[PC]=R[LR]; break; // 處理RET指令 45 | default: c.log("Error:invalid op (%s)", hex(op)); 46 | } // switch 47 | c.log("PC=%s IR=%s SW=%s R[%s]=0x%s=%d", // 印出 PC, IR, R[ra]暫存器的值,以利觀察 48 | c.hex(tpc,4), c.hex(R[IR],8), c.hex(R[SW],8), c.hex(ra,2), c.hex(R[ra], 8), R[ra]); 49 | } // while 50 | } 51 | 52 | run(process.argv[2]); 53 | -------------------------------------------------------------------------------- /source/netcountry.md: -------------------------------------------------------------------------------- 1 | ## 網路世代所需要的制度與法律 -- 虛擬國家的慨念 2 | 3 | 在苗栗大浦案激化之後,抗議的朋友們喊出了「今天拆大埔,明天拆政府」的口號,甚至還導致 4 | 政大教授徐世榮被在喊口號時當街被逮捕,後來更衍生出陳為廷、楊儒門、李建成等人也因潑漆事件而被逮捕的事件。 5 | 6 | 但是、筆者在此要討論的,不是這個事件,而是拆除政府的方法。 7 | 8 | 在過去尚未發展出民主制度的時代,拆政府的方法只有一種,那就是革命了,但是民主制度發展出來之後, 9 | 每到選舉時政府就會被拆掉然後重建。因此、民主制度可以說一種定期拆除政府的制度。 10 | 11 | 可惜的是,我們的民主政治似乎走到了一個困境,每次選舉都會拆掉政府,然後原地重建。但是新的政府往往沒有更好, 12 | 而且很可能更爛。 13 | 14 | 這次由「洪仲秋事件」,在台灣引發了「公民 1985」聯盟發起上凱達格蘭大道抗議的活動,展現了台灣網路世代的力量, 15 | 在盡可能排除政黨勢力介入的情況下,集結了 25 萬人上街頭,卻又非常有秩序,而且有組織的進行了一場完美的街頭運動。 16 | 17 | 這件事讓筆者深受啟發,我認為這件事代表了「網路世代」是可以形成政治力量的,但是我也擔心這股力量隨著「洪仲秋事件」 18 | 的落幕而消散,網路世代從此又成為政治的邊緣人。這個世界仍然繼續由傳統的藍綠政治勢力所主導,那是我不願看到的。 19 | 20 | 兩年前我也曾經因為某個突然的啟發,開始了一場小革命,用網路來對抗現有的教育體制,以下是這場小革命的一些相關資訊: 21 | 22 | * [為台灣教育界投下一顆震撼彈!(首篇) -- 陳鍾誠給李家同的一封公開信](http://ccckmit.wikidot.com/po:bomb) 23 | * [為台灣教育界投下一顆震撼彈!(續篇) -- 陳鍾誠給李家同的第二封公開信](http://ccckmit.wikidot.com/po:bomb2) 24 | * [為台灣教育界投下一顆震撼彈!(最終篇) -- 我的夢想,我的遺書!](http://ccckmit.wikidot.com/po:bomb3) 25 | * [我有一個夢 -- 網路民主軍成立的原因](http://ccckmit.wikidot.com/po:dream2) 26 | 27 | 以及我最近模仿賈伯斯的演講,講述了有關自己親身經歷的三個有關網路社群的故事,這篇讀的人比較多,而且有被 inside 網站轉載。 28 | 29 | * [台灣落入困境的根本原因-陳鍾誠的網站](http://ccckmit.wikidot.com/po:taiwanproblem ) 30 | * [台灣落入困境的根本原因-Inside 硬塞的網路趨勢觀察](http://www.inside.com.tw/2013/06/03/taiwan-stuck ) 31 | * [網路社群與雲端應用](http://www.slideshare.net/ccckmit/ss-22270119) 32 | 33 | 後來這場革命逐漸退燒了,我決定回到正常的生活,做一些有意義的事情,於是在去年底我決定創辦了「程式人雜誌」, 34 | 也就是各位現在看到的這本雜誌。 35 | 36 | 但是在 2013/8/3 日 25 萬人上凱道的事情過後,我內心哪個被壓抑下來的熱情又重新燃燒起來了,這也讓我思考 37 | 了好幾個晚上,甚至輾轉難眠。 38 | 39 | 我認為根本的問題是,網路世代其實被上一代所創建的體制所壓抑了,8 月 3 日的集結代表的不僅僅是抗議一個人被軍方虐死的事件, 40 | 而更深層的反應了「網路世代」企圖掙脫上一代所創造的枷鎖,然後創造一個更美好的世界。 41 | 42 | 但是、這種枷鎖根深蒂固的透過政治體制綑綁了我們,我們又如何能掙脫出來呢? 43 | 44 | 突然間、我想到一個可能的辦法,那就是讓網民們建立一個「虛擬國家」,然後用這個虛擬國家的力量,來影響實體國家, 45 | 讓政治有機會變得更好。 46 | 47 | 例如、在網路上,智慧財產權是一個很大的問題,我們每天的資訊分享幾乎都在觸犯法律,但是透過制定「網路虛擬國家」的憲法, 48 | 我們有機會得到與實體世界法律相抗衡的力量,這個想法乃是直接延伸自「開放原始碼」的 GPL 授權而來的,甚至也受「創作共用」 49 | (Creative Commons) 的影響很深。 50 | 51 | 於是我寫了一些「網路憲法」的不成熟草案,希望透過這樣的方式改變現實世界的智慧財產權困境,以下是幾項不成熟的條文想法: 52 | 53 | 1. 任何人都可以經由明文宣誓的方式,成為網路公民國 (以下簡稱本國) 的公民 (以下簡稱網民)。 54 | 2. 網民除了本國之外,還可以自由參加任何組織或實體國家,本國並無任何禁止「雙重國籍」的規定。 55 | 3. 網民有上網之自由,任何組礙或限制網民上網的行為,都違反本憲法之精神。 56 | 4. 網民有集會結社之基本權利,任何損害此一權利的組織,都將視為本國之敵人,本國有封鎖該組織的權利。 57 | 5. 網民的任何作品,只要不附加「著作權宣告」,就被預設視為「公共領域」之作品,任何網民都擁有合法修改、複製、散布之權利。 58 | 6. 網民可以下載任何未被身分認證機制所保護的內容,而不被控以侵犯著作權之自由。 59 | 60 | 這樣的法律其實意在保障網民們的自由,並且同時尊重創作者的權力,但是將著作權的預設值反轉過來,從 CopyRight 「版權所有」的 61 | All Rights Reserved 轉化為「版權所無」的 No Rights Reserved 的情況,這讓網路自由可以得到法律基礎。 62 | 63 | 這種手法與 GNU 的 GPL 有些不同,GPL 是透過法律來挑戰法律,但「網路虛擬國家」則直接透過「建國」與「制憲」挑戰傳統的政治結構。 64 | 65 | 「虛擬國家」的概念,目前仍然沒有明確的定義,在我的想法中,「虛擬國家」不會只是一個網路社團而已,還會有「憲法、虛擬領土、主權」、 66 | 甚至也可以「宣戰,媾和」。 67 | 68 | 根據德國公學者耶林內克(G.Jellinek)的說法,國家的四個構成要素是「人民、土地、政府、主權」。 69 | 70 | 在這四項要素中,「虛擬國家」擁有人民,也就是網民,擁有「主權」,像是智慧財產權等等,也可以建立「政府」,雖然這個政府可能只 71 | 是個「網路平台基礎建設」,以及一些維持這個基礎建設正常運作的志工,就像是維基百科一樣,但是仍然是個「政府」,而且大部分的 72 | 政策都可以透過「直接投票」-- 或說是「公民投票」而決定。 73 | 74 | 「虛擬國家」或許不會擁有土地,但是卻擁有「網路空間上的領土」,可以透過「封鎖」、「不提供資訊」與實體國家進行對抗,網民們 75 | 也有可能透過像「鍵盤戰」的方式,進行某種形式的「虛擬戰爭」。 76 | 77 | 更重要的是,「虛擬國家」沒有禁止「雙重國籍」的規定,網民們在實體世界的國家裏,還是有投票權的。因此、「虛擬國家」可以透過 78 | 「公投」制定政策,試圖影響某個實體國家的政策,讓這些國家的政治可以更好。 79 | 80 | 舉例而言,如果台灣的「網民」們聯合起來,形成一個「虛擬國家」,例如叫做「網路公民國」(簡稱網國),就可以先在網路上制定政策 81 | 並且透過「公投」表決,決定建議國民將選票投給「認養」這個政策的「立委」或「政黨」,然後告訴「國民黨」與「民進黨」這個遊戲規則, 82 | 用「虛擬國家」的政策影響甚至左右「實體國家」的政策。 83 | 84 | 於是、這個虛擬國家成了一個「國中之國」,而且可以發揮強大的政治影響力,這就是我對「虛擬國家」運作方式的初步想法。 85 | 86 | 87 | 【本文由陳鍾誠撰寫】 88 | -------------------------------------------------------------------------------- /htm/netsong.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |

網路公民國之歌 (1) : 你若是對政府生氣

17 |
Do you hear the people sing? Singing a song of angry men.
18 | 你若是對政府生氣 不免用生命拼下去
19 | 
20 | It is the music of a people who will not be slaves again!
21 | 只要用你的手指 點點滑鼠 然後按下去
22 | 
23 | When the beating of your heart echoes the beating of the drums
24 | 然後回去看電視 冷氣開好來吹下去
25 | 
26 | There is a life about to start when tomorrow comes!
27 | 他就會自動辦好 回來給我們請示
28 |

網路公民國之歌 (2) :你咁有聽著阮唱歌

29 |
第 1 段
30 | 
31 | Do you hear the people sing? Singing a song of angry men.
32 | 你咁有聽著阮唱歌 唱出得眾人的心聲
33 | 
34 | It is the music of a people who will not be slaves again!
35 | 議會的制度實在問題很多 國家攏害了了
36 | 
37 | When the beating of your heart echoes the beating of the drums
38 | 咱ㄟ厝給拆去來 咱ㄟ子給人抵虐待
39 | 
40 | There is a life about to start when tomorrow comes!
41 | 才隔來給阮騙說 全是為好將來
42 | 
43 | 第 2 段
44 | 
45 | Will you join in our crusade who will be strong and stand with me?
46 | 政客嘛實在厲害 騙咱民眾憨大呆
47 | 
48 | Beyond the barricade is there a world you long to see?
49 | 幾十年憨憨轉 給他格騙來又騙去
50 | 
51 | Then join in the fight that will give you the right to be free!
52 | 團結起來 非常厲害 給一死
53 | 
54 | 第 3 段
55 | 
56 | Do you hear the people sing? Singing a song of angry men.
57 | 你哪是整天怨嘆這 完全是浪費沒採工
58 | 
59 | It is the music of a people who will not be slaves again!
60 | 嘎阮做陣來參加網路國家 麥格浪費時間
61 | 
62 | When the beating of your heart echoes the beating of the drums
63 | 咱用投票定憲法 咱用網路團結起來
64 | 
65 | There is a life about to start when tomorrow comes!
66 | 只要你動動手指 他就未甲你害
67 | 
68 | 第 4 段
69 | 
70 | Will you give all you can give so that our banner may advance
71 | 你一定會想貢 這是瘋子 才會這麼做
72 | 
73 | Some will fall and some will live will you stand up and take your chance?
74 | 網路甘有可能 會凍改變 政治的問題
75 | 
76 | The blood of the martyrs will water the meadows of France!
77 | 不願相信 只好給他 繼續害
78 | 
79 | 第 5 段
80 | 
81 | Do you hear the people sing? Singing a song of angry men.
82 | 你咁有聽著阮唱歌 唱出得未來的希望
83 | 
84 | It is the music of a people who will not be slaves again!
85 | 你若是相信 就來甲阮做陣建立網路國家
86 | 
87 | When the beating of your heart echoes the beating of the drums
88 | 咱ㄟ心頭抓得定 最夥來建立新國家
89 | 
90 | There is a life about to start when tomorrow comes!
91 | 為這咱下一代 來創造出好將來
92 |

【本文歌曲來自悲慘世界歌劇,作詞與編輯者為陳鍾誠】

93 |
94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /htm/video1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 | 21 |

看影片瞭解「鍵盤革命」的「資訊政治學」

22 |

現在、讓我們透過影片來看看,台灣與國際上對鍵盤革命的一些看法與想法,以便讓大家能夠進一步的思考:「資訊技術對政治領域,會產生甚麼樣的影響呢」?

23 |

國際上的鍵盤革命

24 | 46 |

台灣的鍵盤革命

47 | 65 |

參考文獻

66 | 69 |

【本文由陳鍾誠撰寫】

70 |
71 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /htm/message3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 | 21 |

資訊政治:g0v 政府零時差組織

22 |

高嘉良所發起的 g0v 組織,是一個企圖用程式改變政治的組織,有興趣的人可以參考一下他們的網站。

23 | 26 |

g0v 做了很多有趣的「政治性」程式,以下是 g0v 的專案列表:

27 | 30 |

您可以看到其中有琳瑯滿目的專案,大部分是與資訊揭露有關的,像是:

31 | 43 |

最近我與 g0v 創辦人高嘉良連絡時,發現他們正在關注「柏林海盜黨」所釋出的一個實驗性開放原始碼軟體 liquidfeedback,網址如下:

44 | 47 |

而且他們正在進行一個工作,就是將 liquidfeedback 修改為中文版,並且嘗試用這種方式改變台灣的政治環境,您可以從 github 上下載這個專案。

48 | 51 |

當然、並不是只有 g0v 在進行「用程式改造社會」的活動,另外像 Code for Tomorrow 也是一個具有類似想法的台灣程式團體。

52 | 55 |

而在美國也有像 Code for America 這樣的組織,企圖用程式讓美國社會變得更好。

56 | 59 |

筆者覺得、如果真的能用「程式讓世界變得更美好」,那真的是一件非常有意義的事情啊!希望 g0v 能夠有更多好的想法, 並發展出更多改善社會的程式,讓我們的社會能夠變得更美好啊!

60 |

【本文由陳鍾誠取材撰寫】

61 |
62 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /htm/message2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |
17 | 20 |
21 |

資訊政治:海盜黨簡介

22 |

海盜黨是近年來在政治領域上異軍突起的一個政治團體,而德國海盜黨則是各國海盜黨當中發展得最好的一個,以下是海盜黨的一些相關資料,請讀者參考:

23 | 29 |

第一個海盜黨是由 李卡德·法克明炎於2006年1月1日成立於瑞典的組織,稱為 Piratpartiet。該組織認為現時的版權制度已經過時,危害到人們傳播知識的權力。 2006年海盜黨成為了瑞典無議會席位政黨之中最大的一個,後來奧地利、丹麥、芬蘭、德國、愛爾蘭、荷蘭、波蘭和西班牙也先後成立了海盜黨。

30 |

海盜黨的主張主要有三個:一是改革版權法,二是廢除專利,三是尊重私隱。他們認為現在的版權制度已經過時,很多企業利用版權限制知識發放, 侷限了很多創造性工作。所以於網路上分享電影、音樂等等行為不應該被視為違法。

31 |

2009年 4月 17 日,4名 海盜灣經營者被瑞典法庭判處 1 年有期徒刑之後,盜版黨黨員人數暴增到 2萬8千多人,躍身為瑞典第三大黨,並於2009年歐洲議會 選舉中在瑞典獲得了 7.1% 的選票,在歐洲議會中將擁有1個席位。

32 |

2011 年,德國海盜黨針對柏林州議會選舉推出 15 位候選人,全上。其後幾次其他的州議會選舉,德國海盜黨也獲得 7-8% 的得票率,取得席次。

33 |

海盜黨的一些網路民主的實施方法可以參考以下的文章:

34 | 37 |

我們將上述文章的重點摘要如下:

38 |
    39 |
  • 海盜黨的多數的決策都是先在網路上經過許多人的討論,例如用 PiratePad、聊天室、wiki 和郵件論壇來協作。
  • 40 |
  • 投票時,每人一票。但是,因為並非大家都能夠詳閱政策內容,所以系統允許成員可以委託他人代為投票。委託範圍可以是所有提案、某個主題的提案、或是某特定提案。而被委派投票的成員,還可以把這些票、包括自己的一票,再度委託給他人投票!
  • 41 |
  • Liquid Feedback 這種以信任為基礎的模式,類似信譽系統(reputation system),只不過成員的參與所換到的不是點數,而是選票。理論上,這種投票鏈可能會把票集中到人緣好的菁英或獨裁者身上,但好在有個防錯機制,可以在任何時候取消委託投票,有野心的海盜也得認真才能成事。Bormuth 說,我們讓有戰鬥力的人可以成事,但也讓大家有權控制這些人。
  • 42 |
43 |

雖然海盜黨在很多國家都成立了,但是在台灣卻被政府禁止成立,請參考以下新聞。

44 | 47 |

不過還是有人在網路上成立了這樣的社團,像是 Google Plus 上就有下列社團:

48 | 51 |

結語

52 |

雖然德國的國情與台灣不同,不過在網路時代,各國的做法都可以很透明的被大家所參考模仿,然後經過嘗試後找到一個比較適合自己國家的實施方式, 運用網路來改變政治結構啊!

53 |

【本文由陳鍾誠取材並修改自維基百科】

54 |
55 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /code/oc/as.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); // 引用檔案函式庫 2 | var c = require("./ccc"); // 引用基本函式庫 ccc.js 3 | var Memory = require("./memory"); // 引用記憶體物件 memory.js 4 | 5 | var as = function(opTable) { // 抽象組譯器物件 6 | this.opTable = opTable; // 取得指令表 opTable 7 | 8 | this.assemble = function(asmFile, objFile) { // 組譯器的主要函數 9 | this.lines = []; this.codes = []; // 設定程式碼行 (lines),指令陣列 (codes) 10 | this.symTable = {}; // 建立空的符號表 (symTable) 11 | c.log("Assembler:asmFile=%s objFile=%s", asmFile, objFile); // 輸入組合語言、輸出目的檔 12 | c.log("===============Assemble============="); 13 | var text = fs.readFileSync(asmFile, "utf8"); // 讀取檔案到 text 字串中 14 | this.lines = text.split(/[\r\n]+/); // 將組合語言分割成一行一行 15 | c.log(this.lines); // 印出組合語言以便觀察 16 | this.pass1(); // 第一階段:計算位址 17 | c.log("===============SYMBOL TABLE========="); 18 | for (s in this.symTable) { // 印出符號表以便觀察 19 | c.log("%s %s", c.fill(' ',s,8), c.hex(this.symTable[s].address, 4)); 20 | } 21 | this.pass2(); // 第二階段:建構目的碼 22 | this.saveObjFile(objFile); // 輸出目的檔 23 | } 24 | 25 | this.pass1 = function() { // 第一階段的組譯 26 | var address = 0; // 程式計數器 PC 的起始位址為 0 27 | c.log("=================PASS1================"); 28 | for (var i in this.lines) { // 對於每一行 29 | try { 30 | var code = this.parse(this.lines[i]); // 剖析並建立 code 物件 31 | code.address = address; // 設定該行的位址 32 | if (code.label.length != 0) { // 如果有標記符號 33 | this.symTable[code.label] = code; // 加入符號表中 34 | } 35 | this.codes.push(code); // 將剖析完成的指令放入陣列中 36 | c.log("%s", code); // 印出指令物件 37 | address += this.size(code); // 計算下一個指令位址 38 | } catch (err) { // 語法有錯,印出錯誤的行號與內容 39 | c.error(c.format("line %d : %s", i, this.lines[i]), err); 40 | } 41 | } 42 | } 43 | 44 | this.pass2 = function(codes) { // 組譯器的第二階段 45 | c.log("=============PASS2=============="); 46 | for (var i in this.codes) { // 對每一個指令 47 | try { 48 | this.translate(this.codes[i]); // 將組合語言指令翻譯成機器碼 49 | c.log("%s", this.codes[i]); // 印出指令物件 (含組合語言與機器碼) 50 | } catch (err) { // 語法有錯,印出錯誤的行號與內容 51 | c.error(c.format("line %d : %s", i, this.lines[i]), err); 52 | } 53 | } 54 | } 55 | 56 | this.saveObjFile = function(objFile) { // 儲存目的檔 57 | c.log("=================SAVE OBJ FILE================"); 58 | var obj = ""; // obj 為目的檔的 16 進位字串,初始化為空字串 59 | for (var i in this.codes) // 對於每個指令 60 | obj += this.codes[i].obj; // 都將目的碼加入 obj 字串中。 61 | var m = new Memory(1); // Memory 物件,用來將 16 進位目的碼轉為 2 進位儲存。 62 | m.loadhex(obj); // 將 16 進位目的碼載入記憶體 63 | m.dump(); // 輸出記憶體內容 64 | m.save(objFile); // 將記憶體內容除存到目的檔 objFile 中。 65 | } 66 | 67 | this.size = function(code) { // 計算指令所佔空間大小,在 pass1() 當中會呼叫此函數 68 | var len = 0, unitSize = 1; // len: 指令大小 , unitSize:每單位大小 (BYTE=1, WORD=4) 69 | switch (code.op.name) { // 根據運算碼 op 70 | case "RESW" : return 4 * parseInt(code.args[0]); // 如果是 RESW, 大小為 4*保留量(參數 0) 71 | case "RESB" : return 1 * parseInt(code.args[0]); // 如果是 RESB, 大小為 1*保留量(參數 0) 72 | case "WORD" : unitSize = 4; // 沒有 break,繼續執行到 BYTE 部分的程式 (共用) 73 | case "BYTE" : // 如果是BYTE, 大小是 1*參數個數 74 | for (i in code.args) { // 對於 BYTE 或 WORD 中的每個元素 75 | if (code.args[i].match(/^\".*?\"$/)) // 如果是字串,像 "Hello!" 76 | len += (code.args[i].length - 2) * unitSize; // 則大小為 unitSize*字串長度 77 | else // 否則 大小就是 unitSize (BYTE=1, WORD=4) 78 | len += unitSize; 79 | } 80 | return len; 81 | case "" : return 0; // 如果只是標記, 大小為 0 82 | default : return 4; // 其他情形 (指令), 大小為 4 83 | } 84 | } 85 | } 86 | 87 | module.exports = as; // 匯出「抽象組譯器物件 as 」 -------------------------------------------------------------------------------- /code/oc/jc1.js: -------------------------------------------------------------------------------- 1 | // STMTS = {} | STMT {; STMT_LIST}? 2 | // STMT = ASSIGN | FOR | WHILE | IF | return E; 3 | // ASSIGN = (ID[++|--]?)?(=E)? 4 | // E=T ([+|-|*|/|%|&|^|||&&||||>>|<<|==|<=|>=|<|>] F)? 5 | // T=STRING | INTEGER | FLOAT | '(' E ')' | ID ('('ARGS')')? 6 | // ARGS = {} | E {, ARGS}? 7 | 8 | require("./ccc"); 9 | 10 | var symTable = {}; 11 | 12 | var tempIdx = 0; 13 | var nextTemp=function() { return "T"+tempIdx++; } 14 | 15 | var stack = []; 16 | var push=function(o) { stack.push(o); } 17 | var pop=function() { return stack.pop(); } 18 | 19 | var tokens = []; 20 | var tokenIdx = 0; 21 | // 本來應該用 .*? 來比對 /*...*/ 註解的,但 javascript 的 . 並不包含 \n, 因此用 \s\S 代替 . 就可以了。 22 | var retok = /(\/\*[\s\S]*?\*\/)|(\/\/[^\r\n])|(\d+)|([a-zA-Z]\w*)|(\r?\n)|(.)/gm; // *?, +? non greedy, m for multiline 23 | 24 | var source = ""; 25 | var scan=function(text) { 26 | tokenIdx = 0; 27 | tokens = text.match(retok); 28 | return tokens; 29 | } 30 | 31 | var error=function(o) { printf("Error: %j\n", o); } 32 | var pcode = function(op, t, t1, t2) { printf("%s %s %s %s\n", op, t, t1, t2); } 33 | 34 | var next=function(o) { 35 | if (o==null || isNext(o)) 36 | return tokens[tokenIdx++]; 37 | error(token); 38 | } 39 | 40 | var isNext=function(o) { 41 | if (tokenIdx >= tokens.length) 42 | return false; 43 | var token = tokens[tokenIdx]; 44 | if (o instanceof RegExp) { 45 | return token.match(o); 46 | } else { 47 | return (token == o); 48 | } 49 | } 50 | 51 | var compile=function(text) { 52 | scan(text); 53 | printf("text=%s\n", text); 54 | printf("tokens=%j\n", tokens); 55 | E(); 56 | printf("symTable=%j\n", symTable); 57 | } 58 | 59 | // STMT_LIST = {} | STMT {; STMT_LIST}? 60 | var STMT_LIST=function() { 61 | STMT(); 62 | if (isNext(';')) STMTS_LIST(); 63 | return t1; 64 | } 65 | 66 | // STMT = FOR | WHILE | IF | return E | ASSIGN 67 | var STMT=function() { 68 | if (isNext("for")) { 69 | FOR(); 70 | } else if (isNext("while")) { 71 | WHILE(); 72 | } else if (isNext("if")) { 73 | IF(); 74 | } else if (isNext("return")) { 75 | next("return"); 76 | E(); 77 | } else { 78 | ASSIGN(); 79 | } 80 | } 81 | 82 | // ASSIGN = (ID[++|--]?)?(=E)? 83 | var ASSIGN=function() { 84 | var id="", op=""; 85 | if (isNextType("ID")) { 86 | id = next(null); 87 | if (isNext("++") || isNext("--")) 88 | op = next(null); 89 | } 90 | if (isNext("=")) { 91 | E(); 92 | } 93 | } 94 | 95 | // E=T ([+|-|*|/|%|&|^|||&&||||>>|<<|==|<=|>=|<|>] T)? 96 | var E=function() { 97 | var op = ""; 98 | t1 = T(); 99 | if (isNext(/([\+\-\*\/%&^|<>])|(&&)|(||)|(>>)|(<<)|(<=)|(>=)/)) 100 | op = next(null); 101 | t2 = T(); 102 | t = nextTemp(); 103 | pcode(op, t, t1, t2); 104 | } 105 | } 106 | 107 | // T=STRING | INTEGER | FLOAT | '(' E ')' | ID ('('ARGS')')? 108 | var T=function() { 109 | if (isNextType("STRING|INTEGER|FLOAT")) { 110 | return next(null); 111 | } else if (isNext("(")) { 112 | next("("); E(); next(")"); 113 | } else if (isNextType("ID")) { 114 | id=next(null); next("("); ARGS(); next(")"); 115 | pcode("call", nextTemp(), id, ""); 116 | } 117 | } 118 | 119 | printf("=== EBNF Grammar =====\n"); 120 | printf("E=T ([+-] T)*\n"); 121 | printf("T=F ([*/] F)*\n"); 122 | printf("F=NUMBER | ID | '(' E ')'\n"); 123 | compile("32+5*(182+degree*4-20)"); 124 | // printf("typeof(/\w+/)=%s /\w+/ instanceof RegExp=%s\n", typeof(/\w+/), /\w+/ instanceof RegExp); 125 | // printf("typeof(str)=%s\n", typeof("str")); 126 | 127 | -------------------------------------------------------------------------------- /code/oc/jexpc.js: -------------------------------------------------------------------------------- 1 | // STMTS = {} | STMT {; STMT_LIST}? 2 | // STMT = ASSIGN | FOR | WHILE | IF | return E; 3 | // ASSIGN = (ID[++|--]?)?(=E)? 4 | // E=T ([+|-|*|/|%|&|^|||&&||||>>|<<|==|<=|>=|<|>] F)? 5 | // T=STRING | INTEGER | FLOAT | '(' E ')' | ID ('('ARGS')')? 6 | // ARGS = {} | E {, ARGS}? 7 | 8 | var c = require("./ccc"); 9 | 10 | var symTable = {}; 11 | 12 | var tempIdx = 0; 13 | var nextTemp=function() { return "T"+tempIdx++; } 14 | 15 | var stack = []; 16 | var push=function(o) { stack.push(o); } 17 | var pop=function() { return stack.pop(); } 18 | 19 | var tokens = []; 20 | var tokenIdx = 0; 21 | // 本來應該用 .*? 來比對 /*...*/ 註解的,但 javascript 的 . 並不包含 \n, 因此用 \s\S 代替 . 就可以了。 22 | var retok = /(\/\*[\s\S]*?\*\/)|(\/\/[^\r\n])|(\d+)|([a-zA-Z]\w*)|(\r?\n)|(.)/gm; // *?, +? non greedy, m for multiline 23 | 24 | var source = ""; 25 | var scan=function(text) { 26 | tokenIdx = 0; 27 | tokens = text.match(retok); 28 | return tokens; 29 | } 30 | 31 | var error=function(o) { printf("Error: %j\n", o); } 32 | var pcode = function(op, t, t1, t2) { printf("%s %s %s %s\n", op, t, t1, t2); } 33 | 34 | var next=function(o) { 35 | if (o==null || isNext(o)) 36 | return tokens[tokenIdx++]; 37 | error(token); 38 | } 39 | 40 | var isNext=function(o) { 41 | if (tokenIdx >= tokens.length) 42 | return false; 43 | var token = tokens[tokenIdx]; 44 | if (o instanceof RegExp) { 45 | return token.match(o); 46 | } else { 47 | return (token == o); 48 | } 49 | } 50 | 51 | var compile=function(text) { 52 | scan(text); 53 | printf("text=%s\n", text); 54 | printf("tokens=%j\n", tokens); 55 | E(); 56 | printf("symTable=%j\n", symTable); 57 | } 58 | 59 | // STMT_LIST = {} | STMT {; STMT_LIST}? 60 | var STMT_LIST=function() { 61 | STMT(); 62 | if (isNext(';')) STMTS_LIST(); 63 | return t1; 64 | } 65 | 66 | // STMT = FOR | WHILE | IF | return E | ASSIGN 67 | var STMT=function() { 68 | if (isNext("for")) { 69 | FOR(); 70 | } else if (isNext("while")) { 71 | WHILE(); 72 | } else if (isNext("if")) { 73 | IF(); 74 | } else if (isNext("return")) { 75 | next("return"); 76 | E(); 77 | } else { 78 | ASSIGN(); 79 | } 80 | } 81 | 82 | // ASSIGN = (ID[++|--]?)?(=E)? 83 | var ASSIGN=function() { 84 | var id="", op=""; 85 | if (isNextType("ID")) { 86 | id = next(null); 87 | if (isNext("++") || isNext("--")) 88 | op = next(null); 89 | } 90 | if (isNext("=")) { 91 | E(); 92 | } 93 | } 94 | 95 | // E=T ([+|-|*|/|%|&|^|||&&||||>>|<<|==|<=|>=|<|>] T)? 96 | var E=function() { 97 | var op = ""; 98 | t1 = T(); 99 | if (isNext(/([\+\-\*\/%&^|<>])|(&&)|(||)|(>>)|(<<)|(<=)|(>=)/)) 100 | op = next(null); 101 | t2 = T(); 102 | t = nextTemp(); 103 | pcode(op, t, t1, t2); 104 | } 105 | } 106 | 107 | // T=STRING | INTEGER | FLOAT | '(' E ')' | ID ('('ARGS')')? 108 | var T=function() { 109 | if (isNextType("STRING|INTEGER|FLOAT")) { 110 | return next(null); 111 | } else if (isNext("(")) { 112 | next("("); E(); next(")"); 113 | } else if (isNextType("ID")) { 114 | id=next(null); next("("); ARGS(); next(")"); 115 | pcode("call", nextTemp(), id, ""); 116 | } 117 | } 118 | 119 | printf("=== EBNF Grammar =====\n"); 120 | printf("E=T ([+-] T)*\n"); 121 | printf("T=F ([*/] F)*\n"); 122 | printf("F=NUMBER | ID | '(' E ')'\n"); 123 | compile("32+5*(182+degree*4-20)"); 124 | // printf("typeof(/\w+/)=%s /\w+/ instanceof RegExp=%s\n", typeof(/\w+/), /\w+/ instanceof RegExp); 125 | // printf("typeof(str)=%s\n", typeof("str")); 126 | 127 | -------------------------------------------------------------------------------- /htm/message1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 | 21 |

資訊政治:台灣「鍵盤革命」的歷史與近況

22 |

前言

23 |

最近台灣的「程式人」很多都投入了政治運動,企圖用程式改變政治,因此今年的開源人年會 COSCUP 上也出現了好幾場的「政治相關」演講。

24 |

這個現象或許可以用「鍵盤革命」、「網路政治」、「程式政治學」等詞彙描述。

25 |

莫拉克風災

26 |

從 2009 年的莫拉克風災開始,台灣的程式人就開始運用專業發揮了不小的影響力,以下是當年的一則 PTT 報導:

27 | 30 |

莫拉克風災是我第一次看到「網友們」展現政治力量的事件,雖然這件事情很不政治,但是基於孫中山的名言:「管理眾人之事便是政治」, 我們看到當政府失能的時候,網友們透過網路進行救災,彌補掉政府的無能,讓資訊得以快速流通的的「政治事件」。

31 |

洪仲秋被虐死引發 25 萬人上凱達格蘭大道

32 |

然後,在 2013 年,我們看到了一次「重要的網路政治事件」,那就是最近因「洪仲秋被虐死一案」,透過 公民 1985 行動聯盟 這個網路組織的協調,引發了 2013/8/3 日 25 萬人上凱達格蘭大道包圍總統府,卻又盡可能排除政黨介入的情況下,仍然表現出高度的組織能力,以及保持了良好秩序的事件。

33 |

以下的空拍圖片為這個事件留下了一個重要的見證,這是「鍵盤革命」的重要里程碑,也是台灣「網路世代」開始參與政治運動的一個明證。

34 |
35 | 圖、photo by Jack0000

圖、photo by Jack0000

36 |
37 |
    38 |
  • 圖片來源:親愛的芭樂人類學家專欄, 25萬人上街抗議真的有用嗎?, 2013/08/05 公民運動 政治 洪仲丘 社會運動 39 |
  • 42 |
43 |

結語

44 |

雖然政治令人覺得很黑暗,也讓很多人討厭,但是如果透過「程式專業」與「網路社群」,有機會能讓這個世界變得更好的話, 我相信還是有許多程式人願意付出時間來讓世界變得更美好的!

45 |

參考文獻

46 | 52 |

【本文由陳鍾誠取材並修改自維基百科,原本寫得很長,但是後來決定簡化,若您想看那個長的版本,我們也有留著,請點選 這裏

53 |
54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /source/discuss1long.md: -------------------------------------------------------------------------------- 1 | ## 網路與政治:網友們可以形成一個「虛擬國家」嗎? 2 | 3 | 受到 2013/8/3 時 25 萬人上凱達格蘭大道這件事的激勵,讓我想到能否號召網友們,形成一個沒有實體領土,只有虛擬領土的「網路國家」呢? 4 | 5 | 透過這個國家,我們可以制定法律、提出政策、甚至發動資訊戰。 6 | 7 | 然後這些網民仍然是某些實體國家(例如台灣)的國民,因此仍然具有該國的投票權,所以就可以透過「網路公投」決定政策後, 8 | 要求政黨或立委認養這些政策並簽下契約,以換取將這些網民的票投給他們的「交易」。 9 | 10 | 我認為這種方式讓網民可以有效的影響政府,並且跨過「公投法門檻過高」的問題。 11 | 12 | 於是我發了以下的訊息在「程式人雜誌的討論區」以及自己的 facebook 上: 13 | 14 | 問題:我想我又瘋了,今年初我辦了一本新的雜誌,現在居然想成立一個新的國家 ([「網路公民國」](https://www.facebook.com/groups/netcountry/) ) 15 | 16 | 原始討論網址: 17 | 18 | 回應訊息: 19 | 20 | * P○○ 陳老師,此處所謂之「國家」是指「真的國家」還是某個「網路社群」? 21 | * 陳○○ 所謂的國家構成是 公民 主權 領土 能有支持者,在網路的領土上,就具備有一定的影響力,如果這樣說來,創造所謂"跨形式國界"的國家,也不是不可能的。 22 | * 陳鍾誠 23 | * 其實目前沒有一定的定義,這個慨念是流動發展中的。我想用「虛擬國家」這個詞彙,或許比較能抓到這類的國家概念, 24 | * 不是只有一個社團,而且有「憲法、虛擬領土、主權」、也可以宣戰,媾和。 25 | * E○○ 關於宣戰....網路戰爭,也是一種戰爭。例如:廣大興號事件和菲律賓之間的鍵盤戰爭。 26 | * P○○ 陳○○,抱歉,法律不是我的專業,我也不是要潑冷水,而是真的真的很有興趣想瞭解,所以向您請教一下。 27 | * 如果某國「公民 (網路鄉民)」的實體生命需靠其他國家 (如中華民國) 提供保障;「主權」需靠網路業者提供等價服務;「領土」則存在於電子訊號充斥的網路空間及各式儲存設備中,那麼… 28 | * 1. 外敵侵犯該國公民實體生命時,該國的對策是? 29 | * 2. 網路服務斷線時,維護主權的對策是? 30 | * 3. 停電斷訊或是儲存資料遺失時,該國的領土位置是? 31 | * 又,如果真的要「脫離母國,自立門戶」,那麼該國公民在離線 (等同出國) 的時候,是否應依法向中華民國申請簽証才能把網路設備關掉呢?且若是中華民國不發簽証的話,那麼離線和偷渡的差異是? 32 | * 陳鍾誠 我在想,由於全球化的時代來臨,即使一個國家封鎖網路,也不可能全世界的網路都封起來,所以虛擬國仍然可以活著。 33 | * 陳鍾誠 34 | * 1. 外敵侵犯該國公民實體生命時,該國的對策是? 35 | * 當網民遭受不合理對待時,網路公民國可以禁止該國存取「網路公民國」的一切線上資源,作為報復! 36 | * 陳○○ 37 | * 恩,很多看似目前沒有的東西,不見得以後不會存在。 38 | * 不過對這個,所謂的外敵應該是會侵害這種公民權利存在的外力,類似言論自由限制、限制ip等等方式。 最近台灣就做了類似這種事情。 39 | * 40 | * 我是覺得所謂的公民,應該是要贊同一定理念的人,拋開ㄧ些國籍問題,能夠真正的就事論事,追求自己相信的理念比較重要。 41 | * 你說的那類申請國籍等等的問題,沉默的艦隊裡面是全部拋開了。在這邊應該是偏向於著作的討論吧,就是對於真理和學術價值的追求吧。在討論這些的時候,單純點也是好的。(雖然說大學自治,不受國家權力限制本身就是這個涵意) 42 | * 所以說,能夠跨國界的想法很好,能把不同國籍、領域、價值的人都納入溝通和了解。 43 | * 對於追尋真理和捍衛這份價值,會是最大的貢獻吧。 44 | * 45 | * 陳鍾誠 46 | * 2. 網路服務斷線時,維護主權的對策是? 47 | * 至少在兩個以上國家的雲端分站,因此斷線應該也不是問題。 48 | * 陳鍾誠 49 | * 3. 停電斷訊或是儲存資料遺失時,該國的領土位置是? 50 | * 兩個以上的備援,因此認一個停電資料都不會遺失,甚至會放在 Amazon EC2 或 Google 服務上,或者 Github 等,因此這個國家根本不需要固定的領土。 51 | * 陳鍾誠 有朋友說這樣報復有點邪惡 .... 52 | * 我用這的例子想說明的是,網路虛擬國家仍然是有能力與真實國家對抗的,但並不見得要這樣做。 53 | * 網路國家運作的方法,應該還是會取決於類似公民投票的方式,即使要宣戰,也必須要網路公民投票啊! 54 | * F○○ 也許可以找到志同道合的人 55 | * S○○ 沉默的艦隊… 56 | * 黃○○ 你超和平 ok的 57 | * E○○ P○○ 1. 外敵侵犯該國公民實體生命時,該國的對策是? 58 | * 或許可以參考這個: 59 | * P○○ 60 | * E○○ 假設某 A 為網路公民國之公民。他在離線 (出國) 並偷渡到中華民國某市某街巷口的便利商店利用中華民國的貨幣購買午餐時被歹徒殺害。依您的建議,某 A 之親屬朋友向美國白宮發起連署。 61 | * 上述的情境中,哪一個部份是「網路公民國」對其公民提供的保障?又,假設中華民國的確向網路公民國交出行兇的人犯,網路公民國將如何處置?剝奪該人終生上網的權利? 62 | * E○○ P○○ 如果可以改你的問題: 63 | * 我會改成「網路」向「政府」要求交出人犯並處置。(就像這次1985聯盟一樣) 網路可以是社群、團體、聯盟、組織....也許未來可以叫國家、地球聯邦、星際聯邦、宇宙XX什麼的.....只是名字的差別。 64 | * 或許有人會支持「英雄聯盟」也不一定...開玩笑,幽默一下...虛擬的背後有實體,雖然虛擬不能完全取代實體,比如開心農場的拔回來的菜是不能吃的,SF(特種部隊)中彈之後人也不會死.....虛擬世界可以輔助真實世界,比如網路戀愛,最後結婚。又如網路可以人肉,但是最後還是要靠實體的警察來抓人。善用網路讓世界更美好,至於怎麼用?就要靠大家了.... 65 | * A○○ 黃仁宇《中國大歷史》 有意思。我以前也讀過一本中國通史, 也是感觸良多。找時間讀讀。 66 | * 陳鍾誠 可否請大家幫忙分享我這篇文章呢? 67 | * 陳鍾誠 非常建議看黃仁宇的「資本主義與 21 世紀」。 68 | * A○○ 這主意有“三把火”的感覺。當初那些魯蛇都是非自願也非計劃的做出那些行為,是被迫的邊移動邊開火。但其成果確演化演變成偉大的事件。與現況相比個人認為有差距。 69 | * P○○ 70 | * 陳老師您好,不知能否在您的版面回應,如果老師覺得不對,不好,不妥,請和我說,我一定刪除並加道歉。我期待大國民、小政府的時代來臨。 71 | * 在那之前,我不認為「因為我們的政府或是制度很糟,而我們的鄉民很有力量,所以我們乾脆像五月花的先輩一樣脫離母國,而去建立一個不只是社群,而是國家為名的組織,有『憲法、虛擬領土、主權」、也可以宣戰,媾和!』」是一個好的解決方法。 72 | * 自己的 bug 自己解,自己的國家自己救。 73 | * 真抱歉,我知道講這些一定很礙眼。誠心地說聲 SORRy。 74 | * 陳鍾誠 非常歡迎 P○○ ,我已經將您加為好友,也可以私訊給我! 75 | * T○○ 分裂國土, 如果是實際的領土或領海的話, 會觸犯刑法的,但是如果只是喊爽用的網路上的虛擬國度,如果不涉及實際的領土或領海, 應該是無罪的 76 | -------------------------------------------------------------------------------- /code/oc/cc1.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | require("./ccc"); 3 | var cpu = require("./cpu1"); 4 | var Memory = require("./memory"); 5 | var cpu1 = new cpu(); 6 | var R = cpu1.R; 7 | 8 | var bits = function(word, from, to) { return word << (31-to) >>> (31-to+from); } // 取得 from 到 to 之間的位元 9 | var signbits = function(word, from, to) { return word << (31-to) >> (31-to+from); } // 取得 from 到 to 之間的位元 10 | var ID = function(op) { 11 | // printf("op=%s\n", op); 12 | return cpu1.opTable[op].id; 13 | } 14 | 15 | var vm = function() { 16 | this.memory = new Memory(1); 17 | 18 | this.run = function(objFile) { 19 | m = this.memory; 20 | m.load(objFile); 21 | IR = 16; 22 | PC = 15; 23 | LR = 14; 24 | SP = 13; 25 | SW = 12; 26 | stop = false; 27 | printf("run\n"); 28 | while (!stop) { // 如果尚未結束 29 | tpc = R[PC]; 30 | R[0] = 0; // R[0] 永遠為 0 31 | R[IR] = m.geti(R[PC]); // 指令擷取,IR=[PC..PC+3] 32 | R[PC] += 4; // 擷取完將 PC 加 4,指向下一個指令 33 | op = bits(R[IR], 24, 31); // 取得 op 欄位,IR[24..31] 34 | ra = bits(R[IR], 20, 23); // 取得 ra 欄位,IR[20..23] 35 | rb = bits(R[IR], 16, 19); // 取得 rb 欄位,IR[16..19] 36 | c16= signbits(R[IR], 0, 15); // 取得 16 位元的 cx 37 | c5 = bits(R[IR], 0, 4); 38 | addr = R[rb]+c16; 39 | // printf("IR=%s op=%s ra=%s rb=%s c16=%s N=%d Z=%d\n", hex(R[IR],8), hex(op,2), hex(ra,1), hex(rb,1), hex(c16,4), N, Z); 40 | // printf("addr=%s\n", hex(R[rb]+c16, 4)); 41 | 42 | switch (op) { // 根據op執行動作 43 | case ID("LD") : R[ra] = m.geti(addr); break; // 處理 LD 指令 44 | case ID("ST") : m.seti(addr, R[ra]); printf("m[%s]=%s\n", hex(addr,4), m.geti(addr)); break; // 處理 ST 指令 45 | case ID("LDB"): R[ra] = m.getb(addr); break; // 處理 LDB 指令 46 | case ID("STB"): m.setb(addr, R[ra]); break; // 處理 STB 指令 47 | case ID("ADDI"):R[ra] = R[rb] + c16; break; // 處理 ADDI 指令 48 | case ID("ADD"): R[ra] += m.geti(addr); break; // 處理ADD指令 49 | case ID("SUB"): R[ra] -= m.geti(addr); break; // 處理SUB指令 50 | case ID("MUL"): R[ra] *= m.geti(addr); break; // 處理MUL指令 51 | case ID("DIV"): R[ra] /= m.geti(addr); break; // 處理DIV指令 52 | case ID("AND"): R[ra] &= m.geti(addr); break; // 處理AND指令 53 | case ID("OR") : R[ra] |= m.geti(addr); ; break; // 處理OR指令 54 | case ID("XOR"): R[ra] ^= m.geti(addr); ; break; // 處理XOR指令 55 | // case ID("ROL"): R[ra] = ROL(R[rb],c5); break; // 處理ROL指令 56 | // case ID("ROR"): R[ra] = ROR(R[rb],c5); break; // 處理ROR指令 57 | case ID("SHL"): R[ra] = R[rb]<>c5; break; // 處理SHR指令 59 | case ID("JZ") : if (R[ra]==0) R[PC] = R[rb]+c16; break; // 處理JZ指令 60 | case ID("PUSH"):R[SP]-=4; R[ra]=m.geti(addr); m.seti(R[SP], R[ra]); break; // 處理PUSH指令 61 | case ID("POP"): R[ra] = m.geti(R[SP]); R[SP]+=4; break; // 處理POP指令 62 | case ID("PUSHB"):R[SP]--; R[ra]=m.getb(addr); m.setb(R[SP], R[ra]); break; // 處理PUSH指令 63 | case ID("POPB"):R[ra] = m.getb(R[SP]); R[SP]++; break; // 處理POPB指令 64 | case ID("RET"): stop=true; R[PC]=R[LR]; break; // 處理RET指令 65 | // default: printf("Error:invalid op (%s)\n", hex(op)); 66 | } // switch 67 | printf("PC=%s IR=%s SW=%s R[%s]=0x%s=%d\n", // 印出 PC, IR, R[ra]暫存器的值,以利觀察 68 | hex(tpc,4), hex(R[IR],8), hex(R[SW],8), hex(ra,2), hex(R[ra], 8), R[ra]); 69 | } // while 70 | } 71 | } 72 | 73 | // #define ROR(i, k) (((UINT32)i>>k)|(bits(i,32-k, 31)<<(32-k)))// 向右旋轉k位元 74 | // #define ROL(i, k) (((UINT32)i< 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 | 21 |

網路與政治:網友們可以形成一個「虛擬國家」嗎?

22 |

受到 2013/8/3 時 25 萬人上凱達格蘭大道這件事的激勵,讓我想到能否號召網友們,形成一個沒有實體領土,只有虛擬領土的「網路國家」呢?

23 |

透過這個國家,我們可以制定法律、提出政策、甚至發動資訊戰。

24 |

而且、這些網民仍然是某些實體國家(例如台灣)的國民,因此仍然具有該國的投票權,所以就可以透過「網路公投」決定政策後, 要求政黨或立委認養這些政策並簽下契約,以換取將這些網民的票投給他們的「交易」。

25 |

我認為這種方式或許能讓網民可以有效的影響政府,並且跨過「公投法門檻過高」的問題。

26 |

於是我發了以下的訊息在「程式人雜誌的討論區」以及自己的 facebook 上,並引發了一些討論:

27 | 33 |

我之所以會認為應該用「虛擬國家」的概念,而非採用像「海盜黨」這樣的「黨」的慨念,或許原因之一是「黨」這個中文字 其實隱含了非常糟糕的負面意義,但是在英文中的 Party 卻沒有這種意思。

34 |

還有一個原因是,我想法中的這種網路組織,其實更像是一個國家,因為這個組織可以擁有「人民、土地、政府、主權」這四種形成國家的要素,只不過其領土 乃是在網路上的虛擬領土,而非真實世界的領土而已,有興趣的讀者可以參考以下兩篇文章。

35 | 39 |

那麼、虛擬國家的憲法應該是什麼樣的呢?以下是一個我構思中的範例:

40 |
    41 |
  1. 任何人都可以經由明文宣誓的方式,成為網路公民國 (以下簡稱本國) 的公民 (以下簡稱網民)。
  2. 42 |
  3. 網民除了本國之外,還可以自由參加任何組織或實體國家,本國並無任何禁止「雙重國籍」的規定。
  4. 43 |
  5. 網民有上網之自由,任何組礙或限制網民上網的行為,都違反本憲法之精神。
  6. 44 |
  7. 網民有集會結社之基本權利,任何損害此一權利的組織,都將視為本國之敵人,本國有封鎖該組織的權利。
  8. 45 |
  9. 網民的任何作品,只要不附加「著作權宣告」,就被預設視為「公共領域」之作品,任何網民都擁有合法修改、複製、散布之權利。
  10. 46 |
  11. 網民可以下載任何未被身分認證機制所保護的內容,而不被控以侵犯著作權之自由。 ....
  12. 47 |
48 |

這樣的法律其實意在保障網民們的自由,並且同時尊重創作者的權力,但是將著作權的預設值反轉過來,從 CopyRight 「版權所有」的 All Rights Reserved 轉化為「版權所無」的 No Rights Reserved 的情況,這讓網路自由可以得到法律基礎。

49 |

這種手法與 GNU 的 GPL 有些不同,GPL 是透過法律來挑戰法律,但「網路虛擬國家」則直接透過「建國」與「制憲」挑戰傳統的政治結構。

50 |

「虛擬國家」或許不會擁有土地,但是卻擁有「網路空間上的領土」,可以透過「封鎖」、「不提供資訊」與實體國家進行對抗,網民們 也有可能透過像「鍵盤戰」的方式,進行某種形式的「虛擬戰爭」。

51 |

更重要的是,「虛擬國家」沒有禁止「雙重國籍」的規定,網民們在實體世界的國家裏,還是有投票權的。因此、「虛擬國家」可以透過 「公投」制定政策,試圖影響某個實體國家的政策,讓這些國家的政治可以更好。

52 |

舉例而言,如果台灣的「網民」們聯合起來,形成一個「虛擬國家」,例如叫做「網路公民國」(簡稱網國),就可以先在網路上制定政策 並且透過「公投」表決,決定建議國民將選票投給「認養」這個政策的「立委」或「政黨」,然後告訴「國民黨」與「民進黨」這個遊戲規則, 用「虛擬國家」的政策影響甚至左右「實體國家」的政策。

53 |

於是、這個虛擬國家成了一個「國中之國」,而且可以發揮強大的政治影響力,這就是我對「虛擬國家」運作方式的初步想法。

54 |

後記:我們甚至連國歌都寫好了,直接採用悲慘世界的革命之歌,配上自己填的歌詞,有興趣的朋友可以點選下列網址。

55 | 58 |

不過可惜的是,由於這個理想尚未得到真實國家的認同,筆者怕因為將自己唱國歌的錄音上網而被告,所以現在這首國歌只能私下唱, 因為這首歌的商業權還在華納公司的手上啊!請參考下列文章。

59 | 62 |

這也正是我們為何在上述憲法中要加入那些 CopyLeft 版權條款的原因啊!

63 |

當然、您也可以直接宣誓加入這個虛擬國家,只要在 facebook 上按一下加入就行了。

64 | 67 |

【本文由陳鍾誠撰寫】

68 |
69 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /code/oc/jc1parser.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | require("./ccc"); 3 | 4 | var tokens = []; 5 | var tokenIdx = 0; 6 | 7 | var scan=function(text) { 8 | var re = new RegExp(/(\/\*[\s\S]*?\*\/)|(\/\/[^\r\n])|(".*?")|(\d+(\.\d*)?)|([a-zA-Z]\w*)|([>== tokens.length) 40 | return false; 41 | var token = tokens[tokenIdx].token; 42 | if (o instanceof RegExp) { 43 | return token.match(o); 44 | } else { 45 | return (token == o); 46 | } 47 | } 48 | 49 | var isNextType=function(pattern) { 50 | var type = tokens[tokenIdx].type; 51 | return (("|"+pattern+"|").indexOf("|"+type+"|")>=0); 52 | } 53 | 54 | var compile=function(text) { 55 | printf("text=%s\n", text); 56 | scan(text); 57 | printf("tokens=%j\n", tokens); 58 | STMT_LIST(); 59 | } 60 | 61 | // BLOCK = { STMT_LIST } 62 | var BLOCK=function() { 63 | next("{"); STMT_LIST(); next("}"); 64 | } 65 | 66 | // STMT_LIST = {} | STMT {; STMT_LIST}? 67 | var STMT_LIST=function() { 68 | STMT(); 69 | if (isNext(';')) { next(';'); STMT_LIST(); } 70 | } 71 | 72 | // STMT = FOR | WHILE | IF | return E | ASSIGN 73 | var STMT=function() { 74 | if (isNext("for")) { 75 | FOR(); 76 | } else if (isNext("while")) { 77 | WHILE(); 78 | } else if (isNext("if")) { 79 | IF(); 80 | } else if (isNext("return")) { 81 | next("return"); 82 | E(); 83 | } else { 84 | ASSIGN(); 85 | } 86 | } 87 | 88 | // FOR = for (STMT; E; STMT) BLOCK 89 | var FOR=function() { 90 | next("for"); next("("); STMT(); next(";"); E(); next(";"); STMT(); next(")"); BLOCK(); 91 | } 92 | 93 | // WHILE = while (E) BLOCK 94 | var WHILE=function() { 95 | next("while"); next("("); E(); next(")"); BLOCK(); 96 | } 97 | 98 | // IF = if (E) BLOCK (else if (E) BLOCK)* (else BLOCK)? 99 | var IF=function() { 100 | next("if"); next("("); E(); next(")"); BLOCK(); 101 | while (isNext("else")) { 102 | next("else"); 103 | if (isNext("if")) { 104 | next("if"); next("("); E(); next(")"); BLOCK(); 105 | } else { 106 | BLOCK(); 107 | } 108 | } 109 | } 110 | 111 | // ASSIGN = (ID[++|--]?)?(=E)? 112 | var ASSIGN=function() { 113 | var id="", op=""; 114 | if (isNextType("id")) { 115 | id = next(null); 116 | if (isNext("++") || isNext("--")) 117 | op = next(null); 118 | } 119 | if (isNext("=")) { 120 | next("="); 121 | E(); 122 | } 123 | } 124 | 125 | // E=T ([+|-|*|/|%|&|^|||&&||||>>|<<|==|<=|>=|<|>] T)? 126 | var E=function() { 127 | t1 = T(); 128 | if (isNextType("op2")) { 129 | var op = next(null); 130 | T(); 131 | } 132 | } 133 | 134 | // T=STRING | INTEGER | FLOAT | ( E ) | FUNCTION | ID (ARGS)? 135 | var T=function() { 136 | if (isNextType("string|integer|float")) { 137 | return next(null); 138 | } else if (isNext("(")) { 139 | next("("); E(); next(")"); 140 | } else if (isNext("function")) { 141 | FUNCTION(); 142 | } else if (isNextType("id")) { 143 | id=next(null); 144 | if (isNext("(")) { next("("); ARGS(); next(")"); } 145 | } else error(); 146 | } 147 | 148 | // FUNCTION = function(ARGS) BLOCK 149 | var FUNCTION = function() { 150 | next("function"); next("("); ARGS(); next(")"); BLOCK(); 151 | } 152 | 153 | var source = fs.readFileSync("test.j1", "utf8"); 154 | compile(source); 155 | -------------------------------------------------------------------------------- /htm/people1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 | 21 |

資訊政治人:Stallman, Lessig, Swartz 與 Assange

22 |

看到上述的人名,很多讀者勢必心中會產生一大堆問號?他們是誰?這些人之間有甚麼關連呢?

23 |

程式人雜誌曾經介紹過這四位當中的兩位,也就是 Stallman 與 Swartz,甚至也曾經談到過 Lessig , 但是還沒有介紹過 Assange,讓我們稍微介紹一下這些人的重要事蹟。

24 | 30 |

筆者之所以將這些人寫在一起,原因在於這些人是「鍵盤革命」這一個概念當中的重要人物,他們都利用「電腦、程式、網路」等工具,與當權者進行對抗。

31 |

Stallman 因為不滿程式碼被商業公司封閉起來,而創造了 GNU 組織與 GPL 這個開放原始碼的程式授權,以便強制商業公司開放原始碼。 Lessig 延續 Stallman 的想法,將開放原始碼的概念引入一般著作與網頁,創造出了 Creative Commons 授權。而 Swartz 則為了讓資訊的流通更容易, 創造出 Markdown 格式與 RSS 訂閱技術,並且因為想把學術論文開放而遭到起訴,最後更因此而自殺。

32 |

至於 Assange,則因為將那些政府機密大量上網,成為各國政府的頭號公敵,並因「性犯罪」的罪名而被瑞典通輯,因此後來向厄瓜多駐倫敦大使館尋求政治庇護,目前英國還企圖與「厄瓜多」談判將 Assange 引渡到瑞典受審當中。

33 |

以上這些人與事件,都涉及到「資訊揭露」的政治學,有些人用合法的方式企圖揭露資訊 (像是 Stallman, Lessig),而有些人則用目前法律不允許的手段去揭露資訊 (像是 Swartz 與 Assange)。

34 |

18 世紀工業革命 (第二波) 的結果,造成工業取代農業,因此政治上從封建莊園制度轉向了議會政治,權力的核心從封建領主轉向了資本家。

35 |

在今日 21 世紀的資訊革命 (第三波) 當中,權力又將如何移轉,這個世界會如何變化呢?

36 |

未來、網路與資訊科技會帶領我們建立怎麼樣的一個「政治結構」呢?這是筆者很想知道,但卻也還在探索當中的一個重要關注項目啊!

37 |

參考文獻

38 | 50 |

【本文由陳鍾誠取材並修改自維基百科,原本寫得很長,但是後來決定簡化,若您想看那個長的版本,我們也有留著,請點選 這裏

51 |
52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /htm/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |

關於程式人雜誌

17 |

程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌。

18 |

雜誌下載

19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
出刊年月epubipad:PDFA4:PDF單頁 HTM原始碼全部下載
2013年9月epubipad.pdfA4.pdfpmag.htmlcode.zipall.zip
43 |

說明:本期取材比較特殊,前半部分討論「網路與政治」這個與程式距離較遠的主題,不喜歡政治主題的讀者請直接從「程式人文集」開始閱讀,謝謝!

44 |

本期內容

45 | 80 |

雜誌取得

81 |

程式人雜誌預定於每個月 1 日出刊,您可以從下列網址取得程式人雜誌的所有內容 (包含當月最新出刊的雜誌)。

82 | 85 |

連絡我們

86 |

竭誠歡迎程式人投稿,或者成為本雜誌的專欄作家,現在就可以加入 程式人雜誌社團 一同共襄盛舉。

87 |

本雜誌編輯為「陳鍾誠 (@ccckmit)」,若要聯絡編輯,請寄信到

93 |
94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /htm/netcountry.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 | 21 |

網路世代所需要的制度與法律 -- 虛擬國家的慨念

22 |

在苗栗大浦案激化之後,抗議的朋友們喊出了「今天拆大埔,明天拆政府」的口號,甚至還導致 政大教授徐世榮被在喊口號時當街被逮捕,後來更衍生出陳為廷、楊儒門、李建成等人也因潑漆事件而被逮捕的事件。

23 |

但是、筆者在此要討論的,不是這個事件,而是拆除政府的方法。

24 |

在過去尚未發展出民主制度的時代,拆政府的方法只有一種,那就是革命了,但是民主制度發展出來之後, 每到選舉時政府就會被拆掉然後重建。因此、民主制度可以說一種定期拆除政府的制度。

25 |

可惜的是,我們的民主政治似乎走到了一個困境,每次選舉都會拆掉政府,然後原地重建。但是新的政府往往沒有更好, 而且很可能更爛。

26 |

這次由「洪仲秋事件」,在台灣引發了「公民 1985」聯盟發起上凱達格蘭大道抗議的活動,展現了台灣網路世代的力量, 在盡可能排除政黨勢力介入的情況下,集結了 25 萬人上街頭,卻又非常有秩序,而且有組織的進行了一場完美的街頭運動。

27 |

這件事讓筆者深受啟發,我認為這件事代表了「網路世代」是可以形成政治力量的,但是我也擔心這股力量隨著「洪仲秋事件」 的落幕而消散,網路世代從此又成為政治的邊緣人。這個世界仍然繼續由傳統的藍綠政治勢力所主導,那是我不願看到的。

28 |

兩年前我也曾經因為某個突然的啟發,開始了一場小革命,用網路來對抗現有的教育體制,以下是這場小革命的一些相關資訊:

29 | 35 |

以及我最近模仿賈伯斯的演講,講述了有關自己親身經歷的三個有關網路社群的故事,這篇讀的人比較多,而且有被 inside 網站轉載。

36 | 41 |

後來這場革命逐漸退燒了,我決定回到正常的生活,做一些有意義的事情,於是在去年底我決定創辦了「程式人雜誌」, 也就是各位現在看到的這本雜誌。

42 |

但是在 2013/8/3 日 25 萬人上凱道的事情過後,我內心哪個被壓抑下來的熱情又重新燃燒起來了,這也讓我思考 了好幾個晚上,甚至輾轉難眠。

43 |

我認為根本的問題是,網路世代其實被上一代所創建的體制所壓抑了,8 月 3 日的集結代表的不僅僅是抗議一個人被軍方虐死的事件, 而更深層的反應了「網路世代」企圖掙脫上一代所創造的枷鎖,然後創造一個更美好的世界。

44 |

但是、這種枷鎖根深蒂固的透過政治體制綑綁了我們,我們又如何能掙脫出來呢?

45 |

突然間、我想到一個可能的辦法,那就是讓網民們建立一個「虛擬國家」,然後用這個虛擬國家的力量,來影響實體國家, 讓政治有機會變得更好。

46 |

例如、在網路上,智慧財產權是一個很大的問題,我們每天的資訊分享幾乎都在觸犯法律,但是透過制定「網路虛擬國家」的憲法, 我們有機會得到與實體世界法律相抗衡的力量,這個想法乃是直接延伸自「開放原始碼」的 GPL 授權而來的,甚至也受「創作共用」 (Creative Commons) 的影響很深。

47 |

於是我寫了一些「網路憲法」的不成熟草案,希望透過這樣的方式改變現實世界的智慧財產權困境,以下是幾項不成熟的條文想法:

48 |
    49 |
  1. 任何人都可以經由明文宣誓的方式,成為網路公民國 (以下簡稱本國) 的公民 (以下簡稱網民)。
  2. 50 |
  3. 網民除了本國之外,還可以自由參加任何組織或實體國家,本國並無任何禁止「雙重國籍」的規定。
  4. 51 |
  5. 網民有上網之自由,任何組礙或限制網民上網的行為,都違反本憲法之精神。
  6. 52 |
  7. 網民有集會結社之基本權利,任何損害此一權利的組織,都將視為本國之敵人,本國有封鎖該組織的權利。
  8. 53 |
  9. 網民的任何作品,只要不附加「著作權宣告」,就被預設視為「公共領域」之作品,任何網民都擁有合法修改、複製、散布之權利。
  10. 54 |
  11. 網民可以下載任何未被身分認證機制所保護的內容,而不被控以侵犯著作權之自由。
  12. 55 |
56 |

這樣的法律其實意在保障網民們的自由,並且同時尊重創作者的權力,但是將著作權的預設值反轉過來,從 CopyRight 「版權所有」的 All Rights Reserved 轉化為「版權所無」的 No Rights Reserved 的情況,這讓網路自由可以得到法律基礎。

57 |

這種手法與 GNU 的 GPL 有些不同,GPL 是透過法律來挑戰法律,但「網路虛擬國家」則直接透過「建國」與「制憲」挑戰傳統的政治結構。

58 |

「虛擬國家」的概念,目前仍然沒有明確的定義,在我的想法中,「虛擬國家」不會只是一個網路社團而已,還會有「憲法、虛擬領土、主權」、 甚至也可以「宣戰,媾和」。

59 |

根據德國公學者耶林內克(G.Jellinek)的說法,國家的四個構成要素是「人民、土地、政府、主權」。

60 |

在這四項要素中,「虛擬國家」擁有人民,也就是網民,擁有「主權」,像是智慧財產權等等,也可以建立「政府」,雖然這個政府可能只 是個「網路平台基礎建設」,以及一些維持這個基礎建設正常運作的志工,就像是維基百科一樣,但是仍然是個「政府」,而且大部分的 政策都可以透過「直接投票」-- 或說是「公民投票」而決定。

61 |

「虛擬國家」或許不會擁有土地,但是卻擁有「網路空間上的領土」,可以透過「封鎖」、「不提供資訊」與實體國家進行對抗,網民們 也有可能透過像「鍵盤戰」的方式,進行某種形式的「虛擬戰爭」。

62 |

更重要的是,「虛擬國家」沒有禁止「雙重國籍」的規定,網民們在實體世界的國家裏,還是有投票權的。因此、「虛擬國家」可以透過 「公投」制定政策,試圖影響某個實體國家的政策,讓這些國家的政治可以更好。

63 |

舉例而言,如果台灣的「網民」們聯合起來,形成一個「虛擬國家」,例如叫做「網路公民國」(簡稱網國),就可以先在網路上制定政策 並且透過「公投」表決,決定建議國民將選票投給「認養」這個政策的「立委」或「政黨」,然後告訴「國民黨」與「民進黨」這個遊戲規則, 用「虛擬國家」的政策影響甚至左右「實體國家」的政策。

64 |

於是、這個虛擬國家成了一個「國中之國」,而且可以發揮強大的政治影響力,這就是我對「虛擬國家」運作方式的初步想法。

65 |

【本文由陳鍾誠撰寫】

66 |
67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /htm/info.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 9 月號 (開放公益出版品)

14 |
15 |
16 |
17 | 25 |
26 |

雜誌訊息

27 |

讀者訂閱

28 |

程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌,如果您願意成為本雜誌的專欄作家,請加入 程式人雜誌社團 一同共襄盛舉。

29 |

我們透過發行這本雜誌,希望讓大家可以讀到想讀的書,學到想學的技術,同時也讓寫作的朋友的作品能產生良好價值 – 那就是讓讀者根據雜誌的價值捐款給慈善團體。 讀雜誌做公益也不需要有壓力,您不需要每讀一本就急著去捐款,您可以讀了十本再捐,或者使用固定的月捐款方式,當成是雜誌訂閱費,或者是季捐款、一年捐一次等都 OK ! 甚至是單純當個讀者我們也都很歡迎! 本雜誌每期參考價:NT 50 元,如果您喜歡本雜誌,請將書款捐贈公益團體。例如可捐贈給「羅慧夫顱顏基金會 彰化銀行(009) 帳號:5234-01-41778-800」。(若匯款要加註可用「程式人雜誌」五個字)

30 |

想訂閱本雜誌的讀者,請按 雜誌訂閱 連結並填寫表單,我們會在每一期雜誌出刊時寄送通知與下載網址到您的信箱。

31 |

投稿須知

32 |

給專欄寫作者: 做公益不需要有壓力。如果您願意撰寫專欄,您可以輕鬆的寫,如果當月的稿件出不來,我們會安排其他稿件上場。

33 |

給網誌捐贈者: 如果您沒時間寫專欄或投稿,沒關係,只要將您的網誌以 [創作共用的「姓名標示、非商業性、相同方式分享」授權] 並通知我們,我們會自動從中選取需要的文章進行編輯,放入適當的雜誌當中出刊。

34 |

給文章投稿者: 程式人雜誌非常歡迎您加入作者的行列,如果您想撰寫任何文章或投稿,請用 markdown 或 LibreOffice 編輯好您的稿件,並於每個月 25 日前投稿到程式人雜誌社團 的檔案區,我們會盡可能將稿件編入隔月1號出版程式人雜誌當中,也歡迎您到社團中與我們一同討論。

35 |

如果您要投稿給程式人雜誌,我們最希望的格式是採用 markdown 的格式撰寫,然後將所有檔按壓縮為 zip 上傳到社團檔案區給我們, 如您想學習 markdown 的撰寫出版方式,可以參考 [程式人雜誌的出版方法] 一文。

36 |

如果您無法採用 markdown 的方式撰寫,也可以直接給我們您的稿件,像是 MS. Word 的 doc 檔或 LibreOffice 的 odt 檔都可以,我們 會將這些稿件改寫為 markdown 之後編入雜誌當中。

37 |

參與編輯

38 |

您也可以擔任程式人雜誌的編輯,甚至創造一個全新的公益雜誌,我們誠摯的邀請您加入「開放公益出版」的行列,如果您想擔任編輯或創造新雜誌,也歡迎到 程式人雜誌社團 來與我們討論相關事宜。

39 |

公益資訊

40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 74 | 75 | 76 | 77 |
公益團體聯絡資訊服務對象捐款帳號
財團法人羅慧夫顱顏基金會http://www.nncf.org/

02-27190408分機 232
顱顏患者 (如唇顎裂、小耳症或其他罕見顱顏缺陷)銀行:009彰化銀行民生分行
帳號:5234-01-41778-800
社團法人台灣省兒童少年成長協會http://www.cyga.org/

04-23058005
單親、隔代教養.弱勢及一般家庭之兒童青少年銀行:新光銀行
戶名:台灣省兒童少年成長協會
帳號:103-0912-10-000212-0
78 |
79 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /code/oc/jparser.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | require("./ccc"); 3 | 4 | var tokens = []; 5 | var tokenIdx = 0; 6 | 7 | var scan=function(text) { 8 | var re = new RegExp(/(\/\*[\s\S]*?\*\/)|(\/\/[^\r\n])|(".*?")|(\d+(\.\d*)?)|([a-zA-Z]\w*)|([>== tokens.length) 40 | return false; 41 | var token = tokens[tokenIdx].token; 42 | if (o instanceof RegExp) { 43 | return token.match(o); 44 | } else { 45 | return (token == o); 46 | } 47 | } 48 | 49 | var isNextType=function(pattern) { 50 | var type = tokens[tokenIdx].type; 51 | return (("|"+pattern+"|").indexOf("|"+type+"|")>=0); 52 | } 53 | 54 | var compile=function(text) { 55 | printf("text=%s\n", text); 56 | scan(text); 57 | printf("tokens=%j\n", tokens); 58 | PROG(); 59 | } 60 | 61 | // NTS = NT { sep NT }* 62 | var repeat=function(f, sep) { 63 | f(); 64 | while (isNext(sep)) { 65 | next(sep); 66 | f(); 67 | } 68 | } 69 | 70 | // PROG = STMTS 71 | var PROG=function() { 72 | repeat(STMT, ';'); 73 | } 74 | 75 | // BLOCK = { STMTS } 76 | var BLOCK=function() { 77 | next("{"); 78 | if (!isNext("}")) repeat(STMT, ";"); 79 | next("}"); 80 | } 81 | 82 | // STMT = FOR | WHILE | IF | return EXP | ASSIGN 83 | var STMT=function() { 84 | if (isNext("for")) { 85 | FOR(); 86 | } else if (isNext("while")) { 87 | WHILE(); 88 | } else if (isNext("if")) { 89 | IF(); 90 | } else if (isNext("return")) { 91 | next("return"); 92 | EXP(); 93 | } else { 94 | ASSIGN(); 95 | } 96 | } 97 | 98 | // FOR = for (STMT; EXP; STMT) BLOCK 99 | var FOR=function() { 100 | next("for"); next("("); STMT(); next(";"); EXP(); next(";"); STMT(); next(")"); BLOCK(); 101 | } 102 | 103 | // WHILE = while (EXP) BLOCK 104 | var WHILE=function() { 105 | next("while"); next("("); EXP(); next(")"); BLOCK(); 106 | } 107 | 108 | // IF = if (EXP) BLOCK (else if (EXP) BLOCK)* (else BLOCK)? 109 | var IF=function() { 110 | next("if"); next("("); EXP(); next(")"); BLOCK(); 111 | while (isNext("else")) { 112 | next("else"); 113 | if (isNext("if")) { 114 | next("if"); next("("); EXP(); next(")"); BLOCK(); 115 | } else { 116 | BLOCK(); 117 | } 118 | } 119 | } 120 | 121 | // ASSIGN = (ID[++|--]?)?(=EXP)? 122 | var ASSIGN=function() { 123 | var id="", op=""; 124 | if (isNextType("id")) { 125 | id = next(null); 126 | if (isNext("++") || isNext("--")) 127 | op = next(null); 128 | } 129 | if (isNext("=")) { 130 | next("="); 131 | EXP(); 132 | } 133 | } 134 | 135 | // EXP=TERM (op2 TERM)? 136 | var EXP=function() { 137 | t1 = TERM(); 138 | if (isNextType("op2")) { 139 | var op = next(null); 140 | TERM(); 141 | } 142 | } 143 | 144 | // TERM=STRING | INTEGER | FLOAT | FUNCTION | ARRAY | TABLE | ID (TERMS)? | ( EXP ) 145 | var TERM=function() { 146 | if (isNextType("string|integer|float")) { 147 | return next(null); 148 | } else if (isNext("function")) { 149 | FUNCTION(); 150 | } else if (isNext("[")) { 151 | ARRAY(); 152 | } else if (isNext("{")) { 153 | TABLE(); 154 | } else if (isNextType("id")) { 155 | id=next(null); 156 | } else if (isNext("(")) { 157 | next("("); EXP(); next(")"); 158 | if (isNext("(")) { next("("); TERMS(); next(")"); } 159 | } else error(); 160 | } 161 | 162 | // FUNCTION = function(IDS) BLOCK 163 | var FUNCTION = function() { 164 | next("function"); next("("); 165 | if (!isNext(")")) repeat(ID, ","); 166 | next(")"); BLOCK(); 167 | } 168 | 169 | // ARRAY = [ TERMS ]; 170 | var ARRAY = function() { 171 | next("["); 172 | if (!isNext("]")) repeat(TERM, ","); 173 | next("]"); 174 | } 175 | 176 | // TABLE = { PAIRS } 177 | var TABLE = function() { 178 | next("{"); 179 | if (!isNext("}")) repeat(PAIR, ","); 180 | next("}"); 181 | } 182 | 183 | // PAIR = TERM:TERM 184 | var PAIR = function() { 185 | TERM(); next(":"); TERM(); 186 | } 187 | 188 | var source = fs.readFileSync("test.j1", "utf8"); 189 | compile(source); 190 | compile(fs.readFileSync("test2.j1", "utf8")); -------------------------------------------------------------------------------- /code/oc/as0.js: -------------------------------------------------------------------------------- 1 | var c = require("./ccc"); // 引用基本函式庫 ccc.js 2 | var as = require("./as"); // 引用抽象組譯器物件 as.js 3 | var code = require("./code"); // 引用指令物件 code.js 4 | var cpu0 = require("./cpu0"); // 引用處理器物件 cpu0.js 5 | 6 | var as0 = new as(cpu0.opTable); // 建立 as0 組譯器物件 7 | 8 | as0.parse = function(line) { // 剖析組合語言指令,建立 code 物件 9 | return new code(line, this.opTable); 10 | } 11 | 12 | as0.translate = function(code) { // 指令的編碼函數 13 | var ra=0, rb=0, rc=0, cx=0; 14 | var pc = code.address + 4; // 提取後PC為位址+4 15 | var args = code.args, parseR = code.parseR; // 取得 code 物件的函數 16 | var labelCode = null; // JMP label 中 label 所對應行的物件,稱為 labelCode 17 | if (code.op == undefined) { // 如果沒有指令碼 (只有標記),則清空目的碼 18 | code.obj = ""; 19 | return; 20 | } 21 | switch (code.op.type) { // 根據指令型態 22 | case 'J' : // 處理 J 型指令,編出目的碼 OP Ra+cx 23 | switch (code.op.name) { 24 | case "RET": case "IRET" : // 如果式返回或中斷返回,則只要輸出 op 碼 25 | break; 26 | case "SWI" : // 如果是軟體中斷指令,則只有 cx 參數有常數值 27 | cx = parseInt(args[0]); 28 | break; 29 | default : // 其他跳躍指令,例如 JMP label, JLE label 等 30 | labelCode = this.symTable[args[0]]; // 取得 label 符號位址 31 | cx = labelCode.address - pc; // 計算 cx 欄位 32 | break; 33 | } 34 | code.obj = c.hex(code.op.id,2)+c.hex(cx, 6); // 編出目的碼 OP Ra+cx 35 | break; 36 | case 'L' : // 處理 L 型指令,編出目的碼 OP Ra, Rb, cx 37 | ra = parseR(args[0]); // 取得 Ra 欄位 38 | switch (code.op.name) { 39 | case "LDI" : // 處理 LDI 指令 40 | cx = parseInt(args[1]); // 取得 cx 欄位 41 | break; 42 | default : // 處理 LD, ST, LDB, STB 指令 43 | if (args[1].match(/^[a-zA-Z]/)){ // 如果是 LD LABEL 這類情況 44 | labelCode = this.symTable[args[1]]; // 取得標記的 code 物件 45 | rb = 15; // R[15] is PC 46 | cx = labelCode.address - pc; // 計算標記與 PC 之間的差值 47 | } else { // 否則,若是像 LD Ra, Rb+100 這樣的指令 48 | rb = parseR(args[2]); // 取得 rb 欄位 49 | cx = parseInt(args[3]); // 取得 cx 欄位 (例如 100) 50 | } 51 | break; 52 | } 53 | code.obj = c.hex(code.op.id, 2)+c.hex(ra, 1)+c.hex(rb, 1)+c.hex(cx, 4); // 編出目的碼 OP Ra, Rb, cx 54 | break; 55 | case 'A' : // 處理 A 型指令,編出目的碼 OP Ra, Rb, Rc, cx 56 | ra = parseR(args[0]); // 取得 Ra 欄位 57 | switch (code.op.name) { 58 | case "LDR": case "LBR": case "STR": case "SBR": // 處理 LDR, LBR, STR, SBR 指令,例如 LDR Ra, Rb+Rc 59 | rb = parseR(args[1]); // 取得 Rb 欄位 60 | rc = parseR(args[2]); // 取得 Rc 欄位 61 | break; 62 | case "CMP": case "MOV" : // 處理 CMP 與 MOV 指令,CMP Ra, Rb; MOV Ra, Rb 63 | rb = parseR(args[1]); // 取得 Rb 64 | break; 65 | case "SHL": case "SHR": case "ADDI": // 處理 SHL, SHR, ADDI 指令,例如 SHL Ra, Rb, Cx 66 | rb = parseR(args[1]); // 取得 Rb 欄位 67 | cx = parseInt(args[2]); // 取得 cx 欄位 (例如 3) 68 | break; 69 | case "PUSH": case "POP": case "PUSHB": case "POPB" : // 處理 PUSH, POP, PUSHB, POPB 70 | break; // 例如 PUSH Ra, 只要處理 Ra 就好,A 型一進入就已經處理 Ra 了。 71 | default : // 其他情況,像是 ADD, SUB, MUL, DIV, AND, OR, XOR 等,例如 ADD Ra, Rb, Rc 72 | rb = parseR(args[1]); // 取得 Rb 欄位 73 | rc = parseR(args[2]); // 取得 Rc 欄位 74 | break; 75 | } 76 | code.obj = c.hex(code.op.id, 2)+c.hex(ra, 1)+c.hex(rb, 1)+c.hex(rc,1)+c.hex(cx, 3); // 編出目的碼 OP Ra, Rb, Rc, cx 77 | break; 78 | case 'D' : { // 我們將資料宣告 RESW, RESB, WORD, BYTE 也視為一種指令,其形態為 D 79 | var unitSize = 1; // 預設的型態為 BYTE,資料大小 = 1 80 | switch (code.op.name) { 81 | case "RESW": case "RESB": // 如果是 RESW 或 RESB,例如 a:RESB 2 82 | code.obj = c.dup('0', this.size(code)*2); // 1 個 byte 的空間要用兩個16進位的 00 去填充 83 | break; // 例如:a RESB 2 會編為 '0000' 84 | case "WORD": // 如果是 WORD ,佔 4 個 byte 85 | unitSize = 4; 86 | case "BYTE": { // 如果是 BYTE ,佔 1 個 byte 87 | code.obj = ""; // 一開始目的碼為空的 88 | for (var i in args) { // 對於每個參數,都要編為目的碼 89 | if (args[i].match(/^\".*?\"$/)) { // 該參數為字串,例如: "Hello!" 轉為 68656C6C6F21 90 | var str = args[i].substring(1, args[i].length-1); // 取得 "..." 中間的字串內容 91 | code.obj += c.str2hex(str); // 將字串內容 (例如 Hello!) 轉為 16 進位 (例如 68656C6C6F21) 92 | } else if (args[i].match(/^\d+$/)) { // 該參數為常數,例如 26 93 | code.obj += c.hex(parseInt(args[i]), unitSize*2); // 將常數轉為 16 進位目的碼 (例如 26 轉為 1A) 94 | } else { // 該參數為標記,將標記轉為記憶體位址,例如 msgptr: WORD msg 中的 msg 轉為位址 (例如:00000044) 95 | labelCode = this.symTable[args[i]]; // 取得符號表內的物件 96 | code.obj += c.hex(labelCode.address, unitSize*2); // 取得位址並轉為 16 進位,塞入目的碼中。 97 | } 98 | } 99 | break; 100 | } // case BYTE: 101 | } // switch 102 | break; 103 | } // case 'D' 104 | } 105 | } 106 | 107 | // 使用範例 node as0 sum.as0 sum.ob0 108 | // 其中 argv[2] 為組合語言檔, argv[3] 為目的檔 109 | as0.assemble(process.argv[2], process.argv[3]); 110 | -------------------------------------------------------------------------------- /source/article1.md: -------------------------------------------------------------------------------- 1 | ## Arduino入門教學(9) – 在 2x16 LCD 上顯示 "Hello World" 訊息 (作者:Cooper Maa) 2 | 3 | ### 實驗目的 4 | 5 | 練習使用 HD44780 相容的文字型 LCD(Liquid crystal display),在 2x16 LCD 上顯示 "Hello World” 訊息。 6 | 7 | ### 2x16 LCD 簡介 8 | 9 | ![圖片來源: arduino.cc](../img/Arduino_LCD_device1.png) 10 | 11 | HD44780 相容的 2x16 LCD 可以顯示兩行訊息,每行 16 個字元,它可以顯示英文字母、希臘字母、標點符號以及數學符號,除了顯示訊息外,它還有其它功能,包括訊息捲動(往左和往右捲動)、顯示游標和 LED背光等。 12 | 13 | ![圖片來源: LCD 101](../img/Arduino_LCD_device2.png) 14 | 15 | LCD 總共有 14 支接腳,如果內建背光的話是 16 支,這些腳位的功能整理於下表: 16 | 17 | 腳位編號 名稱 說明 18 | --------- ----------------------------------------- -------------------------------------------------------------------------- 19 | 1 Vss 接地 (0V) 20 | 2 Vdd 電源 (+5V) 21 | 3 Vo 或稱 Vee 對比(0-5V), 可接一顆 1k 電阻,或利可變電阻調整適當的對比 22 | 4 RS Register Select: 1: D0 – D7 當作資料解釋 0: D0 – D7 當作指令解釋 23 | 5 R/W Read/Write mode: 1: 從 LCD 讀取資料 0: 寫資料到 LCD, 因為很少從 LCD 這端讀取資料,可將此腳位接地以節省 I/O 腳位。 24 | 6 E Enable 25 | 7 D0 Bit 0 LSB 26 | 8 D1 Bit 1 27 | 9 D2 Bit 2 28 | 10 D3 Bit 3 29 | 11 D4 Bit 4 30 | 12 D5 Bit 5 31 | 13 D6 Bit 6 32 | 14 D7 Bit 7 MSB 33 | 15 A+ 背光(串接 330R 電阻到電源) 34 | 16 K- 背光(GND) 35 | 36 | 日立 HD44780 相容的 LCD 有 4-bit 和 8-bit 兩種使用模式,使用 4-bit 模式主要的好處是節省 I/O 腳位,通訊的時候只會用到 4 個高位元 (D4-D7),D0-D3 這四支腳位可以不用接。每個送到 LCD 的資料會被分成兩次傳送 – 先送 4 個高位元,然後才送 4 個低位元。 37 | 38 | ### 材料 39 | 40 | * 麵包板 x 1 41 | * Arduino 主板 x 1 42 | * HD44780 相容 LCD x 1 (本文所用的為 14 pin 無背光 LCD) 43 | * 旋轉式可變電阻 x 1 44 | * 單心線 x N 45 | 46 | ### 接線 47 | 48 | * 將 LCD 的 RS, Enable, D4, D5, D6, D7 依序接到 12, 11, 5, 4, 3, 2 等腳位上 49 | * 將 LCD 的 Vss 及 R/W 接到 GND,Vdd 接到 +5V 50 | * 可變電阻中間腳位接到 LCD 的 Vo,剩下的兩支腳位,一支接到 5V,另外一支接到 GND (註:也可以不使用可變電阻,只要在 LCD 的 Vo 上串接一顆 1k ohm 電阻連到 GND 即可) 51 | 52 | ![](../img/Arduino_LCD_board1.png) 53 | 54 | ### 電路圖 55 | 56 | ![](../img/Arduino_LCD_circuit1.png) 57 | 58 | ### 程式碼 59 | 60 | 要在 LCD 上顯示訊息,會涉及初始化 LCD 、下指令以及傳送資料給 LCD 等工作,Arduino LiquidCrystal Library 已經把這些工作簡化了,所以你不需要知道這些低階的指令。底下的程式在 2x16 LCD 上第一行顯示 "hello, world!” 訊息,並在第二行不斷更新 Arduino 重開之後經過的秒數,使用的是 4-bit 模式(HelloWorld.pde): 61 | 62 | ```CPP 63 | 64 | /* Lab9 - 在 2x16 LCD 上顯示 "Hello World" 訊息 65 | The circuit: 66 | * LCD RS pin to digital pin 12 67 | * LCD Enable pin to digital pin 11 68 | * LCD D4 pin to digital pin 5 69 | * LCD D5 pin to digital pin 4 70 | * LCD D6 pin to digital pin 3 71 | * LCD D7 pin to digital pin 2 72 | * 10K Potentiometer: 73 | * ends to +5V and ground 74 | * wiper to LCD VO pin (pin 3) 75 | 76 | This example code is in the public domain. 77 | http://www.arduino.cc/en/Tutorial/LiquidCrystal 78 | */ 79 | 80 | // 引用 LiquidCrystal Library 81 | #include 82 | 83 | // 建立 LiquidCrystal 的變數 lcd 84 | // LCD 接腳: rs, enable, d4, d5, d6, d7 85 | // 對應到 Arduino 接腳: 12, 11, 5, 4, 3, 2 86 | LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 87 | 88 | void setup() { 89 | // 設定 LCD 的行列數目 (2 x 16) 90 | lcd.begin(16, 2); 91 | 92 | // 列印 "Hello World" 訊息到 LCD 上 93 | lcd.print("hello, world!"); 94 | } 95 | 96 | void loop() { 97 | // 將游標設到 column 0, line 1 98 | // (注意: line 1 是第二行(row),因為是從 0 開始數起): 99 | lcd.setCursor(0, 1); 100 | 101 | // 列印 Arduino 重開之後經過的秒數 102 | lcd.print(millis()/1000); 103 | } 104 | ``` 105 | 106 | 如果訊息沒有顯示在螢幕上,或者是模糊朦朧的,首先應該做的事是檢查可變電阻以調整對比。 107 | 108 | 註:這支是 Arduino 內建的範例程式,點選 File > Examples > LiquidCrystal > HelloWorld 就可以找到。 109 | 110 | ### 範例照片/影片 111 | 112 | * Arduino 筆記 -- Lab9 在 2x16 LCD 上顯示 "Hello World" 訊息 -- 113 | 114 | ### 動動腦 115 | 116 | 1. 接一顆光敏電阻或可變電阻,然後寫一支程式讀取光敏電阻或可變電阻的讀值,並將讀到的數值顯示在 LCD 上。 117 | 2. 寫一支 SerialLCD 程式,程式的邏輯是: 接受來自 Serial Port 的資料(從 PC 或筆電端送出),然後把資料顯示在 LCD 上。 118 | 3. 承上題,把 SerialLCD 變成一個網路型的 LCD,讓電腦透過網路就可以把資料丟到 LCD 上顯示。 119 | 120 | ### 延伸閱讀 121 | 122 | * [How to control a HD44780-based Character LCD](http://home.iae.nl/users/pouweha/lcd/lcd.shtml) 123 | * [ladyada – Wiring up a character LCD to Arduino](http://www.ladyada.net/learn/lcd/charlcd.html) 124 | * [LCD 101](http://www.spikenzielabs.com/SpikenzieLabs/LCD_How_To.html) 125 | * [Scroll](http://arduino.cc/en/Tutorial/LiquidCrystalScroll) : scroll text left and right. 126 | * [Autoscroll](http://arduino.cc/en/Tutorial/LiquidCrystalAutoscroll) : shift text right and left. 127 | 128 | 【本文作者為馬萬圳,原文網址為: ,由陳鍾誠編輯後納入本雜誌】 129 | -------------------------------------------------------------------------------- /css/pmag.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, applet, object, iframe, 2 | p, blockquote, pre, 3 | a, abbr, acronym, address, big, cite, code, 4 | del, dfn, em, img, ins, kbd, q, s, samp, 5 | small, strike, strong, sub, sup, tt, var, 6 | b, u, i, center, 7 | dl, dt, dd, 8 | fieldset, form, label, legend, 9 | table, caption, tbody, tfoot, thead, tr, th, td, 10 | article, aside, canvas, details, embed, 11 | figure, figcaption, footer, header, hgroup, 12 | menu, nav, output, ruby, section, summary, 13 | time, mark, audio, video { 14 | margin: 0; 15 | padding: 0; 16 | border: 0; 17 | font: inherit; 18 | vertical-align: baseline; 19 | line-height:160%; 20 | font-family: 'Tahoma', 'Pmingliu'; 21 | } 22 | 23 | #cover-image { 24 | width:100%; 25 | } 26 | 27 | div>ol.toc { 28 | list-style-type:disc; 29 | } 30 | 31 | ol.toc { 32 | list-style-type:circle; 33 | } 34 | 35 | blockquote { 36 | margin: 10px; 37 | padding-left: 10px; 38 | padding-right: 10px; 39 | padding-top: 1px; 40 | padding-bottom: 1px; 41 | border: 1px solid #373737; 42 | background-color: #efefef; 43 | } 44 | 45 | h1, h1 a { font-size: xx-large; color:#050505; text-align:center; margin:30px; font-weight: bold; font-family: 'Tahoma', 'DFKai-sb'; } 46 | 47 | h2, h2 a { font-size: x-large; color:#000033; margin-top:30px; margin-bottom:30px; font-weight: bold; font-family: 'Tahoma', 'DFKai-sb'; } 48 | 49 | h3, h3 a { font-size: large; color:#000066; font-weight: bold; font-family: 'Tahoma', 'DFKai-sb'; } 50 | 51 | h4, h4 a { font-size: medium; color:#4B0082; font-weight: bold; font-family: 'Tahoma', 'DFKai-sb'; } 52 | 53 | h5, h5 a { font-size: small ; color:#708090; font-weight: bold; font-family: 'Tahoma', 'DFKai-sb'; } 54 | 55 | h6, h6 a { font-size: x-small; color:#000080; } 56 | 57 | p { 58 | font-family: 'Tahoma', 'Pmingliu'; 59 | margin: 10px 0 15px 0; 60 | font-size:100%; 61 | color:#353535; 62 | } 63 | 64 | li { 65 | font-size:100%; 66 | } 67 | 68 | footer p { 69 | color: #f2f2f2; 70 | } 71 | 72 | a { 73 | text-decoration: none; 74 | color: #007edf; 75 | text-shadow: none; 76 | 77 | transition: color 0.5s ease; 78 | transition: text-shadow 0.5s ease; 79 | -webkit-transition: color 0.5s ease; 80 | -webkit-transition: text-shadow 0.5s ease; 81 | -moz-transition: color 0.5s ease; 82 | -moz-transition: text-shadow 0.5s ease; 83 | -o-transition: color 0.5s ease; 84 | -o-transition: text-shadow 0.5s ease; 85 | -ms-transition: color 0.5s ease; 86 | -ms-transition: text-shadow 0.5s ease; 87 | } 88 | 89 | table { 90 | border-collapse: collapse; 91 | border-spacing: 0; 92 | border: 1px solid #373737; 93 | margin-bottom: 20px; 94 | text-align: left; 95 | margin-left:auto; 96 | margin-right:auto; 97 | } 98 | 99 | th { 100 | padding: 10px; 101 | background-color:black; 102 | color:white; 103 | } 104 | 105 | td { 106 | padding: 10px; 107 | vertical-align: middle; 108 | border: 1px solid #373737; 109 | } 110 | 111 | em { 112 | font-weight:bold; 113 | } 114 | 115 | #header_wrap { 116 | margin: 0; 117 | padding: 16px; 118 | border: 0; 119 | font: inherit; 120 | vertical-align: baseline; 121 | background-color:black; 122 | color:white; 123 | } 124 | 125 | #header_wrap h1, #header_wrap h1 sub, #header_wrap h1 a { 126 | color:white; 127 | font-family: 'Tahoma', 'DFKai-sb'; 128 | } 129 | 130 | #header_wrap sub { 131 | color:white; 132 | font-size:60%; 133 | } 134 | 135 | .title, .author, .date { 136 | color:#333333; 137 | text-align:center; 138 | font-family: 'Tahoma', 'DFKai-sb'; 139 | } 140 | 141 | .title { font-size:xx-large; line-height:800%; } 142 | 143 | .author { font-size:large; line-height:300%; } 144 | 145 | .date { font-size:large; line-height:300%; } 146 | 147 | 148 | #content { 149 | margin:10px; 150 | padding:10px; 151 | } 152 | 153 | pre { 154 | border: 1px solid #373737; 155 | background-color:#efefef; 156 | color:#3f3f3f; 157 | font-size:medium; 158 | width:95%; 159 | padding:10px; 160 | } 161 | 162 | code { 163 | font-family: SimSun; 164 | font-size:100%; 165 | } 166 | 167 | .figure { 168 | margin:10px; 169 | padding:10px; 170 | margin-left: auto; 171 | margin-right: auto; 172 | display: block; 173 | } 174 | 175 | .figure img { 176 | border: 1px solid #373737; 177 | margin-left: auto; 178 | margin-right: auto; 179 | display: block; 180 | } 181 | 182 | .figure .caption { 183 | text-align:center; 184 | } 185 | 186 | #TOC { 187 | } 188 | 189 | #footer { 190 | text-align:center; 191 | font-size:small; 192 | color:#6f6f6f; 193 | margin: 10px; 194 | padding: 10px; 195 | } 196 | 197 | /* JavaScript Style */ 198 | table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 199 | margin: 0; padding: 0; vertical-align: baseline; border: none; } 200 | table.sourceCode { width: 100%; } 201 | td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #afafaf; border-right: 1px solid #aaaaaa; } 202 | td.sourceCode { padding-left: 5px; } 203 | code > span.kw { color: #007020; font-weight: bold; } 204 | code > span.dt { color: #902000; } 205 | code > span.dv { color: #40a070; } 206 | code > span.bn { color: #40a070; } 207 | code > span.fl { color: #40a070; } 208 | code > span.ch { color: #4070a0; } 209 | code > span.st { color: #4070a0; } 210 | code > span.co { color: #60a0b0; font-style: italic; } 211 | code > span.ot { color: #007020; } 212 | code > span.al { color: #ff0000; font-weight: bold; } 213 | code > span.fu { color: #06287e; } 214 | code > span.er { color: #ff0000; font-weight: bold; } 215 | 216 | -------------------------------------------------------------------------------- /source/people1long.md: -------------------------------------------------------------------------------- 1 | ## 資訊政治人:Stallman, Lessig, Swartz 與 Assange 2 | 3 | 看到上述的人名,很多讀者勢必心中會產生一大堆問號?他們是誰?這些人之間有甚麼關連呢? 4 | 5 | 程式人雜誌曾經介紹過這四位當中的兩位,也就是 Stallman 與 Swartz,甚至也曾經談到過 Lessig , 6 | 但是還沒有介紹過 Assange,讓我們稍微介紹一下這些人的重要事蹟。 7 | 8 | * Stallman : [開放原始碼之父–Richard Stallman], 是著名的程式人, GNU 組織的創建者,GPL 授權的制定者。 9 | * Lessig : [勞倫斯·雷席格], 哈佛大學憲法學教授,創作共用 (Creative Commons) 授權的創造者。 10 | * Swartz : [Markdown 與 RSS 的創造者-Aaron Swartz], 並且因從 MIT 校園內大量論文一案被起訴,然後不堪檢察官威脅而在 2013 年 1 月 11 日時自殺身亡。 11 | * Assange : 維基解密組織的創建者與核心人物。 12 | 13 | 筆者之所以將這些人寫在一起,原因在於這些人是「鍵盤革命」這一個概念當中的重要人物,他們都利用「電腦、程式、網路」等工具,與當權者進行對抗。 14 | 15 | Stallman 因為不滿程式碼被商業公司封閉起來,而創造了 GNU 組織與 GPL 這個開放原始碼的程式授權,以便強制商業公司開放原始碼。 16 | Lessig 延續 Stallman 的想法,將開放原始碼的概念引入一般著作與網頁,創造出了 Creative Commons 授權。而 Swartz 則為了讓資訊的流通更容易, 17 | 創造出 Markdown 格式與 RSS 訂閱技術,並且因為想把學術論文開放而遭到起訴,最後更因此而自殺。 18 | 19 | 至於 Assange,則因為將那些政府機密大量上網,成為各國政府的頭號公敵,並因「性犯罪」的罪名而被瑞典以通輯,因此後來向厄瓜多駐倫敦大使館尋求政治庇護,目前英國還企圖與「厄瓜多」談判將 Assange 引渡到瑞典受審當中。 20 | 21 | 以上這些人與事件,都涉及到「資訊揭露」的政治學,有些人用合法的方式企圖揭露資訊 (像是 Stallman, Lessig),而有些人則用目前法律不允許的手段去揭露資訊 (像是 Swartz 與 Assange)。 22 | 23 | 如果從「大歷史」的長遠角度來看,參考 [第三波 (The Third Wave)] 中 Alvin Toffler 對歷史的區分方法,人類歷史可以用「農業文明 => 工業文明 => 資訊文明」的方式簡化的描述,那麼我們現在正處於「資訊文明」的改變過程當中,以下是這三個時期的特徵列表。 24 | 25 | (第一波) 農業文明:17 世紀之前,土地、獸力、耕種社會、家族型態,… 26 | (第二波) 工業文明:1600-1950,工廠、銀行、技術、蒸氣機、引擎、資本主義,商業社會,重商主義,… 27 | (第三波) 資訊文明:1950-現今,電腦、網路、電子、資訊、媒體、全球化、… 28 | 29 | 在工業文明的前期,引發了「工業革命」這一浪潮,這個浪潮從「地理大發現」時期開始醞釀,到了「英國工業革命」時正式成形,並且也導致了後來的法國大革命與英國殖民主義的擴張,形成了「日不落帝國」,並讓「英語」成為了世界性通用的語言。 30 | 31 | 工業文明造成整個世界結構的改變,為了使得工廠的生產得以順利進行,讓得「大量生產、大量消費」的體制能夠順利運作、啟動了工業革命,結果造成「生產集中化、產品標準化、工作專門化、生產同步化、規模極大化、管理集權化」等工業文明的特性。 32 | 33 | ### 第二波:工業文明 34 | 35 | 第二波的社會結構以工廠為核心,所有組織都仿照工廠的形式,由於青壯年到工廠工作,兒童就進入學校,老人進入養老院。為了配合就業上的機動性,家庭結構因而解體為小家庭。 36 | 37 | 第二波的昂貴設備必須有較大的市場使生產貨物予以攤銷,但是如果一踏出自己的區域,就遇上不同的關稅、義務、勞工規定與貨幣,則規模化將無法達成。於是,歐洲中古世紀的莊園結構被取代,規模較大,統一性較高的現代國家於是形成。 38 | 39 | 工業文明利用機械力讓生產規模極大化,仰賴分工的原則,工作專門化的結果導致了生產者與消費者分離的現象 (產銷分離)。於是家庭自己自足的情況不復存在,這也造成了許多社會問題,像是家庭的解體、金錢至上、物欲橫流、功利主義等等。 40 | 41 | 產銷分離導致了市場交換網路的巨幅成長,利用大量生產、大量運送、大量消費的方式,讓工廠的產品得以送達全國,廉價的能源與燃料是這種輸送系統得以運行的重要原因。 42 | 43 | 產銷分離的結果也讓青少年無法與生產接軌,導致更多的青少年問題。兒童養育成本變得更高,於是少子化的狀況出現。家庭變得更不穩定,於是許多兒童與老人無人照料,仰賴社會救助的情況相當普遍。 44 | 45 | 極細緻的分工結果導致了專門化的社會,這樣的社會仰賴綜合者進行統合,於是全力集中在綜合者的身上,這些綜合者也就是公司的經理人、幕僚等等。 46 | 47 | 第二波社會的綜合管理方式大致上分為資本主義社會與共產主義社會,共產主義社會以強制的方式進行綜合,但資本主義社會則利用市場機制進行綜合,結果是資本主義社會較為有效,這也導致了後來的共產社會解體,紛紛向資本主義社會前進。 48 | 49 | 第二波的精神體系以機械論的科學體系為主,注重因果關係、可預測性、合理化,採用線性的時空觀念,輕視不可量化的東西,讚美規律,並懲罰想像力。 50 | 51 | 經濟理論上以市場機制為核心,亞當斯密國富論中的看不見的手、分工的好處與李嘉圖的國際分工論都傾向於強化交換網路。 52 | 53 | ### 第三波:資訊文明 54 | 55 | 技術上使用光電資訊,並以電腦為工具,最重要的資源為數位資訊,採用網路傳輸的通訊方式,社會結構分化成多元組織,家庭結構則變得多樣而多變。 56 | 57 | 艾文、托佛勒對第一波、第二波、第三波的描述令人激賞,他就像一個外星人來到地球上一般,一眼看出地球的社會組織架構與其他星球的差別。 58 | 59 | 托佛勒關於第一波、第二波的描述至今仍深受我認同,並成功的指出了第三波的資訊文明的到來,以及電腦網路所造成的巨大影響。 60 | 61 | 然而,以 1980 年代的視野,畢竟難以想像 40 年後的今天,資訊文明發展到何種程度,也難以預料到全球資訊網 Web 的發展途徑。如今,Web 已經發展了將近 20 年,我們得以看清一些當年托佛勒所無法看清的事實,也因此能站在托佛勒的肩牓上,進一步的思考資訊文明的過去、現在與未來。 62 | 63 | 資訊文明與工業文明最大的不同點,在於數位內容的生產領域,也就是文字、影像、音樂、程式等產品,這些產品不需送到工廠製造,只要透過網路即可進行銷售。 64 | 65 | 數位內容的主要成本為人事成本,一但建構完成,其複制成本幾近為零,因此銷授範圍變得更大。又因為使用者對軟體程式等領域具有學習門檻等問題,於是讓銷售市場更加統一 (梅特卡夫定律),微軟的 DOS, Windows 等軟體就是此類現像的典型證明。 66 | 67 | 托佛勒於第三波一書中,認為第三波會導致社會中產銷合一情況的增強,但這並不是我們今天所看到的樣子。 68 | 69 | 托佛勒認為所強調的『生產者-消費者』之分離現象區隔無法反映今日情況的奧妙之處,因此,筆者從電子商務領域借用 B (Business:商務) 與 C (Customer:客戶) 等兩個概念,取代『生產者-消費者』的分類法,以說明今日的情況。 70 | 71 | 電子商務將網路市場區分為 B2B, B2C, C2C 等 3 類,如此更能反映網路市場的演變情況,傳統商務著重在 B2B 與 B2C 這兩塊,但在網路中 C2C 的市場不斷的被突顯出來,而且快速的成長。但是這個市場並非托佛勒於第三波一書所說的產銷合一之市場,因為兩個 C 所代表的是兩個客戶端之間的交易行為,客戶端繼進行消費,也從事生產,但卻非自產自銷,而是將產品賣給網路上的其他客戶,形成獨特的 C2C 市場。 72 | 73 | 在早期的 C2C 市場中,由 eBay, Yahoo, 露天等網路拍賣市集所形成的市場已經越來越成熟,這些市場透過宅配等通路,形成了一個實體的 C2C 市場結構。 74 | 75 | 接著、iPad 與 Kindle 的成功讓「數位產品」得以形成一個 C2C 的市場結構,這個結構是最近幾年來的改變重心之所在,「iPod、數位音樂、iPad、手機、App、行動裝置、電子書、線上電影」等都是在此一 C2C 結構下的產品。 76 | 77 | 但是、上述的 Stallman, Lessig, Swartz 與 Assange 等人,他們並非像 Steve Jobs 這樣用商業方法改變世界的人,而是用「政治方法」企圖改變世界的人。 78 | 這代表我們的世界很可能將進入一個由「資訊技術」所驅動的「政治改變」時期,而「資訊的揭露」則是此一改變的起點。 79 | 80 | ### 工業文明的政治結構 81 | 82 | 第二波的工業革命,推翻了原本「貴族統治」的封建莊園結構,並將世界帶進了「資本主義」結構,在「資本主義」的結構下,有幾個不同的實現方式, 83 | 一種是「自由市場型的議會制度」,像是「英、美」等國的發展路線,一種是從「極權型的國家資本主義」,像是「德國、日本」等國的發展路線。 84 | 另外還有一種不屬於「自由市場」,而且是反「資本主義」的發展方式,那就是「共產主義」。 85 | 86 | 雖然這些主義之間有很大的不同,但是在讓得「大量生產、大量消費」的基礎上,同樣有「生產集中化、產品標準化、工作專門化、生產同步化、 87 | 規模極大化、管理集權化」的特性。 88 | 89 | ### 資訊文明的政治結構 90 | 91 | 但是在第三波的資訊文明中,透過電腦與網路,我們似乎正在解構這種「大量生產、大量消費」的「極權化」情況,雖然在很多資訊產品上,大量生產與消費 92 | 的現像比之前更加嚴重,但是在網路這個技術的影響下,C2C 的市場正在快速成長,少量多樣的市場也逐漸茁壯,人們對取得「資訊」的渴望,逐漸從 93 | 「程式領域」延伸到「一般性文章與影片」,然後再延伸到「政治性文件與影片」。 94 | 95 | 未來、網路與資訊科技會帶領我們建立怎麼樣的一個「政治結構」呢?這是筆者很想知道,但卻也還在探索當中的一個重要關注項目啊! 96 | 97 | ### 參考文獻 98 | * [開放原始碼之父–Richard Stallman], 程式人雜誌 2013 年 3 月號 99 | * [Markdown 與 RSS 的創造者-Aaron Swartz], 程式人雜誌 2013 年 4 月號 100 | * 101 | * 維基百科:[勞倫斯·雷席格] 102 | * 103 | * 維基百科:[朱利安·阿桑奇] 104 | * [英國厄瓜多爾或商談阿桑奇去留問題](http://www.apdnews.com/news/27457.html), 作者:亞太日報綜合報導 發稿地:香港 時間:2013-6-03 105 | * 106 | * [第三波 (The Third Wave)], 作者:艾文‧托佛勒 (Alvin Toffler), 譯者:黃明堅, 時報出版社, 1994年06月20日. 107 | * [第三波 - 農業、工業與資訊文明](http://ccckmit.wikidot.com/thethirdwave), 陳鍾誠的網站。 108 | 109 | 110 | [開放原始碼之父–Richard Stallman]:https://dl.dropboxusercontent.com/u/101584453/pmag/201303/htm/people1.html 111 | [Markdown 與 RSS 的創造者-Aaron Swartz]:https://dl.dropboxusercontent.com/u/101584453/pmag/201304/htm/people2.html 112 | [勞倫斯·雷席格]:http://zh.wikipedia.org/wiki/%E5%8B%9E%E5%80%AB%E6%96%AF%C2%B7%E9%9B%B7%E5%B8%AD%E6%A0%BC 113 | [朱利安·阿桑奇]:http://zh.wikipedia.org/wiki/Julian_Assange 114 | [第三波 (The Third Wave)]:http://www.books.com.tw/exep/prod/booksfile.php?item=0010069728 115 | 116 | 【本文由陳鍾誠取材並修改自維基百科】 117 | 118 | 119 | -------------------------------------------------------------------------------- /source/message1long.md: -------------------------------------------------------------------------------- 1 | ## 資訊政治:台灣「鍵盤革命」的歷史與近況 2 | 3 | ### 台灣的鍵盤革命 4 | 5 | 「鍵盤革命」雖然是最近才開始為人所知一個名詞,但是卻是我們很多人過去十年來一直在做的事情,特別是那些使用 facebook 等社群網站, 6 | 與部落格網誌寫文章評論政治的人,所不斷推動的事情。 7 | 8 | 但是要訴說台灣「鍵盤革命」的故事,我們將從一個很不政治的故事開始: 9 | 10 | ### 莫拉克風災的網路救援 11 | 12 | 2009 年 [中度颱風莫拉克] 掃過台灣,雖然風速不算很強,但卻帶來超大豪雨,結果導致了 [八八水災] ,並引發了嚴重的山崩與土石流事件, 13 | 其中以位於高雄縣甲仙鄉小林村小林部落滅村事件最為嚴重,造成數百人活埋。 14 | 15 | 台灣政府的救災行動指揮系統反應緩慢,結果很多「程式人」與「部落客」開始利用網路 (Blog、Google Map,...) 進行災情資訊彙整, 16 | 如以下 PTT 的文章所寫的一樣: 17 | 18 | * PTT 精華區 - 閱讀文章 (Emergency) -- 19 | 20 | > 知名部落客比利潘率先發難,當天深夜以 Google Map 模式標明災情資訊,發展出「莫拉克颱風災情地圖」(http://bit.ly/KKDVh),並號召義工將網路上陸續傳出的災情逐筆標 21 | 示,兩天內標示了超過1200個救災情報,Google 也將此努力成果納入台灣官方首頁( )。 22 | > 23 | > 曾因破解總統府預錄治國週記而聲名大噪的網友 XDite,這次也不再惡搞,身為程式設計師的她使出渾身解數架設網站,僅花一個小時,在8月9日凌晨1點讓「莫拉克颱風災情支 24 | 援網」( )率先上線。 25 | > 26 | > 她當天徹夜不眠,讓這個網站在龐大流量湧入,仍屹立不搖,成為「唯一」沒掛的民間救災網站。XDite 說:「架網站傳遞訊息,讓災民獲救,讓家屬心安,是我唯一能做,而且 27 | 做得非常好的一件事。」 28 | > 台灣數位文化協會理事長徐挺耀與他的伙伴們,這一夜同樣熱血沸騰一場SKYPE網路會議後,8月9日凌晨3點左右「莫拉克災情網路中心」( )開始 29 | 運作,該協會長期與政府合作投入縮短數位落差工程,此次也成為唯一進駐中央及地方災害應變中心協助整合災情資訊的民間團體。 30 | > 31 | > 同一天夜裡,從未有顯赫名氣的網友 Rickz、Shadow 兩人熬夜架設「莫拉克災情資料表」( ),於8月9日凌晨3點上線;災情通報告一段落後,該網站開始倒數計時預告即將關閉,最後Rickz發表標題為「不管再過多久本站也不會關閉」的文章平息風波。 32 | > 33 | > Rickz 說:「這個網站的目的就是為了幫助人,今後不管受到什麼樣的壓力,只要還能再幫助一個人、再救一條人命,那就是對的事情,就要堅持下去。」 34 | > 35 | > 全台灣最大網路社群 PTT(批踢踢實業坊, )同樣沒在這一夜缺席,網友 waterdisney 凌晨2點42分發文提議PTT網友共組「救災團」,不到20分鐘,站長開設 36 | Emergency專版,由他擔任總召,包括合購物資、募集志工與物資、出動醫療團等任務他們逐一完成,終於在8月22日救災工作告一段落後總辭。 37 | > 38 | > waterdisney 說:「這是我活到 25 歲為止,最忙,最沈重,但卻是最有意義的一周,不會因為什麼都沒做而後悔。」 39 | > 40 | > 阿宅反抗軍發起人、奇幻藝術文化基金會執行長朱學恒指出,這次政府並未提供任何橋接口,是網友以先進技術「強行介入」,主導災情資訊通報,讓政府很不堪,但關鍵處理災 41 | 情的能力仍掌握在政府手裡,「因此當網友得到比政府多 100 倍的資訊,認為政府無能的程度也增加了100倍。」 42 | > 43 | > 不少人拿 921 地震時救災經驗與此次風災相比,卻罕見人將焦點聚焦在「網友」身上。根據資策會統計,民國 88 年 6 月,我國 12 歲以上的上網人口甫突破 400 萬人;但行政院研考會 44 | 去年進行調查,我國 12 歲以上國民上網率已達 68.5%,換算為人口約 1371 萬人,上網人口足足增加近千萬。 45 | > 46 | > 朱學恒直言,「網民即國民,國民即網民」的時代已經來臨,當幾乎所有國民都會上網,一旦網友對政府施政不滿意,政府民調滿意度自然很差,「政府官員若還不懂網路,那就 47 | 完蛋了!」 48 | > 49 | > 許多人認為,網友大多是足不出戶、不關心社會的阿宅,但這個颱風夜,這群網友有名也好,無名也罷,齊心為台灣盡心盡力,搖身一變成為凝聚台灣團結力量的關鍵英雄,或許 50 | 這也是台灣將進入網路世代的新契機。 51 | 52 | 莫拉克風災是我第一次看到「網友們」展現政治力量的事件,雖然這件事情很不政治,但是基於孫中山的名言:「管理眾人之事便是政治」,我們看到當政府失能的時候,網友們透過網路進行救災,彌補掉政府的無能,讓資訊得以快速流通的的「政治事件」。 53 | 54 | ### 洪仲秋被虐死引發 25 萬人上凱達格蘭大道 55 | 56 | 然後,在 2013 年,我們看到了一次「重要的網路政治事件」,那就是最近因「[洪仲秋被虐死一案]」,透過 [公民 1985 行動聯盟] 這個網路組織的協調,引發了 2013/8/3 日 25 萬人上凱達格蘭大道包圍總統府,卻又盡可能排除政黨介入的情況下,仍然表現出高度的組織能力,以及保持了良好秩序的事件。 57 | 58 | 以下的空拍圖片為這個事件留下了一個重要的見證,這是「鍵盤革命」的重要里程碑,也是台灣「網路世代」開始參與政治運動的一個明證。 59 | 60 | ![圖、photo by Jack0000](../img/SilverCross.jpg) 61 | 62 | * 圖片來源:親愛的芭樂人類學家專欄, 25萬人上街抗議真的有用嗎?, 2013/08/05 公民運動 政治 洪仲丘 社會運動 63 | * 64 | 65 | ### 零時差政府 -- g0v 組織 66 | 67 | 但是、以上兩個事件我想代表了「網路世代」政治力量的匯集結果。但事實上、在網路上隨時都有很多零星的組織,不斷的進行著「鍵盤革命」,以我個人比較熟悉的 68 | 程式領域而言,就看到了像「g0v」這樣企圖用公開政府資訊的方式,改變政治的組織,還有像「Code for tomorrow」這個仿照美國「Code for America」的組織,企圖用柔性的方式,「寫程式改造社會」的組織,以下是這些組織的網址: 69 | 70 | * 零時政府 -- 71 | * Code for Tomorrow -- 72 | * Code for America -- 73 | 74 | ### 教育界的網路小革命 75 | 76 | 另外、在教育領域,也有一些組織與個人正在進行著網路小革命,像是 Khan Academy 的 Salman Khan 就透過網路,讓美國小學到高中的教育有了很大的改變, 77 | 產生了「翻轉教學法」等更適合網路的做法,我最近也用 Khan Academy 來教小孩「用英文學數學」。 78 | 79 | 而像 Sugata Mitra 在「建立雲端的學校」這個 TED 演講中,也闡述了他在教育上利用電腦與網路來讓那些極度貧窮無法接觸電腦的小孩,透過自我學習 80 | 所發展出的獨特方法,也是非常令人感動的,該影片的網址如下。 81 | 82 | * 83 | 84 | 另外、像是我個人、還有洪朝貴、彭明輝、李家同、洪士翰等人,也常常撰寫關於教育方面的文章,希望能透過這樣的分享,讓大家更清楚教育現在所遭遇到的困境, 85 | 並且嘗試著用各種方法來改變教育的缺陷。 86 | 87 | 我相信像這樣的小革命,正是匯聚出以上較大事件的動力,而政治的現況也終將會被網路所改變,至於會如何改變,則是目前所難以預言的了! 88 | 89 | ### 網路政治組織 -- 海盜黨 90 | 91 | 最近我與 g0v 創辦人高嘉良連絡時,發現他們正在關注「柏林海盜黨」所釋出的一個實驗性開放原始碼軟體 liquidfeedback,網址如下: 92 | 93 | * 94 | 95 | 而且他們正在進行一個工作,就是將 liquidfeedback 修改為中文版,並且嘗試用這種方式改變台灣的政治環境,您可以從 github 96 | 上下載這個專案。 97 | 98 | * 99 | 100 | 以下是海盜黨的一些相關資料,請讀者參考: 101 | 102 | * 維基百科, [海盜黨國際](http://zh.wikipedia.org/zh-tw/%E6%B5%B7%E7%9B%9C%E9%BB%A8%E5%9C%8B%E9%9A%9B) 103 | * 維基百科, [德國海盜黨](http://zh.wikipedia.org/zh-tw/%E5%BE%B7%E5%9C%8B%E6%B5%B7%E7%9B%9C%E9%BB%A8) 104 | * Wikipedia:[Pirate_Party_Germany](http://en.wikipedia.org/wiki/Pirate_Party_Germany) 105 | * [「遙控民主」新實驗,讓百年大黨取經的七歲駭客政黨 - 專訪海盜黨主席(上)](http://hatetyping.blogspot.de/2013/08/blog-post_24.html) 106 | 107 | 海盜黨的一些網路民主的實施方法可以參考以下的文章: 108 | 109 | * [德國海盜黨的流動式民主](http://charlesc.ilovemeow.net/blog/20130110/1202) 110 | 111 | 我們將上述文章的重點摘要如下: 112 | 113 | * 2011 年,德國海盜黨針對柏林州議會選舉推出 15 位候選人,全上。其後幾次其他的州議會選舉,德國海盜黨也獲得7-8%的得票率,取得席次。 114 | * 海盜黨的多數的決策都是先在網路上經過許多人的討論,例如用 [PiratePad]、聊天室、wiki 和郵件論壇來協作。 115 | * 投票時,每人一票。但是,因為並非大家都能夠詳閱政策內容,所以系統允許成員可以委託他人代為投票。委託範圍可以是所有提案、某個主題的提案、或是某特定提案。而被委派投票的成員,還可以把這些票、包括自己的一票,再度委託給他人投票! 116 | * Liquid Feedback 這種以信任為基礎的模式,類似信譽系統(reputation system),只不過成員的參與所換到的不是點數,而是選票。理論上,這種投票鏈可能會把票集中到人緣好的菁英或獨裁者身上,但好在有個防錯機制,可以在任何時候取消委託投票,有野心的海盜也得認真才能成事。Bormuth 說,我們讓有戰鬥力的人可以成事,但也讓大家有權控制這些人。 117 | 118 | ### 結語 119 | 120 | 雖然德國的國情與台灣不同,不過在網路時代,各國的做法都可以很透明的被大家所參考模仿,然後經過嘗試後找到一個比較適合自己國家的實施方式, 121 | 運用網路來改變政治結構啊! 122 | 123 | ### 參考文獻 124 | * [工程師的鍵盤革命:拆政府,原地重建](http://www.inside.com.tw/2013/08/05/coscup-2013-coders-keyboard-revolution), inside 網站。 125 | * [PTT 精華區 - 閱讀文章 (Emergency)](http://www.ptt.cc/man/Emergency/D8B1/M.1252037298.A.654.html) 126 | * 維基百科:[中度颱風莫拉克] 127 | * 維基百科:[八八水災] 128 | 129 | [中度颱風莫拉克]:http://zh.wikipedia.org/zh-tw/%E9%A2%B1%E9%A2%A8%E8%8E%AB%E6%8B%89%E5%85%8B_(2009%E5%B9%B4) 130 | [八八水災]:http://zh.wikipedia.org/wiki/%E5%85%AB%E5%85%AB%E6%B0%B4%E7%81%BD 131 | [洪仲秋被虐死一案]:http://zh.wikipedia.org/zh-tw/%E6%B4%AA%E4%BB%B2%E4%B8%98%E6%9E%89%E6%AD%BB%E4%BA%8B%E4%BB%B6 132 | [公民 1985 行動聯盟]:http://zh.wikipedia.org/wiki/%E5%85%AC%E6%B0%911985%E8%A1%8C%E5%8B%95%E8%81%AF%E7%9B%9F 133 | [PiratePad]:http://www.piratenpad.de/ 134 | 135 | 【本文由陳鍾誠取材並修改自維基百科】 136 | 137 | -------------------------------------------------------------------------------- /code/oc/as1_bak.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | var util = require("util"); 3 | var c = require("./ccc"); 4 | var opTable = require("./cpu1").opTable; 5 | var Memory = require("./memory"); 6 | 7 | var parseR = function(str) { 8 | var rmatch = /R(\d+)/.exec(str); 9 | if (rmatch == null) 10 | return NaN; 11 | return parseInt(rmatch[1]); 12 | } 13 | 14 | var Assembler = function() { 15 | 16 | this.symTable = {}; 17 | 18 | this.assemble = function(asmFile, objFile) { // 組譯器的主要函數 19 | c.log("\nAssembler:asmFile=%s objFile=%s\n", asmFile, objFile); // 輸入組合語言、輸出目的檔 20 | c.log("===============Assemble=============\n"); 21 | 22 | var text = fs.readFileSync(asmFile, "utf8"); // 讀取檔案到 text 字串中 23 | this.lines = text.split(/[\r\n]+/); // 將組合語言分割成一行一行 24 | c.log(this.lines); 25 | 26 | this.pass1(this.lines); // 第一階段:計算位址 27 | c.log("===============SYMBOL TABLE=========\n"); // 印出符號表 28 | for (s in this.symTable) { 29 | c.log("%s %s\n", c.fill(' ',s,8), c.hex(this.symTable[s].address, 4)); 30 | } 31 | this.pass2(this.codes); // 第二階段:建構目的碼 32 | this.saveObjFile(objFile); // 輸出目的檔 33 | } 34 | 35 | this.pass1 = function(lines) { // 第一階段的組譯 36 | var address = 0; 37 | c.log("\n=================PASS1================\n"); 38 | this.codes = []; 39 | for (i in lines) { // 對於每一行 40 | if (lines[i].length == 0) continue; 41 | var code = new Code(lines[i]); // 剖析並建立 code 物件 42 | code.address = address; // 設定該行的位址 43 | if (code.label.length != "") // 如果有標記符號 44 | this.symTable[code.label] = code; // 加入符號表中 45 | this.codes.push(code); 46 | code.print(); 47 | address += code.size(); // 計算下一個指令位址 48 | } 49 | } 50 | 51 | this.pass2 = function() { // 組譯器的第二階段 52 | c.log("=============PASS2==============\n"); 53 | for (i in this.codes) { // 對每一個指令 54 | var code = this.codes[i]; 55 | this.translate(code); // 進行編碼動作 56 | code.print(); 57 | } 58 | } 59 | 60 | this.translate = function(code) { // 指令的編碼函數 61 | var ra=0, rb=0, rc=0, cx=0; 62 | var pc = code.address + 4; // 提取後PC為位址+4 63 | var args = code.args; 64 | var labelCode = null; 65 | var symTable = this.symTable; 66 | if (code.op.type == "N") { 67 | code.obj = c.hex(code.op.id, 2) + c.hex(0, 6); 68 | } else if (code.op.type == "C") { 69 | ra = parseR(args[0]); 70 | rb = parseR(args[1]); 71 | cx = parseInt(args[2]); 72 | code.obj = c.hex(code.op.id, 2)+c.hex(ra, 1)+c.hex(rb, 1)+c.hex(cx, 4); 73 | } else if (code.op.type == "L") { 74 | ra = parseR(args[0]); 75 | rb = 15; 76 | labelCode = symTable[args[1]]; 77 | cx = labelCode.address - pc; 78 | code.obj = c.hex(code.op.id, 2)+c.hex(ra, 1)+c.hex(rb, 1)+c.hex(cx, 4); 79 | } else if (code.op.type == "D") { 80 | var unitSize = 1; 81 | switch (code.op.name) { 82 | case "RESW": // 如果是 RESW 83 | case "RESB": // 或 RESB 84 | code.obj = c.dup('0', code.size()*2); 85 | break; 86 | case "WORD": // 如果是 WORD: 87 | unitSize = 4; 88 | case "BYTE": { // 如果是 BYTE : 輸出格式為 %2x 89 | code.obj = ""; 90 | for (i in args) { 91 | if (args[i].match(/\d+/)) // 常數 92 | code.obj += c.hex(parseInt(args[i]), unitSize*2); 93 | else { // 標記 94 | labelCode = symTable[args[i]]; 95 | code.obj += c.hex(labelCode.address, unitSize*2); 96 | } 97 | } 98 | break; 99 | } // case BYTE: 100 | } // switch 101 | } // if 102 | } 103 | 104 | this.saveObjFile = function(objFile) { 105 | c.log("\n=================SAVE OBJ FILE================\n"); 106 | var obj = ""; 107 | for (i in this.codes) { 108 | obj += this.codes[i].obj; 109 | } 110 | c.log("%s\n", obj); 111 | 112 | var m = new Memory(1); 113 | m.loadhex(obj); 114 | m.save(objFile); 115 | } 116 | } 117 | 118 | var Code = function(line) { 119 | this.print = function() { 120 | c.log(this.toString()); 121 | } 122 | 123 | this.toString = function() { 124 | return util.format("%s %s %s %s %s %s", c.hex(this.address,-4), 125 | c.fill(' ',this.label,8), c.fill(' ',this.op.name, 8), 126 | c.fill(' ',this.args, 16), c.hex(this.op.id,2), this.obj); 127 | } 128 | 129 | this.size = function() { 130 | switch (this.op.name) { // 根據運算碼 op 131 | case "RESW" : return 4 * parseInt(this.args[0]); // 如果是 RESW, 大小為 4*保留量(參數 0) 132 | case "RESB" : return 1 * parseInt(this.args[0]); // 如果是 RESB, 大小為 1*保留量(參數 0) 133 | case "WORD" : return 4 * this.args.length; // 如果是WORD, 大小是 4*參數個數 134 | case "BYTE" : return 1 * this.args.length; // 如果是BYTE, 大小是 1*參數個數 135 | case "" : return 0; // 如果只是標記, 大小為 0 136 | default : return 4; // 其他情形 (指令), 大小為 4 137 | } 138 | } 139 | 140 | var labCmd = /^((\w+):)?\s*([^;]*)/; 141 | var parts = labCmd.exec(line); // 分割出標記與命令 142 | this.label = c.nonull(parts[2]); // 取出標記 (\w+) 143 | var tokens = parts[3].split(/[ ,\t\r]+/); // 將命令分割成基本單元 144 | var opName = tokens[0]; // 取出指令名稱 145 | this.args = tokens.slice(1); // 取出參數部份 146 | this.op = opTable[opName]; 147 | this.obj = ""; 148 | } 149 | 150 | var argv = process.argv; 151 | var a = new Assembler(); 152 | a.assemble(argv[2], argv[3]); 153 | 154 | module.exports = Assembler; -------------------------------------------------------------------------------- /code/oc/vm0.js: -------------------------------------------------------------------------------- 1 | var c = require("./ccc"); 2 | var cpu1 = require("./cpu0"); 3 | var Memory = require("./memory"); 4 | 5 | var isDump = process.argv[3] == "-d"; 6 | 7 | var IR = 16, PC = 15, LR = 14, SP = 13, SW = 12; 8 | var ID = function(op) { return cpu1.opTable[op].id; } 9 | 10 | var run = function(objFile) { 11 | R = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 13, -1, 0, 16]; 12 | m = new Memory(1); 13 | m.load(objFile); 14 | if (isDump) m.dump(); 15 | var stop = false; 16 | while (!stop) { // 如果尚未結束 17 | var tpc = R[PC]; 18 | R[0] = 0; // R[0] 永遠為 0 19 | R[IR] = m.geti(R[PC]); // 指令擷取,IR=[PC..PC+3] 20 | R[PC] += 4; // 擷取完將 PC 加 4,指向下一個指令 21 | var op = c.bits(R[IR], 24, 31); // 取得 op 欄位,IR[24..31] 22 | var ra = c.bits(R[IR], 20, 23); // 取得 ra 欄位,IR[20..23] 23 | var rb = c.bits(R[IR], 16, 19); // 取得 rb 欄位,IR[16..19] 24 | var rc = c.bits(R[IR], 12, 15); // 取得 rc 欄位,IR[12..15] 25 | var c24= c.signbits(R[IR], 0, 23); // 取得 24 位元的 cx 26 | var c16= c.signbits(R[IR], 0, 15); // 取得 16 位元的 cx 27 | var c5 = c.bits(R[IR], 0, 4); // 取得 16 位元的 cx 28 | var addr = R[rb]+c16; 29 | var raddr = R[rb]+R[rc]; // 取得位址[Rb+Rc] 30 | var N = c.bits(R[SW], 31, 31); 31 | var Z = c.bits(R[SW], 30, 30); 32 | // c.log("IR=%s ra=%d rb=%d rc=%d c24=%s c16=%s addr=%s", c.hex(R[IR], 8), ra, rb, rc, c.hex(c24, 6), c.hex(c16, 4), c.hex(addr, 8)) 33 | switch (op) { // 根據op執行動作 34 | case ID("LD") : R[ra] = m.geti(addr); break; // 處理 LD 指令 35 | case ID("ST") : // 處理 ST 指令 36 | m.seti(addr, R[ra]); 37 | if (isDump) c.log("m[%s]=%s", c.hex(addr,4), m.geti(addr)); 38 | break; 39 | case ID("LDB"): R[ra] = m.getb(addr); break; // 處理 LDB 指令 40 | case ID("STB"): m.setb(addr, R[ra]); break; // 處理 STB 指令 41 | case ID("LDR"): R[ra] = m.geti(raddr); break; // 處理 LDR 指令 42 | case ID("STR"): m.seti(raddr, R[ra]); break; // 處理 STR 指令 43 | case ID("LBR"): R[ra] = m.getb(raddr); break; // 處理 LBR 指令 44 | case ID("SBR"): m.setb(raddr, R[ra]); break; // 處理 SBR 指令 45 | case ID("LDI"): R[ra] = c16; break; // 處理 LDI 指令 46 | case ID("CMP"): { // 處理 CMP指令,根據比較結果,設定 N,Z 旗標 47 | if (R[ra] > R[rb]) { // > : SW(N=0, Z=0) 48 | R[SW] &= 0x3FFFFFFF; // N=0, Z=0 49 | } else if (R[ra] < R[rb]) { // < : SW(N=1, Z=0, ....) 50 | R[SW] |= 0x80000000; // N=1; 51 | R[SW] &= 0xBFFFFFFF; // Z=0; 52 | } else { // = : SW(N=0, Z=1) 53 | R[SW] &= 0x7FFFFFFF; // N=0; 54 | R[SW] |= 0x40000000; // Z=1; 55 | } 56 | ra = 12; 57 | break; 58 | } 59 | case ID("MOV"): R[ra] = R[rb]; break; // 處理MOV指令 60 | case ID("ADD"): R[ra] = R[rb]+R[rc]; break; // 處理ADD指令 61 | case ID("SUB"): R[ra] = R[rb]-R[rc]; break; // 處理SUB指令 62 | case ID("MUL"): R[ra] = R[rb]*R[rc]; break; // 處理MUL指令 63 | case ID("DIV"): R[ra] = R[rb]/R[rc]; break; // 處理DIV指令 64 | case ID("AND"): R[ra] = R[rb]&R[rc]; break; // 處理AND指令 65 | case ID("OR") : R[ra] = R[rb]|R[rc]; break; // 處理OR指令 66 | case ID("XOR"): R[ra] = R[rb]^R[rc]; break; // 處理XOR指令 67 | case ID("SHL"): R[ra] = R[rb]<>c5; break; // 處理SHR指令 69 | case ID("ADDI"):R[ra] = R[rb] + c16; break; // 處理 ADDI 指令 70 | case ID("JEQ"): if (Z==1) R[PC] += c24; break; // 處理JEQ指令 Z=1 71 | case ID("JNE"): if (Z==0) R[PC] += c24; break; // 處理JNE指令 Z=0 72 | case ID("JLT"): if (N==1&&Z==0) R[PC] += c24; break; // 處理JLT指令 NZ=10 73 | case ID("JGT"): if (N==0&&Z==0) R[PC] += c24; break; // 處理JGT指令 NZ=00 74 | case ID("JLE"): if ((N==1&&Z==0)||(N==0&&Z==1)) R[PC]+=c24; break; // 處理JLE指令 NZ=10 or 01 75 | case ID("JGE"): if ((N==0&&Z==0)||(N==0&&Z==1)) R[PC]+=c24; break; // 處理JGE指令 NZ=00 or 01 76 | case ID("JMP"): R[PC]+=c24; break; // 處理JMP指令 77 | case ID("SWI"): // 處理SWI指令 78 | switch (c24) { 79 | case 3: c.printf("%s", m.getstr(R[9])); break; 80 | case 4: c.printf("%d", R[9]); break; 81 | default: 82 | var emsg = c.format("SWI cx=%d not found!", c24); 83 | c.error(emsg, null); 84 | break; 85 | } 86 | break; 87 | case ID("JSUB"):R[LR] = R[PC]; R[PC]+=c24; break; // 處理JSUB指令 88 | case ID("RET"): if (R[LR]<0) stop=true; else R[PC]=LR; break; // 處理RET指令 89 | case ID("PUSH"):R[SP]-=4; R[ra]=m.geti(addr); m.seti(R[SP], R[ra]); break; // 處理PUSH指令 90 | case ID("POP"): R[ra] = m.geti(R[SP]); R[SP]+=4; break; // 處理POP指令 91 | case ID("PUSHB"):R[SP]--; R[ra]=m.getb(addr); m.setb(R[SP], R[ra]); break; // 處理PUSH指令 92 | case ID("POPB"):R[ra] = m.getb(R[SP]); R[SP]++; break; // 處理POPB指令 93 | default: c.error("OP not found!", null); 94 | } // switch 95 | if (isDump) 96 | c.log("PC=%s IR=%s SW=%s R[%s]=0x%s=%d", // 印出 PC, IR, R[ra]暫存器的值,以利觀察 97 | c.hex(tpc,4), c.hex(R[IR],8), c.hex(R[SW],8), c.hex(ra,2), c.hex(R[ra], 8), R[ra]); 98 | } // while 99 | } 100 | 101 | run(process.argv[2]); 102 | -------------------------------------------------------------------------------- /source/article2.md: -------------------------------------------------------------------------------- 1 | ## JavaScript (9) – Google 的語音合成 API 之使用 (作者:陳鍾誠) 2 | 3 | ### 簡介 4 | 5 | 我還記得在 1996 年時,我到中研院許老師的實驗室當助理,做了兩年自然語言處理的相關程式, 6 | 學習到其中主要較成熟的技術像是「注音轉國字」(對應產品為自然輸入法),然後這兩年整個實驗室 7 | 還試圖去研究一些較不成熟,但卻具有挑戰性的技術,特別是「自然語言理解」領域的一些嘗試,例如 8 | 有位同事就發展出了一個有趣的程式,當您輸入小學課本中的數學問題時,該程式可以輸出該問題的解答。 9 | 10 | 自然語言技術一直是筆者相當關心的領域,雖然筆者的關注比較偏向「文字」部分,在去年於金門大學 11 | 教授「計算語言學」這門課時,我就將這些相關的技術寫成了一本書,放在筆者的 github 當中,您可以 12 | 從以下的網址找到這本書。 13 | 14 | * 陳鍾誠的教科書 -- 15 | * 語言處理技術 -- 16 | 17 | 但是,自然語言處理可以說是一門既深奧又困難的領域,雖然研究了很久,但筆者一直還沒有去觸碰 18 | 「語音合成」與「語音辨識」這兩個領域的主題,對這種「語音領域」的東西可以說是既期待又怕受傷害啊! 19 | 20 | 不過、現在由於「微軟」與 Google 等軟體大廠,都已經投入了非常多的資源在研究這些先進的領域, 21 | 並且製作出了足以商品化的功能,因此我們只要善用他們所釋出的 API,就可以輕鬆的應用這些功能了。 22 | 23 | 在本文中,我們將介紹如何使用 HTML+JavaScript 技術,去使用 Google 所提供的「語音辨識與合成」的服務。 24 | 25 | ### 語音合成的 Google 服務 26 | 27 | Google 的語音合成服務非常容易使用,因為您只要利用 Google 翻譯中的 TTS (Text to Speech) 功能,將 28 | 文字放到以下網址中的 {query} 欄位中,然後設定正確的語言欄 {lang},就可以取得這句話的語音檔了。 29 | 30 | > http://translate.google.com/translate_tts?ie=utf-8&tl={lang}&q={query} 31 | 32 | 舉例而言,假如您想讓瀏覽器說出 Text to speech 這句英文,只要將 {lang} 設為 en,然後將 {query} 設為 Text to speech 33 | 即可,您可以點選下列網址聽到 Google 所合成的語音。 34 | 35 | * [http://translate.google.com/translate_tts?ie=utf-8&tl=en&q=Text to speech](http://translate.google.com/translate_tts?ie=utf-8&tl=en&q=Text to speech) 36 | 37 | 如果您想讓瀏覽器說中文,那麼 {lang} 欄位就必須要設定為 zh,例如您可以點選下列網址廳到「語音合成」這句話。 38 | 39 | * 40 | 41 | 一但瞭解了 Google TTS 功能的使用方式之後,您就可以很容易的在網頁中嵌入這樣的「功能元件」了。 42 | 43 | 在 HTML 5.0 當中有個特殊的標記, 可以在網頁中嵌入語音,那就是 `