#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "ktypes.h"
#include "memory.h"

/* ----------------------------------------------------- */
// display klunk pattern as specified data type

void show_int (klunk k)
{ printf("%lld",k); }

void show_flt (klunk k)
{ printf("%f",klunk2flt(k)); }

void show_chr (klunk k)
{ printf("%c",k); }

void show_str (klunk k)
{ printf("%s",*((str64*)(&k))); }

void show_hex (klunk k)
{ printf("%016llx",k); }

/* ----------------------------------------------------- */
// interpret klunk pattern as specific data type

int64 klunk2int (klunk k)
{ return *((int64*)(&k)); }

flt64 klunk2flt (klunk k)
{ return *((flt64*)(&k)); }

chr64 klunk2chr (klunk k)
{ return *((chr64*)(&k)); }

str64 klunk2str (klunk k)
{ return (str64)(k); }

/* ----------------------------------------------------- */
// interpret data type bit pattern as simple klunk

klunk int2klunk (int64 i)
{ return *((klunk*)(&i)); }

klunk flt2klunk (flt64 f)
{ return *((klunk*)(&f)); }

klunk chr2klunk (chr64 c)
{ return *((klunk*)(&c)); }

klunk str2klunk (str64 s)
{ return (klunk)s; }

/* ----------------------------------------------------- */
// represent immediate value as simple klunk

klunk literal2klunk (str64 lit)
{
  char symbol = lit[0];
  if (symbol == '\"')
  // string literal
  {
    // remove leading and trailing '\"'
    str64 result = (char*) malloc (LITERAL_SIZE);
    int new_len = strlen(lit)-2;
    for (int i = 0;i < new_len;i++)
      result[i] = lit[i+1];
    result[new_len] = '\0';
    return str2klunk (result);
  }
  else if (symbol == '\'')
  // character literal
    return chr2klunk (lit[1]);
  else if ((symbol == '+') ||
           (symbol == '-') ||
           (isdigit(symbol)))
  // numeric literal
    if (strchr(lit,'.') ||
        strchr(lit,'e') ||
        strchr(lit,'E'))
    // floating point literal
      return flt2klunk (atof(lit));
    else
    // integer literal
      return int2klunk (atoll(lit));
  else
  {
    printf ("invalid literal encountered: %s\n",lit);
    exit (EXIT_FAILURE);
  }
}

/* ----------------------------------------------------- */
