#include <stdlib.h>
#include <assert.h>
#include "ast.h"

/* utility functions */

void *checked_malloc(int i) {
  void *p = malloc(i);
  assert(p != NULL);
  return p;
}

char *strsave(char* s) {
  char *r = checked_malloc(strlen(s) + 1);
  strcpy(r,s);
  return r;
}

/* AST constuctor functions */

Exp mk_VarExp(id i) {
  Exp e = checked_malloc(sizeof(*e));
  e->kind = VarExp;
  e->u.varexp.i = i;
  return e;
}

Exp mk_ConstExp(int n) {
  Exp e = checked_malloc(sizeof(*e));
  e->kind = ConstExp;
  e->u.constexp.n = n;
  return e;
}

Exp mk_PlusExp(Exp l, Exp r) {
  Exp e = checked_malloc(sizeof(*e));
  e->kind = PlusExp;
  e->u.plusexp.l = l;
  e->u.plusexp.r = r;
  return e;
}

Exp mk_MinusExp(Exp l, Exp r) {
  Exp e = checked_malloc(sizeof(*e));
  e->kind = MinusExp;
  e->u.minusexp.l = l;
  e->u.minusexp.r = r;
  return e;
}


Exp mk_AsgnExp(id i, Exp e) {
  Exp e0 = checked_malloc(sizeof(*e));
  e0->kind = AsgnExp;
  e0->u.asgnexp.i = i;
  e0->u.asgnexp.e = e;
  return e0;
}

Exp mk_If0Exp(Exp e, Exp t, Exp f) {
  Exp e0 = checked_malloc(sizeof(*e0));
  e0->kind = If0Exp;
  e0->u.if0exp.e = e;
  e0->u.if0exp.t = t;
  e0->u.if0exp.f = f;
  return e0;
}

Exp mk_BlockExp(ids is, Exps es) {
  Exp e = checked_malloc(sizeof(*e));
  e->kind = BlockExp;
  e->u.blockexp.is = is;
  e->u.blockexp.es = es;
  return e;
}

Exps mk_Exps(Exp e, Exps next) {
  Exps es0 = checked_malloc(sizeof(*es0));
  es0->e = e;
  es0->next = next;
  return es0;
}

ids mk_ids(id i, ids next) {
  ids is0 = checked_malloc(sizeof(*is0));
  is0->i = i;
  is0->next = next;
  return is0;
}
