#include "ast.h"

void jpdisp_Exp(Exp *p, char *myID, int level);
void jpdisp_ExpList(ExpList *p, char *myID, int level);

/* adapted from autogenerated code, courtesy of me */

void jpdisp_LitExp(LitExp *p, char *myID, int level) {
  if (!p) return;
  if (p->Type==TYPE_int) {
    printf("%d", p->litInt);
  }
  if (p->Type==TYPE_real) {
    printf("%f", p->litReal);
  }
  if (p->Type==TYPE_string) {
    printf("\"%s\"", p->litStr);
  }
}

void jpdisp_SubCallExp(SubCallExp *p, char *myID, int level) {
  if (!p) return;
  printf("(");
  printf("%s(", p->idt.id);
  jpdisp_ExpList(p->expList, "expList", level + 1);
  printf(")");
  printf(")");
}

void jpdisp_VarExp(VarExp *p, char *myID, int level) {
  if (!p) return;
  printf("%s", p->idt.id);
  if (p->offsets) {
    printf("[");
    jpdisp_ExpList(p->offsets, "offsets", level + 1);
    printf("]");
  }
}

void jpdisp_LogicExp(LogicExp *p, char *myID, int level) {
  if (!p) return;
  printf("(");
  jpdisp_Exp(p->x, "x", level + 1);
  switch(p->op) {
  case _AND:
    printf("&&");
    break;
  case _OR:
    printf("||");
    break;
  case _NOT:
    printf("!");
    break;
  }
  jpdisp_Exp(p->y, "y", level + 1);
  printf(")");
}

void jpdisp_ArithExp(ArithExp *p, char *myID, int level) {
  if (!p) return;
  printf("(");
  jpdisp_Exp(p->x, "x", level + 1);
  switch(p->op) {
  case _PLUS:
    printf("+");
    break;
  case _MINUS:
    printf("-");
    break;
  case _MUL:
    printf("*");
    break;
  case _DIV:
    printf("/");
    break;
  case _REM:
    printf("%%");
    break;
  }
  jpdisp_Exp(p->y, "y", level + 1);
  printf(")");
}


void jpdisp_RelExp(RelExp *p, char *myID, int level) {
  if (!p) return;
  printf("(");
  jpdisp_Exp(p->x, "x", level + 1);
  switch(p->op) {
  case _LT:
    printf("<");
    break;
  case _LTE:
    printf("<=");
    break;
  case _GT:
    printf(">");
    break;
  case _GTE:
    printf(">=");
    break;
  case _EQ:
    printf("=");
    break;
  case _NEQ:
    printf("<>");
    break;
  }
  jpdisp_Exp(p->y, "y", level + 1);
  printf(")");
}

void jpdisp_Exp(Exp *p, char *myID, int level) {
  if (!p) return;
  jpdisp_VarExp(p->varExp, "varExp", level + 0);
  jpdisp_LitExp(p->litExp, "litExp", level + 0);
  jpdisp_SubCallExp(p->callExp, "callExp", level + 0);
  jpdisp_LogicExp(p->logicExp, "logicExp", level + 0);
  jpdisp_ArithExp(p->arithExp, "arithExp", level + 0);
  jpdisp_RelExp(p->relExp, "relExp", level + 0);
  jpdisp_Exp(p->nestedExp, "nestedExp", level + 0);
}

void jpdisp_ExpList(ExpList *p, char *myID, int level) {
  while (p) {
    jpdisp_Exp(p->exp, "exp", level + 0);
    p = p->next;
    if (p) {
	printf(", ");
    }
  }
}

