(6) 控制结构(粗略看一下)   http://www.tcl.tk/man/tcl8.6/TclLib/NRE.htm#M5
          tcl的控制语言结构,如下看一下while循环
           while  {val > 0} {
                    result  *= val ;
                    val   -= 1;
           }
           大家可以看到,这个语句是“while   {语句一}   {语句二}”这样的方式出现的,  我现在给大家说,这个while循环的过程 ,这个tcl脚本解释器,这个跟shell脚本解释器其实差不多,这个解释器特别简单,它就只能解释单个的tcl指令,或者执行多个单个命令的过程集合。他就是简答的替换,while循环处理的过程如下图
           
关于上面说的这些个处理过程,我事先查看了一下关于这个while循环的源码,大家有兴趣的话可以自己查看, 如果你实在看不懂源码里面的细节内容的话,可以参照我开头给的那个链接,点进去看看源码里面的每个函数主要的功能在哪里,然后你一个一个去对照,也能看懂,所以我就是先打开开头那个链接,查看一下关于一个TclNRAddCallback的函数,然后再说说源码,首先这个TclNRAddCallback这个函数呢,其实是一个宏定义,在tclInt.h文件中
 定义 : #define TclNRAddCallback(interp,postProcPtr,data0,data1,data2,data3)
关于这个函数的官方解释如下
Tcl_NRAddCallback是 当在interp指定的解析器中的当前跳转函数指令返回的时候调用的一个C的回调函数,这哥们有6个参数
第一个参数是 : interp 解析器的指针
第二个参数是 : Tcl_NRPostProc * postProcPtr的指针指向的回调函数
后面的就是几个参数
typedef int  Tcl_NRPostProc(
             ClientData data[],
             Tcl_Interp *interp,
             int result);
当跳板函数调用回调函数的时候,这个data参数是指向一个包含4个参数的数组传递给Tcl_NRAddCallback的data0到data3中,tcl解析器被interp这个参数指定的,result函数的值则是有命令指向的结果赋值进去的,result的值可能为:(TCL_OK, TCL_ERROR, TCL_RETURN, TCL_BREAK or TCL_CONTINUE),这个回调函数就会返回一个result去控制后面的执行结果
多个TclNRAddCallback调用就会请求多个相同的或者不同的回调函数,如果多个回调函数被请求,遵从“后入先出”的的规则,也就是,最后被执行的那个回调函数首先返回
看了上面一堆官方文档,可能有人压根没看懂我再搞什么,所以我专门查了查这个while的过程的源码,源码的解析过程如下
我下载的源码是tcl8.6.7版本,然后,找到这个generic文件夹,然后找到这个“tclBasic.c"、“tcl.h”和“tclCmdMZ.c”的文件,一起打开他们,我们来分析一下这个while过程,这个分析的过程中,你其实没必要关心太多这个C语言这么多代码的东西,我们就专一一点,就看这个跟while过程相关的代码,其他的我们就不管了,如果各位有兴趣,留言给我,等我把这个tcl、tk做完之后,我会考虑把这个tcl、tk解析器的源码做一个系列,不过是各位得有兴趣的前提
   1 : 打开“tclBase.c”,找到这个CmdInfo的结构 (这个结构定义了while命令调用的回调函数)     
typedef struct {
const char *name;        /* 命令的名称. */
Tcl_ObjCmdProc *objProc;    /* 实现这个命令的函数.  咱就看这个 */
CompileProc *compileProc;    /* 编译这个命令的函数 */
Tcl_ObjCmdProc *nreProc;    /* NR-based function for command */
int flags;            /*标示, as defined below. */
} CmdInfo;
#define  CMD_IS_SAFE    1
下面是重点了
static const CmdInfo builtInCmds[] = {
.....直接到重点......
{"while",        Tcl_WhileObjCmd,    TclCompileWhileCmd,    TclNRWhileObjCmd,    CMD_IS_SAFE},
.......如果你对生活充满激情,你可以看看其他的.....
............
}
你应该看到了,跟这个命令相关的三个函数就是下面这三个
  Tcl_WhileObjCmd,   
  TclCompileWhileCmd,    //就不看这个函数了,没啥关系
  TclNRWhileObjCmd
那么这三个函数的藏身之处就在“tclCmdMZ.c”这个文件里面,至于为什么,你如果习惯用sourceinsight,你就能查到,但是这个有源头的,tcl每个源文件,都差不多是按照类的方式放置的,每个函数在哪个文件中,这个文件中具体是做什么的。你都可以在 http://www.tcl.tk/man/tcl8.6/TclLib这里找得到
int
Tcl_WhileObjCmd(
ClientData dummy,        /* Not used. */
Tcl_Interp *interp,        /* Current interpreter. */
int objc,            /* Number of arguments. */
Tcl_Obj *const objv[])    /* Argument objects. */
{
return Tcl_NRCallObjProc(interp, TclNRWhileObjCmd, dummy, objc, objv);
}
int
TclNRWhileObjCmd(
ClientData dummy,        /* Not used. */
Tcl_Interp *interp,        /* Current interpreter. */
int objc,            /* Number of arguments. */
Tcl_Obj *const objv[])    /* Argument objects. */
{
ForIterData *iterPtr;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "test command");
return TCL_ERROR;
}
/*
* We reuse [for]'s callback, passing a NULL for the 'next' script.
*/
TclSmallAllocEx(interp, sizeof(ForIterData), iterPtr);
iterPtr->cond = objv[1];
iterPtr->body = objv[2];
iterPtr->next = NULL;
iterPtr->msg  = "\n    (\"while\" body line %d)";
iterPtr->word = 2;
TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL,
NULL, NULL);
return TCL_OK;
}
看完上面的源码,我觉得大家可能都晕晕乎乎的,我们再看一下官方文档
有下面一句话,需要注意的,就是这个while循环他调用了别的指令,set, incr指令
在tcl中,tcl命令如果调用了其他的tcl命令的话,就是下面三个步骤
    1 : 预处理阶段
    2 : Tcl_EvalObjEx(interp, objPtr, flags);//Tcl_EvalObjEx执行存储在objPtr里面的脚本,
    3 : 后处理程序
为了使一个命令看起来像是基于trampoline计算过的,这个命令要拆分成下面三个步骤
1 : 一个none-tramploline的实现,theCmdNewObjProc:这玩意就是创建一个trampoline,然后调用trampoline-based 的实现
2 : 一个trampoline-enabled的实现,, TheCmdNRObjProc:这个函数执行,初始化,命令执行完毕以后请求trampoline调用后处理程序,最后请求trampoline调用内部命令
3 : 后处理程序,TheCmdPostProc:这个函数在TheCmdObjProc里面的内部命令返回后会继续执行后处理程序直到完成
对应上诉三句话就是下面的例子程序
(1)这个none-trampoline  实现就像下面这样子

int
TheCmdNewObjProc(
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
return Tcl_NRCallObjProc(interp, TheCmdNRObjProc,
clientData, objc, objv);
}

(2)这个trampoline-enable 的实现请求后处理程序,然后返回给trampoline请求命令执行计算

int
TheCmdNRObjProc
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
Tcl_Obj *objPtr;
... preparation ...
Tcl_NRAddCallback(interp, TheCmdPostProc,
data0, data1, data2, data3);
/* data0 .. data3 are up to four one-word items to
* pass to the postprocessing procedure */
return Tcl_NREvalObj(interp, objPtr, 0);
}

(3)无论原始指令在内部计算后返回了什么,后处理程序都返回

int
TheCmdNRPostProc(
ClientData data[],
Tcl_Interp *interp,
int result)
{
/* data[0] .. data[3] are the four words of data
* passed to Tcl_NRAddCallback */
... postprocessing ...
return result;
}

我们再对应这个while指令的实现
首先 : 是一个none-trampoline的实现 : Tcl_WhileObjCmd
其次 :  是一个trampoline-enable的实现 : TclNRWhileObjCmd
最后 :  是后处理程序的实现 :  TclNRForIterCallback
说道这里,你就改知道了,这个while指令其实是重用了for指令的回调函数
所以我为什么会说,这个while执行的时候,就是后面那两个大括号都当成了参数传到while命令里面去了,while并不认识后面的是什么,他就是把后续的程序都传到回调函数,回调函数会调用里面的内部指令,然后一步步往后 执行
(7) 事件绑定
         后面再看,主要就是TK的时间绑定
          

tcl/tk学习笔记《二》 tcl/tk概览二相关推荐

  1. 学习笔记之数据可视化(二)——页面布局(上)

    ~续上一章 2. 项目页面布局 2.1 基础布局 2.1.1 PC端屏幕宽度适配设置 2.1.2 主体容器viewport背景图片 2.1.3 HTML结构 2.1.4 css样式代码 2.2 边框图 ...

  2. 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码

    吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...

  3. 学习笔记之数据可视化(二)—— 页面布局(下)

    续上一章 2.7 地图区域(.map) 2.7.1 实现步骤: 2.8 用户统计模块 2.8.1 布局: 2.8.2 柱状图 2.9 订单模块 2.9.1 订单区域布局 2.9.2 订单区域(orde ...

  4. 学习笔记之数据可视化(二)——页面布局(中)

    续上一章 2.6 监控区域布局 2.6.1 布局结构解析: 2.6.2 样式描述: 2.6.3 HTML结构及CSS样式代码 2.6.3 ### 监控区域-效果 2.6.7 点位区域(point) 2 ...

  5. STM32学习笔记:FLASH读写之二

    因为关于STM32的Flash相关的知识点比较多,所以该内容的学习我们分为以下4个部分 1.RAM和ROM的一些基本概念 -- STM32学习笔记:FLASH读写之一 2.STM32的Flash寄存器 ...

  6. 强化学习学习笔记——马尔可夫决策过程(二)

    强化学习学习笔记--马尔可夫决策过程(二) 马尔科夫奖励过程(Markov Reword Process,MRP) 爱学习的马尔科夫蛙 状态值函数(State-Value Function) 马尔科夫 ...

  7. Java学习笔记-Day64 Spring 框架(二)

    Java学习笔记-Day64 Spring 框架(二) 一.控制反转IOC和依赖注入DI 1.控制反转IOC 2.依赖注入DI 3.Spring IOC容器 3.1.简介 3.2.实现容器 3.2.获 ...

  8. # java学习笔记 2020 2/8(十二)慕课网 构造方法

    java学习笔记 2020 2/8(十二)慕课网 构造方法 构造方法是一种特殊的方法,它是一个与类同名的方法. 对象的创建就是通过构造方法来完成,其功能主要是完成对象的初始化. 当类实例化一个对象时会 ...

  9. Deep Learning(深度学习)学习笔记整理系列之(二)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  10. OpenCV学习笔记(一)(二)(三)(四)(五)

    OpenCV学习笔记(一) 决心开始研究OpenCV.闲言少叙,sourceforge网站最近的版本是2011年8月的OpenCV2.3.1,下载安装,我这里使用的开发环境是vs2008,网上搜了一下 ...

最新文章

  1. cad卸载_30年CAD老师傅一步步教你怎么把CAD卸载得一干二净
  2. 第二期冲刺站立会议个人博客15(2016/6/08)
  3. 纯数学思想——在哈尔滨的寒风中
  4. 【数据结构与算法】之深入解析二叉树的算法实现和递归套路深度实践
  5. 【解题报告+通法】_九宫幻方 蓝桥杯 2017年C组第八题(dfs解法)
  6. Bootstrap学习一
  7. mysql中limit后面不能使用运算符
  8. 【推荐实践】Flink 状态(State)管理在推荐场景中的应用
  9. web文件上传(二)--使用form还是ajax
  10. springboot 整合 Servlet、Filter、Listener、访问静态资源
  11. python免费教程视频-28岁想从零开始自学python,有哪些靠谱免费的视频?
  12. 理清网站数据分析思路导图
  13. [贪心][模拟] Jzoj P5811 简单的填数
  14. javascript中的滚动到顶部和Scroll有关的方法
  15. C++编程视频教程《VC知识库大讲堂C++教程》
  16. jxls设置隐藏列隐藏行
  17. 疫情时代无接触AI人脸识别技术助力智慧工地迅猛发展
  18. MOS管当开关控制时,一般用PMOS做上管NMOS做下管的原因
  19. 第三方理财平台海银财富上市破发,IPO筹划两年募资规模缩水至3千万美元
  20. android mp4 画面裁剪,Android视频时长裁剪

热门文章

  1. pgsql的pg_basebackup
  2. 北京燃油车指标转成新能源指标怎么转?
  3. TJA1044---具有待机模式的高速CAN收发器
  4. 无人机宽带自组网技术(随笔)
  5. 关于捕捞所有宝物的最小消耗体力量的问题
  6. linux中常见中英文单词对照表
  7. Quantal Response Equilibrium调研
  8. 2016 Unicode Conference拾遗(一)
  9. python爬虫爬拼多多销量_Python爬取各大汽车销量信息
  10. 走方格跳格子(dp,递归,排列组合三种方法)