[obsidian] vault backup: 2025-09-25 14:38:57[
Some checks failed
Build / build (push) Failing after 12m59s

This commit is contained in:
2025-09-25 14:38:57 +09:00
parent a1ed1f1f74
commit 857e71b45e

View File

@@ -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<StaticData>
externals:<ExternalItems>
functions:Vec<FuncProto>
}
struct Operation{
dest:Option<VRegister>,
inst:Instruction
}
struct UpIndex(usize)
struct UpIndexStorage(Vec<StackSlot>)
impl UpIndexStorage{
fn get_upv_index(&self,i:UpIndex)->Option<StackSlot>{
self.0.get(i.0)
}
}
struct FuncProto{
upindexes:UpIndexStorage,
instructions: Vec<Operation>
}
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>)->(Value,Type){
match e.to_expr() {