main method
void
main()
Implementation
void main() {
ClipProc.errorProc = ( err, num, func, token ){
String str = ClipProcError.getDefString( err, token, false, false );
debugPrint( "$func: $num行: $str" );
};
ClipProc.printAnsMultiPrec = ( str ){
debugPrint( str );
};
ClipProc.doCommandPrint = ( topPrint, flag ){
String str = "";
ClipProcPrint? cur = topPrint;
while (cur != null) {
if (cur.string() != null) {
ParamString tmp = ParamString(cur.string());
tmp.replaceNewLine("\n");
str += tmp.str();
}
cur = cur.next();
}
// if (flag) {
// str += "\n";
// }
debugPrint( str );
};
EasyClip clip = EasyClip();
List<String> script = [
"func _mp_param &a[]",
" if strlen a > 0 # 文字列の場合",
" :ptype",
" a = mp a",
" end",
"end",
"func _mp_abs &rop[]",
" :mint",
" _mp_param rop",
" rop = abs rop",
"end",
"func _mp_fabs &rop[]",
" :global MP_PREC",
" :mfloat MP_PREC",
" _mp_param rop",
" rop = abs rop",
"end",
"func _mp_add &ret[] a[] b[]",
" :mint",
" _mp_param a",
" _mp_param b",
" ret = a + b",
"end",
"func _mp_fadd &ret[] a[] b[]",
" :global MP_PREC",
" :mfloat MP_PREC",
" _mp_param a",
" _mp_param b",
" ret = a + b",
"end",
"func _mp_div &q[] a[] b[] &r[]",
" :mint",
" _mp_param a",
" _mp_param b",
" if b == 0; return TRUE; end",
" q = a / b",
" r = a % b",
" return FALSE",
"end",
"func _mp_fdiv2 &ret[] a[] b[] prec",
" :mfloat prec",
" _mp_param a",
" _mp_param b",
" if b == 0; return TRUE; end",
" ret = a / b",
" return FALSE",
"end",
"func _mp_mul &ret[] a[] b[]",
" :mint",
" _mp_param a",
" _mp_param b",
" ret = a * b",
"end",
"func _mp_fmul &ret[] a[] b[] prec",
" :mfloat prec",
" _mp_param a",
" _mp_param b",
" ret = a * b",
"end",
"func _mp_neg &rop[]",
" :mint",
" _mp_param rop",
" rop = [-]rop",
"end",
"func _mp_fneg &rop[]",
" :global MP_PREC",
" :mfloat MP_PREC",
" _mp_param rop",
" rop = [-]rop",
"end",
"func _mp_set &rop[] op[]",
" :mint",
" _mp_param op",
" rop = op",
"end",
"func _mp_fset &rop[] op[]",
" :global MP_PREC",
" :mfloat MP_PREC",
" _mp_param op",
" rop = op",
"end",
"func _mp_sub &ret[] a[] b[]",
" :mint",
" _mp_param a",
" _mp_param b",
" ret = a - b",
"end",
"func _mp_fsub &ret[] a[] b[]",
" :global MP_PREC",
" :mfloat MP_PREC",
" _mp_param a",
" _mp_param b",
" ret = a - b",
"end",
"func _mp_fsqrt &ret[] a[] prec",
" :mfloat prec",
" _mp_param a",
" ret = sqrt a",
"end",
"func _mp_ftrunc &rop[] op[]",
" :global MP_PREC",
" :mfloat MP_PREC",
" _mp_param op",
" rop = int op",
"end"
];
clip.procScript( script );
List<String> script2 = [
"#多倍長計算を行う。エラー時はTRUEを返す。",
"#_mp <expr> [<prec>]",
"#precに0を指定すると整数モードになる。",
"#引数がexprのみの場合、桁数としてグローバル変数MP_PRECの値が参照される。",
"#",
"#書式:",
"# 演算の優先順位を指定する括弧()を使用することができる。",
"# 括弧は釣り合いがとれていなくても構わない。",
"#",
"#定数:",
"# 12345 符号なし整数",
"# \\-6789 符号付き整数",
"# 12.345 小数点表記の浮動小数点数",
"# 1.234e\\-5 指数表記の浮動小数点数",
"# \\-1.234e+5",
"# 1.234e5 eの後ろの+は省略できる。",
"#",
"#変数:",
"# Ans 計算結果用変数(親プロセスでの@@:0)",
"# a~z 変数(親プロセスでの@@a~@@z)",
"#",
"#演算子:",
"# 単項 \\-",
"# 二項 * / % + \\-",
"# 代入 =",
"#",
"#関数:",
"# abs(x) 絶対値",
"# sqr(x) 自乗",
"# sqrt(x) 平方根",
"# trunc(x) 小数点以下の切り捨て",
"#",
"#制限事項:",
"# %は整数モードのみ。",
"# sqrt,trunc関数は浮動小数点数モードのみ。",
"",
"func checkOp op",
" switch op",
" case 'N",
" return 4",
" case '\\*",
" case '\\/",
" case '\\%",
" return 3",
" case '\\+",
" case '\\-",
" return 2",
" case '\\=",
" return 1",
" end",
" return 0",
"end",
"",
"func isParenthesis token[] index",
" return token index (token index 0) == '\\(",
"end",
"",
"func insToken &token[] &tokenNum pos",
" :ans FALSE",
" for @i = tokenNum; @i > pos; @i--",
" :arraycopy token (@i-1) 0 token @i 0 (1 + token (@i-1) 0)",
" end",
" tokenNum++",
"end",
"",
"func makeToken expr[] &token[] &tokenNum",
" :ans FALSE",
"",
" # 空白を取り除く",
" :var exprLen",
" exprLen = 0",
" for @i = 0; expr @i != 0; @i++",
" if expr @i != [' ]",
" expr (exprLen++) = expr @i",
" end",
" end",
" expr exprLen = 0 # 文字列終端",
"",
" @c = 0",
" :var prev",
" @i = 0",
" token @i 0 = 0 # 文字数",
" @t = 0",
" for @j = 0; @j < exprLen; @j++",
" prev = @c",
" @c = expr @j",
" switch @c",
" case '\\(",
" case '\\)",
" case '\\*",
" case '\\/",
" case '\\%",
" case '\\+",
" case '\\-",
" case '\\=",
" if (@c == '\\() && (prev >= 'a && prev <= 'z)",
" token @i ([++]@t) = @c",
" token @i 0 = @t # 文字数",
" @i++",
" token @i 0 = 0 # 文字数",
" @t = 0",
" break",
" end",
" if (@c == '\\+) || (@c == '\\-)",
" if (prev == 'e) || (prev == 'E)",
" token @i ([++]@t) = @c",
" break",
" end",
" end",
" if @t > 0",
" token @i 0 = @t # 文字数",
" @i++",
" token @i 0 = 0 # 文字数",
" @t = 0",
" elif @c == '\\-",
" if (@j < exprLen - 1) && ((expr (@j + 1) >= '0 && expr (@j + 1) <= '9) || expr (@j + 1) == '.)",
" token @i ([++]@t) = @c",
" break",
" end",
" @c = 'N",
" end",
" token @i ([++]@t) = @c",
" token @i 0 = @t # 文字数",
" @i++",
" token @i 0 = 0 # 文字数",
" @t = 0",
" break",
" default",
" token @i ([++]@t) = @c",
" break",
" end",
" end",
" if @t > 0",
" token @i 0 = @t # 文字数",
" tokenNum = @i + 1",
" else",
" tokenNum = @i",
" end",
"",
" :var cur top end",
" :var level topLevel assLevel",
" assLevel = checkOp '\\=",
" :var retTop retEnd",
"",
" # 演算子の優先順位に従って括弧を付ける",
" cur = 0",
" while cur < tokenNum",
" if (token cur 0 == 1) && (checkOp (token cur 1) > 0)",
" # 自分自身の演算子の優先レベルを調べておく",
" level = checkOp (token cur 1)",
"",
" retTop = 0",
" retEnd = 0",
"",
" # 前方検索",
" @i = 0",
" top = cur - 1",
" while top >= 0",
" if isParenthesis token top # 括弧の始まりの場合",
" if @i > 0",
" @i--",
" else",
" retTop = 1",
" end",
" elif token top 1 == '\\) # 括弧の終わりの場合",
" @i++",
" elif (token top 0 == 1) && (checkOp (token top 1) > 0)",
" if @i == 0",
" topLevel = checkOp (token top 1)",
" if ((topLevel == assLevel) && (level == assLevel)) || (topLevel < level)",
" retTop = 2",
" end",
" end",
" end",
"",
" if retTop == 2",
" # 後方検索",
" @i = 0",
" end = cur + 1",
" while end < tokenNum",
" if isParenthesis token end # 括弧の始まりの場合",
" @i++",
" elif token end 1 == '\\) # 括弧の終わりの場合",
" if @i > 0",
" @i--",
" else",
" retEnd = 1",
" end",
" elif (token end 0 == 1) && (checkOp (token end 1) > 0)",
" if @i == 0",
" if (topLevel != assLevel) && (checkOp (token end 1) <= topLevel)",
" retEnd = 2",
" end",
" end",
" end",
" if retEnd > 0",
" break",
" end",
" end++",
" end",
"",
" @t = top + 1",
" insToken token tokenNum @t",
" token @t 1 = '\\(",
" token @t 0 = 1 # 文字数",
" cur++",
" end++",
"",
" if retEnd > 0",
" insToken token tokenNum end",
" token end 1 = '\\)",
" token end 0 = 1 # 文字数",
" end",
" end",
"",
" if retTop > 0",
" break",
" end",
" top--",
" end",
" end",
" cur++",
" end",
"",
" # 括弧を整える",
" @i = 0",
" cur = 0",
" while cur < tokenNum",
" if isParenthesis token cur # 括弧の始まりの場合",
" @i++",
" elif token cur 1 == '\\) # 括弧の終わりの場合",
" @i--",
" for ; @i < 0; @i++",
" insToken token tokenNum 0",
" token 0 1 = '\\(",
" token 0 0 = 1 # 文字数",
" cur++",
" end",
" end",
" cur++",
" end",
" for ; @i > 0; @i--",
" token tokenNum 1 = '\\)",
" token tokenNum 0 = 1 # 文字数",
" tokenNum++",
" end",
"end",
"",
"func tokenStr token[] index &str[]",
" :ans FALSE",
" :arraycopy token index 1 str 0 (token index 0)",
" str (token index 0) = 0 # 文字列終端",
"end",
"",
"func mp_abs &rop[]",
" :ans FALSE",
" if MP_PROC_INT; _mp_abs rop",
" else; _mp_fabs rop",
" end",
"end",
"func mp_add &ret[] a[] b[]",
" :ans FALSE",
" if MP_PROC_INT; _mp_add ret a b",
" else; _mp_fadd ret a b",
" end",
"end",
"func mp_div &q[] a[] b[]",
" if MP_PROC_INT; @r = _mp_div q a b",
" else; @r = _mp_fdiv2 q a b MP_PREC",
" end",
" return @r",
"end",
"func mp_mul &ret[] a[] b[]",
" :ans FALSE",
" if MP_PROC_INT; _mp_mul ret a b",
" else; _mp_fmul ret a b MP_PREC",
" end",
"end",
"func mp_neg &rop[]",
" :ans FALSE",
" if MP_PROC_INT; _mp_neg rop",
" else; _mp_fneg rop",
" end",
"end",
"func mp_set &rop[] op[]",
" :ans FALSE",
" if MP_PROC_INT; _mp_set rop op",
" else; _mp_fset rop op",
" end",
"end",
"func mp_sub &ret[] a[] b[]",
" :ans FALSE",
" if MP_PROC_INT; _mp_sub ret a b",
" else; _mp_fsub ret a b",
" end",
"end",
"",
"func proc token[] tokenNum top &end &ans[]",
" :parent @@:0",
" for @i = 'a; @i <= 'z; @i++",
" :parent @@:@i",
" end",
"",
" @f = TRUE # 初回かどうか",
" @l = \\-1",
" for @i = top; @i < tokenNum; @i++",
" tokenStr token @i @@S",
" if @f",
" @f = FALSE",
" if @@S 0 == 'N",
" @o = 'N",
" @i++",
" if @i >= tokenNum",
" :println [\"単項-の右辺がありません]",
" return TRUE",
" end",
" tokenStr token @i @@S",
" end",
" elif @@S 0 == '\\) # 括弧の終わりの場合",
" end = @i",
" mp_set ans @@L",
" return FALSE",
" else",
" @o = @@S 0",
" @i++",
" if @i >= tokenNum",
" !putchar @o",
" :println [\"の右辺がありません]",
" return TRUE",
" end",
" tokenStr token @i @@S",
" if @@S 0 == '\\) # 括弧の終わりの場合",
" !putchar @o",
" :println [\"の右辺がありません]",
" return TRUE",
" end",
" end",
"",
" # 左辺または右辺の値を取得する",
" if @@S (strlen @@S - 1) == '\\( # 括弧の始まりの場合",
" if @l < 0",
" @l = '\\(",
" @c = 'L",
" else",
" @c = 'R",
" end",
" if proc token tokenNum (@i + 1) @i @@:@c",
" return TRUE",
" end",
" if strcmp @@S [\"abs(] == 0",
" mp_abs @@:@c",
" elif strcmp @@S [\"sqr(] == 0",
" mp_mul @@:@c @@:@c @@:@c",
" elif strcmp @@S [\"sqrt(] == 0",
" if MP_PROC_INT",
" :println [\"sqrtは浮動小数点数モードでしか使えません]",
" return TRUE",
" else",
" if _mp_fsqrt @@:@c @@:@c MP_PREC",
" :println [\"sqrtの引数が負の値になりました]",
" return TRUE",
" end",
" end",
" elif strcmp @@S [\"trunc(] == 0",
" if MP_PROC_INT",
" :println [\"truncは浮動小数点数モードでしか使えません]",
" return TRUE",
" else",
" _mp_ftrunc @@:@c @@:@c",
" end",
" end",
" else",
" @a = strcmp @@S [\"Ans]",
" if @l < 0",
" @l = (@a == 0) ? 0 (@@S 0)",
" @c = 'L",
" else",
" @c = 'R",
" end",
" if @a == 0",
" mp_set @@:@c @@:0",
" elif @@S 0 >= 'a && @@S 0 <= 'z",
" mp_set @@:@c @@:(@@S 0)",
" else",
" mp_set @@:@c @@S",
" end",
" end",
" if @c == 'L",
" if @o == 'N",
" mp_neg @@L",
" end",
" continue",
" end",
"",
" # 演算結果を左辺の値にする",
" switch @o",
" case '\\*",
" mp_mul @@L @@L @@R",
" break",
" case '\\/",
" if mp_div @@L @@L @@R",
" :println [\"ゼロで除算しました]",
" return TRUE",
" end",
" break",
" case '\\%",
" if MP_PROC_INT",
" if _mp_div @@D @@L @@R @@L",
" :println [\"ゼロで除算しました]",
" return TRUE",
" end",
" else",
" :println [\"%は整数モードでしか使えません]",
" return TRUE",
" end",
" break",
" case '\\+",
" mp_add @@L @@L @@R",
" break",
" case '\\-",
" mp_sub @@L @@L @@R",
" break",
" case '\\=",
" if @l == 0 || (@l >= 'a && @l <= 'z)",
" mp_set @@:@l @@R",
" mp_set @@L @@:@l",
" else",
" :println [\"=の左辺は変数でなければなりません]",
" return TRUE",
" end",
" break",
" end",
" end",
"",
" mp_set ans @@L",
" return FALSE",
"end",
"",
"func _mp expr[] prec",
" :global MP_PREC MP_PROC_INT",
" if @! > 1",
" MP_PREC = prec",
" end",
" MP_PROC_INT = (MP_PREC == 0)",
"",
" :parent @@:0",
" for @i = 'a; @i <= 'z; @i++",
" :parent @@:@i",
" end",
"",
" makeToken expr @@T @T",
"",
" if proc @@T @T 0 @t @@A",
" return TRUE",
" end",
"",
" mp_set @@:0 @@A",
"",
" return FALSE",
"end"
];
clip.procScript( script2 );
List<String> script3 = [
"#Gauss\\-Legendre(ガウス=ルジャンドル)のアルゴリズム",
"#pi_out5e <prec> <start> <count>",
"#startの値は更新されるので、次回呼出しに渡せる。",
"func pi_out5e prec &start count",
" :parent @@:0",
" :parent @@a",
" :parent @@b",
" :parent @@t",
" :parent @@p",
" @N = int (log prec / log 2) # 繰り返し回数。log2(prec)程度の反復でよい。",
" :global MP_PREC",
" MP_PREC = prec",
" if start == 0",
" _mp [\"a=1]",
" _mp [\"b=1/sqrt(2)]",
" _mp [\"t=1/4]",
" _mp [\"p=1]",
" end",
" for @i = 0; @i < count; @i++",
" _mp [\"n=(a+b)/2]",
" _mp [\"b=sqrt(a*b)]",
" _mp [\"t=t-p*sqr(a-n)]",
" _mp [\"p=2*p]",
" _mp [\"a=n]",
" start++",
" end",
" _mp [\"sqr(a+b)/(4*t)] prec",
" return (start < @N)",
"end"
];
clip.procScript( script3 );
clip.procLine( "@0=time" );
clip.procLine( "@a=0; while pi_out5e 1000 @a 1; end" );
clip.procScript( [
"@1 = time",
"@0 = @1 - @0",
"@h = int (int @0 / (60 * 60)); @0 -= @h * 60 * 60",
"@m = int (int @0 / 60 ); @0 -= @m * 60",
":println @h [\"h ] @m [\"m ] @0 [\"s]"
] );
clip.procLine( ":mfloat 1000" );
clip.procLine( ":print @@:0" );
}