#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#define MAXNAME 128
#define MAXLENGTH 128
#define MAX_ARGS 10
#define INTEGER 1
#define DOUBLE 2
#define TRUE 3
#define FALSE 4

/* 木構造を作るノードの構造体 */
struct node  
{
  int no_of_children;
  struct node *children[MAX_ARGS];
  char name[MAXNAME];
};

/* 値を格納する構造体 */
struct value 
{
  int type;
  int ikata;
  double dkata;
  char ckata[MAXNAME];
};

/* 文字を取り込む関数 */
void get_next_token(char *buf)
{
  int   ibuf;
  int   i = 0;
  while ((ibuf = getchar()) != EOF) {
    if (isspace((char) ibuf)) {
      buf[i] = '\0';
      break;
    } else if (((char) ibuf) == ')') {
      ungetc((char) ibuf,stdin);
      buf[i] = '\0';
      break;
    } else {
      buf[i++] = (char) ibuf;
    }
  }
}


/* 木構造を組み立てる関数 */
struct node *read_tree()
{
  int   i,j;
  struct node *t;
  char  buf[MAXLENGTH];
  if (scanf("%1s",buf) == EOF) return (struct node *) EOF;
  if ((t = (struct node *) malloc(sizeof(struct node))) == NULL) {
    printf("Error: memory overflow\n");
    exit(1);
  }
  t -> no_of_children=0;
  if (buf[0] == '(') {    
    scanf("%1s", buf);
    ungetc(buf[0],stdin);
    get_next_token(buf);
    strcpy(t->name,buf); 
    scanf("%1s",buf);
    for(i = 0; buf[0] != ')'; scanf("%1s",buf)) {
      ungetc(buf[0],stdin);
      t->children[i++] = read_tree();
    }
    t->no_of_children=i;
    ungetc(buf[0], stdin);
    scanf(")");
  } else if (buf[0] == ')') {     /* ')'ならポインタをNULLにする */
    scanf(")");
    return NULL;
  } else {
    ungetc(buf[0],stdin);
    get_next_token(buf);
    strcpy(t->name,buf); 
    t->children[0] = NULL;
  }
  return(t);
}

/* 木構造をプリントする関数．デバッグ用 */
void print_tree(struct node *nd)
{
  int j;
  if (nd->no_of_children == 0){
    printf(" %s",nd->name);
    return;
  } else {
    printf(" (%s",nd->name);
    for(j=0;j<nd->no_of_children; j++)
      print_tree(nd->children[j]);
    printf(")");
  }
}

/* スペースを解放する関数 */
void free_tree(struct node *nd)
{
  int j;
  for (j=0;j < nd->no_of_children;j++)
    free_tree(nd->children[j]);
  free(nd);
}

/* 値を評価する関数 */
struct value *eval_tree(struct node *nd, struct value *val)
{
  int j,k,i;
  double l,r,num,num2;
  struct value child;
  char *p;
  // 以下はデバッグ用のプリント
  //  printf("%s %d\n", nd->name, nd->no_of_children);
  // 終端ノードの場合
  if (nd->no_of_children == 0){
    if (*nd->name == '-' || isdigit(*nd->name)){  /* 数値の場合 */
      val->ikata = atoi(nd->name);     /* 数値を格納する構造体に型別に格納 */
      val->dkata = atof(nd->name);
      val->type = INTEGER;
      p = nd->name;
      while(*p != '\0')
          if (*p++ == '.') val->type = DOUBLE;
    }
    else printf("Undefined symbol : %s\n",nd->name);
  }
  // 関数ノードの場合
  else {
    // + 演算子
    if (strcmp(nd->name,"+") == 0){
      val->ikata = 0;
      val->dkata = 0;
      val->type = INTEGER;
      for (j=0;j<nd->no_of_children;j++){    
           eval_tree(nd->children[j],&child);
           // 以下はデバッグ用のプリント
           // printf("%f\n", child.dkata);
           val->ikata += child.ikata;
           val->dkata += child.dkata;
           if (child.type == DOUBLE) val->type = DOUBLE;
      }
      return;
    }
    // * 演算子
    if (strcmp(nd->name,"*") == 0){
      val->ikata = 1;
      val->dkata = 1;
      val->type = INTEGER;
      for (j=0;j<nd->no_of_children;j++){
           eval_tree(nd->children[j],&child);
           val->ikata *= child.ikata;
           val->dkata *= child.dkata;
           if (child.type == DOUBLE) val->type = DOUBLE;
      }
      return;
    }
    // - 演算子
    if (strcmp(nd->name,"-") == 0){
      eval_tree(nd->children[0],&child);
      val->ikata = child.ikata;
      val->dkata = child.dkata;
      val->type = child.type;
      for (j=1;j<nd->no_of_children;j++){
           eval_tree(nd->children[j],&child);
           val->ikata -= child.ikata;
           val->dkata -= child.dkata;
           if (child.type == DOUBLE) val->type = DOUBLE;
      }
      return;
    }
    // / 演算子
    if (strcmp(nd->name,"/") == 0){
      eval_tree(nd->children[0],&child);
      val->ikata = child.ikata;
      val->dkata = child.dkata;
      val->type = child.type;
      for (j=1;j<nd->no_of_children;j++){
           eval_tree(nd->children[j],&child);
           val->ikata /= child.ikata;
           val->dkata /= child.dkata;
           if (child.type == DOUBLE) val->type = DOUBLE;
      }
      return;
    }    
    // cos 関数
    if (strcmp(nd->name,"COS") == 0){
      val->dkata = 0;
      val->type = DOUBLE;
      eval_tree(nd->children[0],&child);
      val->dkata = cos(child.dkata);
      return;
    }
    // sin 関数
    if (strcmp(nd->name,"SIN") == 0){
      val->dkata = 0;
      val->type = DOUBLE;
      eval_tree(nd->children[0],&child);
      val->dkata = sin(child.dkata);
      return;
    }
    // < 比較演算子
    if (strcmp(nd->name,"<") == 0){
      eval_tree(nd->children[0],&child);
      l = child.dkata;
      eval_tree(nd->children[1],&child);
      r = child.dkata;
      if (l < r) val->type = TRUE;
      else val->type = FALSE;
      return;
    }
    // > 比較演算子
    if (strcmp(nd->name,">") == 0){
      eval_tree(nd->children[0],&child);
      l = child.dkata;
      eval_tree(nd->children[1],&child);
      r = child.dkata;
      if (l > r) val->type = TRUE;
      else val->type = FALSE;
      return;
    }
    // eq 演算子
    if (strcmp(nd->name,"EQ") == 0){
      k = 0;
      eval_tree(nd->children[0],&child);
      num = child.dkata;
      for (j=0;j<nd->no_of_children;j++){
           eval_tree(nd->children[j],&child);
           if (num == child.dkata) k++;
      }
      if (k == nd->no_of_children) val->type = TRUE;
      else val->type = FALSE;
      return;
    }
    // AND 演算子
    if (strcmp(nd->name,"AND") == 0){
      val->type = TRUE;
      for (j=0;j<nd->no_of_children;j++){
           eval_tree(nd->children[j],&child);
           if (child.type != TRUE) {
                val->type = FALSE;
                break;
           }
      }
      return;
    }
    // OR 演算子
    if (strcmp(nd->name,"OR") == 0){
      val->type = FALSE;
      for (j=0;j<nd->no_of_children;j++){
           eval_tree(nd->children[j],&child);
        if (child.type == TRUE) {
          val->type = TRUE;
          break;
        }
      }
      return;
    } 
    // undefined symbol
    printf("Undefined function : %s\n",nd->name);
    return;
  }
}

/* main関数 */
main()
{
  struct node *root;
  int ct,i;
  struct value val;
  while(1){
    // プロンプトを表示し，S式を読み込む
    printf(">");
    root = read_tree();
    // 入力されたS式を表示: デバッグ用
    // printf("--->\n");
    // print_tree(root);
    // printf("\n");
    // S式の評価
    eval_tree(root, &val);
    switch(val.type){       
    case INTEGER: printf("%d",val.ikata);break;
    case DOUBLE: printf("%f",val.dkata);break;
    case TRUE: printf("T");break;
    case FALSE: printf("NIL");break; 
    }
    free_tree(root);
    printf("\n");
  }
}
