by konisi » 2008年8月09日(土) 20:19
暇なので立ててみました。
目的
・コンパイラの限界とバグを知る
・短く簡潔に書く方法を学ぶ
ルール
・コンパイルが通る事
・正しいデータを渡した時、正しい結果を返す事
・あまりにも多くのメモリや時間を使わない事
・下記のような定義ファイルを除き、1つのファイルに全てを書くこと
・こんな内容の定義ファイルをインクルードしておいてください。 [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします] Cや他の言語のライブラリで標準定義されているような関数は追加してもいいと思います。
コード: 全て選択
'必ずインクルード元で
'Sub main(argc As Long,argv As **Byte)
'を定義する事。
#console
Declare Function PathGetArgsA Lib "shlwapi" (psz As *Byte) As *Byte
Declare Function atoi Lib "msvcrt" cdecl (buf As *Byte) As Long
_main()
Sub _main()
Dim i As Long
Dim argc As Long,argv As **Byte
Dim CommandLine As *Byte
'コマンドラインの取得・整理
CommandLine=GetCommandLine()
argc=GetArgc(CommandLine)
argv=calloc(argc*4)
For i=0 To argc-1
argv=GetArgv(CommandLine,i)
Next
'呼び出し
main(argc,argv)
'解放
For i=0 To argc-1
free(argv)
Next
free(argv)
End Sub
'引数の総数を取得
'第一引数にコマンドライン文字列をぶち込む
Function GetArgc(CommandLine As *Byte) As Long
Dim i=0 As Long,bufptr As *Byte
GetArgc=1'呼び出し名含めかならず1つ以上ある筈
bufptr=PathGetArgsA(CommandLine)
Do
If bufptr=0 then
If i then
GetArgc++
bufptr+=i
i=0
End If
Exit Do
ElseIf bufptr=10 Or bufptr=32 Or bufptr=40 Or bufptr=44 Or bufptr=47 Or _
bufptr=59 Or bufptr=60 Or bufptr[i]=61 Or bufptr[i]=62 Or bufptr[i]=124 then'区切り文字
GetArgc++
bufptr+=i+1
i=0
Else
i++
End If
Loop
End Function
'呼び出し名を取得する
'第一引数にコマンドライン文字列をぶち込む
'戻り値は自分でfreeする必要がある
Function GetArgv0(CommandLine As *Byte) As *Byte
Dim i As Long
If CommandLine[0]=34 then
i=1
Do
If CommandLine[i]>=128 then'SHIFT-JIS文字対策
i++
ElseIf CommandLine[i]=34 then
i++
Exit Do
ElseIf CommandLine[i]=0 then
Exit Do
End If
i++
Loop
Else
Do
If CommandLine[i]>=128 then'SHIFT-JIS文字対策
i++
ElseIf CommandLine[i]=0 Or CommandLine[i]=10 Or CommandLine[i]=32 Or _
CommandLine[i]=40 Or CommandLine[i]=44 Or CommandLine[i]=47 Or _
CommandLine[i]=59 Or CommandLine[i]=60 Or CommandLine[i]=61 Or _
CommandLine[i]=62 Or CommandLine[i]=124 then'区切り文字
Exit Do
End If
i++
Loop
End If
GetArgv0=calloc(i+1)
memcpy(GetArgv0,CommandLine,i)
End Function
'引数を取得する。
'第一引数にコマンドライン文字列をぶち込む
'戻り値は自分でfreeする必要がある
Function GetArgv(CommandLine As *Byte,ArgvIndex As Long) As *Byte
Dim i As Long,bufptr As *Byte
If ArgvIndex=0 then'呼び出し名を取得する場合
GetArgv=GetArgv0(CommandLine)
Exit Function
ElseIf ArgvIndex<0 then'インデックスがおかしい
Exit Function
End If
bufptr=PathGetArgsA(CommandLine)
i=0
Do
If bufptr[i]=0 then
If i then
ArgvIndex--
If ArgvIndex=0 then
GetArgv=calloc(i+1)
memcpy(GetArgv,bufptr,i)
Exit Do
End If
bufptr+=i
i=0
End If
Exit Do
ElseIf bufptr[0]=34 then
i=1
Do
If bufptr[i]>=128 then'SHIFT-JIS文字対策
i++
ElseIf bufptr[i]=34 then
i++
Exit Do
ElseIf bufptr[i]=0 then
Exit Do
End If
i++
Loop
ElseIf bufptr[i]=10 Or bufptr[i]=32 Or bufptr[i]=40 Or bufptr[i]=44 Or bufptr[i]=47 Or _
bufptr[i]=59 Or bufptr[i]=60 Or bufptr[i]=61 Or bufptr[i]=62 Or bufptr[i]=124 then'区切り文字
ArgvIndex--
If ArgvIndex=0 then
GetArgv=calloc(i+1)
memcpy(GetArgv,bufptr,i)
Exit Do
End If
bufptr+=i+1
i=0
Else
i++
End If
Loop
End Function
Sub putchar(a As Byte)
Dim dwAccessBytes As DWord
WriteFile(_System_hConsoleOut,VarPtr(a),1,VarPtr(dwAccessBytes),ByVal 0)
End Sub
Function getchar() As Byte
Dim dwAccessBytes As DWord
ReadFile(_System_hConsoleIn,VarPtr(getchar),1,VarPtr(dwAccessBytes),ByVal 0)
End Function
・お題提供者はまず自分で簡単に作ったコードを投稿する(それが考えうる中での最短である必要はない)
・「TypeDefを定義ファイルに入れて3バイト短縮!」とかはしないでください
文字数の測り方は、
・上記のような定義ファイルをインクルードするための部分は無視
・改行コードは1バイト
・先頭のインデントは無視(ただし先頭以外の部分のスペースやタブ等は計算に含める)
でいきたいと思います。
例(おなじみのHello,World! 40バイト)コード: 全て選択
Sub main(a,b)
Print"Hello,World!"
EndSub
暇なので立ててみました。
目的
・コンパイラの限界とバグを知る
・短く簡潔に書く方法を学ぶ
ルール
・コンパイルが通る事
・正しいデータを渡した時、正しい結果を返す事
・あまりにも多くのメモリや時間を使わない事
・下記のような定義ファイルを除き、1つのファイルに全てを書くこと
[hide=・こんな内容の定義ファイルをインクルードしておいてください。] Cや他の言語のライブラリで標準定義されているような関数は追加してもいいと思います。[code]'必ずインクルード元で
'Sub main(argc As Long,argv As **Byte)
'を定義する事。
#console
Declare Function PathGetArgsA Lib "shlwapi" (psz As *Byte) As *Byte
Declare Function atoi Lib "msvcrt" cdecl (buf As *Byte) As Long
_main()
Sub _main()
Dim i As Long
Dim argc As Long,argv As **Byte
Dim CommandLine As *Byte
'コマンドラインの取得・整理
CommandLine=GetCommandLine()
argc=GetArgc(CommandLine)
argv=calloc(argc*4)
For i=0 To argc-1
argv[i]=GetArgv(CommandLine,i)
Next
'呼び出し
main(argc,argv)
'解放
For i=0 To argc-1
free(argv[i])
Next
free(argv)
End Sub
'引数の総数を取得
'第一引数にコマンドライン文字列をぶち込む
Function GetArgc(CommandLine As *Byte) As Long
Dim i=0 As Long,bufptr As *Byte
GetArgc=1'呼び出し名含めかならず1つ以上ある筈
bufptr=PathGetArgsA(CommandLine)
Do
If bufptr[i]=0 then
If i then
GetArgc++
bufptr+=i
i=0
End If
Exit Do
ElseIf bufptr[i]=10 Or bufptr[i]=32 Or bufptr[i]=40 Or bufptr[i]=44 Or bufptr[i]=47 Or _
bufptr[i]=59 Or bufptr[i]=60 Or bufptr[i]=61 Or bufptr[i]=62 Or bufptr[i]=124 then'区切り文字
GetArgc++
bufptr+=i+1
i=0
Else
i++
End If
Loop
End Function
'呼び出し名を取得する
'第一引数にコマンドライン文字列をぶち込む
'戻り値は自分でfreeする必要がある
Function GetArgv0(CommandLine As *Byte) As *Byte
Dim i As Long
If CommandLine[0]=34 then
i=1
Do
If CommandLine[i]>=128 then'SHIFT-JIS文字対策
i++
ElseIf CommandLine[i]=34 then
i++
Exit Do
ElseIf CommandLine[i]=0 then
Exit Do
End If
i++
Loop
Else
Do
If CommandLine[i]>=128 then'SHIFT-JIS文字対策
i++
ElseIf CommandLine[i]=0 Or CommandLine[i]=10 Or CommandLine[i]=32 Or _
CommandLine[i]=40 Or CommandLine[i]=44 Or CommandLine[i]=47 Or _
CommandLine[i]=59 Or CommandLine[i]=60 Or CommandLine[i]=61 Or _
CommandLine[i]=62 Or CommandLine[i]=124 then'区切り文字
Exit Do
End If
i++
Loop
End If
GetArgv0=calloc(i+1)
memcpy(GetArgv0,CommandLine,i)
End Function
'引数を取得する。
'第一引数にコマンドライン文字列をぶち込む
'戻り値は自分でfreeする必要がある
Function GetArgv(CommandLine As *Byte,ArgvIndex As Long) As *Byte
Dim i As Long,bufptr As *Byte
If ArgvIndex=0 then'呼び出し名を取得する場合
GetArgv=GetArgv0(CommandLine)
Exit Function
ElseIf ArgvIndex<0 then'インデックスがおかしい
Exit Function
End If
bufptr=PathGetArgsA(CommandLine)
i=0
Do
If bufptr[i]=0 then
If i then
ArgvIndex--
If ArgvIndex=0 then
GetArgv=calloc(i+1)
memcpy(GetArgv,bufptr,i)
Exit Do
End If
bufptr+=i
i=0
End If
Exit Do
ElseIf bufptr[0]=34 then
i=1
Do
If bufptr[i]>=128 then'SHIFT-JIS文字対策
i++
ElseIf bufptr[i]=34 then
i++
Exit Do
ElseIf bufptr[i]=0 then
Exit Do
End If
i++
Loop
ElseIf bufptr[i]=10 Or bufptr[i]=32 Or bufptr[i]=40 Or bufptr[i]=44 Or bufptr[i]=47 Or _
bufptr[i]=59 Or bufptr[i]=60 Or bufptr[i]=61 Or bufptr[i]=62 Or bufptr[i]=124 then'区切り文字
ArgvIndex--
If ArgvIndex=0 then
GetArgv=calloc(i+1)
memcpy(GetArgv,bufptr,i)
Exit Do
End If
bufptr+=i+1
i=0
Else
i++
End If
Loop
End Function
Sub putchar(a As Byte)
Dim dwAccessBytes As DWord
WriteFile(_System_hConsoleOut,VarPtr(a),1,VarPtr(dwAccessBytes),ByVal 0)
End Sub
Function getchar() As Byte
Dim dwAccessBytes As DWord
ReadFile(_System_hConsoleIn,VarPtr(getchar),1,VarPtr(dwAccessBytes),ByVal 0)
End Function[/code][/hide]・お題提供者はまず自分で簡単に作ったコードを投稿する(それが考えうる中での最短である必要はない)
・「TypeDefを定義ファイルに入れて3バイト短縮!」とかはしないでください
文字数の測り方は、
・上記のような定義ファイルをインクルードするための部分は無視
・改行コードは1バイト
・先頭のインデントは無視(ただし先頭以外の部分のスペースやタブ等は計算に含める)
でいきたいと思います。
例(おなじみのHello,World! 40バイト)[code]Sub main(a,b)
Print"Hello,World!"
EndSub[/code]