以前に、インタプリターを作ったことがあるので、計算部分だけ載せておきます。
;モジュール----------------------------------------------------------------
#module
#defcfunc Search_Str var v1, var v2, str s1, int p1, str p2, str p3, int p4
buf.0 = s1
buf.1 = p2
buf.2 = p3
prm.0 = varptr(v1)
prm.1 = varptr(v2)
prm.2 = varptr(buf.0)
prm.3 = p1
prm.4 = varptr(buf.1)
prm.5 = varptr(buf.2)
prm.6 = p4
return callfunc(prm,sPtr,7)
#defcfunc SearchBlock_Str var v1, var v2, str s1, str s2, int p1, str p2, str p3
buf.0 = s1
buf.1 = s2
buf.2 = p2
buf.3 = p3
prm.0 = varptr(v1)
prm.1 = varptr(v2)
prm.2 = varptr(buf.0)
prm.3 = varptr(buf.1)
prm.4 = p1
prm.5 = varptr(buf.2)
prm.6 = varptr(buf.3)
return callfunc(prm,bPtr,7)
#deffunc Del_Str var v1,str s1,str s2,str s3
buf.0 = s1
buf.1 = s2
buf.2 = s3
prm.0 = varptr(v1)
prm.1 = varptr(buf.0)
prm.2 = varptr(buf.1)
prm.3 = varptr(buf.2)
a = callfunc(prm,dPtr,4)
return 0
#deffunc UnquoteSpaces var v1
prm.0 = varptr(v1)
a = callfunc(prm,uPtr,1)
return 0
#deffunc __init__
_searchstr_.0 = $83ec8b55,$8b5308ec,$75030c75,$f8758914,$8b105d8b
_searchstr_.5 = $7d8b1855,$3a801c,$7fe80574,$33000000,$f0e38c9
_searchstr_.10 = $13284,$204d3800,$33524974,$fc5589d2,$48ae432
_searchstr_.15 = $75c00a1a,$74c90b0c,$1ce95a33,$eb000001,$752c3c23
_searchstr_.20 = $74c90b16,$ce95a08,$eb000001,$fc45ff13,$eb42e432
_searchstr_.25 = $3809ebd5,$4743104,$1b4c933,$175e40a,$c2eb4241
_searchstr_.30 = $8a1deb5a,$c0841904,$c9850a75,$e5850f,$ceb0000
_searchstr_.35 = $74310438,$ebf10304,$e3eb4103,$b1e8,$ff77e900
_searchstr_.40 = $3353ffff,$32c933db,$fc6588e4,$a13048a,$b0f75c0
_searchstr_.45 = $30774c9,$32e8f1,$c35b0000,$2c3c26eb,$c90b1975
_searchstr_.50 = $f1030b74,$1fe8,$ebc35b00,$fc45fe13,$eb43e432
_searchstr_.55 = $3809ebcf,$4743104,$1b4c933,$175e40a,$bceb4341
_searchstr_.60 = $fc558a52,$db334ceb,$e432c933,$a3b048a,$800e75c0
_searchstr_.65 = $7500fc7d,$74c90b31,$eb3aeb2d,$752c3c21,$fc7d8014
_searchstr_.70 = $85047700,$fe2a75c9,$e432fc4d,$ebd5eb43,$31043809
_searchstr_.75 = $c9330474,$e40a01b4,$43410175,$5588c2eb,$ce8fc
_searchstr_.80 = $3e800000,$5aaf7500,$4ef103c3,$68ac35a,$976803c
_searchstr_.85 = $472b13c,$176dd3c,$b8c34646,$ffffffff,$8bc3c95b
_searchstr_.90 = $458b087d,$2b0789fc,$c68bf875,$55c3c95b,$ec83ec8b
_searchstr_.95 = $758b5308,$1875030c,$8bf87589,$558b105d,$207d8b1c
_searchstr_.100 = $3a80e432,$50077400,$ffff05e8,$c93358ff,$bb740e38
_searchstr_.105 = $8419048a,$b1475c0,$fe0e74c9,$1fc80c4,$f1030775
_searchstr_.110 = $2bf87589,$3808ebf1,$3753104,$53ddeb41,$a145d8b
_searchstr_.115 = $331d74e4,$19048ac9,$c75c084,$674c90b,$c438ccfe
_searchstr_.120 = $8eb1274,$75310438,$e5eb4103,$ff5ce85b,$9eebffff
_searchstr_.125 = $f8458b5b,$452bf02b,$8558b0c,$c95b3289,$ec8b55c3
_searchstr_.130 = $5308ec83,$8bfc9c66,$5d8b0875,$10558b0c,$32147d8b
_searchstr_.135 = $740638c0,$74023867,$fe78e805,$3357ffff,$32c933ff
_searchstr_.140 = $1f048ae4,$d75c00a,$3074c90b,$33e8,$ebeeeb00
_searchstr_.145 = $752c3c1f,$74c90b12,$22e807,$3eb0000,$eb47e432
_searchstr_.150 = $3809ebd8,$4743104,$1b4c933,$175e40a,$c5eb4741
_searchstr_.155 = $fedce85f,$a7ebffff,$3fe8b56,$ebe432f1,$2738a401
_searchstr_.160 = $335efb75,$c3ff33c9,$c95b9d66,$6e652dc3
sPtr = varptr(_searchstr_)
bPtr = sPtr + 93*4 + 3
dPtr = bPtr + 35*4 + 2
_unquotespaces_.0 = $8bec8b55,$3e800875,$662b7522,$fe8bfc9c,$ffb9c032
_unquotespaces_.5 = $f2ffffff,$d9f741ae,$22fe7f80,$47881275,$46fe8bfe
_unquotespaces_.10 = $2e9c151,$8359a5f3,$a4f303e1,$c35d9d66
uPtr = varptr(_unquotespaces_)
VarCount = 0
VarList = ""
Variable = ""
return
#defcfunc GetType var v1
a = peek(v1)
return a!='+' && a!='-' && a<'0' || a>'9'
#deffunc Sub_Variable var v1
v1 = "("+v1+")":a = instr( VarList,0,v1 )
if a == -1 :return -1
a + strlen(v1):getstr get1,VarList,a,')':a + strsize
return int(get1)
#deffunc Save_Variable var v1,str s1,int p1
; v1 = 変数名
; s1 = 代入する文字列
; p1 = 0なら数字として,1なら文字列として扱うタイプ
get = v1
Sub_Variable get
if stat == -1 {
VarList + get + VarCount + ")" + p1 + ")"
Variable.VarCount = s1 :VarCount++
return
}
Variable.stat = s1
getstr get,VarList,a,')'
if int(get) != p1 :get = ""+p1 :memcpy VarList,get,1,a
return
#deffunc Load_Variable var v1
get = v1:Sub_Variable get :if stat == -1 :return 0
v1 = Variable.stat
getstr get,VarList,a,')'
return int(get)
#enum EQU = 0
#enum SHL
#enum SHR
#enum ADD
#enum SUB
#enum MOL
#enum DIV
#enum MOD
#enum _NOT
#enum _AND
#enum _OR
#enum _XOR
#defcfunc Calculation str s1,local tmp, local ti, local ts
tmp = s1
Del_Str tmp," ,\t","\"","\""
ti = SearchBlock_Str( ts,tmp,"(",")",0,"\"","\"" )
if ti != -1 {
buf1 = strmid(tmp,ti,ts)
buf1 = Calculation(buf1)
a = ti+ts+1
tmp = strmid(tmp,0,ti-1) + buf1 + strmid( tmp,a,strlen(tmp)-a )
tmp = Calculation(tmp)
}
Vsig = 0; ←数値か文字列か、判断する変数
ci = 0
repeat
gosub *Operator
if a == -1 {
if GetType(tmp) && peek(tmp)!='\"' :Load_Variable tmp :if cnt == 0 && stat :Vsig = 1
break
}
buf1 = strmid( tmp,0,a ) :getstr tmp,tmp,a + 1 + (c < ADD)
ct = c
ci = 0
gosub *Operator
if a == -1 {
buf2 = tmp
tmp = ""
} else {
buf2 = strmid( tmp,0,a ) :getstr tmp,tmp,a
}
i = strlen(tmp)
UnquoteSpaces buf1
UnquoteSpaces buf2
if Vsig == 0 {
if GetType(buf1) :Load_Variable buf1 :if cnt == 0 && stat :Vsig = 1
if GetType(buf2) :Load_Variable buf2
}
*@
if Vsig {
switch ct
case ADD
tmp = "\""+buf1 + buf2+"\"" + tmp
goto *@f
case EQU
tmp = "" + (buf1 == buf2) + tmp
goto *@f
case _NOT
tmp = "" + (buf1 != buf2) + tmp
goto *@f
default
dialog "サポートされない機能を選択しました",1 :end
swend
}
switch ct
case EQU
tmp = "" + (double(buf1) == double(buf2)) + tmp
swbreak
case SHL
tmp = "" + (int(buf1) << int(buf2)) + tmp
swbreak
case SHR
tmp = "" + (int(buf1) >> int(buf2)) + tmp
swbreak
case ADD
tmp = "" + (double(buf1) + double(buf2)) + tmp
swbreak
case SUB
tmp = "" + (double(buf1) - double(buf2)) + tmp
swbreak
case MOL
tmp = "" + (double(buf1) * double(buf2)) + tmp
swbreak
case DIV
tmp = "" + (double(buf1) / double(buf2)) + tmp
swbreak
case MOD
tmp = "" + (int(buf1) \ int(buf2)) + tmp
swbreak
case _NOT
tmp = "" + (int(buf1) ! int(buf2)) + tmp
swbreak
case _AND
tmp = "" + (int(buf1) & int(buf2)) + tmp
swbreak
case _OR
tmp = "" + (int(buf1) | int(buf2)) + tmp
swbreak
case _XOR
tmp = "" + (int(buf1) ^ int(buf2)) + tmp
swend
*@
if a == -1 :break
ci = strlen(tmp) - i
loop
UnquoteSpaces tmp
return tmp
*Operator
// 文字列チェック
if cnt == 0 && peek(tmp) == '\"' :Vsig = 1
// 負号チェック
repeat
a = Search_Str( c,tmp,"==,<<,>>,+,-,*,/,%,!,&,|,^",ci,"\"","\"",1 )
if a == -1 :break
if c == SUB {
if Vsig :break
if ctmp :ci++ :continue
}
a + ci
break
loop
ctmp = strmid(tmp,a+1,1) == "-"
return
#global
; 初期化
__init__
;------------------------------------------------------------------------
;----- メイン -----;
#define 数値 0
#define 文字 1
// 変数名
vname = "var"
; 数値を代入
Save_Variable vname,"10",数値
;
mes Calculation("var + (5 * 2) / 15")
; 文字列を代入
Save_Variable vname,"abc",文字
;
mes Calculation("var + 5 + 50 + 100")
長くてすみません...。
変数の内容は、文字列型の配列変数に退避しておきます。
変数名は、変数名のリストを作成しています。
↑この場合だと、変数の管理がすべて文字列になるので、
WinApi の HeapAlloc を使うのもありです。(HeapAllocはこの掲示板で教えてもらいました)
モジュールの詳しい内容は、
http://hspwiki.nm.land.to/?%CA%B8%BB%FA%CE%F3%A4%CE%B7%D7%BB%BB%A5%E2%A5%B8%A5%E5%A1%BC%A5%EB
にあります。