overview
contents
show-all
home
#+TITLE: 小蟬語於 SZDIY
#+AUTHOR: 謝宇恆 / XIE Yuheng
* ===================================
* 題解
** cicada-nymph 的解釋器
*** 執行函數
#+begin_src cicada-nymph
3 4 add .
3
4
add
.
4 dup mul .
4
dup
mul
.
#+end_src
*** 定義函數
#+begin_src cicada-nymph
: square
dup mul
end
; define-function
4 square .
#+end_src
*** 遞歸函數
#+begin_src cicada-nymph
: factorial
dup one? if
end
then
dup sub1 factorial mul
end
; define-function
4 factorial .
4 3 2 1 mul mul mul .
#+end_src
** cicada-instar
* 珠子
** 我只記住了抽象的模型
* 我忘記了具體實現這個模型的代碼是什麼
我只記住了抽象的模型
** 珠子的分類
* 素函數珠 [primitive-function-jo] 用匯編代碼寫
* 函數珠 [function-jo] 用線串碼寫
* 變量珠 [variable-jo]
* 一顆珠子代表一個函數
一串珠子代表一些函數的複合做形成的函數體
一個函數體可以被給以名字
而定義爲一個新的函數
** 珠子比喻函數 一串珠子比喻函數體
* 定義新的函數就是
1. 用已有的函數 *構造* 一個 *函數體*
2. 給這個 函數體 一個名字
* 這裏 *構造* 的方式就是 *函數複合*
就是 函數的相機作用
就是 把珠子串成串
一串珠子就代表 函數體
穿珠子的過程就像是 製作複合函數的過程
** 關於函數複合
* 數學裏記做
(g ∘ f)(x) = g(f(x))
我記做
f g
參數 x 在參數棧裏 不用明顯寫出來
** 珠子的詞典
* label dup 的值[即一個內存中的地址]
就被理解爲 dup 這個珠子 在珠子的詞典中的位置
* 找到了這個位置
就找到了詞典中這個條目下的所有信息
* 素珠
** define_primitive_function
#+begin_src fasm
macro define_primitive_function string, jo {
name__#jo:
xx current_free_address$string_area
make_primitive_string string
link__#jo:
xx link
link = link__#jo
jo:
xx assembly_code__#jo
assembly_code__#jo:
}
#+end_src
** dup
#+begin_src fasm
define_primitive_function "dup", dup
pop_argument_stack rax
push_argument_stack rax
push_argument_stack rax
next
name__dup:
xx current_free_address$string_area
make_primitive_string "dup"
link__dup:
xx link
link = link__dup
dup:
xx assembly_code__dup
assembly_code__dup:
pop_argument_stack rax
push_argument_stack rax
push_argument_stack rax
next
#+end_src
* 非素珠
** define_function
#+begin_src fasm
macro define_function string, jo {
name__#jo:
xx current_free_address$string_area
make_primitive_string string
link__#jo:
xx link
link = link__#jo
jo:
xx explain$function
}
#+end_src
** square
#+begin_src fasm
define_function "square", square
xx dup
xx multiple
xx end
name__square:
xx current_free_address$string_area
make_primitive_string "square"
link__square:
xx link
link = link__square
square:
xx explain$function
xx dup
xx multiple
xx end
#+end_src
* 棧 [掠過]
* 函數語義之形成
** 參數棧與返回棧
* 參數棧 [argument-stack]
* 返回棧 [return-stack]
** 參數傳遞
* 利用 參數棧
* 你可以想像每個 素函數珠
能夠幫你召喚出一個小機器人[或者小精靈]
來爲你做一些計算和操作
* 計算的材料都要從 參數棧 中取 [即函數的參數]
並且計算的結果也要返回 棧參數 中 [即函數的返回值]
比如
#+begin_src return-stack
(mul) : 素函數珠
它召喚出來一個小精靈
幫你做乘法
(dup) : 素函數珠
它召喚出來一個小精靈
來把 參數棧 頂部的數複製一下
(square) : 複合函數珠
因爲它是被分解成
上面的兩個 素函數 的複合的
#+end_src
* 這樣 參數棧 就成了 小精靈們 傳遞計算結果的場所
一個 小精靈 計算成果
可以被作爲 另一個 小精靈 的參數
** 函數的 嵌套定義 與 嵌套調用 用 next 和 explain$function 實現
*** next
#+begin_src fasm
macro next {
pop_return_stack rbx
mov rax, [rbx]
add rbx, cell_size
push_return_stack rbx
jmp dword [rax]
}
#+end_src
*** explain$function
* find a jojo from a function-jo
and push the jojo to return-stack
* use rax as an argument
which stores a jo
#+begin_src fasm
explain$function:
add rax, cell_size
push_return_stack rax
next
#+end_src
** 函數的 嵌套定義 與 嵌套調用 的抽象描述
* 你可以把 返回棧 return-stack 想像成一個鉄棍子
棍子串着一溜圈子
#+begin_src return-stack
- [ . ] - [ . ] - [ . ] - [ . ] - [ . ]
#+end_src
圈子上可以卡珠子
一串珠子中的某個珠子 可以被卡在棍子的圈子上
#+begin_src return-stack
(666)
(22) (666)
- [ (22) ] - [ (33) ] - [ (666) ] - [ . ] - [ . ]
(22) (33)
(22) (33)
(33)
#+end_src
* 只要把一串珠子放到返回棧裏
然後啓動 線串碼解釋器
就能形成函數 調用 與 返回 的語義了
* 比如下面的例子所展示的
*** at the beginning
* argument-stack
<< 2 >>
* return-stack
#+begin_src return-stack
- [ (square) ]
(square)
(end)
#+end_src
*** next (1)
* argument-stack
<< 2 >>
* return-stack
#+begin_src return-stack
(square)
- [ (square) ] - [ (dup) ]
(end) (mul)
(end)
#+end_src
*** next (2)
* argument-stack
<< 2, 2 >>
* return-stack
#+begin_src return-stack
(square) (dup)
- [ (square) ] - [ (mul) ]
(end) (end)
#+end_src
*** next (3)
* argument-stack << 4 >>
* return-stack
#+begin_src return-stack
(dup)
(square) (mul)
- [ (square) ] - [ (end) ]
(end)
#+end_src
*** next (4)
* argument-stack << 4 >>
* return-stack
#+begin_src return-stack
(square)
- [ (square) ]
(end)
#+end_src
*** next (5)
* argument-stack << 4 >>
* return-stack
#+begin_src return-stack
(square)
(square)
- [ (end) ] - [ (dup) ]
(mul)
(end)
#+end_src
*** next (6)
* argument-stack
<< 4, 4 >>
* return-stack
#+begin_src return-stack
(square)
(square) (dup)
- [ (end) ] - [ (mul) ]
(end)
#+end_src
*** next (7)
* argument-stack
<< 16 >>
* return-stack
#+begin_src return-stack
(square) (dup)
(square) (mul)
- [ (end) ] - [ (end) ]
#+end_src
*** next (8)
* argument-stack
<< 16 >>
* return-stack
#+begin_src return-stack
(square)
(square)
- [ (end) ]
#+end_src
*** next (9)
* argument-stack
<< 16 >>
* return-stack
#+begin_src return-stack
- [ ]
#+end_src
* it is really simple
^-^
is it not ?
* ===================================