Программа-интерпретатор для учебного языка SPL, страница 11

  }

  prog();

  interp();

  return;

}

void newob( char *nm, int wt, int vl ) {

  odc *p, *pe;

  if (out)

    pe = TOB;

  else

    pe = ptol;

  for (p = pto-1; p >= pe; p--)

    if (!strcmp( p->name, nm )) {

      puts( "Объект nm описан дважды!" );

      exit( 0 );

    }

  if (pto >= TOB+100) {

    puts( "Переполнение TOB!" );

    exit( 0 );

  }

  else {

    pto->name = nm;

    pto->what = wt;

    pto->val = vl;

  }

  pto++;

  return;

}

odc *findob( char *nm ) {

  odc *p;

  for (p = pto-1; p >= TOB; p--)

    if (!strcmp( p->name, nm ))

      return p;

  printf( "Нет объекта %s в TOB!\n", p->name);

  exit( 0 );

}

fnd *newfn( char *nm, int is, int cp, int st) {

  if (ptf >= TFN+30) {

    puts( "Переполнение таблицы функций TFN!" );

    exit( 0 );

  }

  else {

    ptf->name = nm;

    ptf->isd = is;

    ptf->cpt = cp;

    ptf->start = st;

  }

  return ptf++;

}

fnd *findfn( char *nm ) {

  fnd *p;

  for (p = ptf-1; p >= TFN; p--)

    if (!strcmp( p->name, nm ))

      return p;

  return NULL;

}

fnd *eval( char *nm, int cp ) {

  fnd *p;

  p = findfn( nm );

  if (p == 0)

    newfn( nm, 0, cp, -1 );

  else {

    if (p->cpt == cp)

      return p;

    else {

      printf( "У функции %s не совпадает количество параметров!\n", nm );

      exit( 0 );

    }

  }

}

void defin( char *nm, int cp, int st) {

  fnd *p;

  int c1, c2;

  p = findfn( nm );

  if (p) {

    if (p->isd) {

      printf( "Функция %s описана!\n", nm );

      exit( 0 );

    }

    if (p->cpt != cp) {

      printf( "Не совпадает количество параметров у функции %s!\n", nm );

      exit( 0 );

    }

    p->isd = 1;

    for (c1 = p->start; c1 != -1; c1 = c2) {

      c2 = TCD[c1].opd;

      TCD[c1].opd = st;

    }

    p->start = st;

  }

  else

    newfn( nm, 1, cp, st );

  return;

}

fnd *fmain() {

  fnd *p;

  fnd *pm = NULL;

  static char nm[] = "main";

  for (p = ptf-1; p >= TFN; p--) {

    if (p->isd == 0) {

      printf( "Функция %s не описана!\n", p->name );

      exit( 0 );

    }

    else

      if (!strcmp(p->name, nm))

      pm = p;

  }

  if (pm)

    return pm;

  else {

    puts( "Нет функции main!" );

    exit( 0 );

  }

}

int gen( int co, int op ) {

  if (tc >= 300) {

    puts( "Переполнение таблицы команд!" );

    exit( 0 );

  }

  TCD[tc].cod = co;

  TCD[tc].opd = op;

  return tc++;

}

int body() {

  int st;

  exam( '{' );

  clv = 0;

  while (lex == INTL || lex == CONSTL)

    if (lex == INTL)

      dvarb();

    else

      dconst();

  st = gen( INI, clv );

  stml();

  exam( '}' );

  gen( OPR, 10 );

  return st;

}

void stat() {

  int t1, t2;

  odc *p;

  switch (lex) {

    case IDEN: p = findob( (char *)lval );

         get();

         exam( '=' );

         expr();

         if (p->what == 1) {

           printf( "%s константа!\n", p->name );

           exit( 0 );

         }

         gen( p->what == 2 ? STE : STI, p->val );

         break;

    case READL: get();

                p = findob( (char *)lval );

                gen( OPR, 1 );

                if (p->what == 1) {

                  printf( "%s константа!\n", p->name );

                  exit( 0 );

                }

                gen( p->what == 2 ? STE : STI, p->val );

                exam( IDEN );

                break;

    case RETRL: get();

                expr();

                gen( OPR, 9 );

                break;

    case PRITL: get();

                expr();

                gen( OPR, 2 );

                break;

    case IFL: get();

              expr();

              exam( THENL );