Skip to content

Instantly share code, notes, and snippets.

@Velgail-HSP
Created August 25, 2021 10:45
Show Gist options
  • Save Velgail-HSP/deaccc78df0bc82cb49a6a2ef3cf6549 to your computer and use it in GitHub Desktop.
Save Velgail-HSP/deaccc78df0bc82cb49a6a2ef3cf6549 to your computer and use it in GitHub Desktop.
#module jsonfunction
#deffunc setstat int p
return p
#deffunc jsonError str a, str b
dialog a,1,"HSP-JSON Error:"+b
end
return
#defcfunc skipWS var in,int spos
for i,spos,strlen(in)
ef=0
switch peek(in,i)
case ' '
case '\t'
case 10
case 13
swbreak
default
ef=1
swbreak
swend
if ef{
_break
}
next
return i
#defcfunc nextWS var in,int spos
for i,spos,strlen(in)
ef=0
switch peek(in,i)
case ' '
case '\t'
case 10
case 13
ef=1
swbreak
swend
if ef{
_break
}
next
return i
#defcfunc isEndOfValue int tmp,local ret
ret=0
switch tmp
case ' '
case '\t'
case 10
case 13
case ','
case ']'
case '}'
ret=1
swbreak
swend
return ret
#global
#module jsonstring s
#modinit var in,int spos
s=""
for i,spos+1,strlen(in)
if (peek(in,i)=='\\'){
i++
switch peek(in,i)
case '\"'
s+="\""
swbreak
case '\\'
s+="\\"
swbreak
case '/'
s+="/"
swbreak
case 'b'
s+="\\b"
swbreak
case 'f'
s+="\\f"
swbreak
case 'n'
s+="\n"
swbreak
case 'r'
s+="\n"
swbreak
case 't'
s+="\t"
swbreak
case 'u'
s+="\\u"+strmid(in,i+1,4)
i+=4
swbreak
swend
}else:if(peek(in,i)=='\"'){
i++
_break
}else{
s+=strmid(in,i,1)
}
next
return i
#modcfunc getValue_s
return s
#global
#module jsonspecial p
#modinit str key
p=key
return
#global
#module jsonnumber objtype,objdata
/*objtype
0 : error
1 : Integer
2 : Double
*/
#modinit var in,int spos,local step,local s,local tmp
step=0
s=""
objtype=1
for i,spos,strlen(in)
tmp=peek(in,i)
switch step
case 0://符号検査
step++
if(tmp=='-'){
s+="-"
swbreak
}
case 1://0検査
if(tmp=='0'){
s+="0"
step=3
swbreak
}
if (('1'<=tmp) and (tmp<='9')){
s+=strmid(in,i,1)
step=2
}else{
mes i
jsonError "数値処理エラー(パースエラー1)","Numeric Parse Error 1"
}
swbreak
case 2://数値入力
if (('0'<=tmp) and (tmp<='9')){
s+=strmid(in,i,1)
step=2
swbreak
}else{
step=3
}
case 3://Fraction/Exponent/End判定
step++
if(tmp=='.'){
s+="."
objtype=2
step=2//数値入力へ
swbreak
}else:if((tmp=='E')or(tmp=='e')){
s+="e"
tmp=peek(in,i+1)
if(tmp=='+'){
i++
s+="+"
}else:if(tmp=='-'){
i++
s+="-"
}
objtype=2
step=2//数値入力へ
swbreak
}else:if(isEndOfValue(tmp)){
step=4
swbreak
}else{
jsonError "数値処理エラー(パースエラー2)","Numeric Parse Error 2"
}
swbreak
swend
if(step==4){
_break
}
next
if(objtype=1){
objdata=int(s)
}
if(objtype=2){
objdata=double(s)
}
return i
#modcfunc getValue_n
return objdata
#global
#module jsonvalue objtype,objdata,objkeys
/*objtype
0 : error
1 : Number
2 : String
3 : Object
4 : Array
5 : Special
*/
#modinit var in,int spos
if(strlen(in)<=spos){
return
}
p=skipWS(in,spos)
l=strmid(in,p,1)
if(l=="{"){
// newmod objdata,jsonobj,in,p
setupObject thismod,in,spos+1
objtype=3
}else:if(l=="["){
setupArray thismod,in,spos+1
objtype=4
}else:if(l=="\""){
newmod objdata,jsonstring,in,p
objtype=2
}else{
pk=strmid(in,p,4)
objtype=5
if(pk=="true"){
newmod objdata,jsonspecial,"true"
setstat p+4
}else:if(pk=="null"){
newmod objdata,jsonspecial,"null"
setstat p+4
}else:if(strmid(in,p,5)=="false"){
newmod objdata,jsonspecial,"false"
setstat p+5
}else{
newmod objdata,jsonnumber,in,p
objtype=1
}
}
return stat
#modfunc local setupObject var in,int spos
p=spos
repeat
p=skipWS(in,p)
newmod objkeys,jsonstring,in,p
p=skipWS(in,stat)
if(peek(in,p)!=':'){
jsonError "オブジェクト処理エラー1(:が必要)","Object Parse Error1(Missing :)"
}
p=skipWS(in,p+1)
newmod objdata,jsonvalue,in,p
p=skipWS(in,stat)
if(peek(in,p)=='}'){
p++
break
}else:if(peek(in,p)==','){
p++
}else{
mes p
jsonError "オブジェクト処理エラー1(,で区切られていません)","Object Parse Error1(Missing , separator)"
}
loop
return p
#modfunc local setupArray var in,int spos
p=spos
repeat
p=skipWS(in,p)
newmod objdata,jsonvalue,in,p
p=skipWS(in,stat)
if(peek(in,p)==']'){
p++
break
}else:if(peek(in,p)==','){
p++
}else{
jsonError "配列処理エラー1(,で区切られていません)","Array Parse Error1(Missing , separator)"
}
loop
return p
#modcfunc getValueType_jV str key
if(key==""){
return objtype
}
return 0
#modcfunc getValue_jV str key, local ret, local nextkey,local thiskey,local ptr
if(key==""){
switch objtype
case 1
ret=getValue_n(objdata)
swbreak
case 2
ret=getValue_s(objdata)
swbreak
swend
}else{
nextkey=key
if(strmid(nextkey,0,1)!="."){
jsonError "キー指定エラー1(ルートを示す.が必要)","Key Definition Error1(missing root of period)"
}
nextkey=strmid(nextkey,1,strlen(nextkey))
if(instr(nextkey,0,".")>0){
thiskey=strmid(nextkey,0,instr(nextkey,0,"."))
nextkey=strmid(nextkey,instr(nextkey,0,"."),strlen(nextkey))
}else{
thiskey=nextkey
nextkey=""
}
if(peek(thiskey,0)=='['){
ptr=int(strmid(thiskey,1,instr(thiskey,1,"]")))
ret=getValue_jv(objdata(ptr),nextkey)
}else{
found=0
foreach objkeys
if(getValue_s(objkeys(cnt))==thiskey){
ret=getValue_jv(objdata(cnt),nextkey)
break
}
loop
}
}
return ret
#modfunc getKeys_jV str key, array ret, local nextkey
sdim ret,,length(objkeys)
foreach objkeys
ret(cnt)=getValue_s(objkeys(cnt))
loop
return
#global
#module hspjson root
#modinit str _in,local in
in=_in
newmod root,jsonvalue,in,0
return ""
#modcfunc getValueType str key
return getValueType_jV(root,key)
#modcfunc getValue str key
return getValue_jV(root,key)
#modfunc getKeys str key,array ret
getKeys_jV root,key,ret
return
#global
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment