- [x] downgrade stage - [ ] resolve stage - [ ] dynamic attr resolution - [ ] import resolution - [ ] static path resolution - [ ] eval stage - [ ] dynamic path resolution - [ ] graph update - [ ] stack storage 阻拦变量解析的是 `with import` 而不是一般的 `with` 解析阶段可以解决除涉及非字符串常量拼接路径导入之外的问题 静态分析图与求值期图分离,动态生成求值期图 依赖类型: 1. 强依赖 (x!) - builtins.toString x => x! - x + y => x! y! - { x = 1; ${sym} = 2; } => sym! 2. 弱依赖 a.k.a. thunk (x?) - builtins.seq x y => x! y? 3. 递归依赖 (x!!) - builtins.deepSeq x y => x!! y? e.g. - let a? = { inherit a?; }; in a! => a! - a! => { a = } - f: let x? = f! x?; in x! => f! x! - let ret? = (self: { x? = 1; y? = self.x! + 1; }) ret?; in ret.y! => ret! x! y! 工作流程: 1. string -> AST 2. AST -> HIR (alloc ExprId) 3. HIR -> LIR (resolve var, build graph) 4. LIR -> Value ```mermaid flowchart TD Start([Context::eval]) --> Eval[EvalContext::eval] Eval --> AddNode[add node to graph] AddNode --> CheckType{check expression type} CheckType -->|AttrSet| A_EvalKeys[eval keys] A_EvalKeys --> A_Construct[construct attrset] A_Construct --> A_Return[return attrset] A_Return --> End A_EvalKeys -.->|eval| Eval CheckType -->|List| L_Construct[construct list] L_Construct --> L_Return[return list] L_Return --> End CheckType -->|HasAttr| HA_ForceAttrSet[force attrset] HA_ForceAttrSet --> HA_ForceAttrPath[force attrpath] HA_ForceAttrPath --> HA_Return[return bool] HA_Return --> End HA_ForceAttrSet -.->|eval| Eval HA_ForceAttrPath -.->|eval| Eval CheckType -->|BinOp| B_ForceLeft[force left operand] B_ForceLeft --> B_ForceRight[force right operand] B_ForceRight --> B_Apply[apply operator] B_Apply --> B_Return[return value] B_Return --> End B_ForceLeft -.->|eval| Eval B_ForceRight -.->|eval| Eval CheckType -->|UnOp| U_ForceOperand[force operand] U_ForceOperand --> U_Apply[apply operator] U_Apply --> U_Return[return value] U_Return --> End U_ForceOperand -.->|eval| Eval CheckType -->|Select| S_ForceAttrSet[force attrset] S_ForceAttrSet --> S_ForceAttrPath[force attrpath] S_ForceAttrPath --> S_CallEval[call eval on value] S_CallEval --> S_Return[return value] S_Return --> End S_ForceAttrSet -.->|eval| Eval S_ForceAttrPath -.->|eval| Eval S_CallEval -.-> Eval CheckType -->|If| I_ForceCond[force condition] I_ForceCond --> I_Cond{condition} I_Cond -->|true| I_ForceConsq[force consequence] I_Cond -->|false| I_ForceAlter[force alternative] I_ForceConsq --> I_CallEvalConsq[call eval on consequence] I_ForceAlter --> I_CallEvalAlter[call eval on alternative] I_CallEvalConsq --> I_ReturnConsq[return value] I_CallEvalAlter --> I_ReturnAlter[return value] I_ReturnConsq --> End I_ReturnAlter --> End I_ForceCond -.->|eval| Eval I_ForceConsq -.->|eval| Eval I_ForceAlter -.->|eval| Eval I_CallEvalConsq -.-> Eval I_CallEvalAlter -.-> Eval CheckType -->|Call| C_RegArg[register argument] C_RegArg --> C_ForceBody[force body] C_ForceBody --> C_CallEval[call eval on body] C_CallEval --> C_Return[return value] C_Return --> End C_ForceBody -.->|eval| Eval C_CallEval -.-> Eval CheckType -->|With| W_EnterWith[enter with] W_EnterWith --> W_ForceBody[force body] W_ForceBody --> W_CallEval[call eval on body] W_CallEval --> W_Return[return value] W_Return --> End W_ForceBody -.->|eval| Eval W_CallEval -.-> Eval CheckType -->|Assert| As_ForceCond[force condition] As_ForceCond --> As_Cond{condition} As_Cond -->|true| As_ForceBody[force body] As_Cond -->|false| As_Throw[throw Catchable] As_ForceBody --> As_CallEval[call eval on body] As_CallEval --> End As_ForceCond -.->|eval| Eval As_ForceBody -.->|eval| Eval As_CallEval -.-> Eval CheckType -->|ConcatStrings| CS_ForceParts[force string parts] CS_ForceParts --> CS_Construct[construct string] CS_Construct --> End CS_ForceParts -.->|eval| Eval CheckType -->|Const| Co_Return[return constant] Co_Return --> End CheckType -->|Str| St_Return[return string] St_Return --> End CheckType -->|Var| V_Lookup[lookup var] V_Lookup --> V_Return[return value] V_Return --> End CheckType -->|Arg| Ar_Lookup[lookup arg] Ar_Lookup --> End CheckType -->|Func| F_Construct[construct function] F_Construct --> End CheckType -->|StrictRef| SR_Eval[eval referenced expr] SR_Eval --> Eval CheckType -->|LazyRef| LR_Resolve[resolve dynamic variable lookups of the referenced expr] LR_Resolve --> LR_Contruct[construct lazy reference] LR_Contruct --> End End([return result]) ```