.版本 2
.支持库 spec
.支持库 eAPI

.程序集 即时解释虚拟机
.程序集变量 词, 词, , "0"
.程序集变量 函数列表, 抽象语法树节点, , "0"
.程序集变量 上一运算结果, 双精度小数型

.子程序 解释代码入口
    .参数 代码, 文本型
    .局部变量 行, 文本型, , "0"
    .局部变量 i, 整数型
    .局部变量 根, 抽象语法树节点

    行 ＝ 分割文本 (代码, #换行符, )
    .计次循环首 (取数组成员数 (行), i)
        词法分析 (行 [i], 词)
        根 ＝ 语法分析 (词)
        ' 输出语法分析结果 (根, )
        解释代码 (根)
    .计次循环尾 ()
    

.子程序 交互运行
    .局部变量 根, 抽象语法树节点
    .局部变量 解释返回, 文本型

    .判断循环首 (真)
        标准输出 (, “>>> ”)
        词法分析 (标准输入 (), 词)
        根 ＝ 语法分析 (词)
        .如果真 (解释代码 (根) ＝ “表达式求值”)
            标准输出 (, 到文本 (上一运算结果) ＋ #换行符)
        .如果真结束
        
    .判断循环尾 ()

.子程序 解释代码, 文本型
    .参数 节点, 抽象语法树节点
    .局部变量 节点语类, 整数型
    .局部变量 节点词类, 整数型
    .局部变量 节点参量, 整数型
    .局部变量 节点名, 文本型

    节点语类 ＝ 节点.获取语类 ()
    节点词类 ＝ 节点.获取词类 ()
    节点参量 ＝ 节点.获取参数数量 ()
    节点名 ＝ 节点.获取函数名 ()
    
    .如果真 (节点语类 ＝ #语类_根)
        .如果 (节点参量 ＝ 1)
            返回 (解释代码 (节点.获取参数节点 (1)))
        .否则
            .如果真 (节点参量 ＞ 1)
                调试输出 (“警告 根节点有超过一个子节点”)
            .如果真结束
            
        .如果结束
        
    .如果真结束
    
    .如果真 (节点.包含语类 (#语类_nop))
        调试输出 (“警告 nop 泄露到了运行时”)
    .如果真结束
    
    .如果真 (节点词类 ＝ #词类_注释)
        返回 (“注释”)
    .如果真结束
    
    .如果真 (节点语类 ＝ #语类_定义)
        ' 现在所有的定义都是函数定义
        添加函数 (节点)
        返回 (“定义”)
    .如果真结束
    
    .如果真 (节点.包含语类 (#语类_函数调用))
        ' 这里的函数调用包含 f(x) 式的, 也包含 1+1 式的
        上一运算结果 ＝ 表达式求值 (节点, , )
        返回 (“表达式求值”)
    .如果真结束
    返回 (“无匹配”)
    

.子程序 表达式求值, 双精度小数型
    .参数 节点, 抽象语法树节点
    .参数 可用上层参数名, 文本型, 可空 数组
    .参数 可用上层参数值, 双精度小数型, 可空 数组
    .局部变量 节点名, 文本型
    .局部变量 i, 整数型
    .局部变量 待输出文本组, 文本型, , "0"
    .局部变量 待输出文本, 文本型
    .局部变量 节点词类, 整数型

    节点名 ＝ 节点.获取函数名 ()
    节点词类 ＝ 节点.获取词类 ()
    ' 调试输出 (“准备表达式求值”, 节点.生成展示文本 (), 可用上层参数名, 可用上层参数值)
    .如果真 (节点名 ＝ “output”)
        清除数组 (待输出文本组)
        .计次循环首 (节点.获取参数数量 (), i)
            加入成员 (待输出文本组, 格式化文本 (“%s”, 到文本 (表达式求值 (节点.获取参数节点 (i)))))
        .计次循环尾 ()
        待输出文本 ＝ 连接字符串 (待输出文本组, “, ”) ＋ #换行符
        标准输出 (, 待输出文本)
        返回 (取文本长度 (待输出文本) － 2) ' #换行符长度为2
    .如果真结束
    .如果真 (节点名 ＝ “dir”)
        标准输出 (, “当前函数如下: ” ＋ #换行符)
        .计次循环首 (取数组成员数 (函数列表), i)
            标准输出 (, 到文本 (i) ＋ #换行符)
            输出语法分析结果 (函数列表 [i], )
        .计次循环尾 ()
        返回 (取数组成员数 (函数列表))
    .如果真结束
    .如果真 (节点词类 ＝ #词类_数字)
        返回 (到数值 (节点名))
    .如果真结束
    .如果真 (节点词类 ＝ #词类_算符)
        返回 (处理算符 (节点, 可用上层参数名, 可用上层参数值))
    .如果真结束
    .如果真 (节点词类 ＝ #词类_括号)
        返回 (表达式求值 (节点.获取参数节点 (1), 可用上层参数名, 可用上层参数值))
    .如果真结束
    .如果真 (节点.获取参数数量 () ＝ 0 且 节点词类 ＝ #词类_标识符)
        返回 (处理标识符 (节点, 可用上层参数名, 可用上层参数值))
    .如果真结束
    
    ' 到这个地步 只有 f(x) 式的函数调用了
    返回 (处理函数调用 (节点, 可用上层参数名, 可用上层参数值))
    

.子程序 处理标识符, 双精度小数型, , 如果要处理标识符值, 应当从当前函数参数值中找匹配的标识符
    .参数 节点, 抽象语法树节点
    .参数 可用上层参数名, 文本型, 可空 数组
    .参数 可用上层参数值, 双精度小数型, 可空 数组
    .局部变量 i, 整数型
    .局部变量 节点名, 文本型

    节点名 ＝ 节点.获取函数名 ()
    ' 调试输出 (可用上层参数名, 可用上层参数值)
    .计次循环首 (取数组成员数 (可用上层参数名), i)
        .如果真 (节点名 ＝ 可用上层参数名 [i])
            返回 (可用上层参数值 [i])
        .如果真结束
        
    .计次循环尾 ()
    
    标准输出 (, “[错误] 找不到标识符: ” ＋ 节点名 ＋ #换行符)
    标准输入 ()
    结束 ()
    返回 (0)

.子程序 处理函数调用, 双精度小数型, , 只处理 f(x) 式的
    .参数 节点, 抽象语法树节点
    .参数 可用上层参数名, 文本型, 可空 数组
    .参数 可用上层参数值, 双精度小数型, 可空 数组
    .局部变量 节点名, 文本型
    .局部变量 节点词类, 整数型
    .局部变量 参数数量, 整数型
    .局部变量 i, 整数型
    .局部变量 函数原型, 抽象语法树节点
    .局部变量 同参量函数, 抽象语法树节点, , "0"
    .局部变量 同参量函数_匹配度, 整数型, , "0"
    .局部变量 当前最大匹配度, 整数型
    .局部变量 当前最大匹配度索引, 整数型

    .局部变量 同名函数数, 整数型
    .局部变量 参数求值结果, 双精度小数型, , "0"
    .局部变量 参数值完全匹配数量, 整数型
    .局部变量 函数参数索引, 整数型
    .局部变量 待匹配参数节点, 抽象语法树节点
    .局部变量 当前待匹配值, 双精度小数型
    .局部变量 当前匹配度, 整数型

    .局部变量 可用本层参数名, 文本型, 数组, "0"
    .局部变量 可用本层参数值, 双精度小数型, 数组, "0"
    .局部变量 待调用函数, 抽象语法树节点
    .局部变量 当前结果, 双精度小数型

    节点名 ＝ 节点.获取函数名 ()
    节点词类 ＝ 节点.获取词类 ()
    参数数量 ＝ 节点.获取参数数量 ()
    清除数组 (参数求值结果)
    
    .计次循环首 (参数数量, i)
        当前结果 ＝ 表达式求值 (节点.获取参数节点 (i), 可用上层参数名, 可用上层参数值)
        加入成员 (参数求值结果, 当前结果)
        ' 调试输出 (“参数求值结果”, 节点.获取参数节点 (i).获取函数名 (), 当前结果)
    .计次循环尾 ()
    
    ' 找同名函数
    清除数组 (同参量函数)
    清除数组 (同参量函数_匹配度)
    
    清除数组 (可用本层参数名)
    清除数组 (可用本层参数值)
    
    .计次循环首 (取数组成员数 (函数列表), i)
        函数原型 ＝ 函数列表 [i].获取参数节点 (1)
        .如果真 (函数原型.获取函数名 () ＝ 节点名)
            同名函数数 ＝ 同名函数数 ＋ 1
            .如果真 (函数原型.获取参数数量 () ＝ 参数数量)
                加入成员 (同参量函数, 函数列表 [i])
                参数值完全匹配数量 ＝ 0
                .计次循环首 (参数数量, 函数参数索引)
                    待匹配参数节点 ＝ 函数原型.获取参数节点 (函数参数索引)
                    ' 词类是标识符的是未知数  不论如何不会增加最佳匹配量, 之外的, 可以求值然后对比值
                    ' 如果求值结果不同, 一定不能加入匹配, 直接打散到最小上
                    .如果真 (待匹配参数节点.获取词类 () ≠ #词类_标识符)
                        当前待匹配值 ＝ 表达式求值 (待匹配参数节点)
                        .如果 (当前待匹配值 ＝ 参数求值结果 [函数参数索引])
                            参数值完全匹配数量 ＝ 参数值完全匹配数量 ＋ 1
                        .否则
                            参数值完全匹配数量 ＝ -9999
                            跳出循环 ()
                        .如果结束
                        
                    .如果真结束
                    
                .计次循环尾 ()
                加入成员 (同参量函数_匹配度, 参数值完全匹配数量)
            .如果真结束
            
        .如果真结束
        
    .计次循环尾 ()
    ' 给出合适的报错
    .如果真 (同名函数数 ＝ 0)
        标准输出 (, “[错误] 找不到函数 ” ＋ 节点名 ＋ “. 相关上下文如下: ” ＋ #换行符 ＋ #换行符)
        输出语法分析结果 (节点, )
        标准输入 ()
        结束 ()
    .如果真结束
    
    .如果真 (取数组成员数 (同参量函数) ＝ 0)
        标准输出 (, “[错误] 找不到可重载函数, 同名函数有: ” ＋ #换行符)
        .计次循环首 (取数组成员数 (同参量函数), i)
            标准输出 (, 到文本 (i) ＋ “:” ＋ #换行符)
            输出语法分析结果 (同参量函数 [i], )
        .计次循环尾 ()
        标准输入 ()
        结束 ()
    .如果真结束
    
    ' 找到最佳匹配度的那个函数
    当前最大匹配度 ＝ -99999
    当前最大匹配度索引 ＝ 0
    .计次循环首 (取数组成员数 (同参量函数), i)
        当前匹配度 ＝ 同参量函数_匹配度 [i]
        .如果真 (当前匹配度 ＞ 当前最大匹配度)
            当前最大匹配度索引 ＝ i
            当前最大匹配度 ＝ 当前匹配度
        .如果真结束
        
    .计次循环尾 ()
    
    ' 把标识符参数拿出来并给值
    函数原型 ＝ 同参量函数 [当前最大匹配度索引].获取参数节点 (1)
    待调用函数 ＝ 同参量函数 [当前最大匹配度索引].获取参数节点 (2)
    ' 输出语法分析结果 (同参量函数 [当前最大匹配度索引], )
    ' 输出语法分析结果 (函数原型, )
    
    .计次循环首 (参数数量, 函数参数索引)
        
        待匹配参数节点 ＝ 函数原型.获取参数节点 (函数参数索引)
        ' 输出语法分析结果 (待匹配参数节点, )
        .如果真 (待匹配参数节点.获取词类 () ＝ #词类_标识符)
            加入成员 (可用本层参数名, 函数原型.获取参数节点 (函数参数索引).获取函数名 ())
            加入成员 (可用本层参数值, 参数求值结果 [函数参数索引])
            ' 调试输出 (“可用本层参数”, 函数原型.获取参数节点 (函数参数索引).获取函数名 (), 参数求值结果 [函数参数索引])
        .如果真结束
        
    .计次循环尾 ()
    
    
    ' 调试输出 (“调用一个函数”, 节点.生成展示文本 ())
    
    返回 (表达式求值 (待调用函数, 可用本层参数名, 可用本层参数值))

.子程序 处理算符, 双精度小数型
    .参数 节点, 抽象语法树节点
    .参数 可用上层参数名, 文本型, 可空 数组
    .参数 可用上层参数值, 双精度小数型, 可空 数组
    .局部变量 节点名, 文本型
    .局部变量 l, 双精度小数型
    .局部变量 r, 双精度小数型

    节点名 ＝ 节点.获取函数名 ()
    ' 调试输出 (可用上层参数名, 可用上层参数值)
    
    l ＝ 表达式求值 (节点.获取参数节点 (1), 可用上层参数名, 可用上层参数值)
    r ＝ 表达式求值 (节点.获取参数节点 (2), 可用上层参数名, 可用上层参数值)
    
    .判断开始 (节点名 ＝ “+”)
        返回 (l ＋ r)
    .判断 (节点名 ＝ “-”)
        返回 (l － r)
    .判断 (节点名 ＝ “*”)
        返回 (l × r)
    .判断 (节点名 ＝ “/”)
        返回 (l ÷ r)
    .默认
        调试输出 (“警告 遇到奇怪的算符”, 节点名)
    .判断结束
    返回 (0)

.子程序 添加函数
    .参数 节点, 抽象语法树节点

    调试输出 (“新增一个函数”, 节点.获取参数节点 (1).获取函数名 ())
    加入成员 (函数列表, 节点)
    

.子程序 取最小, 双精度小数型
    .参数 a, 双精度小数型
    .参数 b, 双精度小数型

    .如果真 (a ＞ b)
        返回 (b)
    .如果真结束
    返回 (a)

