Jackiesteed

www.github.com/jackiesteed

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

这一次增加的对结构体的支持, 但是还不很完善.

下面具体讲讲:

1.只允许在全局空间里面声明结构体(在局部的话, 需要局部作用于失效的时候也销毁结构体声明, 可搞), 形式如下:

1 struct mm
2 {
3     int x, y;
4     char ppp;
5 };

2.暂时不支持一边声明结构体一边定义一个相应的变量(这个也可搞), 例如:

1 struct mm
2 {
3     int x, y;
4     char ppp;
5 }m; //this is not supported yet

3.允许在全局空间和局部空间里面声明结构体, 同时允许初始化, 也允许使用{1, 2, 3}形式对结构体进行赋值.

也允许相同类型的结构体之间进行赋值(初始化时{}里面一定要足够, 下次处理一下不够的情况).如下:

 1 struct mm
 2 {
 3     int x, y;
 4     char ppp;
 5 };
 6 mm a;
 7 mm a1 = {1, 2, 'm'};
 8 struct mm b;
 9 struct mm b = {1, 1, 'c'};
10 b = {1, 2, 'c'};

4.不允许结构体里面声明函数, 不允许匿名的结构体(函数的就先别想了, 匿名肯定可以).

----------------------------------------------------------------------------------------------------------------------------

对于结构体的实现, 就是用一个vector<var> 来模拟的, 然后在全局层面存一个已经声明的struct的数组, 效率肯定不高,

因为真正的C++里面, 结构体底层就是一块内存, 使用推算member在结构体里面的位移来使用结构体的, 效率很好, 但是我们是在用C++来解释C++, 所以搞那么底层反而无趣了..

程序的耦合度进一步增大了, 现在我看这代码就像一坨翔了, 哈哈, 下一次一定好好重构一下..

估计下一次修改, 应该会改进对struct的支持, 同时适当重构一下代码.

翠花, 上代码:

Source Code
   1 //mccommon.h
   2 
   3 
   4 /************************************************************************/
   5 /* mccommon.h, 头文件里面声明了Minicpp使用的函数, 声明主要使用的
   6  * 最新修改时间2012-9-15, 主要增加了var.cpp里面函数的声明                */
   7 /************************************************************************/
   8 
   9 #include <vector>
  10 using namespace std;
  11 const int MAX_T_LEN  = 128;   // max token length
  12 const int MAX_ID_LEN = 31;    // max identifier length
  13 const int PROG_SIZE  = 10000; // max program size
  14 const int NUM_PARAMS = 31;    // max number of parameters
  15 
  16 // Enumeration of token types.
  17 enum tok_types { UNDEFTT, DELIMITER, IDENTIFIER,
  18                  NUMBER, KEYWORD, TEMP, STRING, BLOCK, TYPE
  19                };
  20 
  21 // Enumeration of internal representation of tokens.
  22 //大部分指定的是C++里面的关键字, 当然cout和cin也被加进来了
  23 enum token_ireps { UNDEFTOK, ARG, BOOL, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, STRUCT, FALSE, TRUE, SWITCH,
  24                    CASE, IF, ELSE, FOR, DO, WHILE, BREAK,
  25                    RETURN, COUT, CIN, END, ENDL, DEFAULT, CONTINUE, NONE
  26                  };
  27 
  28 
  29 //上面两个枚举的区别是上面的比较广义,指代各种token的类型, 比如block, 这个是不会是关键字的,
  30 //下面的可以理解成就是关键字
  31 struct var;
  32 struct struct_type
  33 {
  34     struct_type()
  35     {
  36         type_name[0] = '\0';
  37         data.clear();
  38     }
  39     char type_name[MAX_ID_LEN + 1];
  40     vector<var> data;
  41 };
  42 
  43 //这是个匿名的var结构体, 存储了变量的类型和值, 但是是个匿名的,
  44 //类似python里面的变量的引用的概念
  45 struct anonymous_var
  46 {
  47     token_ireps var_type; // data type, 这里只用那些数据类型, 包括struct
  48     long int_value;
  49     double float_value;
  50     struct_type struct_value;
  51 };
  52 
  53 // This structure encapsulates the info
  54 // associated with variables.
  55 struct var
  56 {
  57     char var_name[MAX_ID_LEN + 1]; // name
  58     anonymous_var value;
  59 };
  60 
  61 
  62 
  63 
  64 // This structure encapsulates function info.
  65 struct func_type
  66 {
  67     char func_name[MAX_ID_LEN + 1]; // name
  68     token_ireps ret_type; // return type
  69     char *loc; // location of entry point in program
  70 };
  71 
  72 // Enumeration of two-character operators, such as <=.
  73 //这里注意从1开始, 以免用到0出现误解.
  74 enum double_ops { LT = 1, LE, GT, GE, EQ, NE, LS, RS, INC, DEC };
  75 
  76 // These are the constants used when throwing a
  77 // syntax error exception.
  78 //
  79 // NOTE: SYNTAX is a generic error message used when
  80 // nothing else seems appropriate.
  81 enum error_msg
  82 {
  83     SYNTAX, NO_EXP, NOT_VAR, DUP_VAR, DUP_FUNC,
  84     SEMI_EXPECTED, UNBAL_BRACES, FUNC_UNDEF,
  85     TYPE_EXPECTED, RET_NOCALL, PAREN_EXPECTED,
  86     WHILE_EXPECTED, QUOTE_EXPECTED, DIV_BY_ZERO,
  87     BRACE_EXPECTED, COLON_EXPECTED, UNSUPPORTED_TYPE, MORE_MEMBER_THAN_EXPECTED
  88     //最后加了一个UNSUPPORTED_TYPE, 是因为最近只支持一些简单的内建类型
  89 };
  90 
  91 //下面这些是全局变量, 用来控制解析的, 估计以后如果重构的话就是parser类的主要成员变量.
  92 extern char *prog;  // current location in source code
  93 extern char *p_buf; // points to start of program buffer
  94 
  95 extern char token[MAX_T_LEN + 1]; // string version of token
  96 extern tok_types token_type; // contains type of token
  97 extern token_ireps tok; // internal representation of token
  98 
  99 extern anonymous_var ret_value; // function return value
 100 
 101 extern bool breakfound; // true if break encountered
 102 extern bool continuefound;//true if continue encountered
 103 
 104 // Exception class for Mini C++.
 105 class InterpExc
 106 {
 107     error_msg err;
 108 public:
 109     InterpExc(error_msg e)
 110     {
 111         err = e;
 112     }
 113     error_msg get_err()
 114     {
 115         return err;
 116     }
 117 };
 118 
 119 // Interpreter prototypes.
 120 void prescan();
 121 void decl_global();
 122 void decl_struct_type();//完成结构体的声明.
 123 void dump_struct_type(); //这个函数在控制台输出所有目前已经声明的结构体的内容.
 124 bool is_struct_type(char* type_name); //在全局声明的struct里面找, 看是不是一个已经声明的struct
 125 bool get_struct_type_by_name(char* struct_name, struct_type& s_type);
 126 void decl_struct();
 127 bool get_member_var(char* p, anonymous_var*& v);
 128 bool get_type_by_name(char* vname, char* type_name);
 129 void call();
 130 void putback();
 131 void decl_local();
 132 void exec_if();
 133 void find_eob();
 134 void exec_for();
 135 void exec_switch();
 136 void get_params();
 137 void get_args();
 138 void exec_while();
 139 void exec_do();
 140 void exec_cout();
 141 void exec_cin();
 142 void assign_var(char *var_name, anonymous_var value);
 143 bool load_program(char *p, char *fname);
 144 
 145 
 146 anonymous_var find_var(char *s);
 147 void interp();
 148 void func_ret();
 149 char *find_func(char *name);
 150 bool is_var(char *s);
 151 token_ireps find_var_type(char *s);
 152 void find_eol();
 153 
 154 
 155 // Parser prototypes, 这些函数主要用来parse表达式.
 156 void eval_exp(anonymous_var &value);
 157 void eval_exp0(anonymous_var &value);
 158 void eval_exp1(anonymous_var &value);
 159 void eval_exp2(anonymous_var &value);
 160 void eval_exp3(anonymous_var &value);
 161 void eval_exp4(anonymous_var &value);
 162 void eval_exp5(anonymous_var &value);
 163 void atom(anonymous_var &value);
 164 void sntx_err(error_msg error);
 165 void putback();
 166 bool isdelim(char c);
 167 token_ireps look_up(char *s);
 168 anonymous_var find_var(char *s);
 169 tok_types get_token();
 170 int internal_func(char *s);
 171 bool is_var(char *s);
 172 void init_struct(char* struct_name, anonymous_var& value);
 173 
 174 
 175 // "Standard library" prototypes, 这几个函数里面是调用了一下C++的库函数, 封装了一下.
 176 anonymous_var call_getchar();
 177 anonymous_var call_putchar();
 178 anonymous_var call_abs();
 179 anonymous_var call_rand();
 180 
 181 
 182 
 183 //下面这些是为了支持多种类型二增加的一些函数.
 184 //在var.cpp里面实现.
 185 anonymous_var add(anonymous_var &a, anonymous_var &b);
 186 anonymous_var sub(anonymous_var &a, anonymous_var &b);
 187 anonymous_var mul(anonymous_var &a, anonymous_var &b);
 188 anonymous_var div(anonymous_var &a, anonymous_var &b);
 189 void cin_var(anonymous_var &v);
 190 void cout_var(anonymous_var &v);
 191 bool is_valid_simple_type(token_ireps ti);
 192 void init_var(anonymous_var &v);
 193 void neg_var(anonymous_var &v);
 194 bool zero(double x);
 195 void abs_var(anonymous_var &v);
 196 int cmp(anonymous_var &a, anonymous_var &b);
 197 bool is_float_type(token_ireps type);
 198 bool is_int_type(token_ireps type);
 199 bool get_bool_val(anonymous_var &v);
 200 void adaptive_assign_var(anonymous_var &a, anonymous_var &b);
 201 
 202 
 203 //var.cpp
 204 /********************************************************************
 205 var.cpp, 主要是为了增加对多种数值类型的支持而添加的
 206 目前支持bool, char, short, int, long, float, double
 207 基本只使用long和double进行结算.
 208 **********************************************************************/
 209 
 210 #include <iostream>
 211 #include <cmath>
 212 #include <cassert>
 213 #include "mccommon.h"
 214 using namespace std;
 215 
 216 extern vector<struct_type> struct_decls;
 217 
 218 inline bool zero(double x)
 219 {
 220     const double EPS = 1e-9;
 221     return abs(x) < EPS;
 222 }
 223 bool is_int_type(token_ireps type)
 224 {
 225     if(type >= BOOL && type <= LONG) return true;
 226     return false;
 227 }
 228 bool is_float_type(token_ireps type)
 229 {
 230     if(type >= FLOAT && type <= DOUBLE) return true;
 231     else return false;
 232 }
 233 bool check_valid_type(anonymous_var &val)
 234 {
 235     if(!(is_int_type(val.var_type) || is_float_type(val.var_type))) return false;
 236     return true;
 237 }
 238 anonymous_var add(anonymous_var &a, anonymous_var &b)
 239 {
 240     if(!check_valid_type(a) || !check_valid_type(b)) throw InterpExc(UNSUPPORTED_TYPE);
 241     anonymous_var res;
 242     if(a.var_type > b.var_type) res.var_type = a.var_type;
 243     else res.var_type = b.var_type;
 244 
 245     if(is_int_type(res.var_type))
 246     {
 247         res.int_value = a.int_value + b.int_value;
 248     }
 249     else
 250     {
 251         if(is_int_type(a.var_type))
 252         {
 253             res.float_value = double(a.int_value) + b.float_value;
 254         }
 255         else if(is_int_type(b.var_type))
 256         {
 257             res.float_value = a.float_value + double(b.int_value);
 258         }
 259         else
 260         {
 261             res.float_value = a.float_value + b.float_value;
 262         }
 263     }
 264     return res;
 265 }
 266 
 267 anonymous_var sub(anonymous_var &a, anonymous_var &b)
 268 {
 269     if(!check_valid_type(a) || !check_valid_type(b)) throw InterpExc(UNSUPPORTED_TYPE);
 270     anonymous_var res;
 271     if(a.var_type > b.var_type) res.var_type = a.var_type;
 272     else res.var_type = b.var_type;
 273 
 274     if(is_int_type(res.var_type))
 275     {
 276         res.int_value = a.int_value - b.int_value;
 277     }
 278     else
 279     {
 280         if(is_int_type(a.var_type))
 281         {
 282             res.float_value = double(a.int_value) - b.float_value;
 283         }
 284         else if(is_int_type(b.var_type))
 285         {
 286             res.float_value = a.float_value - double(b.int_value);
 287         }
 288         else
 289         {
 290             res.float_value = a.float_value - b.float_value;
 291         }
 292     }
 293     return res;
 294 
 295 }
 296 
 297 anonymous_var mul(anonymous_var &a, anonymous_var &b)
 298 {
 299     if(!check_valid_type(a) || !check_valid_type(b)) throw InterpExc(UNSUPPORTED_TYPE);
 300     anonymous_var res;
 301 
 302     if(a.var_type > b.var_type) res.var_type = a.var_type;
 303     else res.var_type = b.var_type;
 304 
 305     if(is_int_type(res.var_type))
 306     {
 307         res.int_value = a.int_value * b.int_value;
 308     }
 309     else
 310     {
 311         if(is_int_type(a.var_type))
 312         {
 313             res.float_value = double(a.int_value) * b.float_value;
 314         }
 315         else if(is_int_type(b.var_type))
 316         {
 317             res.float_value = a.float_value * double(b.int_value);
 318         }
 319         else
 320         {
 321             res.float_value = a.float_value * b.float_value;
 322         }
 323     }
 324     return res;
 325 }
 326 
 327 anonymous_var div(anonymous_var &a, anonymous_var &b)
 328 {
 329     if(!check_valid_type(a) || !check_valid_type(b)) throw InterpExc(UNSUPPORTED_TYPE);
 330     anonymous_var res;
 331     if(a.var_type > b.var_type) res.var_type = a.var_type;
 332     else res.var_type = b.var_type;
 333 
 334     if(is_int_type(b.var_type))
 335     {
 336         if(0 == a.int_value) throw InterpExc(DIV_BY_ZERO);
 337     }
 338     else
 339     {
 340         if(zero(b.float_value)) throw InterpExc(DIV_BY_ZERO);
 341     }
 342 
 343     if(is_int_type(res.var_type))
 344     {
 345         res.int_value = a.int_value / b.int_value;
 346     }
 347     else
 348     {
 349         if(is_int_type(a.var_type))
 350         {
 351             res.float_value = double(a.int_value) / b.float_value;
 352         }
 353         else if(is_int_type(b.var_type))
 354         {
 355             res.float_value = a.float_value / double(b.int_value);
 356         }
 357         else
 358         {
 359             res.float_value = a.float_value / b.float_value;
 360         }
 361     }
 362     return res;
 363 }
 364 
 365 
 366 //因为现在我只用long 和double来存储表示所有的数值类型,
 367 //在从控制台读取内容的时候会不方便, 现在先用
 368 void cin_var(anonymous_var &v)
 369 {
 370     switch (v.var_type)
 371     {
 372     case BOOL:
 373     {
 374         bool tmp_var;
 375         cin >> tmp_var;
 376         v.int_value = tmp_var;
 377         break;
 378     }
 379     case CHAR:
 380     {
 381         char tmp_var;
 382         cin >> tmp_var;
 383         v.int_value = tmp_var;
 384         break;
 385     }
 386     case SHORT:
 387     {
 388         short tmp_var;
 389         cin >> tmp_var;
 390         v.int_value = tmp_var;
 391         break;
 392     }
 393     case INT:
 394     {
 395         int tmp_var;
 396         cin >> tmp_var;
 397         v.int_value = tmp_var;
 398         break;
 399     }
 400     case LONG:
 401     {
 402         long tmp_var;
 403         cin >> tmp_var;
 404         v.int_value = tmp_var;
 405         break;
 406     }
 407     case FLOAT:
 408     {
 409         float tmp_var;
 410         cin >> tmp_var;
 411         v.float_value = tmp_var;
 412         break;
 413     }
 414     case DOUBLE:
 415     {
 416         double tmp_var;
 417         cin >> tmp_var;
 418         v.float_value = tmp_var;
 419         break;
 420     }
 421     default:
 422         throw InterpExc(UNSUPPORTED_TYPE);
 423         break;
 424     }
 425 }
 426 
 427 
 428 //输出的时候, 要先转化成相应的类型, 然后再打印
 429 void cout_var(anonymous_var &v)
 430 {
 431     switch(v.var_type)
 432     {
 433     case BOOL:
 434         cout << bool(v.int_value != 0);
 435         break;
 436     case CHAR:
 437         cout << char(v.int_value);
 438         break;
 439     case SHORT:
 440         cout << short(v.int_value);
 441         break;
 442     case INT:
 443         cout << int(v.int_value);
 444         break;
 445     case LONG:
 446         cout << long(v.int_value);
 447         break;
 448     case FLOAT:
 449         cout << float(v.float_value);
 450         break;
 451     case DOUBLE:
 452         cout << double(v.float_value);
 453         break;
 454     default:
 455         throw InterpExc(UNSUPPORTED_TYPE);
 456         break;
 457     }
 458 }
 459 
 460 bool is_valid_simple_type(token_ireps ti)
 461 {
 462     return ti >= BOOL && ti <= DOUBLE;
 463 }
 464 
 465 void init_var(anonymous_var &v)
 466 {
 467     v.int_value = 0;
 468     v.float_value = 0.0;
 469     v.struct_value.data.clear();
 470     //v.struct_value.type_name[0] = '\0';
 471     if(0 == strcmp(v.struct_value.type_name, "")) return;
 472 
 473     //如果是个结构体, 我们已经获得了结构体的名字了, 可以拿来指导初始化.
 474     int sz = struct_decls.size();
 475     for(int i = 0; i < sz; i++)
 476     {
 477         if(strcmp(v.struct_value.type_name, struct_decls[i].type_name) == 0)
 478         {
 479             int len = struct_decls[i].data.size();
 480             for(int j = 0; j < len; j++)
 481             {
 482                 var member_var = struct_decls[i].data[j];
 483                 v.struct_value.data.push_back(member_var);
 484             }
 485         }
 486     }
 487 }
 488 
 489 void neg_var(anonymous_var &v)
 490 {
 491     if(is_int_type(v.var_type))
 492     {
 493         v.int_value = -v.int_value;
 494     }
 495     else if(is_float_type(v.var_type))
 496     {
 497         v.float_value = v.float_value;
 498     }
 499     else
 500     {
 501         throw InterpExc(UNSUPPORTED_TYPE);
 502     }
 503 }
 504 
 505 void abs_var(anonymous_var &v)
 506 {
 507     if(is_int_type(v.var_type))
 508     {
 509         v.int_value = abs(v.int_value);
 510     }
 511     else if(is_float_type(v.var_type))
 512     {
 513         v.float_value = abs(v.float_value);
 514     }
 515     else
 516     {
 517         throw InterpExc(UNSUPPORTED_TYPE);
 518     }
 519 }
 520 
 521 
 522 
 523 int cmp(anonymous_var &a, anonymous_var &b)
 524 {
 525     if(!check_valid_type(a) || !check_valid_type(b)) throw InterpExc(UNSUPPORTED_TYPE);
 526     if(is_int_type(a.var_type))
 527     {
 528         if(is_int_type(b.var_type))
 529         {
 530             if(a.int_value == b.int_value) return 0;
 531             if(a.int_value < b.int_value) return -1;
 532             return 1;
 533         }
 534         else if(is_float_type(a.var_type))
 535         {
 536             if(zero(a.int_value - b.float_value)) return 0;
 537             if(a.int_value < b.float_value) return -1;
 538             return 1;
 539         }
 540     }
 541     else
 542     {
 543         if(is_int_type(b.var_type))
 544         {
 545             if(zero(a.float_value - b.int_value)) return 0;
 546             if(a.float_value < b.int_value) return -1;
 547             return 1;
 548         }
 549         else
 550         {
 551             if(zero(a.float_value - b.float_value)) return 0;
 552             if(a.float_value < b.float_value) return -1;
 553             return 1;
 554         }
 555     }
 556     return 0;
 557 }
 558 
 559 bool get_bool_val(anonymous_var &v)
 560 {
 561     bool bool_val = false;
 562     if(is_int_type(v.var_type))
 563     {
 564         bool_val = v.int_value != 0;
 565     }
 566     else if(is_float_type(v.var_type))
 567     {
 568         bool_val = !zero(v.float_value);
 569     }
 570     else
 571     {
 572         throw InterpExc(UNSUPPORTED_TYPE);
 573     }
 574     return bool_val;
 575 }
 576 
 577 
 578 //这个函数适配性地进行了赋值.
 579 void adaptive_assign_var(anonymous_var &a, anonymous_var &b)
 580 {
 581     if(a.var_type == STRUCT && b.var_type == STRUCT)
 582     {
 583         
 584         assert(0 == strcmp(a.struct_value.type_name, b.struct_value.type_name));
 585         assert(a.struct_value.data.size() == b.struct_value.data.size());
 586         int sz = b.struct_value.data.size();
 587         for(int i = 0; i < sz; i++)
 588         {
 589             adaptive_assign_var(a.struct_value.data[i].value, b.struct_value.data[i].value);
 590         }
 591         return;
 592     }
 593     if(!check_valid_type(a) || !check_valid_type(b)) throw InterpExc(UNSUPPORTED_TYPE);
 594 
 595     if(is_int_type(a.var_type))
 596     {
 597         if(is_int_type(b.var_type))
 598         {
 599             a.int_value = b.int_value;
 600         }
 601         else
 602         {
 603             a.int_value = int(b.float_value);
 604         }
 605     }
 606     else
 607     {
 608         if(is_int_type(b.var_type))
 609         {
 610             a.float_value = double(b.int_value);
 611         }
 612         else
 613         {
 614             a.float_value = b.float_value;
 615         }
 616     }
 617 }
 618 
 619 //parser.cpp
 620 
 621 /*********************************************************************
 622  parser.cpp 用来递归下降地解析表达式, 使用anonymous_var类型传递中间结果
 623 *********************************************************************/
 624 
 625 
 626 // Recursive descent parser for integer expressions.
 627 //
 628 #include <iostream>
 629 #include <cstring>
 630 #include <cstdlib>
 631 #include <cctype>
 632 #include "mccommon.h"
 633 
 634 using namespace std;
 635 
 636 // This structure links a library function name
 637 // with a pointer to that function.
 638 struct intern_func_type
 639 {
 640     char *f_name; // function name
 641     anonymous_var (*p)();   // pointer to the function
 642 } intern_func[] =
 643 {
 644     "getchar", call_getchar,
 645     "putchar", call_putchar,
 646     "abs", call_abs,
 647     "rand", call_rand,
 648     "", 0  // null terminate the list
 649 };
 650 
 651 // Keyword lookup table.
 652 // Keywords must be entered lowercase.
 653 // 定义关键字, 对应一个tok的id, 能提高些效率
 654 struct commands
 655 {
 656     char command[20];
 657     token_ireps tok;
 658 } com_table[] =
 659 {
 660     "if", IF,
 661     "else", ELSE,
 662     "for", FOR,
 663     "do", DO,
 664     "while", WHILE,
 665     "bool", BOOL,
 666     "char", CHAR,
 667     "short", SHORT,
 668     "int", INT,
 669     "long", LONG,
 670     "float", FLOAT,
 671     "double", DOUBLE,
 672     "return", RETURN,
 673     "switch", SWITCH,
 674     "break", BREAK,
 675     "case", CASE,
 676     "cout", COUT,
 677     "cin", CIN,
 678     "endl", ENDL,
 679     "default", DEFAULT,
 680     "continue", CONTINUE,
 681     "true", TRUE,
 682     "false", FALSE,
 683     "struct", STRUCT,
 684     "", END  // mark end of table
 685 };
 686 
 687 //eval_exp不根据之前读到的信息来操作, 是在eval_exp函数里面, 读到什么就调用相应的处理过程.
 688 // Entry point into parser.
 689 void eval_exp(anonymous_var &value)
 690 {
 691     get_token();
 692 
 693     if(!*token)
 694     {
 695         throw InterpExc(NO_EXP);
 696     }
 697 
 698     //对于空语句给予一个默认的设置.
 699     if(*token == ';')
 700     {
 701         value.var_type = BOOL; // empty expression
 702         value.int_value = false;
 703         return;
 704     }
 705 
 706     eval_exp0(value);
 707     //这里会把处理完之后读出来的token再返回去.
 708     
 709     putback(); // return last token read to input stream
 710 }
 711 
 712 
 713 // Process an assignment expression.
 714 void eval_exp0(anonymous_var &value)
 715 {
 716     
 717     //这个函数前面已经调用了get_token了, 所以你看到函数开始的时候没有调用get_token
 718     //对于每一种处理, 其实在哪里调用get_token都可以, 只不过如果你要在函数内部调一次的话
 719     // 你在外面putback一下就可以
 720     // temp holds name of var receiving the assignment.
 721     char temp[MAX_ID_LEN + 1];
 722 
 723     tok_types temp_tok;
 724 
 725     if(token_type == IDENTIFIER)
 726     {
 727         if(is_var(token))   // if a var, see if assignment
 728         {
 729             strcpy(temp, token);
 730             temp_tok = token_type;
 731             get_token();
 732             if(*token == '=')   // is an assignment
 733             {
 734                 
 735                 get_token();
 736                 
 737                 if(*token == '{') //专门处理一下对于结构体之间的赋值.
 738                 {
 739                     
 740                     putback();
 741                     char type_name[64];
 742                     get_type_by_name(temp, type_name);
 743                     init_struct(type_name, value);
 744                 }
 745                 else
 746                 {
 747                     //printf("putback\n");
 748                     //printf("%s tttttt\n", token);
 749                     //putback();
 750                     eval_exp0(value); // get value to assign
 751                 }
 752                 assign_var(temp, value); // assign the value
 753 
 754                 return;
 755             }
 756             else   // not an assignment
 757             {
 758                 putback(); // restore original token
 759                 strcpy(token, temp);
 760                 token_type = temp_tok;
 761             }
 762         }
 763     }
 764     eval_exp1(value);
 765 }
 766 
 767 // Process relational operators.
 768 void eval_exp1(anonymous_var &value)
 769 {
 770     
 771     anonymous_var partial_value;
 772     char op;
 773     char relops[] =
 774     {
 775         LT, LE, GT, GE, EQ, NE, 0
 776     };
 777 
 778     eval_exp2(value);
 779 
 780     op = *token;
 781     if(strchr(relops, op))
 782     {
 783         get_token();
 784         eval_exp2(partial_value);
 785 
 786         switch(op)   // perform the relational operation
 787         {
 788         case LT:
 789         {
 790             int res = cmp(value, partial_value);
 791             value.var_type = BOOL;
 792             value.int_value = res < 0;
 793             break;
 794         }
 795         case LE:
 796         {
 797             int res = cmp(value, partial_value);
 798             value.var_type = BOOL;
 799             value.int_value = res <= 0;
 800             break;
 801         }
 802         case GT:
 803         {
 804             int res = cmp(value, partial_value);
 805             value.var_type = BOOL;
 806             value.int_value = res > 0;
 807             break;
 808         }
 809         case GE:
 810         {
 811             int res = cmp(value, partial_value);
 812             value.var_type = BOOL;
 813             value.int_value = res >= 0;
 814             break;
 815         }
 816         case EQ:
 817         {
 818             int res = cmp(value, partial_value);
 819 
 820             value.var_type = BOOL;
 821             value.int_value = (res == 0);
 822             break;
 823         }
 824         case NE:
 825         {
 826             int res = cmp(value, partial_value);
 827             value.var_type = BOOL;
 828             value.int_value = !(res == 0);
 829             break;
 830         }
 831         }
 832     }
 833 }
 834 
 835 // Add or subtract two terms.
 836 void eval_exp2(anonymous_var &value)
 837 {
 838     
 839     char  op;
 840     anonymous_var partial_value;
 841     char okops[] =
 842     {
 843         '(', INC, DEC, '-', '+', 0
 844     };
 845 
 846     eval_exp3(value);
 847 
 848     while((op = *token) == '+' || op == '-')
 849     {
 850         get_token();
 851 
 852         if(token_type == DELIMITER &&
 853                 !strchr(okops, *token))
 854             throw InterpExc(SYNTAX);
 855 
 856         eval_exp3(partial_value);
 857 
 858 
 859 
 860         switch(op)   // add or subtract
 861         {
 862         case '-':
 863         {
 864             value = sub(value, partial_value);
 865             break;
 866         }
 867         case '+':
 868         {
 869             value = add(value, partial_value);
 870             break;
 871         }
 872         }
 873     }
 874 }
 875 
 876 // Multiply or divide two factors.
 877 void eval_exp3(anonymous_var &value)
 878 {
 879     char  op;
 880     anonymous_var partial_value;
 881     char okops[] =
 882     {
 883         '(', INC, DEC, '-', '+', 0
 884     };
 885 
 886     eval_exp4(value);
 887 
 888     while((op = *token) == '*' || op == '/'
 889             || op == '%')
 890     {
 891         get_token();
 892 
 893         if(token_type == DELIMITER &&
 894                 !strchr(okops, *token))
 895             throw InterpExc(SYNTAX);
 896 
 897         eval_exp4(partial_value);
 898 
 899         switch(op)   // mul, div, or modulus
 900         {
 901         case '*':
 902         {
 903             value = mul(value, partial_value);
 904             break;
 905         }
 906 
 907         case '/':
 908         {
 909             //判断除零异常在程序里面做了
 910             value = div(value, partial_value);
 911             break;
 912         }
 913         case '%':
 914         {
 915             anonymous_var tmp = div(value, partial_value);
 916             tmp = mul(partial_value, tmp);
 917             value = sub(value, tmp);
 918             break;
 919         }
 920         }
 921     }
 922 }
 923 
 924 // Is a unary +, -, ++, or --.
 925 void eval_exp4(anonymous_var &value)
 926 {
 927     char  op;
 928     char temp;
 929 
 930     op = '\0';
 931     if(*token == '+' || *token == '-' ||
 932             *token == INC || *token == DEC)
 933     {
 934         temp = *token;
 935         op = *token;
 936         get_token();
 937         value = find_var(token); //这里也处理结构体的成员变量..
 938         //处理前缀++, --要把变化反应到变量身上.
 939         if(temp == INC)
 940         {
 941             anonymous_var tmp_var;
 942             tmp_var.int_value = 1;
 943             tmp_var.var_type = value.var_type;
 944             value = add(value, tmp_var);
 945             assign_var(token, value); //这个token也包括了对结构体成员变量的处理.
 946             get_token();
 947             return;
 948         }
 949         if(temp == DEC)
 950         {
 951             anonymous_var tmp_var;
 952             tmp_var.int_value = 1;
 953             tmp_var.var_type = value.var_type;
 954             value = add(value, tmp_var);
 955             assign_var(token, value);
 956             get_token();
 957             return;
 958         }
 959     }
 960 
 961     eval_exp5(value);
 962     if(op == '-')
 963     {
 964         neg_var(value);
 965     }
 966 }
 967 
 968 // Process parenthesized expression.
 969 void eval_exp5(anonymous_var &value)
 970 {
 971     if((*token == '('))
 972     {
 973         get_token();
 974 
 975         eval_exp0(value); // get subexpression
 976 
 977         if(*token != ')')
 978             throw InterpExc(PAREN_EXPECTED);
 979         get_token();
 980     }
 981     else
 982         atom(value);
 983 }
 984 
 985 // Find value of number, variable, or function.
 986 //增加一个处理功能, 处理浮点数, 但目前只允许***.***的形式, 不允许科学技术法.
 987 void atom(anonymous_var &value)
 988 {
 989     int i;
 990     char temp[MAX_ID_LEN + 1];
 991 
 992     switch(token_type)
 993     {
 994     case IDENTIFIER:
 995         i = internal_func(token);
 996         if(i != -1)
 997         {
 998             // Call "standard library" function.
 999             value = ((*intern_func[i].p)());
1000         }
1001         else if(find_func(token))
1002         {
1003             // Call programmer-created function.
1004             call();
1005             value = ret_value;//目前函数还只支持int返回值
1006         }
1007         else
1008         {
1009 
1010             //在这里处理了后缀++, --
1011             value = find_var(token); // get var's value
1012             strcpy(temp, token); // save variable name
1013 
1014             // Check for ++ or --.
1015             get_token();
1016             if(*token == INC || *token == DEC)
1017             {
1018                 anonymous_var tmp_val = find_var(temp);
1019                 value = tmp_val;
1020                 if(*token == INC)
1021                 {
1022                     anonymous_var one;
1023                     one.int_value = 1;
1024                     one.var_type = tmp_val.var_type;
1025                     tmp_val = add(tmp_val, one);
1026                     assign_var(temp, tmp_val);
1027                 }
1028                 else
1029                 {
1030                     anonymous_var one;
1031                     one.int_value = 1;
1032                     one.var_type = tmp_val.var_type;
1033                     tmp_val = sub(tmp_val, one);
1034                     assign_var(temp, tmp_val);
1035                 }
1036 
1037             }
1038             else putback();
1039         }
1040 
1041         get_token();
1042         return;
1043     case NUMBER: // is numeric constant
1044         //这里对浮点和整型类型做个判断
1045         //printf("in number %s\n", token);
1046         if(strchr(token, '.'))
1047         {
1048 
1049             value.var_type = DOUBLE;
1050             value.float_value = atof(token);
1051         }
1052         else
1053         {
1054             value.var_type = INT;
1055             value.int_value = atoi(token);
1056         }
1057         get_token();
1058 
1059         return;
1060 
1061         //char constant
1062     case DELIMITER: // see if character constant
1063         if(*token == '\'')
1064         {
1065             value.var_type = CHAR;
1066             value.int_value = *prog;
1067             prog++;
1068             if(*prog != '\'')
1069                 throw InterpExc(QUOTE_EXPECTED);
1070 
1071             prog++;
1072             get_token();
1073 
1074             return ;
1075         }
1076         if(*token == ')') return; // process empty expression
1077         else throw InterpExc(SYNTAX);  // otherwise, syntax error
1078     case KEYWORD:
1079     {
1080         if(0 == strcmp(token, "true"))
1081         {
1082             //cout << "jackieddddd" << endl;
1083             value.var_type = BOOL;
1084             value.int_value = 1;
1085         }
1086         else if(0 == strcmp(token, "false"))
1087         {
1088             value.var_type = BOOL;
1089             value.int_value = 0;
1090         }
1091         else
1092         {
1093             throw InterpExc(SYNTAX);
1094         }
1095         get_token();
1096         break;
1097     }
1098     default:
1099         throw InterpExc(SYNTAX); // syntax error
1100     }
1101 }
1102 
1103 // Display an error message.
1104 void sntx_err(error_msg error)
1105 {
1106     char *p, *temp;
1107     int linecount = 0;
1108 
1109     static char *e[] = //这里的显示信息, 是跟头文件里面定义的错误flag顺序一致的
1110     {
1111         "Syntax error",
1112         "No expression present",
1113         "Not a variable",
1114         "Duplicate variable name",
1115         "Duplicate function name",
1116         "Semicolon expected",
1117         "Unbalanced braces",
1118         "Function undefined",
1119         "Type specifier expected",
1120         "Return without call",
1121         "Parentheses expected",
1122         "While expected",
1123         "Closing quote expected",
1124         "Division by zero",
1125         "{ expected (control statements must use blocks)",
1126         "Colon expected",
1127         "Unsupported type yet",
1128         "More struct member that expected"
1129     };
1130 
1131     // Display error and line number.
1132     cout << "\n" << e[error];
1133     p = p_buf;
1134     while(p != prog)   // find line number of error
1135     {
1136         p++;
1137         if(*p == '\r')
1138         {
1139             linecount++;
1140         }
1141     }
1142     cout << " in line " << linecount << endl;
1143 
1144     temp = p;
1145     while(p > p_buf && *p != '\n') p--;
1146 
1147     // Display offending line.
1148     while(p <= temp)
1149         cout << *p++;
1150 
1151     cout << endl;
1152 }
1153 
1154 // Get a token.
1155 tok_types get_token()
1156 {
1157 
1158     char *temp;
1159 
1160     token_type = UNDEFTT;
1161     tok = UNDEFTOK;
1162 
1163     temp = token;
1164     *temp = '\0';
1165 
1166     // Skip over white space.
1167     while(isspace(*prog) && *prog) ++prog;
1168 
1169     // Skip over newline.
1170     while(*prog == '\r')
1171     {
1172         ++prog;
1173         ++prog;
1174         // Again, skip over white space.
1175         while(*prog && isspace(*prog)) ++prog;
1176     }
1177 
1178     // Check for end of program.
1179     if(*prog == '\0')
1180     {
1181         *token = '\0';
1182         tok = END;
1183         return (token_type = DELIMITER);
1184     }
1185 
1186     // Check for block delimiters.
1187     if(strchr("{}", *prog))
1188     {
1189         *temp = *prog;
1190         temp++;
1191         *temp = '\0';
1192         prog++;
1193         return (token_type = BLOCK);
1194     }
1195 
1196     // Look for comments.
1197     if(*prog == '/')
1198         if(*(prog + 1) == '*') // is a /* comment
1199         {
1200             prog += 2;
1201 
1202             //这个循环很给力
1203             do   // find end of comment
1204             {
1205                 while(*prog != '*') prog++;
1206                 prog++;
1207             }
1208             while (*prog != '/');
1209             prog++;
1210             return (token_type = DELIMITER);
1211         }
1212         else if(*(prog + 1) == '/')   // is a // comment
1213         {
1214             prog += 2;
1215             // Find end of comment.
1216             while(*prog != '\r' && *prog != '\0') prog++;
1217             if(*prog == '\r') prog += 2;
1218             return (token_type = DELIMITER);
1219         }
1220 
1221     // Check for double-ops.
1222     if(strchr("!<>=+-", *prog))
1223     {
1224         switch(*prog)
1225         {
1226         case '=':
1227             if(*(prog + 1) == '=')
1228             {
1229                 prog++;
1230                 prog++;
1231                 *temp = EQ;
1232                 temp++;
1233                 *temp = EQ;
1234                 temp++;
1235                 *temp = '\0';
1236             }
1237             break;
1238         case '!':
1239             if(*(prog + 1) == '=')
1240             {
1241                 prog++;
1242                 prog++;
1243                 *temp = NE;
1244                 temp++;
1245                 *temp = NE;
1246                 temp++;
1247                 *temp = '\0';
1248             }
1249             break;
1250         case '<':
1251             if(*(prog + 1) == '=')
1252             {
1253                 prog++;
1254                 prog++;
1255                 *temp = LE;
1256                 temp++;
1257                 *temp = LE;
1258             }
1259             else if(*(prog + 1) == '<')
1260             {
1261                 prog++;
1262                 prog++;
1263                 *temp = LS;
1264                 temp++;
1265                 *temp = LS;
1266             }
1267             else
1268             {
1269                 prog++;
1270                 *temp = LT;
1271             }
1272             temp++;
1273             *temp = '\0';
1274             break;
1275         case '>':
1276             if(*(prog + 1) == '=')
1277             {
1278                 prog++;
1279                 prog++;
1280                 *temp = GE;
1281                 temp++;
1282                 *temp = GE;
1283             }
1284             else if(*(prog + 1) == '>')
1285             {
1286                 prog++;
1287                 prog++;
1288                 *temp = RS;
1289                 temp++;
1290                 *temp = RS;
1291             }
1292             else
1293             {
1294                 prog++;
1295                 *temp = GT;
1296             }
1297             temp++;
1298             *temp = '\0';
1299             break;
1300         case '+':
1301             if(*(prog + 1) == '+')
1302             {
1303                 prog++;
1304                 prog++;
1305                 *temp = INC;
1306                 temp++;
1307                 *temp = INC;
1308                 temp++;
1309                 *temp = '\0';
1310             }
1311             break;
1312         case '-':
1313             if(*(prog + 1) == '-')
1314             {
1315                 prog++;
1316                 prog++;
1317                 *temp = DEC;
1318                 temp++;
1319                 *temp = DEC;
1320                 temp++;
1321                 *temp = '\0';
1322             }
1323             break;
1324         }
1325 
1326         if(*token) return(token_type = DELIMITER);
1327     }
1328 
1329     // Check for other delimiters.
1330     if(strchr("+-*^/%=;:(),'", *prog))
1331     {
1332         *temp = *prog;
1333         prog++;
1334         temp++;
1335         *temp = '\0';
1336         return (token_type = DELIMITER);
1337     }
1338 
1339     // Read a quoted string.
1340     if(*prog == '"')
1341     {
1342         //printf("in string jackie\n");
1343         prog++;
1344         while(*prog != '"' && *prog != '\r' && *prog)
1345         {
1346             // Check for \n escape sequence.
1347             if(*prog == '\\')
1348             {
1349                 if(*(prog + 1) == 'n')
1350                 {
1351                     prog++;
1352                     *temp++ = '\n';
1353                 }
1354             }
1355             else if((temp - token) < MAX_T_LEN)
1356                 *temp++ = *prog;
1357 
1358             prog++;
1359         }
1360         if(*prog == '\r' || *prog == 0)
1361             throw InterpExc(SYNTAX);
1362         prog++;
1363         *temp = '\0'; //temp是token的滑动指针..
1364         //printf("%s string\n", token);
1365         return (token_type = STRING);
1366     }
1367 
1368     // Read an integer number, or float
1369     //由于现在还没加入结构体和类, 所以直接这样判断'.'还是可以的, 不过会有隐患, 要记得~
1370     if(isdigit(*prog) || *prog == '.')
1371     {
1372         while(isdigit(*prog) || *prog == '.') //!isdelim(*prog), 这个是原来的判断..
1373         {
1374             if((temp - token) < MAX_ID_LEN)
1375                 *temp++ = *prog;
1376             prog++;
1377         }
1378         *temp = '\0';
1379         return (token_type = NUMBER);
1380     }
1381 
1382     // Read identifier or keyword.
1383     if(isalpha(*prog))
1384     {
1385         while(!isdelim(*prog))
1386         {
1387             if((temp - token) < MAX_ID_LEN)
1388                 *temp++ = *prog;
1389             prog++;
1390         }
1391         token_type = TEMP;
1392     }
1393 
1394     *temp = '\0';
1395 
1396     // Determine if token is a keyword or identifier.
1397     if(token_type == TEMP)
1398     {
1399         tok = look_up(token); // convert to internal form
1400         if(tok) token_type = KEYWORD; // is a keyword
1401         else token_type = IDENTIFIER;
1402     }
1403     //还是不要搞下面的内容了, 因为struct关键字本身的tok就是STRUCT
1404     //if(token_type == IDENTIFIER && is_struct_type(token)) 
1405     //{
1406     //    //printf("jackie struct %s\n", token);
1407     //    tok = STRUCT;
1408     //}
1409     
1410     // Check for unidentified character in file.
1411     if(token_type == UNDEFTT)
1412         throw InterpExc(SYNTAX);
1413 
1414     return token_type;
1415 }
1416 
1417 // Return a token to input stream.
1418 void putback()
1419 {
1420     char *t;
1421     t = token;
1422     for(; *t; t++) prog--;
1423 }
1424 
1425 // Look up a token's internal representation in the
1426 // token table.
1427 token_ireps look_up(char *s)
1428 {
1429     int i;
1430 
1431     // See if token is in table.
1432     for(i = 0; *com_table[i].command; i++)
1433     {
1434         if(!strcmp(com_table[i].command, s))
1435             return com_table[i].tok;
1436     }
1437 
1438     return UNDEFTOK; // unknown command
1439 }
1440 
1441 // Return index of internal library function or -1 if
1442 // not found.
1443 int internal_func(char *s)
1444 {
1445     int i;
1446 
1447     for(i = 0; intern_func[i].f_name[0]; i++)
1448     {
1449         if(!strcmp(intern_func[i].f_name, s))  return i;
1450     }
1451     return -1;
1452 }
1453 
1454 // Return true if c is a delimiter.
1455 bool isdelim(char c)
1456 {
1457     if(strchr(" !:;,+-<>'/*%^=()", c) || c == 9 ||
1458             c == '\r' || c == 0) return true;
1459     return false;
1460 }
1461 
1462 
1463 //minicpp.cpp
1464 
1465 /***********************************************************************
1466 minicpp.cpp 主函数在这里, 对于for, if while switch等的实现也写在了这里.
1467 ************************************************************************/
1468 #include <iostream>
1469 #include <fstream>
1470 #include <new>
1471 #include <stack>
1472 #include <vector>
1473 #include <cstring>
1474 #include <cstdlib>
1475 #include <cctype>
1476 #include "mccommon.h"
1477 
1478 using namespace std;
1479 
1480 char *prog;  // current execution point in source code
1481 char *p_buf; // points to start of program buffer
1482 
1483 // This vector holds info for global variables.
1484 vector<var> global_vars;
1485 
1486 // This vector holds info for local variables
1487 // and parameters.
1488 vector<var> local_var_stack;
1489 
1490 // This vector holds info about functions.
1491 vector<func_type> func_table;
1492 
1493 // Stack for managing function scope.
1494 
1495 stack<int> func_call_stack;
1496 
1497 vector<struct_type> struct_decls;//用来存储struct类型的定义..
1498 
1499 // Stack for managing nested scopes.
1500 //整形的栈, 存储的是本函数压栈之前栈的大小.
1501 stack<int> nest_scope_stack;
1502 
1503 char token[MAX_T_LEN + 1]; // current token
1504 tok_types token_type; // token type
1505 token_ireps tok; // internal representation
1506 
1507 anonymous_var ret_value; // function return value
1508 
1509 bool breakfound = false; // true if break encountered
1510 bool continuefound = false;
1511 
1512 
1513 
1514 
1515 int main(int argc, char *argv[])
1516 {
1517     if(argc != 2)
1518     {
1519         cout << "Usage: minicpp <filename>\n";
1520         return 1;
1521     }
1522 
1523     // Allocate memory for the program.
1524     try
1525     {
1526         p_buf = new char[PROG_SIZE];
1527     }
1528     catch (bad_alloc exc)
1529     {
1530         cout << "Could Not Allocate Program Buffer\n";
1531         return 1;
1532     }
1533 
1534     // Load the program to execute.
1535     if(!load_program(p_buf, argv[1])) return 1;
1536 
1537     // Set program pointer to start of program buffer.
1538     prog = p_buf;
1539 
1540     try
1541     {
1542         // Find the location of all functions
1543         // and global variables in the program.
1544         prescan();
1545 
1546         // Next, set up the call to main().
1547 
1548         // Find program starting point.
1549         prog = find_func("main");
1550 
1551         // Check for incorrect or missing main() function.
1552         if(!prog)
1553         {
1554             cout << "main() Not Found\n";
1555             return 1;
1556         }
1557 
1558         // Back up to opening (.
1559         prog--;
1560 
1561         // Set the first token to main
1562         strcpy(token, "main");
1563 
1564         // Call main() to start interpreting.
1565         call();
1566     }
1567     catch(InterpExc exc)
1568     {
1569         sntx_err(exc.get_err());
1570         return 1;
1571     }
1572     catch(bad_alloc exc)
1573     {
1574         cout << "Out Of Memory\n";
1575         return 1;
1576     }
1577 
1578     return ret_value.int_value;
1579 }
1580 
1581 // Load a program.
1582 bool load_program(char *p, char *fname)
1583 {
1584     int i = 0;
1585 
1586     ifstream in(fname, ios::in | ios::binary);
1587     if(!in)
1588     {
1589         cout << "Cannot Open file.\n";
1590         return false;
1591     }
1592 
1593     do
1594     {
1595         *p = in.get();
1596         p++;
1597         i++;
1598     }
1599     while(!in.eof() && i < PROG_SIZE);
1600 
1601     if(i == PROG_SIZE)
1602     {
1603         cout << "Program Too Big\n";
1604         return false;
1605     }
1606 
1607     // Null terminate the program. Skip any EOF
1608     // mark if present in the file.
1609     if(*(p - 2) == 0x1a) *(p - 2) = '\0';
1610     else *(p - 1) = '\0';
1611 
1612     in.close();
1613 
1614     return true;
1615 }
1616 
1617 // Find the location of all functions in the program
1618 // and store global variables.
1619 void prescan()
1620 {
1621     char *p, *tp;
1622     char temp[MAX_ID_LEN + 1];
1623     token_ireps datatype;
1624     func_type ft;
1625 
1626     // When brace is 0, the current source position
1627     // is outside of any function.
1628     int brace = 0;
1629 
1630     p = prog;
1631 
1632     do
1633     {
1634         // Bypass code inside functions, brace==0, 保证了现在是在全局作用域
1635         while(brace)
1636         {
1637             get_token();
1638             if(tok == END) //在这里挂了一次, 因为有"{{"这样的字符串..
1639             {
1640                 throw InterpExc(UNBAL_BRACES);
1641             }
1642             if(0 == strcmp(token, "{")) brace++;
1643             if(0 == strcmp(token, "}")) brace--;
1644         }
1645 
1646         tp = prog; // save current position
1647         get_token();
1648 
1649         if(tok == STRUCT) //在这里处理结构体的声明.
1650         {
1651             char* ttp = prog; //这里用来做这一次回退的, 当然这么搞其实已经很乱了..
1652             get_token();
1653             if(token_type == IDENTIFIER)
1654             {
1655                 get_token();
1656                 if(0 == strcmp(token, "{"))//如果是这样就是一个声明, 否则可能是一个类似 struct mm a;这样的定义
1657                 {
1658                     prog = tp;
1659                     decl_struct_type();
1660                 }
1661                 else
1662                 {
1663                     //printf("%s jackiessss\n", token);
1664                     prog = ttp;
1665                     decl_global();
1666                 }
1667             }
1668         }
1669         else if(is_valid_simple_type(tok) || is_struct_type(token)) // See if global var type or function return type.
1670         {
1671 
1672             datatype = tok; // save data type
1673             get_token();
1674 
1675             if(token_type == IDENTIFIER)
1676             {
1677                 strcpy(temp, token);
1678                 get_token();
1679 
1680                 if(0 != strcmp(token, "("))   // must be global var
1681                 {
1682                     prog = tp; // return to start of declaration
1683                     decl_global();
1684                 }
1685                 else if(*token == '(')   // must be a function
1686                 {
1687                     // See if function already defined.
1688                     for(unsigned i = 0; i < func_table.size(); i++)
1689                         if(!strcmp(func_table[i].func_name, temp))
1690                             throw InterpExc(DUP_FUNC);
1691 
1692                     ft.loc = prog;
1693                     ft.ret_type = datatype;
1694                     strcpy(ft.func_name, temp);
1695                     func_table.push_back(ft);
1696 
1697                     do
1698                     {
1699                         get_token();
1700                     }
1701                     while(0 != strcmp(token, ")")); 
1702                     // Next token will now be opening curly
1703                     // brace of function.
1704                 }
1705                 else putback();
1706             }
1707         }
1708         else
1709         {
1710             if(0 == strcmp(token, "{")) brace++;
1711             if(0 == strcmp(token, "}")) brace--;
1712         }
1713     }
1714     while(tok != END);
1715     if(brace) 
1716     {
1717         throw InterpExc(UNBAL_BRACES);
1718     }
1719     prog = p;
1720 }
1721 
1722 // Interpret a single statement or block of code. When
1723 // interp() returns from its initial call, the final
1724 // brace (or a return) in main() has been encountered.
1725 
1726 //对于interp我做了一个小改动, 如果执行语句里面有break, 那么就在推出interp之前让程序把整个block的代码都走一遍, 但是不执行了
1727 //这样, 以后调用interp的程序就不用再为break后面的语句做清理工作了.
1728 //在interp里面, 遇到{}会产生一个新的名字空间, 遇到int 和char还会declare一个local变量
1729 void interp()
1730 {
1731     //printf("interp\n");
1732     anonymous_var value;
1733     int block = 0;
1734     char *tmp_prog = NULL;
1735     //break语句会对外面的控制流程造成影响, 但是continue不会, 它只会不让本次循环后面的语句不执行.
1736     //但是还是要维护一个全局的continue, 因为本block需要知道子block里面是不是有continue;
1737     do
1738     {
1739         if(breakfound || continuefound)
1740         {
1741 
1742             //如果这是个{}包含的块, 那么就用find_eob把整个块吃掉
1743             if(block && tmp_prog)
1744             {
1745 
1746                 prog = tmp_prog;
1747                 find_eob();
1748             }
1749             else
1750             {
1751                 //对于知识一条语句的块, 在break跳出之前吃掉这个分号
1752                 get_token();
1753 
1754             }
1755             return;
1756         }
1757 
1758         token_type = get_token();
1759 
1760         //printf("%s token\n", token);
1761         //对于那些exec_while, exec_while那个向前看的token是在这里读出来的
1762         //跟eval_exp没有关系.
1763 
1764         // See what kind of token is up.
1765         if((token_type == IDENTIFIER ||
1766             *token == INC || *token == DEC) && !is_struct_type(token))
1767         {
1768             // Not a keyword, so process expression.
1769             putback();  // restore token to input stream for
1770             // further processing by eval_exp()
1771             eval_exp(value); // process the expression
1772             //eval_exp和exec_while是相同的层次, 在interp看到向前看字符的时候, 就会递归调用相应的过程.
1773             if(0 != strcmp(token, ";")) 
1774             {
1775                 throw InterpExc(SEMI_EXPECTED);
1776             }
1777         }
1778         else if(token_type == BLOCK) // block delimiter?
1779         {
1780             if(0 == strcmp(token, "{"))   // is a block
1781             {
1782                 putback();
1783                 tmp_prog = prog;
1784                 get_token();
1785                 block = 1; // interpreting block, not statement
1786                 // Record nested scope.
1787                 nest_scope_stack.push(local_var_stack.size());
1788                 //nest_scope_stack里面存的是上一个block的stack的位置,
1789                 //用户恢复栈.
1790             }
1791             else   // is a }, so reset scope and return
1792             {
1793                 // Reset nested scope.
1794                 local_var_stack.resize(nest_scope_stack.top());
1795                 nest_scope_stack.pop();
1796                 return;
1797             }
1798         } 
1799         else if(is_valid_simple_type(tok) || is_struct_type(token) || tok == STRUCT)
1800         {
1801             if(tok != STRUCT) putback(); //如果tok 是STRUCT那么就不吐回去那个token, 当做不以struct开始一个结构体定义就可以了..
1802             decl_local();
1803         }
1804         else // is keyword
1805             switch(tok)
1806             {
1807             case RETURN:  // return from function call, 不要在这里清理局部作用域了, call里面做了处理.
1808                 /*if(block)
1809                 {
1810                     local_var_stack.resize(nest_scope_stack.top());
1811                     nest_scope_stack.pop();
1812                 }*/
1813                 func_ret();
1814                 return;
1815             case IF:      // process an if statement
1816                 exec_if();
1817                 break;
1818             case ELSE:    // process an else statement
1819                 find_eob(); // find end of else block
1820                 // and continue execution
1821                 break;
1822             case WHILE:   // process a while loop
1823                 exec_while();
1824                 break;
1825             case DO:      // process a do-while loop
1826                 exec_do();
1827                 break;
1828             case FOR:     // process a for loop
1829                 exec_for();
1830 
1831                 break;
1832             case BREAK:   // handle break
1833                 breakfound = true;
1834                 // Reset nested scope.
1835                 //这里要特判一下是不是从一个block里面的break, 因为在我修改之后, for while的循环体现在可以是
1836                 //一个单个的语句了
1837                 if(block)
1838                 {
1839                     local_var_stack.resize(nest_scope_stack.top());
1840                     nest_scope_stack.pop();
1841                 }
1842                 break;
1843             case CONTINUE:
1844             {
1845                 continuefound = true;
1846                 if(block)
1847                 {
1848                     local_var_stack.resize(nest_scope_stack.top());
1849                     nest_scope_stack.pop();
1850                 }
1851                 break;
1852             }
1853             case SWITCH:  // handle a switch statement
1854                 exec_switch();
1855                 break;
1856             case COUT:    // handle console output
1857                 exec_cout();
1858                 //cout << "breakfuond :" << breakfound << endl;
1859                 break;
1860             case CIN:     // handle console input
1861                 exec_cin();
1862                 break;
1863             case END:
1864                 exit(0);
1865 
1866             }
1867     }
1868     while (tok != END && block);
1869     return;
1870 }
1871 
1872 
1873 //可以使用map优化.
1874 // Return the entry point of the specified function.
1875 // Return NULL if not found.
1876 char *find_func(char *name)
1877 {
1878     unsigned i;
1879     unsigned len = func_table.size();
1880     for(i = 0; i < len; i++)
1881         if(!strcmp(name, func_table[i].func_name))
1882             return func_table[i].loc;
1883 
1884     return NULL;
1885 }
1886 
1887 // Declare a global variable, including struct variable.
1888 void decl_global()
1889 {
1890     token_ireps vartype;
1891     var v;
1892     get_token(); // get type
1893     vartype = tok; // save var type
1894     char struct_name[64] = "";
1895     if(is_struct_type(token)) 
1896     {
1897         vartype = STRUCT;
1898         strcpy(struct_name, token);//乳沟是个结构体, 那么就在这里把结构体类型的名字给出,
1899                                    //后面初始化的时候根据这个名字对结构体进行初始化
1900     }
1901     anonymous_var value;
1902     // Process comma-separated list.
1903     do
1904     {
1905         get_token(); // get name
1906         //printf("%s name\n", token);
1907 
1908         v.value.var_type = vartype;
1909         strcpy(v.var_name, token);
1910         if(vartype == STRUCT) strcpy(v.value.struct_value.type_name, struct_name);
1911         init_var(v.value); // init to 0, or init the struct_type considering the struct name.
1912         
1913         // See if variable is a duplicate.
1914         unsigned sz = global_vars.size();
1915         for(unsigned i = 0; i < sz; i++)
1916             if(!strcmp(global_vars[i].var_name, token))
1917                 throw InterpExc(DUP_VAR);
1918 
1919         global_vars.push_back(v);
1920 
1921         //printf("%s jjjjj\n", token);
1922         putback();
1923         eval_exp(value); //这个eval_exp会实现赋值, 这里value只是个哑元, 我们不用
1924         get_token();
1925     }
1926     while(*token == ',');
1927 
1928     if(*token != ';') 
1929     {
1930         throw InterpExc(SEMI_EXPECTED);
1931     }
1932 }
1933 
1934 // Declare a local variable.
1935 void decl_local()
1936 {
1937     token_ireps vartype;
1938     var v;
1939     get_token(); // get type
1940     //printf("%s local\n", token);
1941     vartype = tok; // save var type
1942     char struct_name[64] = "";
1943     if(is_struct_type(token)) 
1944     {
1945         //printf("decl_local, %s\n", token);
1946         vartype = STRUCT;
1947         strcpy(struct_name, token);//乳沟是个结构体, 那么就在这里把结构体类型的名字给出,
1948         //后面初始化的时候根据这个名字对结构体进行初始化
1949     }
1950     anonymous_var value;
1951 
1952     // Process comma-separated list.
1953     do
1954     {
1955         get_token(); // get var name
1956         v.value.var_type = vartype;
1957         strcpy(v.var_name, token);
1958         if(vartype == STRUCT) strcpy(v.value.struct_value.type_name, struct_name);
1959         init_var(v.value); // init to 0, or init the struct_type considering the struct name.
1960 
1961         // See if variable is already the name
1962         // of a local variable in this scope.
1963         if(!local_var_stack.empty())
1964             for(int i = local_var_stack.size() - 1;
1965                     i >= nest_scope_stack.top(); i--)
1966             {
1967                 if(!strcmp(local_var_stack[i].var_name, token))
1968                     throw InterpExc(DUP_VAR);
1969             }
1970 
1971         strcpy(v.var_name, token);
1972         local_var_stack.push_back(v);
1973         putback();
1974         eval_exp(value);//这个eval_exp会实现赋值, 这里value只是个哑元, 我们不用
1975         get_token();
1976     }
1977     while(*token == ',');
1978 
1979     if(*token != ';') throw InterpExc(SEMI_EXPECTED);
1980 }
1981 
1982 // Call a function.
1983 void call()
1984 {
1985     char *loc, *temp;
1986     int lvartemp;
1987 
1988     // First, find entry point of function.
1989     loc = find_func(token);
1990 
1991     if(loc == NULL)
1992         throw InterpExc(FUNC_UNDEF); // function not defined
1993     else
1994     {
1995         // Save local var stack index.
1996         lvartemp = local_var_stack.size();
1997 
1998         //get_args 和get_params先后调用 , 进行了一下替换
1999         get_args(); // get function arguments
2000         temp = prog; // save return location
2001 
2002         func_call_stack.push(lvartemp); // push local var index
2003 
2004         prog = loc; // reset prog to start of function
2005         get_params(); // load the function's parameters with
2006         // the values of the arguments
2007 
2008         interp(); // interpret the function
2009 
2010         prog = temp; // reset the program pointer
2011 
2012         if(func_call_stack.empty()) throw InterpExc(RET_NOCALL);
2013 
2014         // Reset local_var_stack to its previous state.
2015 
2016         //这里的resize会把后面的刚刚压入栈的变量删掉.
2017         local_var_stack.resize(func_call_stack.top());
2018         func_call_stack.pop();
2019     }
2020 }
2021 
2022 // Push the arguments to a function onto the local
2023 // variable stack.
2024 void get_args()
2025 {
2026     anonymous_var value, temp[NUM_PARAMS];
2027     int count = 0;
2028     var vt;
2029 
2030     count = 0;
2031     get_token();
2032     if(*token != '(') throw InterpExc(PAREN_EXPECTED);
2033 
2034     // Process a comma-separated list of values.
2035     do
2036     {
2037         eval_exp(value);
2038         temp[count] = value; // save temporarily
2039         get_token();
2040         count++;
2041     }
2042     while(*token == ',');
2043     count--;
2044 
2045     // Now, push on local_var_stack in reverse order.
2046     for(; count >= 0; count--)
2047     {
2048         vt.value = temp[count];
2049         local_var_stack.push_back(vt);
2050     }
2051 }
2052 
2053 // Get function parameters.
2054 
2055 //在这个函数里面实现了从实参到形参的转化工作, 不错.
2056 void get_params()
2057 {
2058     var *p;
2059     int i;
2060 
2061     i = local_var_stack.size() - 1;
2062 
2063     // Process comma-separated list of parameters.
2064     do
2065     {
2066         get_token();
2067         p = &local_var_stack[i];
2068         if(*token != ')' )
2069         {
2070             if(is_valid_simple_type(tok))
2071                 throw InterpExc(TYPE_EXPECTED);
2072 
2073             p->value.var_type = tok;
2074             get_token();
2075 
2076             // Link parameter name with argument already on
2077             // local var stack.
2078             strcpy(p->var_name, token);
2079             get_token();
2080             i--;
2081         }
2082         else break;
2083     }
2084     while(*token == ',');
2085 
2086     //在这里判了一下, 看最后一个读到的是不是')'
2087     if(*token != ')') throw InterpExc(PAREN_EXPECTED);
2088 }
2089 
2090 // Return from a function.
2091 void func_ret()
2092 {
2093     anonymous_var value;
2094 
2095     //value = 0;
2096 
2097     // Get return value, if any.
2098     //目前设定是只支持int返回值.
2099     eval_exp(value);
2100 
2101     ret_value = value;
2102 }
2103 
2104 // Assign a value to a variable.
2105 void assign_var(char *vname, anonymous_var value)
2106 {
2107     //printf("assign %s\n", vname);
2108     //first check if it's a member of a struct
2109     bool b_contains_dots = false;
2110     int len = strlen(vname);
2111     for(int i = 0; i < len; i++)
2112     {
2113         if(vname[i] == '.') 
2114         {
2115             b_contains_dots = true;
2116             break;
2117         }
2118     }
2119     if(b_contains_dots)
2120     {
2121         anonymous_var* vp = NULL;
2122         get_member_var(vname, vp);
2123         adaptive_assign_var(*vp, value);
2124         return;
2125     }
2126     // First, see if it's a local variable.
2127     // 
2128     if(!local_var_stack.empty())
2129         for(int i = local_var_stack.size() - 1;
2130                 i >= func_call_stack.top(); i--)
2131         {
2132             if(!strcmp(local_var_stack[i].var_name,
2133                        vname))
2134             {
2135                 adaptive_assign_var(local_var_stack[i].value, value);
2136                 return;
2137             }
2138         }
2139 
2140     // Otherwise, try global vars.
2141     for(unsigned i = 0; i < global_vars.size(); i++)
2142         if(!strcmp(global_vars[i].var_name, vname))
2143         {
2144             adaptive_assign_var(global_vars[i].value, value);
2145             //cout << value.float_value << " >>>" << endl;
2146             return;
2147         }
2148     //printf("jackiesteed\n");
2149     throw InterpExc(NOT_VAR); // variable not found
2150 }
2151 
2152 // Find the value of a variable, 这个不需要引用, 因为是拿来做中间变量做运算用的.
2153 anonymous_var find_var(char *vname)
2154 {
2155     anonymous_var* vp = NULL;
2156     if(get_member_var(vname, vp)) 
2157         return *vp;
2158     // First, see if it's a local variable.
2159     if(!local_var_stack.empty())
2160         for(int i = local_var_stack.size() - 1;
2161                 i >= func_call_stack.top(); i--)
2162         {
2163             if(!strcmp(local_var_stack[i].var_name, vname))
2164                 return local_var_stack[i].value;
2165         }
2166 
2167     // Otherwise, try global vars.
2168     for(unsigned i = 0; i < global_vars.size(); i++)
2169         if(!strcmp(global_vars[i].var_name, vname))
2170             return global_vars[i].value;
2171     //printf("jackiesteed %s\n", token);
2172     throw InterpExc(NOT_VAR); // variable not found
2173 }
2174 
2175 
2176 //在处理if的时候也处理了else的模块
2177 // Execute an if statement.
2178 void exec_if()
2179 {
2180     anonymous_var cond;
2181 
2182     eval_exp(cond); // get if expression.
2183 
2184     if(get_bool_val(cond))   // if true, process target of IF
2185     {
2186         // Confirm start of block.
2187 
2188         interp();
2189     }
2190     else
2191     {
2192         // Otherwise skip around IF block and
2193         // process the ELSE, if present.
2194 
2195         find_eob(); // find start of next line
2196         get_token();
2197 
2198         if(tok != ELSE)
2199         {
2200             // Restore token if no ELSE is present.
2201             putback();
2202             return;
2203         }
2204         // Confirm start of block.
2205         get_token();
2206 
2207         if(tok == IF)
2208         {
2209             exec_if();
2210             return;
2211         }
2212         putback();
2213         interp();
2214     }
2215 }
2216 
2217 // Execute a switch statement.
2218 void exec_switch()
2219 {
2220     anonymous_var sval, cval;
2221     int brace;
2222 
2223     eval_exp(sval); // Get switch expression.
2224 
2225     // Check for start of block.
2226     if(*token != '{')
2227         throw InterpExc(BRACE_EXPECTED);
2228 
2229     // Record new scope.
2230     nest_scope_stack.push(local_var_stack.size());
2231 
2232     // Now, check case statements.
2233     for(;;)
2234     {
2235         brace = 1;
2236         // Find a case statement.
2237         do
2238         {
2239             get_token();
2240             if(*token == '{') brace++;
2241             else if(*token == '}') brace--;
2242         }
2243         while(tok != CASE && tok != END && brace && tok != DEFAULT);
2244 
2245         // If no matching case found, then skip.
2246         if(!brace) break;
2247 
2248 
2249         if(tok == END) throw InterpExc(SYNTAX);
2250         if(tok == DEFAULT)
2251         {
2252             get_token();
2253             if(*token != ':')
2254                 throw InterpExc(COLON_EXPECTED);
2255             do
2256             {
2257                 interp();
2258                 get_token();
2259                 if(*token == '}')
2260                 {
2261                     putback();
2262                     break;
2263                 }
2264                 putback();
2265                 //if(*token == '{') brace++;
2266                 //else if(*token == '}') brace--;
2267             }
2268             while(!breakfound && tok != END);
2269 
2270             brace = 1;
2271 
2272             // Find end of switch statement.
2273             while(brace)
2274             {
2275                 get_token();
2276                 if(*token == '{') brace++;
2277                 else if(*token == '}') brace--;
2278             }
2279             breakfound = false;
2280 
2281             break;
2282 
2283         }
2284 
2285         // Get value of the case statement.
2286         eval_exp(cval);
2287 
2288         // Read and discard the :
2289         get_token();
2290 
2291         if(*token != ':')
2292             throw InterpExc(COLON_EXPECTED);
2293 
2294         // If values match, then interpret.
2295         if(0 == cmp(cval, sval))
2296         {
2297 
2298             do
2299             {
2300                 interp();
2301 
2302                 get_token();
2303                 if(*token == '}')
2304                 {
2305                     putback();
2306                     break;
2307                 }
2308                 putback();
2309             }
2310             while(!breakfound && tok != END && brace);
2311 
2312             brace = 1;
2313 
2314             // Find end of switch statement.
2315             while(brace)
2316             {
2317                 get_token();
2318                 if(*token == '{') brace++;
2319                 else if(*token == '}') brace--;
2320             }
2321             breakfound = false;
2322 
2323             break;
2324         }
2325     }
2326 }
2327 
2328 // Execute a while loop.
2329 //同下面的do while, 这个也会putback while
2330 void exec_while()
2331 {
2332     anonymous_var cond;
2333     char *temp;
2334 
2335     putback(); // put back the while
2336     temp = prog; // save location of top of while loop
2337 
2338     get_token();
2339     eval_exp(cond); // check the conditional expression
2340 
2341     if(get_bool_val(cond))
2342         interp(); // if true, interpret
2343     else   // otherwise, skip to end of loop
2344     {
2345         find_eob();
2346         return;
2347     }
2348     continuefound = false;
2349     if(!breakfound)
2350         prog = temp; // loop back to top
2351     else
2352     {
2353         breakfound = false;
2354         return;
2355     }
2356 }
2357 
2358 // Execute a do loop.
2359 
2360 //解释: exec_do是在主函数读到了do的时候才会调用, 因此
2361 //在exec_do调用的时候, do这个token已经被读出来了,
2362 //而exec_do还想要在需要继续执行的时候是prog复位到do, 那么就得在程序开始putback一下.
2363 void exec_do()
2364 {
2365     anonymous_var cond;
2366     char *temp;
2367 
2368     // Save location of top of do loop.
2369     putback(); // put back do
2370     temp = prog;
2371 
2372     get_token(); // get start of loop block
2373 
2374     // Confirm start of block.
2375     get_token();
2376     if(*token != '{')
2377         throw InterpExc(BRACE_EXPECTED);
2378     putback();
2379 
2380     interp(); // interpret loop
2381 
2382     // Check for break in loop.
2383     if(breakfound)
2384     {
2385         breakfound = false;
2386         get_token();
2387         if(tok != WHILE) throw InterpExc(WHILE_EXPECTED);
2388         eval_exp(cond); // check the loop condition
2389         return;
2390     }
2391     if(continuefound)
2392     {
2393         continuefound = false;
2394         prog = temp;
2395         return;
2396     }
2397 
2398     get_token();
2399     if(tok != WHILE) throw InterpExc(WHILE_EXPECTED);
2400 
2401     eval_exp(cond); // check the loop condition
2402 
2403     // If true loop; otherwise, continue on.
2404 
2405     if(get_bool_val(cond)) prog = temp;
2406 }
2407 
2408 // Execute a for loop.
2409 //但是for就不能像while和do while那样, 在需要继续循环的时候复位prog指针了, 因为for
2410 //复位的话, 初始点也跟着复位了, 就是for(int i= 0; i< 12; i++)里面的i也会变成0
2411 void exec_for()
2412 {
2413     anonymous_var cond;
2414     char *temp, *temp2;
2415     int paren ;
2416 
2417     //for_local用来标记是不是在for()内部定义了新变量, 如果是, 就会产生新的作用域
2418     bool for_local = false;
2419 
2420     get_token(); // skip opening (
2421     get_token();
2422 
2423     if(is_valid_simple_type(tok) || is_struct_type(token) || tok == STRUCT)//当前读入的token是个类型关键字, 这样就会触发一个局部作用域
2424     {
2425         if(tok != STRUCT)putback();
2426         nest_scope_stack.push(local_var_stack.size());
2427         for_local = true;
2428         decl_local();
2429     }
2430     else
2431     {
2432         eval_exp(cond); // initialization expression
2433     }
2434 
2435     //这个是decl_local和eval_exp最后读到的token, 已经被读出来了
2436     if(*token != ';') throw InterpExc(SEMI_EXPECTED);
2437 
2438     prog++; // get past the ;
2439     temp = prog;
2440 
2441     for(;;)
2442     {
2443         // Get the value of the conditional expression.
2444         eval_exp(cond);
2445 
2446         if(*token != ';') throw InterpExc(SEMI_EXPECTED);
2447         prog++; // get past the ;
2448         temp2 = prog;
2449 
2450         // Find start of for block.
2451         paren = 1;
2452         while(paren)
2453         {
2454             get_token();
2455             if(*token == '(') paren++;
2456             if(*token == ')') paren--;
2457         }
2458 
2459 
2460         // If condition is true, interpret
2461         //现在从for()后面开始interpret
2462         //
2463         if(get_bool_val(cond))
2464         {
2465             //continue只对interp里面的执行起作用, 不会对外面有影响.
2466             interp();
2467             //cout << prog << endl;
2468 
2469         }
2470         else   // otherwise, skip to end of loop
2471         {
2472             find_eob();
2473             if(for_local)
2474             {
2475                 local_var_stack.resize(nest_scope_stack.top());
2476                 nest_scope_stack.pop();
2477             }
2478             return;
2479         }
2480         if(breakfound)
2481         {
2482             breakfound = false;
2483             if(for_local)
2484             {
2485                 local_var_stack.resize(nest_scope_stack.top());
2486                 nest_scope_stack.pop();
2487             }
2488             return;
2489         }
2490         if(continuefound)
2491         {
2492             continuefound = false;
2493         }
2494 
2495 
2496         prog = temp2; // go to increment expression
2497 
2498         // Check for break in loop.
2499 
2500 
2501 
2502         // Evaluate the increment expression.
2503         eval_exp(cond);
2504 
2505         prog = temp; // loop back to top
2506     }
2507 
2508 }
2509 
2510 // Execute a cout statement.
2511 void exec_cout()
2512 {
2513     anonymous_var val;
2514 
2515     get_token();
2516     if(*token != LS) throw InterpExc(SYNTAX);
2517     do
2518     {
2519         get_token();
2520 
2521         if(token_type == STRING)
2522         {
2523             // Output a string.
2524             cout << token;
2525         }
2526         else if(tok == ENDL)
2527         {
2528             cout << endl;
2529         }
2530         else
2531         {
2532             //cout << token << " :---" << endl;
2533             putback();
2534             eval_exp(val);
2535             //cout << val.float_value << "<<<" << endl;
2536             cout_var(val);
2537         }
2538 
2539         get_token();
2540     }
2541     while(*token == LS); //<<
2542 
2543     if(*token != ';') throw InterpExc(SEMI_EXPECTED);
2544 }
2545 
2546 // Execute a cin statement.
2547 void exec_cin()
2548 {
2549     token_ireps vtype;
2550 
2551     get_token();
2552     if(*token != RS) throw InterpExc(SYNTAX);
2553 
2554     do
2555     {
2556         get_token();
2557         if(token_type != IDENTIFIER)
2558             throw InterpExc(NOT_VAR);
2559 
2560         vtype = find_var_type(token);
2561         anonymous_var tmp;
2562         tmp.var_type = vtype;
2563 
2564         cin_var(tmp);
2565         assign_var(token, tmp);
2566         get_token();
2567     }
2568     while(*token == RS); //RS 是>>
2569 
2570     if(*token != ';') throw InterpExc(SEMI_EXPECTED);
2571 }
2572 
2573 
2574 // Find the end of a block.
2575 //#这里find_eob在逻辑上做了一点修改, 由外部保证调用的正确
2576 //如果开始的是{, 那么就处理一个block, 否则就调用find_eol处理一个;语句.
2577 void find_eob()
2578 {
2579     int brace;
2580 
2581     get_token();
2582     //cout << token <<  " find_eob" <<endl;
2583     if(*token != '{')
2584     {
2585         putback();
2586         find_eol();
2587         return ;
2588     }
2589 
2590     brace = 1;
2591 
2592     do
2593     {
2594         get_token();
2595         //cout << token <<  " find_eob" <<endl;
2596         if(*token == '{') brace++;
2597         else if(*token == '}') brace--;
2598     }
2599     while(brace && tok != END);
2600 
2601     if(tok == END) throw InterpExc(UNBAL_BRACES);
2602 }
2603 
2604 void find_eol()
2605 {
2606     do
2607     {
2608         get_token();
2609     }
2610     while (*token != ';' && tok != END);
2611 
2612     if(tok == END) throw InterpExc(SYNTAX);
2613 }
2614 
2615 // Determine if an identifier is a variable. Return
2616 // true if variable is found; false otherwise.
2617 bool is_var(char *vname)
2618 {
2619     anonymous_var* vp;
2620     if(get_member_var(vname, vp)) return true;
2621     // See if vname a local variable.
2622     if(!local_var_stack.empty())
2623         for(int i = local_var_stack.size() - 1;
2624                 i >= func_call_stack.top(); i--)
2625         {
2626             if(!strcmp(local_var_stack[i].var_name, vname))
2627                 return true;
2628         }
2629 
2630     // See if vname is a global variable.
2631     for(unsigned i = 0; i < global_vars.size(); i++)
2632         if(!strcmp(global_vars[i].var_name, vname))
2633             return true;
2634 
2635     return false;
2636 }
2637 
2638 // Return the type of variable.
2639 token_ireps find_var_type(char *vname)
2640 {
2641     // First, see if it's a local variable.
2642     if(!local_var_stack.empty())
2643         for(int i = local_var_stack.size() - 1;
2644                 i >= func_call_stack.top(); i--)
2645         {
2646             if(!strcmp(local_var_stack[i].var_name, vname))
2647                 return local_var_stack[i].value.var_type;
2648         }
2649 
2650     // Otherwise, try global vars.
2651     for(unsigned i = 0; i < global_vars.size(); i++)
2652         if(!strcmp(global_vars[i].var_name, vname))
2653             return local_var_stack[i].value.var_type;
2654 
2655     return UNDEFTOK;
2656 }
2657 
2658 void decl_struct_type()
2659 {
2660     struct_type type;
2661     get_token();
2662     if(strcmp(token, "struct") != 0)
2663         throw InterpExc(SYNTAX);
2664     get_token();
2665     strcpy(type.type_name, token);
2666 
2667     get_token();
2668 
2669     if(*token != '{')
2670         throw InterpExc(SYNTAX);
2671 
2672     while(true)
2673     {
2674         get_token();
2675 
2676         if(strcmp(token, "}") == 0) break;
2677         var member_var;
2678         member_var.value.var_type = tok;
2679 
2680         do
2681         {
2682             get_token();
2683             strcpy(member_var.var_name, token);
2684             init_var(member_var.value); 
2685             type.data.push_back(member_var);
2686             get_token();
2687         }while(*token == ',');
2688 
2689         if(*token != ';') throw InterpExc(SYNTAX);
2690     }
2691     get_token();
2692     if(*token != ';') throw InterpExc(SYNTAX);
2693     struct_decls.push_back(type);
2694 
2695     dump_struct_type();
2696 }
2697 
2698 void dump_struct_type()
2699 {
2700     char simple_type_names[7][8] = {"bool", "char", "short", "int", "long", "float", "double"};
2701     int len = struct_decls.size();
2702     for(int i = 0; i < len; i++)
2703     {
2704         printf("struct %s\n", struct_decls[i].type_name);
2705         printf("{\n");
2706         struct_type& t = struct_decls[i];
2707         int sz = t.data.size();
2708         for(int j = 0; j < sz; j++)
2709         {
2710             printf("\t%s %s;\n", simple_type_names[t.data[j].value.var_type - BOOL], t.data[j].var_name);
2711         }
2712         printf("};\n");
2713     }
2714 }
2715 
2716 bool is_struct_type(char* type_name)
2717 {
2718     int sz = struct_decls.size();
2719     for(int i = 0; i < sz; i++) if(0 == strcmp(type_name, struct_decls[i].type_name)) return true;
2720     return false;
2721 }
2722 
2723 
2724 bool get_member_var(char* vname, anonymous_var*& v)
2725 {
2726     bool b_contains_dots = false;
2727     char* p = vname;
2728     while(*p)
2729     {
2730         if(*p == '.')
2731         {
2732             b_contains_dots = true;
2733             break;
2734         }
2735         p++;
2736     }
2737     if(!b_contains_dots) return false;
2738     char struct_name[64];
2739     char member_name[64];//这里没做太多假定, 所以你尽量别声明很长的变量名称..
2740     strcpy(struct_name, vname);
2741     int len = strlen(struct_name);
2742     for(int i = 0; i < len; i++)
2743     {
2744         if(struct_name[i] == '.')
2745         {
2746             struct_name[i] = '\0';
2747             break;
2748         }
2749     }
2750     for(int i = 0; i < len; i++)
2751     {
2752         if(vname[i] == '.')
2753         {
2754             strcpy(member_name, vname + i + 1);
2755             break;
2756         }
2757     }
2758     // See if vname a local variable.
2759     if(!local_var_stack.empty())
2760         for(int i = local_var_stack.size() - 1;
2761             i >= func_call_stack.top(); i--)
2762         {
2763             if(local_var_stack[i].value.var_type == STRUCT && strcmp(struct_name, local_var_stack[i].var_name) == 0)
2764             {
2765                 vector<var>& data= local_var_stack[i].value.struct_value.data;
2766                 int len = data.size();
2767                 for(int j = 0; j < len; j++)
2768                 {
2769                     if(0 == strcmp(data[j].var_name, member_name))
2770                     {
2771                         v = &(data[j].value);
2772                         return true;
2773                     }
2774                 }
2775             }
2776         }
2777 
2778         // See if vname is a global variable.
2779         unsigned sz = global_vars.size();
2780         for(unsigned i = 0; i < sz; i++)
2781         {
2782             if(global_vars[i].value.var_type == STRUCT && strcmp(global_vars[i].var_name, struct_name) == 0)
2783             {
2784                 vector<var>& data = global_vars[i].value.struct_value.data;
2785                 int len = data.size();
2786                 for(int j = 0; j < len; j++)
2787                 {
2788                     if(0 == strcmp(data[j].var_name, member_name))
2789                     {
2790                         v = &(data[j].value);
2791                         return true;
2792                     }
2793                 }
2794             }
2795         }
2796 
2797         return false;
2798 }
2799 void init_struct(char* struct_name, anonymous_var& value)
2800 {
2801     get_token();
2802     if(*token != '{') throw InterpExc(SYNTAX);
2803     value.var_type = STRUCT;
2804     strcpy(value.struct_value.type_name, struct_name);
2805     var member_var;
2806     struct_type tp;
2807     get_struct_type_by_name(struct_name, tp);
2808     int sz = tp.data.size();
2809     
2810     int i = 0;
2811     do 
2812     {
2813         
2814         eval_exp(member_var.value);
2815         strcpy(member_var.var_name, tp.data[i].var_name);
2816         
2817         //adaptive_assign_var(value.struct_value.data[i].value, member_var);
2818         value.struct_value.data.push_back(member_var);
2819         
2820         get_token();
2821         if(*token != ',') break;
2822         i++;
2823         if(i >= sz)
2824             throw InterpExc(MORE_MEMBER_THAN_EXPECTED);
2825     } while (true);
2826     if(*token != '}') throw InterpExc(SYNTAX);
2827     get_token();
2828     if(*token != ';') throw InterpExc(SYNTAX);
2829 }
2830 
2831 //通过名字来获得某个结构体的实体.
2832 bool get_struct_type_by_name(char* struct_name, struct_type& s_type)
2833 {
2834     int sz = struct_decls.size();
2835     for(int i = 0; i < sz; i++)
2836     {
2837         if(0 == strcmp(struct_name, struct_decls[i].type_name)) 
2838         {
2839             s_type = struct_decls[i];
2840             return true;
2841         }
2842     }
2843     return false;
2844 }
2845 
2846 
2847 //这个函数目前只为结构体服务, 先不处理关于int, double等的内容...
2848 bool get_type_by_name(char* vname, char* type_name)
2849 {
2850     // See if vname a local variable.
2851     if(!local_var_stack.empty())
2852         for(int i = local_var_stack.size() - 1;
2853             i >= func_call_stack.top(); i--)
2854         {
2855             if(!strcmp(local_var_stack[i].var_name, vname))
2856             {
2857                 strcpy(type_name, local_var_stack[i].value.struct_value.type_name);
2858                 return true;
2859             }
2860         }
2861 
2862         // See if vname is a global variable.
2863     for(unsigned i = 0; i < global_vars.size(); i++)
2864         if(!strcmp(global_vars[i].var_name, vname))
2865         {
2866             strcpy(type_name, global_vars[i].value.struct_value.type_name);
2867             return true;
2868         }
2869 
2870         return false;
2871 }
2872 
2873 
2874 //libcpp.cpp
2875 /***********************************************************************
2876  libcpp.cpp, 主要是对库函数的封装
2877 ************************************************************************/
2878 
2879 // Add more of your own, here.
2880 
2881 #include <iostream>
2882 #include <cstdlib>
2883 #include <cstdio>
2884 #include "mccommon.h"
2885 
2886 using namespace std;
2887 
2888 // Read a character from the console.
2889 // If your compiler supplies an unbuffered
2890 // character intput function, feel free to
2891 // substitute it for the call to cin.get().
2892 anonymous_var call_getchar()
2893 {
2894     char ch;
2895 
2896     ch = getchar();
2897 
2898     // Advance past ()
2899     get_token();
2900     if(*token != '(')
2901         throw InterpExc(PAREN_EXPECTED);
2902 
2903     get_token();
2904     if(*token != ')')
2905         throw InterpExc(PAREN_EXPECTED);
2906     anonymous_var val;
2907     val.var_type = CHAR;
2908     val.int_value = ch;
2909     return val;
2910 }
2911 
2912 // Write a character to the display.
2913 anonymous_var call_putchar()
2914 {
2915     anonymous_var value;
2916 
2917     eval_exp(value);
2918 
2919     putchar(char(value.int_value));
2920 
2921     return value;
2922 }
2923 
2924 // Return absolute value.
2925 anonymous_var call_abs()
2926 {
2927     anonymous_var val;
2928 
2929     eval_exp(val);
2930     abs_var(val);
2931     return val;
2932 }
2933 
2934 // Return a randome integer.
2935 anonymous_var call_rand()
2936 {
2937 
2938     // Advance past ()
2939     get_token();
2940     if(*token != '(')
2941         throw InterpExc(PAREN_EXPECTED);
2942 
2943     get_token();
2944     if(*token != ')')
2945         throw InterpExc(PAREN_EXPECTED);
2946 
2947     anonymous_var val;
2948     val.var_type = INT;
2949     val.int_value = rand();
2950     return val;
2951 }
posted on 2012-11-04 23:33  Jackiesteed  阅读(1158)  评论(2编辑  收藏  举报