⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 littlec.cpp

📁 little c源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include <stdio.h>
#include <setjmp.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#define NUM_FUNC        100
#define NUM_GLOBAL_VARS 100
#define NUM_LOCAL_VARS  200
#define NUM_BLOCK       100
#define ID_LEN          31
#define FUNC_CALLS      31
#define NUM_PARAMS      31
#define PROG_SIZE       10000
#define LOOP_NEST       31

enum tok_types {DELIMITER, IDENTIFIER, NUMBER, KEYWORD,
                TEMP, STRING, BLOCK};

/* add additional C keyword tokens here */
enum tokens {ARG, CHAR, INT, IF, ELSE, FOR, DO, WHILE,
             SWITCH, RETURN, EOL, FINISHED, END};

/* add additional double operators here (such as ->) */
enum double_ops {LT=1, LE, GT, GE, EQ, NE};

/* These are the constants used to call sntx_err() when
   a syntax error occurs. Add more if you like.
   NOTE: SYNTAX is a generic error message used when
   nothing else seems appropriate.
*/
enum error_msg
     {SYNTAX, UNBAL_PARENS, NO_EXP, EQUALS_EXPECTED,
      NOT_VAR, PARAM_ERR, SEMI_EXPECTED,
      UNBAL_BRACES, FUNC_UNDEF, TYPE_EXPECTED,
      NEST_FUNC, RET_NOCALL, PAREN_EXPECTED,
      WHILE_EXPECTED, QUOTE_EXPECTED, NOT_TEMP,
      TOO_MANY_LVARS, DIV_BY_ZERO};

char *prog;    /* current location in source code */
char *p_buf;   /* points to start of program buffer */
jmp_buf e_buf; /* hold environment for longjmp() */

/* An array of these structures will hold the info
   associated with global variables.
*/
struct var_type {
  char var_name[ID_LEN];
  int v_type;
  int value;
}  global_vars[NUM_GLOBAL_VARS];

struct var_type local_var_stack[NUM_LOCAL_VARS];

struct func_type {
  char func_name[ID_LEN];
  int ret_type; 
  char *loc;  /* location of entry point in file */
} func_table[NUM_FUNC];

int call_stack[NUM_FUNC];

struct commands { /* keyword lookup table */
  char command[20];
  char tok;
} table[] = { /* Commands must be entered lowercase */
  "if", IF, /* in this table. */
  "else", ELSE,
  "for", FOR,
  "do", DO,
  "while", WHILE,
  "char", CHAR,
  "int", INT,
  "return", RETURN,
  "end", END,
  "", END  /* mark end of table */
};

char token[80];
char token_type, tok;

int functos;  /* index to top of function call stack */
int func_index; /* index into function table */
int gvar_index; /* index into global variable table */
int lvartos; /* index into local variable stack */

int ret_value; /* function return value */

void print(void), prescan(void);
void decl_global(void), call(void), putback(void);
void decl_local(void), local_push(struct var_type i);
void eval_exp(int *value), sntx_err(int error);
void exec_if(void), find_eob(void), exec_for(void);
void get_params(void), get_args(void);
void exec_while(void), func_push(int i), exec_do(void);
void assign_var(char *var_name, int value);
int load_program(char *p, char *fname), find_var(char *s);
void interp_block(void), func_ret(void);
int func_pop(void), is_var(char *s), get_token(void);
char *find_func(char *name);

int main(int argc, char *argv[])
{
  if(argc != 2) {
    printf("Usage: littlec <filename>\n");
    exit(1);
  }

  /* allocate memory for the program */
  if((p_buf = (char *) malloc(PROG_SIZE))==NULL) {
    printf("Allocation Failure");
    exit(1);
  }

  /* load the program to execute */
  if(!load_program(p_buf, argv[1])) exit(1);
  if(setjmp(e_buf)) exit(1); /* initialize long jump buffer */

  gvar_index = 0;  /* initialize global variable index */

  /* set program pointer to start of program buffer */
  prog = p_buf;
  prescan(); /* find the location of all functions
                and global variables in the program */

  lvartos = 0;     /* initialize local variable stack index */
  functos = 0;     /* initialize the CALL stack index */

  /* setup call to main() */
  prog = find_func("main"); /* find program starting point */

  if(!prog) { /* incorrect or missing main() function in program */
    printf("main() not found.\n");
    exit(1);
  }

  prog--; /* back up to opening ( */
  strcpy(token, "main");
  call(); /* call main() to start interpreting */

  return 0;
}

/* Interpret a single statement or block of code. When
   interp_block() returns from its initial call, the final
   brace (or a return) in main() has been encountered.
*/
void interp_block(void)
{
  int value;
  char block = 0;

  do {
    token_type = get_token();

    /* If interpreting single statement, return on
       first semicolon.
    */

    /* see what kind of token is up */
    if(token_type == IDENTIFIER) {
      /* Not a keyword, so process expression. */
      putback();  /* restore token to input stream for
                     further processing by eval_exp() */
      eval_exp(&value);  /* process the expression */
      if(*token!=';') sntx_err(SEMI_EXPECTED);
    }
    else if(token_type==BLOCK) { /* if block delimiter */
      if(*token == '{') /* is a block */
        block = 1; /* interpreting block, not statement */
      else return; /* is a }, so return */
    }
    else /* is keyword */
      switch(tok) {
        case CHAR:
        case INT:     /* declare local variables */
          putback();
          decl_local();
          break;
        case RETURN:  /* return from function call */
          func_ret();
          return;
        case IF:      /* process an if statement */
          exec_if();
          break;
        case ELSE:    /* process an else statement */
          find_eob(); /* find end of else block
                         and continue execution */
          break;
        case WHILE:   /* process a while loop */
          exec_while();
          break;
        case DO:      /* process a do-while loop */
          exec_do();
          break;
        case FOR:     /* process a for loop */
          exec_for();
          break;
        case END:
          exit(0);
      }
  } while (tok != FINISHED && block);
}

/* Load a program. */
int load_program(char *p, char *fname)
{
  FILE *fp;
  int i=0;

  if((fp=fopen(fname, "rb"))==NULL) return 0;

  i = 0;
  do {
    *p = getc(fp);
    p++; i++;
  } while(!feof(fp) && i<PROG_SIZE);

  if(*(p-2) == 0x1a) *(p-2) = '\0'; /* null terminate the program */
  else *(p-1) = '\0';
  fclose(fp);
  return 1;
}

/* Find the location of all functions in the program
   and store global variables. */
void prescan(void)
{
  char *p, *tp;
  char temp[32];
  int datatype; 
  int brace = 0;  /* When 0, this var tells us that
                     current source position is outside
                     of any function. */

  p = prog;
  func_index = 0;
  do {
    while(brace) {  /* bypass code inside functions */
      get_token();
      if(*token == '{') brace++;
      if(*token == '}') brace--;
    }

    tp = prog; /* save current position */
    get_token();
    /* global var type or function return type */
    if(tok==CHAR || tok==INT) { 
      datatype = tok; /* save data type */
      get_token();
      if(token_type == IDENTIFIER) {
        strcpy(temp, token);
        get_token();
        if(*token != '(') { /* must be global var */
          prog = tp; /* return to start of declaration */
          decl_global();
        }
        else if(*token == '(') {  /* must be a function */
          func_table[func_index].loc = prog;
          func_table[func_index].ret_type = datatype;
          strcpy(func_table[func_index].func_name, temp);
          func_index++;
          while(*prog != ')') prog++;
          prog++;
          /* now prog points to opening curly 
             brace of function */
        }
        else putback();
      }
    }
    else if(*token == '{') brace++;
  } while(tok != FINISHED);
  prog = p;
}

/* Return the entry point of the specified function.
   Return NULL if not found.
*/
char *find_func(char *name)
{
  register int i;

  for(i=0; i < func_index; i++)
    if(!strcmp(name, func_table[i].func_name))
      return func_table[i].loc;

  return NULL;
 }

/* Declare a global variable. */
void decl_global(void)
{
  int vartype;

  get_token();  /* get type */

  vartype = tok; /* save var type */

  do { /* process comma-separated list */
    global_vars[gvar_index].v_type = vartype;
    global_vars[gvar_index].value = 0;  /* init to 0 */
    get_token();  /* get name */
    strcpy(global_vars[gvar_index].var_name, token);
    get_token();
    gvar_index++;
  } while(*token == ',');
  if(*token != ';') sntx_err(SEMI_EXPECTED);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -