例外処理を追加した Lua 処理系
河原 悟
情報特別演習 報告会

January 12, 2016実装

情報特別演習 報告会
概要
実装
parsePEG

ついeval

CPS

実行例
め･課題

つい• 概要◮ン

軽量ー◮ 関数開発

言語 Lua インタロ◮◮◮ 既存処理系

ート言語
組 込トター

実装(FreeBSD LuaLATEX扱え)

い例外処理機能 追加
Code 1: try-catch in Lua Sample-- try blocktry✿✿✿
for i = 1, 10 do
if i > 9 thenthrow() -- goto catch block✿✿✿✿✿✿✿
end
print(i)endcatch--catch block✿✿✿✿✿
print("thrown")
end
概要

1/9

情報特別演習 報告会
概要
実装
parsePEG

ついeval

CPS

実行例
め･課題

つい• 実装
実装 *1
CoffeeScript 類似した簡潔◮ MoonScript

構文

Lua へ変換可能

Code 2: MoonScript Sample
f = (fun, e, n)->for i = 1, n
fun e
f print, "hello", 10-- print "hello" 10 times.
◮ 720 行程度
◮ CPS を用いた例外処理

*1

実装

実装

version 0.4.02(https://github.com/leafo/moonscript/tree/v0.4.0)

2/9

情報特別演習 報告会
概要
実装
parsePEG

ついeval

CPS

実行例
め･課題

つい•parse – PEG◮ Parsing Expression Grammar◮ 構文解析

字句解析を同時◮ Lua 向け PEG モ

ュー略行え
あLPeg*2 を用いた *3........
Colonfunc: P':' * V'Space' * CV'Name' * V'Space' * V'Callargs' / lbl_tbl 'colonfunc', 'func', 'args'
Call: V'Callargs' + V'Colonfunc' -- * V'Space' * V'Callargs' / lbl_tbl'colonfunc'
Prefix: spaces(P'(', V'Exp', P')') + CV'Name'
Suffix: V'Call' + V'Index'
Var: (V'Prefix' * ast(V'Space' * V'Suffix' * #(V'Space' * V'Suffix')) * V'Space' * V'Index' + CV'Name') / gen_tblaccessFuncall: V'Prefix' * ast(V'Space' * V'Suffix' * #(V'Space' * V'Suffix')) / gen_tblaccess * V'Space' * V'Call' / lbl_tbl'funcall'
Funcname: CV'Name' * ast(V'Space' * P'.' * V'Space' * CV'Name') * opt(V'Space' * P':' * V'Space' * CV'Name')
Callargs:
Ct(P'(' * V'Space' * opt(V'Explist' * V'Space') * P')' +(V'Tableconstructor' + V'String'))
Funcdef: K'function' * V'Space' * V'Funcbody' * V'Space' * K'end' / lbl_tbl('annonymousfuncdef', 'args', 'body')
Funcbody: spaces P'(', (opt(V'Parlist') / lbl_tbl'args'), P')', CtV'Block'
Parlist: (V'Namelist' * opt(V'Space' * P',' * V'Space' * CP'...') + CP'...')
Tableconstructor: P'{' * V'Space' * (opt(V'fieldlist' * V'Space') / lbl_tbl'constructor') * P'}'
fieldlist: V'Field' * ast(V'Space' * V'Fieldsep' * V'Space' * V'Field') * opt(V'Space' * V'Fieldsep')
Field:Ct(spaces(P'[', CtV'Exp', P']', P'=', V'Exp')) +Ct(spaces(CV'Name', P'=', V'Exp')) + V'Exp'}......

*2

http://www.inf.puc-rio.br/~roberto/lpeg/*3

実際実装.parse

LPeg

Lua 実装 あLuLPeg を用いた https://github.com/pygy/LuLPeg

3/9

情報特別演習 報告会
概要実装
parsePEG

ついevalCPS

実行例
め･課題

つい•eval – CPS◮ 継続渡し形式

Continuation Passing Style◮ 例外発生時

こ継続を破棄す略

例外処理を実現......
funstack\pushcresume -> eval def.body, nenv, k0
ret = funstack\pop!
ret[2] and unpack ret[2] or nil
k nenv[def.name]eval_args = (arglist, env, k0, k) ->unless arglist[1]k arglist
else
head = remove arglist, 1
argf = -> eval_exp head, env, k0, (x) ->eval_args arglist, env, k0, (y) ->_insert y, 1, x
k yunless arglist[1]if is_funcall head
eval_funcall head[1], head[2], env, k0, (x) ->eval_args arglist, env, k0, (y) ->k with y do for i = 1, #x do _insert y, x[i]elseif head == "..."
eval_args env[head], env, k0, (t) -> k t......

実装.eval

4/9•eval – CPS

例: 整数

トを受け取総乗を返す関数

Code 4: mul_list_cps.moon

Code 3: mul_list.moon
mul_list = (t) ->h = table.remove t, 1switch hwhen nil then 1else h * mul_list t
print mul_list {1, 2, 3} -- 6

実装.eval⇒-> ✿✿x) ->mul_list_cps = (t, k✿✿✿=✿✿(✿x✿)✿✿✿✿
h = table.remove t, 1switch h
1when nil then k✿✿✿else mul_list_cps t, ✿(✿✿x)✿✿✿✿->✿✿k✿✿x✿✿✿* ✿✿hprint mul_list_cps {1, 2, 3} -- 6

5/9

•eval – CPS

Code 6: pseudo mul_list_cps

Code 5: pseudo mul_list
f [1,2,3]= 1 * f [2, 3]= 1 * (2 * f [3])= 1 * (2 * (3 * f []))
= 1 * (2 * (3 * 1))
= 6関数

処理
こ⇒

内容を渡しそを継続

呼処理

しい↓
こ実装.eval関数

f' [1,2,3], ✿✿✿((x✿)✿✿✿✿->✿✿x✿)= f' [2,3],((x) -> ✿1 * x)
= f' [3],((x) -> 1 ✿*✿✿✿2 * x)
= f' [],((x) -> 1 * 2 *✿✿✿3 * x)
= ((x) -> 1 * 2 * 3 * x) 1
= 1 * 2 * 3 * 1= 6関数(継続)を捨こ

例外処理を実現

6/9

•eval – CPS
Code 3,4 拡張: 整数を発生す 関数

トを受け取

Code 7: mul_list_excep.moon
mul_list_excep = (t) ->h = table.remove t, 1switch hwhen 00, print "ZeroMultiple Error"-- error handling, but return 0
when nil then 1
else h * mul_list_excep t
print mul_list_excep {1, 2, 3}-- 6
print mul_list_excep {1, 2, 3, 0}-- ZeroMultiple Error-- 0
実装.eval

総乗を返す

0

含

い 時 例外Code 8: mul_list_excep_cps.moon->✿✿x) ->mul_list_excep_cps = (t, ✿k✿✿=✿✿(✿x✿)✿✿✿
h = table.remove t, 1
switch hwhen 0 then print "ZeroMultiple Error"-- dump `k`when nil then k✿✿✿1⇒else mul_list_excep_cps t,(x) -> k x * h✿✿✿✿✿✿✿✿✿✿✿✿✿✿
print mul_list_excep_cps {1, 2, 3}-- 6
print mul_list_excep_cps {1, 2, 3, 0}-- ZeroMultiple Error
7/9

情報特別演習 報告会
概要
実装
parsePEG

ついeval

CPS

実行例
め･課題

つい• 実行例◮ 対話型電卓◮◮

ロ除算 パー エ ーー 全体 こち *4

例外処理を使用......
try -- catch zero division
for i = 1, #x, 2 do
local op = x[i]local n2 = eval(x[i + 1])
if op == "/" and n2 == 0 then throw() end
n1 = op_table[op](n1, n2)
end
return n1
catch
print "ZeroDivision Error"
end......
*4

実行例

https://gist.github.com/Nymphium/aedeb3fab71fe7f1f412......
try -- parsed or not
local t = parse(l)if not t then throw() end
local e = eval(t)if e thenprint("ANS " .. tostring(e))
end
catch
print "!!parse error!!"end......

8/9

情報特別演習 報告会
概要
実装
parsePEG

ついeval

CPS

実行例
め･課題

つい•

め･課題め◮Lua サLua
◮ 拡張◮

◮◮◮

テット インタター 実装
部分 (while for if functiontable)

実装完了

処理系を CPS 変換
try-catch構文 追加

ト･実行例

◮ 課題
◮◮め･課題実行速度 改善 ⇒Lua へ 完全対応

ンパイ作成9/9