diff --git a/content/mimiumのMIRコンパイル過程を真面目に考える.md b/content/mimiumのMIRコンパイル過程を真面目に考える.md index 445c0b19..ae636fbb 100644 --- a/content/mimiumのMIRコンパイル過程を真面目に考える.md +++ b/content/mimiumのMIRコンパイル過程を真面目に考える.md @@ -48,6 +48,62 @@ $$ ## コンパイル +評価をしながら副作用としてMIRを書き込んでいくような感じ + +Valueとして、次のようなものがあり得る + +```rust +struct VRegister(usize); +struct StackSlot(usize); +enum Value{ + Static(usize), + Global(usize), + Function(usize), + ExternalItem(usize), + Register(VRegister), + StackSlot(StackSlot),//引数とかはこれで処理して良い +} +``` + +原則、Letが出てくればStackSlotに確保、そうでない一次変数はRegisterに確保でよい +LetだけどRegisterに逃がせるとか、RegisterからStackへスピルするとかはオプティマイザの範疇 +基本的にはFuncProtoはValueに依存しない構造にしたい + +今はmir::ValueにmirgenとBytecodeGen両方が依存しているが、Valueは本来Expr→MIR生成時に使われるだけの中間的な値であるべき + +```rust +struct MIR{ + name:Symbol, + static_data:Vec + externals: + functions:Vec +} +struct Operation{ + dest:Option, + inst:Instruction +} +struct UpIndex(usize) +struct UpIndexStorage(Vec) + +impl UpIndexStorage{ + fn get_upv_index(&self,i:UpIndex)->Option{ + self.0.get(i.0) + } +} +struct FuncProto{ + upindexes:UpIndexStorage, + instructions: Vec +} + +enum Instruction{ + Load(StackSlot,Type) + Store{dest:StackSlot,src:Register,Type} + GetUpValue(UpIndex,Type) + //その他、プリミティブな命令はfrom Register to Register +} + +``` + ```rust fn eval(e:ExprNodeId,env:Env)->(Value,Type){ match e.to_expr() {