new_var.c 3.58 KB
/* new_var.c ****************************************************

                  The Anubis Compiler (version 1)
                     Creating global variables. 

****************************************************************/

#include <stdlib.h>
#include "compil.h"

void new_variable (Expr lc,    
                   int global,
                   Expr type, 
                   Expr name,
                   Expr init)
{
  Expr aux, init_ints, init_ints1; 
  int i; 

  if (types_only) return; 

  if (verbose && par_seen)
     printf(msgtext_checking_variable[0],
     string_content(name),
     line_in(lc)); 

  /* parameters are forbidden in type and init */ 
  aux = nil; 
  collect_type_variables(&aux,type); 
  collect_type_variables(&aux,init); 
  if (aux != nil)
    {
      err_line_col(lc,"E001", str_format(
       msgtext_variable_with_parms[0],
       string_content(name))); 
       return; 
    }

  /* check type */ 
  check_explicit_type(lc,type,nil); 
  if (errors) return; 

  /* avoid redeclaration */ 
  for (i = 0; i < next_variable; i++)
    if (variables[i].name == name)
      if (same_type(variables[i].type,nil,type,nil))
 {
   err_line_col(lc,"E002", str_format(
    msgtext_variable_redeclaration[0],
    name)); 
   return ; 
 }

  /* interpret initial value */ 
  init_ints = term_interpretations(type,
                                   init,
                                   nil,
                                   nil,
                                   nil,0); 
   
  /* keep them for error message E006 */ 
  init_ints1 = init_ints; 
   
  /* keep only those interpretations whose type is 'type' */ 
  aux = init_ints; 
  init_ints = nil; 
  while (consp(aux))
    {
      Expr new_env; 

      new_env = unify(type_from_interpretation(car(car(aux)),cdr(car(aux))),
                      cdr(car(aux)),
                      type,
                      nil); 


      if (new_env != not_unifiable)
        init_ints = cons(cons(car(car(aux)),new_env),init_ints);
      aux = cdr(aux); 
    }

  if (init_ints == nil) 
   {
     err_line_col(lc,"E006", str_format(msgtext_variable_no_init[0]));
     show_interpretations_types(errfile,init_ints1);
     return; 
   }
   
  must_be_non_ambiguous(init_ints); 
  if (errors) return; 

  /* record the new variable */ 
  if (next_variable == max_variable)
    {
      max_variable += 100; 
      variables = (struct Variable_struct *)reallocz(variables,
           max_variable*sizeof(struct Variable_struct)); 
    }

  variables[next_variable].name = name;
  variables[next_variable].abs_file_path = new_string(current_file_abs_path);   
  variables[next_variable].global = global;
  variables[next_variable].init = substitute(car(car(init_ints)),cdr(car(init_ints)));
  variables[next_variable].lc = lc;
  variables[next_variable].type = cons(type_GAddr,type); 
  add_symbol_index_entry(name,syms_variable,next_variable); 
  next_variable++; 

#if 0   
  if (predef_aux != NULL)
    {
      fprintf(predef_aux,"\nnew_variable(new_integer(0),%d,\n",global); 
      print_expr_to_C(predef_aux,type); 
      fprintf(predef_aux,"\n"); 
      print_expr_to_C(predef_aux,name); 
      fprintf(predef_aux,"\n"); 
      print_expr_to_C(predef_aux,init); 
      fprintf(predef_aux,"\n"); 
    }
#endif   

  if (predef_npd_aux != NULL)
    {
      fprintf(predef_npd_aux,"\nnew_variable(new_integer(0),%d,\n",global); 
      print_expr_to_C(predef_npd_aux,type); 
      fprintf(predef_npd_aux,"\n"); 
      print_expr_to_C(predef_npd_aux,name); 
      fprintf(predef_npd_aux,"\n"); 
      print_expr_to_C(predef_npd_aux,init); 
      fprintf(predef_npd_aux,"\n"); 
    }

}