LLVM用BASICコンパイラを書いていたり

http://panathenaia.halfmoon.jp/basicll/
Quineで3位*1を取るためだけのBASIC処理系です。まだLISTしか出力命令が無いです。

LLVMで非効率となるgcc拡張構文のひとつに&&labelがあります。LLVMではローカルラベルのアドレスを取れないため、序数に対応付けてswitchが作られます。なんじゃそら。
あとLLVMではスタック操作用にllvm.savestackとllvm.restorestackはあるのですが、単純なpushとpopが無いため、スタックをスタックのように使うことができません。
要するに普通のやり方でGOSUBが実装できません。
最初行番号と対応付けたジャンプテーブル作ろうとしたのですが、それですとGOSUBは良くても今度はFOR-NEXTやWHILE-WENDが困ることに。BASICではソース上で制御文をきちんとした入れ子にする必要が無いのですよ。GOTOして離れたところのNEXTを実行してもちゃんとFORに戻ってこないといけないのです。結局longjmpでいいじゃんと気付いたのでlongjmpにしました。FOR-NEXTやWHILE-WENDはまだ作ってませんが全部longjmpになる予定です。ネイティブコンパイラとは思えません。まだベタに機械語を出力したほうが速くなりそうです。

……あ、まてよ。行ごとに全部別の関数にして次の行に行くときはtail callとかでもいけそうです。それなら関数アドレスを……いや、FOR I=...:FOR J=...状態からいきなりNEXT Iした時にJのループをキャンセルしないといけない動作で詰まる。やはりlongjmpは必要です。

ESPとEIPが直接弄れたらどうにでもなるんですが……。

*1:1位2位はm4とPHPhttp://golf.shinh.org/p.rb?Quine参照