元計算的乙個實際用例

2022-09-20 21:36:15 字數 3108 閱讀 1206

元計算是我設計的太極語言中乙個重要的特徵。這裡元計算指的是在編譯時間執行從源語言**編譯後獲得的目標語言**。受到c語言中的預處理指令字首#(#define, #if-#else等)的啟發,我選用#開頭的一組符號作為各種元運算的算符。比如##expression 是編譯時間執行expression, # if ..., # let ...,  # while ..., # try ... 等將先對後續**進行某種類似lisp的巨集轉換,然後在編譯時間進行計算,通過這種轉換,# if 會有c語言下的條件編譯的效果,# let 等等也都具有各自的功能,因此某種程度上#是c語言的預處理指令通用化以後的乙個算符,如果#後面不是這些特殊語句,而是乙個普通的表示式,那麼其效果與##相同。元算符#.的作用是讓#.expression同時在編譯時間和執行時間有效。

元計算可以有很大的威力,可以想象到很多應用的可能。以下例子,只是很多用途中的一種。

在下面的例子中,text是解析器正在解析的整個文字,cursor是當前全域性解析位置,parserlineno和parserrow分別是全域性行號和列號。

考慮到處理換行符號,匹配任意文字的解析函式可以這樣寫

literal = (string) -> 

start = cursor; lineno = parserlineno; row = parserrow

for c in string

if c==text[cur++]

if c=='\n' then parserlineno++; parserrow = 0

else if c=='\r' then parserrow = 0; continue

else parserrow++

else cursor = start; parserlineno = lineno; parserrow = row; return

true

但是在實際應用中,絕大多數情況下我們都不需要考慮換行符號,因此使用如下的函式就可以了。

literal2 = (string) ->

start = cursor; row = parserrow

for c in string

if c==text[cursor++] then parserrow++

else cursor = start; parserrow = row; return

true

或者更快捷的實現

literal2 = (string) -> if text[cursor...cursor+length]==string then cursor += length; parserrow += length-1; true

下面是解析while語句的函式,作為例子,做了一些簡化:

whilestatement = >

if literl('while') and (test = parser.clause())? and literal('then') and (body=parser.block() or parser.line())

return ['while', test, body]

出於速度的原因,我們應該將上面whilestatement實現**中的literal替換成literal2。

對於這樣乙個功能簡單的小問題引入兩個函式,無疑會增加api的數量,從文件提供和庫使用者的學習使用的角度來講都是一種負擔。另外仔細分析,上面的通用文字處理函式literal還有優化的空間,由此引出了下面第二種方案。

第二種方案

literal = (string) ->

i = 0; linenumber = 0; length = string.length

while c = string[i++]

if c=='\n' then linenumber++; row = 0

else if c=='\r' then _r = true; continue

else row++

if linenumber==0

if _r then -> if text[cursor...cursor+length]==string then cursor += length; parserrow += length-1; true

else -> if text[cursor...cursor+length]==string then cursor += length; parserrow += length; true

else -> if text[cursor...cursor+length]==string then cursor += length; parserlineno += linenumber; parserrow += row; true

在此實現下,whilestatement的**如下:

whilestatement = >

if literal('while')() and (test = parser.clause())? and literal('then')() and (body=parser.block() or parser.line())

return ['while', test, body]

然而,這樣寫並不能提公升速度,反而會有效能損失,因為每次都必須要計算函式閉包。為了達到效能提公升的目的,我們應該把對於的閉包計算提到函式之外:

因此應該這樣寫

while_ = literal('while'); then_ = literal('then')

whilestatement = >

if while_() and (test = parser.clause())? and then_() and (body=parser.block() or parser.line())

return ['while', test, body]

元計算派上用場:

這種情況正好是我設計的新語言的元計算能力的用武之地。

whilestatement = >

if #(literal('while'))() and (test = parser.clause())? and #(literal('then'))() and (body=parser.block() or parser.line())

return ['while', test, body]

元計算讓我們魚和熊掌兼得:同時擁有執行效率和程式設計效率。

用autoIt寫乙個計算稅收的程式

看了一兩個小時教程,發現這個指令碼語言很簡單,適合程式設計基礎薄弱的人。其實,我更想說的是,也許,我適合編寫軟體。ye dim k 3500 dim m,s m inputbox 稅收計算 請輸入你的月工資收入 if error 1 then exit if m then exit if m 350...

用python編寫乙個計算器

1 2 60 30 40.0 5 9 2 5 3 7 3 99 4 2998 10 568 14 4 3 16 3 2 通過python實現,自動判斷括號以及加減乘除的運算優先順序,得出運算結果,顯示運算步驟 import redef atom cal exp if in exp 計算單個的乘法 a...

通過乙個實際的例子學習SQLServer儲存過程

前面寫過一篇 通過乙個實際的例子學習oracle儲存過程,現在再來一篇 通過乙個實際的例子學習sqlserver儲存過程。所謂應用而學。定義儲存過程 create procedure xx p 傳遞引數 ym char 6 as 定義變數,xx表示區域性變數,xx表示全域性變數。定義多個變數用 號分...