/* byte-object.c: -*- C -*-  DESCRIPTIVE TEXT. */

/*  Copyright (c) 1996 Universal Access Inc.
    Author: E. B. Gamble Jr. (ebg@ai.mit.edu) Sun Nov  3 11:50:09 1996.  */

/* Functions on byte objects */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

#include "compile.h"

bc_string_t bc_object_empty = "";
bc_string_t bc_object_true  = "true";
bc_string_t bc_object_false = "false";

/*
 * Symbols
 *
 */
bc_symbol_t bc_list_of_symbols = (bc_symbol_t) NULL;

bc_symbol_t
bc_symbol_find (bc_string_t string)
{
  bc_symbol_t symbol;
  for (symbol = bc_list_of_symbols;
       symbol;
       symbol = BC_SYMBOL_NEXT (symbol))
    if (0 == strcmp (string, BC_SYMBOL_NAME (symbol)))
      return (symbol);
  return ((bc_symbol_t) NULL);
}

bc_symbol_t
bc_symbol_intern (bc_string_t string)
{
  bc_symbol_t symbol =
    bc_symbol_find (string);

  if (!symbol)
    {
      symbol = (bc_symbol_t) xmalloc (sizeof (struct bc_symbol));

      BC_SYMBOL_NAME  (symbol) = string;
      BC_SYMBOL_VALUE (symbol) = "no value";
      BC_SYMBOL_TYPE  (symbol) = BC_STRING_TYPE;
      BC_SYMBOL_HASH  (symbol) = 0;
      BC_SYMBOL_NEXT  (symbol) = bc_list_of_symbols;
      bc_list_of_symbols      = symbol;
    }

  return (symbol);
}

bc_package_t bc_package_list     = (bc_package_t) NULL;
bc_package_t bc_current_package  = (bc_package_t) NULL;
bc_package_t bc_function_package = (bc_package_t) NULL;

extern bc_function_t
bc_function_new (bc_string_t    name,
		 bc_byte_code_t *code,
		 unsigned int   code_count,
		 struct bc_tagged_object *constants,
		 unsigned int        constants_count,
		 unsigned int   stack_size)
{
  bc_function_t function = (bc_function_t)
    xmalloc (sizeof (struct bc_function));

  /* Fillout the function */
  BC_FUNCTION_NAME (function) = name;
  BC_FUNCTION_CODE (function) = code;
  BC_FUNCTION_CODE_COUNT (function) = code_count;
  
  BC_FUNCTION_CONSTANTS (function)       = constants;
  BC_FUNCTION_CONSTANTS_COUNT (function) = constants_count;
  BC_FUNCTION_STACK_SIZE (function)      = stack_size;

  return (function);
}

void
bc_function_free (bc_function_t function)
{
  free (BC_FUNCTION_CODE (function));
  free (BC_FUNCTION_CONSTANTS (function));
  free (function);
}

extern void
bc_format_print (bc_format_t format)
{
  for (; format; format = BC_FORMAT_NEXT (format))
    {
      switch (BC_FORMAT_TYPE (format))
	{
	case BC_STRING_TYPE:
	  printf ("\"%s\"", (bc_string_t) BC_FORMAT_OBJECT (format));
	  break;
	case BC_INDEX_TYPE:
	  printf ("%d", (bc_index_t) BC_FORMAT_OBJECT (format));
	  break;
	default:
	  printf ("***");
	  break;
	}
      if (BC_FORMAT_NEXT (format))
	printf (" ");
    }
}
