SHARE
TWEET

Untitled

a guest Jun 16th, 2019 46 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ci0.c  2013.10.03  Hatada
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. //----------------------------------------------------------------------------//
  7. //                               字句解析                                     //
  8. //----------------------------------------------------------------------------//
  9. #define  SIZETOKEN      1000    // トークン配列のサイズ
  10. #define  OPERATOR2      "== != <= >= |= += -= *= /= >> << ++ -- && || -> "
  11.  
  12. int  fToken, fTrace, fCode;       // コマンド引数オプション
  13. char *Token[SIZETOKEN];                 // トークン配列
  14. int  nToken;                            // トークン数
  15. int  tix = -1;  //カレントトークン.構文解析で使用.エラー関数共用のためここに置く
  16.  
  17. void error(const char *format, ...) {
  18.     vfprintf(stderr, format, (char*)&format + sizeof(char*));
  19.     if (tix >= 0) fprintf(stderr, "\n  Token[%d] = \"%s\"\n", tix, Token[tix]);
  20.     exit(1);
  21. }   // 移植性のために、一般には stdarg.h のマクロを使う方がよい。
  22. int isAlpha(int c) { return (isalpha(c) || c == '_'); }
  23. int isAlNum(int c) { return isAlpha(c) || isdigit(c); }
  24. int isKanji(int c) { return (c>=0x81 && c<=0x9F) || (c>=0xE0 && c<=0xFC); }
  25.  
  26. void lex(const char *srcfile) {
  27.     char linebuf[256], buf[128], op2[4], *p, *pBgn;
  28.     FILE *fpSrc = fopen(srcfile, "r");
  29.     if (fpSrc == NULL) error("file '%s' can't open", srcfile);
  30.     while (fgets(linebuf, sizeof(linebuf), fpSrc) != NULL) {
  31.         for (p = linebuf; *p != '\0'; ) {       // 一行分の字句解析
  32.             if (*p <= ' ') { p++; continue; }   // 空白文字をスキップする
  33.             if (p[0]=='/' && p[1]=='/') break;  // コメント. 行末までスキップ
  34.             pBgn = p;
  35.             if (*p == '"') {   // 文字列. escape文字,2byte文字のとき2byte目をスキップ
  36.                 for (p++; *p != '\0' && *p != '"'; p++)
  37.                     if (*p == '\\' || isKanji(*p)) p++;
  38.                 if (*p++ != '"') error("後ろの引用符がありません<%s>", pBgn);
  39.             } else if (isdigit(*p)) {                   // 数値(10進)
  40.                 for (p++; *p != '\0' && isdigit(*p); p++) ;
  41.             } else if (strncmp(pBgn,"char*",5) == 0) {  // char*
  42.                 p += 5;
  43.             } else if (isAlpha(*p)) {                   // 識別子, 予約語
  44.                 for (p++; *p != '\0' && isAlNum(*p); ) p++;
  45.             } else {                                    // 演算子
  46.                 sprintf(op2, "%c%c ", p[0], p[1]);
  47.                 p += strstr(OPERATOR2, op2) != NULL ? 2 : 1;
  48.             }
  49.             sprintf(buf, "%.*s", p - pBgn, pBgn);
  50.             if (nToken == SIZETOKEN) error("トークン配列オーバフロー");
  51.             Token[nToken++] = strdup(buf);
  52.             if (fToken) printf(strchr(";{}",*buf)!=NULL ? "%s\n" : "%s ", buf);
  53.         }
  54.     }
  55.     fclose(fpSrc);
  56. }
  57.  
  58. //----------------------------------------------------------------------------//
  59. //                               名前管理                                     //
  60. //----------------------------------------------------------------------------//
  61. #define  SIZEGLOBAL     1000    // グローバル名前管理表のサイズ
  62. #define  SIZELOCAL      1000    // ローカル名前管理表のサイズ
  63. enum { NM_VAR = 0x01, NM_FUNC = 0x02 };         // 名前の種別
  64. enum { AD_DATA = 0, AD_STACK, AD_CODE };        // アドレスの種別
  65.  
  66. typedef struct _Name {
  67.     int  type;                  // NM_VAR: 変数、NM_FUNC: 関数
  68.     char *dataType, *name;      // データ型, 変数名または関数名
  69.     int  addrType, address;     // アドレスの種別, 相対アドレス
  70. } Name;
  71.  
  72. Name *GName[SIZEGLOBAL], *LName[SIZELOCAL];    // 名前管理表.
  73. int  nGlobal, nLocal;                          // 同上現在の登録数
  74.  
  75. // 関数または変数情報を名前管理表に登録する
  76. Name *appendName(int nB, int type, char *dataType, char *name, int addrType, int addr) {
  77.     Name nm = { type, dataType, name, addrType, addr };
  78.     Name *pNew = calloc(1, sizeof(Name));
  79.     if (pNew == NULL) error("appendName: メモリが足りません");
  80.     memcpy(pNew, &nm, sizeof(Name));
  81.     if (nB == 0 && nGlobal < SIZEGLOBAL-1) GName[nGlobal++] = pNew;
  82.     else if (nB == 1 && nLocal < SIZELOCAL-1) LName[nLocal++] = pNew;
  83.     else error("appendName: 引数エラーまたは配列オーバーフロー");
  84.     return pNew;        // 新しいエントリのアドレスを返す
  85. }
  86.  
  87. // 指定された名前表から指定された名前を探す
  88. Name *getNameFromTable(int nB, int type, char *name, int fErr) {
  89.     int  n;
  90.     int  nEntry = nB==0 ? nGlobal : nLocal;
  91.     for (n = 0; n < nEntry; n++) {
  92.         Name *e = nB==0 ? GName[n] : LName[n];
  93.         if (strcmp(e->name,name) == 0 && (e->type&type) != 0) return e;
  94.     }
  95.     if (fErr && nB==0) error("'%s' undeclared", name);
  96.     return NULL;        // 見つからなかった。
  97. }
  98.  
  99. // 最初にローカル名前表、なければグローバル名前表から指定された名前を探す
  100. Name *getNameFromAllTable(int type, char *name, int fErr) {
  101.     Name *pName = getNameFromTable(1, type, name, fErr);
  102.     if (pName != NULL) return pName;
  103.     return getNameFromTable(0, type, name, fErr);
  104. }
  105.  
  106. //----------------------------------------------------------------------------//
  107. //                               構文解析                                     //
  108. //----------------------------------------------------------------------------//
  109. void expression(int mode);                      // 式の構文解析
  110. void statement(int locBreak, int locContinue);  // 文の構文解析
  111.  
  112. typedef struct _INSTRUCT { int opcode, type, val; } INSTRUCT;
  113. enum { PUSH = 0, ENTRY, POP, MOV, ADD, ADDSP, SUB, MUL, DIV, MOD, RET, CALL,
  114.        JZ, JMP, CMP, LT, GT, LE, GE, EQ, NE, FUNC, LABEL };
  115. char *OPCODE[] = { "push", "entry", "pop", "mov", "add", "addsp", "sub", "mul", "div", "mod",
  116.          "ret", "call", "jz", "jmp", "cmp", "lt", "gt", "le", "ge", "eq", "ne", "func", "label" };
  117. enum { NIL, IMM, STR, MEM, REF, SKV, SKR, LOC, SP };
  118. char *TYPE[] = { "nil", "int", "str", "mem", "ref", "stack-val", "stack-ref", "loc", "sp" };
  119. #define SIZEDATASECT    1000
  120. enum { VAL=0, ADDR };                   // VAL: 変数の内容, ADDR: 変数のアドレス
  121. enum { ST_FUNC=0, ST_GVAR };            // ST_FUNC: 関数定義中, ST_GVAR: 変数宣言中
  122. char *DataSection[SIZEDATASECT];        // グローバル変数、文字列管理配列
  123. int  ixData;                            // データの登録数
  124. int  baseSpace;                         // スタック上の相対アドレス
  125. int  numLabel = 1;      // ラベルの通し番号(ラベル配列の添え字)
  126. INSTRUCT Inst[1000];    // 命令配列
  127. int  nInst = 0;         // 命令数
  128. int  entryPoint;        // 命令を格納するとき main関数の位置を記録しておく
  129.  
  130. int loc() { return numLabel++; }
  131. int is(char *s) { return strcmp(Token[tix],s) == 0; }
  132. int ispp(char *s) { if (is(s)) { tix++; return 1; } return 0; }
  133. int isTypeSpecifier() { return is("void") || is("int") || is("char*"); }
  134. int isFunctionDefinition() { return *Token[tix+2] == '('; }
  135. void skip(char *s) { if (!ispp(s)) error("'%s' expected", s); }
  136.  
  137. void printInst(int n, INSTRUCT *pI) {
  138.     printf("%d: %s ", n, OPCODE[pI->opcode]);
  139.     if (pI->type == NIL) printf("\n");
  140.     else printf(pI->type==STR ? "%s %s\n" : "%s %d\n", TYPE[pI->type], pI->val);
  141. }
  142.  
  143. INSTRUCT *outInst2(int opcode, int type, int val) {
  144.     INSTRUCT inst = { opcode, type, val };
  145.     return memcpy(&Inst[nInst++], &inst, sizeof(inst));
  146. }
  147. INSTRUCT *outInst(int code){ return outInst2(code, 0,0); }
  148.  
  149. //================================== 式の構文解析 ==============================
  150. /// PrimExpression ::= Identifier | "(" Expr ")" | Constant | FunctionCall
  151. void functionCall() {   // 優先順位 #1
  152.     int n, nParam, posParam[20], nInstSave, ixDataSave, ixNext, rtn;
  153.     char *name  = Token[tix++];
  154.     Name *pName = getNameFromTable(0, NM_FUNC, name, 1);
  155.     skip("(");
  156.     // 引数は最後から順にスタックに積むため、まず位置を求める
  157.     nInstSave  = nInst;
  158.     ixDataSave = ixData;
  159.     for (nParam = 0; !is(")"); nParam++) {
  160.         posParam[nParam] = tix;         // 各引数の先頭トークンの位置
  161.         expression(VAL);
  162.         ispp(",");
  163.     }
  164.     ixNext = tix + 1;                       // ")" の次
  165.     nInst  = nInstSave;
  166.     ixData = ixDataSave;                // 生成したデータを廃棄する
  167.     for (n = nParam; --n >= 0; ) {
  168.         tix = posParam[n];
  169.         expression(VAL);     // 引数を最後から順に評価して、スタックに積む
  170.     }
  171.     tix = ixNext;
  172.     if (pName->address > 0) outInst2(CALL, IMM, pName->address);
  173.     else outInst2(CALL, STR, (int)pName->name);
  174.     outInst2(ADDSP, IMM, nParam);               // スタックポインタ回復
  175. }
  176.  
  177. void primaryExpression(int mode) {      // 優先順位 #1
  178.     if (isdigit(*Token[tix])) {                 // Constant 数値
  179.         outInst2(PUSH, IMM, atoi(Token[tix++]));
  180.     } else if (*Token[tix] == '"') {            // Constant 文字列
  181.         outInst2(PUSH, STR, (int)Token[tix++]);
  182.     } else if (ispp("(")) {                     // "(" Expr ")"
  183.         expression(VAL);
  184.         skip(")");
  185.     } else if (*Token[tix+1] == '(') {          // FuctionCall
  186.         functionCall();
  187.     } else if (isAlpha(*Token[tix])) {          // Identifier
  188.         Name *pName = getNameFromAllTable(NM_VAR, Token[tix], 1);
  189.         int type = (pName->addrType==AD_STACK)? (mode==VAL?SKV:SKR):(mode==VAL?MEM:REF);
  190.         outInst2(PUSH, type, pName->address);
  191.         tix++;
  192.     } else {
  193.         error("primExpr: <%s>", Token[tix]);
  194.     }
  195. }
  196.  
  197. /// MulExpression ::= PrimaryExpression ( ("*" | "/" | "%") PrimaryExpression )*
  198. void mulExpression(int mode) {  // #4
  199.     int fMul=0, fDiv=0;
  200.     primaryExpression(mode);    // [左辺の値]
  201.     while ((fMul=ispp("*")) || (fDiv=ispp("/")) || ispp("%")) {
  202.         primaryExpression(mode); // [右辺の値,左辺の値]
  203.         outInst(fMul ? MUL : fDiv ? DIV : MOD);
  204.     }
  205. }
  206.  
  207. /// AddExpression ::= MulExpression ( ("+" | "-") MulExpression )*
  208. void addExpression(int mode) {  // #5
  209.     int fAdd;
  210.     mulExpression(mode);                // [左辺の値]
  211.     while ((fAdd=ispp("+")) || ispp("-")) {
  212.         mulExpression(mode);            // [右辺の値,左辺の値]
  213.         outInst(fAdd ? ADD : SUB);
  214.     }
  215. }
  216.  
  217. /// RelationalExpression ::= addExpr [("<" | ">" | "<=" | ">=") addExpr]
  218. void relationalExpression(int mode) {    // #7    // 符号付き整数に対応          
  219.     int fLT=0, fGT=0, fLE=0;
  220.     addExpression(mode);        // [左辺の値]
  221.     if ((fLT=ispp("<")) || (fGT=ispp(">")) || (fLE=ispp("<=")) || ispp(">=")){
  222.         addExpression(mode);    // [右辺の値,左辺の値]
  223.         outInst(fLT ? LT : fGT ? GT : fLE ? LE : GE);
  224.     }
  225. }
  226.  
  227. /// EqualityExpression ::= RelationalExpr [ ("==" | "!=") RelationalExpr ]
  228. void equalityExpression(int mode) { // #8
  229.     int fEQ;
  230.     relationalExpression(mode);         // [左辺の値]
  231.     if ((fEQ=ispp("==")) || ispp("!=")) {
  232.         relationalExpression(mode);     // [右辺の値,左辺の値]
  233.         outInst(fEQ ? EQ : NE);
  234.     }
  235. }
  236.  
  237. /// expression ::= [Identifier "="] addExpression
  238. void assign() {
  239.     primaryExpression(ADDR);     // [左辺変数アドレス]
  240.     skip("=");
  241.     addExpression(VAL);         // [右辺の値,左辺変数アドレス]
  242.     outInst(MOV);               // Mem[st1] = st0
  243. }
  244.  
  245. void expression(int mode) {             // #15
  246.     if (strcmp(Token[tix+1],"=") == 0) assign();
  247.     else equalityExpression(mode);
  248. }
  249.  
  250. //================================ 文の構文解析 ================================
  251. /// TypeSpecifier ::= "void" | "char*" | "int"
  252. char *typeSpecifier() {
  253.     if (!isTypeSpecifier()) error("'%s' not typespecfier", Token[tix]);
  254.     return Token[tix++];        // データ型
  255. }
  256.  
  257. /// VarDeclarator ::= Identifier
  258. char *varDeclarator() { return Token[tix++]; }  // 変数名または関数名
  259.  
  260. /// VariableDeclaration ::= TypeSpecifier VarDeclarator ["=" Initializer]
  261. ///                             ("," VarDeclarator ["=" Initializer])*
  262. void variableDeclaration(int status) {
  263.     char *varType = typeSpecifier();
  264.     do {
  265.         char *varName = varDeclarator();
  266.         if (status == ST_FUNC) {
  267.             appendName(1, NM_VAR, varType, varName, AD_STACK, --baseSpace);
  268.             if (is("=")) { tix--; assign(); }
  269.         } else {
  270.             appendName(0, NM_VAR, varType, varName, AD_DATA, ixData);
  271.             if (ispp("=")) DataSection[ixData++] = Token[tix++];
  272.         }
  273.     } while (ispp(","));
  274. }
  275.  
  276. /// CompoundStatement ::= "{" (Statements)* "}"
  277. void compoundStatement(int locBreak, int locContinue) {
  278.     for (skip("{"); tix < nToken && isTypeSpecifier(); skip(";"))
  279.         variableDeclaration(ST_FUNC);   // ローカル変数の宣言
  280.     while (!ispp("}")) statement(locBreak, locContinue);
  281. }
  282.  
  283. /// IfStatement ::= "if" "(" Expression ")" Statement [ "else" Statement ]
  284. void ifStatement(int locBreak, int locContinue) {
  285.     int locElse, locEnd;
  286.     skip("(");
  287.     expression(VAL);
  288.     skip(")");
  289.     outInst2(JZ, IMM, locElse=loc());
  290.     statement(locBreak, locContinue);           // then_statement
  291.     if (is("else")) outInst2(JMP, IMM, locEnd=loc());
  292.     outInst2(LABEL, IMM, locElse);
  293.     if (ispp("else")) {
  294.         statement(locBreak, locContinue);       // else_statement
  295.         outInst2(LABEL, IMM, locEnd);
  296.     }
  297. }
  298.  
  299. /// WhileStatement ::= "while" "(" Expression ")" Statement
  300. void whileStatement(int locBreak, int locContinue) {
  301.     int locExpr, locNext;
  302.     outInst2(LABEL, IMM, locExpr=loc());
  303.     skip("(");
  304.     expression(VAL);
  305.     skip(")");
  306.     outInst2(JZ, IMM, locNext=loc());   // expressionの値が 0 ならば、locNextへジャンプ
  307.     statement(locNext, locExpr);        // locBreak, locContinue
  308.     outInst2(JMP, IMM, locExpr);        // 判定式へ無条件ジャンプ
  309.     outInst2(LABEL, IMM, locNext);      // 次の文を指すラベル
  310. }
  311.  
  312. /// ReturnStatement ::= "return" [Expression] ";"
  313. void returnStatement() {
  314.     if (!is(";")) expression(VAL);
  315.     skip(";");
  316.     outInst(RET);
  317. }
  318.  
  319. /// Statement ::= CompoundStmt | IfStmt | ReturnStmt| Expression ";" | ";"
  320. void statement(int locBreak, int locContinue) {
  321.     if (ispp(";")) ; // null statement
  322.     else if (is("{")) compoundStatement(locBreak, locContinue);
  323.     else if (ispp("if")) ifStatement(locBreak, locContinue);
  324.     else if (ispp("while")) whileStatement(locBreak, locContinue);
  325.     else if (ispp("return")) returnStatement();
  326.     else { expression(VAL); skip(";"); }
  327. }
  328.  
  329. /// FunctionDefinition ::= TypeSpecifier  VarDeclarator
  330. ///     "(" [ VarDeclaration ("," VarDeclaration)* ] ")" CompoundStatement
  331. void functionDefinition() {
  332.     int locFunc = loc(); // この関数の識別番号を得る
  333.     char *varType = typeSpecifier();            // 返り値のデータ型
  334.     char *varName = varDeclarator();            // 関数名
  335.     nLocal = 0;         // ローカル変数表初期化(メモリ解放省略)
  336.     outInst2(FUNC, STR, (int)varName);
  337.     outInst2(LABEL, IMM, locFunc);
  338.     if (strcmp(varName,"main") == 0) entryPoint = nInst;
  339.     appendName(0, NM_FUNC, varType, varName, AD_CODE, locFunc);
  340.     baseSpace = 2;      // 戻り番地と旧bpの分.
  341.     outInst(ENTRY);     // push ebp; mov ebp,espに相当
  342.     INSTRUCT *pSub = outInst2(ADDSP, IMM, 0); // sp -= imm; immの値は後で書き換え
  343.     for (skip("("); !ispp(")"); ispp(",")) {
  344.         varType = typeSpecifier();
  345.         varName = varDeclarator();
  346.         appendName(1, NM_VAR, varType, varName, AD_STACK, baseSpace++);
  347.     }
  348.     baseSpace = 0;              // ここからローカル変数領域
  349.     compoundStatement(0, 0);    // 関数本体
  350.     pSub->val = baseSpace;      // ここで imm の値を変更
  351.     if (Inst[nInst-1].opcode != RET) outInst(RET);
  352. }
  353.  
  354. //============================ 最上位の構文解析 =============================
  355. /// Program ::= (FunctionDefinition | VariableDeclaration ";")*
  356. void program() {
  357.     for (tix = 0; tix < nToken; ) {
  358.         if (fTrace) printf("%3d: %s\n", tix, Token[tix]);
  359.         if (isFunctionDefinition()) functionDefinition();       // 関数定義
  360.         else { variableDeclaration(ST_GVAR); skip(";"); }       // 外部変数宣言
  361.     }
  362. }
  363.  
  364. void parser() {
  365.     appendName(0, NM_FUNC, "int", "printf", AD_CODE, 0);
  366.     program();
  367. }
  368.  
  369. //-----------------------------------------------------------------------------//
  370. //                       命令実行                                              //
  371. //-----------------------------------------------------------------------------//
  372. #define  MAXMEM   1000
  373. int  mem[MAXMEM];       // メモリ
  374. int  sp, bp, pc;        // スタックポインタ、ベースポインタ、プログラムカウンタ
  375. int  pos = 0;           // メモリインデックス. データは上から、スタックは下から
  376. int  location[1000];    // ラベルのアドレス配列
  377.  
  378. void push(int val) {
  379.     if (sp <= pos) error("stack overflow!");
  380.     mem[--sp] = val;
  381. }
  382.  
  383. int pop() {
  384.     if (sp >= MAXMEM) error("stack empty!");
  385.     return mem[sp++];
  386. }
  387.  
  388. int getStr(char *str) {
  389.     int n = strlen(str);
  390.     if (str[n-1] == '"') str[n-1] = '\0';
  391.     return str+1;
  392. }
  393.  
  394. void execute() {
  395.     int n, addr, type, val, rtn;
  396.     if (fTrace) printf("entryPoint = %d\n", entryPoint);
  397.     for (n = 0; n < nInst; n++) {
  398.         if (fCode) printInst(n, &Inst[n]);
  399.         if (Inst[n].opcode == LABEL) location[Inst[n].val] = n;
  400.     }
  401.     for (n = 0; n < ixData; n++)
  402.         mem[pos++] = atoi(DataSection[n]);
  403.     sp = MAXMEM;  // スタックポインタの初期化
  404.     for (pc = entryPoint; pc < nInst; ) {
  405.       if (fTrace) printInst(pc, &Inst[pc]);
  406.       type = Inst[pc].type;
  407.       val  = Inst[pc].val;
  408.       switch (Inst[pc++].opcode) {
  409.         case FUNC:  break;
  410.         case LABEL: break;
  411.         case ENTRY:  // 関数の入り口
  412.             push(bp);
  413.             bp = sp;
  414.             break;
  415.         case ADDSP:
  416.             rtn = pop();        // 関数戻り値がスタックのトップに置かれている
  417.             sp += val;          // 引数分を削除
  418.             push(rtn);          // 改めてスタックのトップに関数戻り値を置く
  419.             break;
  420.         case PUSH:
  421.             if (type == SKV) push(mem[bp+val]);    // ローカル変数の値をpush
  422.             else if (type == SKR) push(bp+val);    // ローカル変数のアドレスをpush
  423.             else if (type == STR) push(getStr((char*)val)); // 文字列のアドレスをpush
  424.             else if (type == IMM) push(val);
  425.             else error("exec.PUSH: %d", type);
  426.             break;
  427.         case MOV:
  428.             val  = pop();
  429.             addr = pop();
  430.             mem[addr] = val;
  431.             break;
  432.         case ADD: mem[sp+1] += mem[sp]; sp++; break;
  433.         case SUB: mem[sp+1] -= mem[sp]; sp++; break;
  434.         case MUL: mem[sp+1] *= mem[sp]; sp++; break;
  435.         case DIV: mem[sp+1] /= mem[sp]; sp++; break;
  436.         case MOD: mem[sp+1] %= mem[sp]; sp++; break;
  437.         case GT:  mem[sp+1] = (mem[sp+1] >  mem[sp]); sp++; break;
  438.         case GE:  mem[sp+1] = (mem[sp+1] >= mem[sp]); sp++; break;
  439.         case LT:  mem[sp+1] = (mem[sp+1] <  mem[sp]); sp++; break;
  440.         case LE:  mem[sp+1] = (mem[sp+1] <= mem[sp]); sp++; break;
  441.         case EQ:  mem[sp+1] = (mem[sp+1] == mem[sp]); sp++; break;
  442.         case NE:  mem[sp+1] = (mem[sp+1] != mem[sp]); sp++; break;
  443.         case JZ:  if (mem[sp++] == 0) pc = location[val]; break;// jz xxx
  444.         case JMP: pc = location[val]; break;
  445.         case CMP: mem[sp+1] -= mem[sp]; sp++; break;
  446.         case CALL:
  447.             if (type == STR) {  // native function call
  448.                 rtn = printf((char*)mem[sp], mem[sp+1], mem[sp+2], mem[sp+3]);
  449.                 push(rtn);
  450.             } else {
  451.                 push(pc);           // 戻り番地格納
  452.                 pc = location[val]; // 関数先頭番地を pc にセット
  453.             }
  454.             break;
  455.         case RET:       // 関数からの戻り
  456.             rtn = pop();        // 関数の戻り値
  457.             sp = bp;            // スタックポインタ回復
  458.             bp = pop();         // ベースポインタ回復
  459.             if (sp == MAXMEM) break;       // main関数からのリターン
  460.             pc = pop();         // pcにCALL命令の次の命令アドレスをセット
  461.             push(rtn);          // スタックの一番上に関数の戻り値を置く
  462.             break;
  463.         default: error("unknown opcode: %d\n", Inst[pc-1].opcode);
  464.       }
  465.     }
  466. }
  467.  
  468. void main(int argc, char *argv[]) {
  469.     char *srcfile = NULL;
  470.     int n;
  471.     for (n = 1; n < argc; n++) {
  472.         if (strcmp(argv[n], "-token") == 0) fToken = 1;
  473.         else if (strcmp(argv[n], "-trace") == 0) fTrace = 1;
  474.         else if (strcmp(argv[n], "-code") == 0) fCode = 1;
  475.         else srcfile = argv[n];
  476.     }
  477.     lex(srcfile);       //==== 字句解析. 結果はToken配列に格納 ====//
  478.     parser();           //==== 構文解析・意味解析・中間語コード生成 ====//
  479.     tix = -1;           // エラー表示で Token[tix] の表示をやめるため
  480.     execute();
  481. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top