void check_if_declared(Node *aux, environment_list *env){
	table_element *temp;
	
	char *s=(char*)strdup(aux->value.s);
	lower(s);
	for(temp = env->locals; temp!=NULL; temp=temp->next){
		
		if(strcmp(temp->name,s)==0){
			return;
		}
	}
	if(env->previous!=NULL){
		
		check_if_declared(aux, env->previous);
	}else{
		printf("Line %d, col %d: Symbol %s not defined\n",aux->line,aux->col,aux->value.s);
		exit(0);
	}
}
Esempio n. 2
0
/*
 * Builds the symbol table, creating scopes as needed, and linking them together.
 * Adds variable and function identifiers to scopes appropriately.
 */
void build_symbol_table(ast_node root, int level, int sibno, symboltable_t *symtab) {
  //calculate the scope for the variable/func declaration
  //calculate the parent for that variable/func declaration
  //need function to take as input
  //printf("here \n");
  symhashtable_t *hash;

  /* Depending on node types, go deeper, create sibling scopes, add to hashtable,
   * or take other appropriate action.
   */
  switch (root->node_type) {
    ast_node param;
    int param_offset = 4;
    int param_count = 0;

    case SEQ_N:     // change main level when see a new sequence
      level++;
      break;

    case FORMAL_PARAMS_N:
      level++;
      param_count = 0;
      insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) );
    //   for(param = root->left_child; param != NULL; param = param->right_sibling){
    //     if(param->node_type == ARRAY_TYPE_N || param->return_type == ARRAY_TYPE_N){
    //      param_count += DEFAULT_ARRAY_PARAM_SIZE;
    //    }
    //    else{
    //      param_count++;
    //    }
    //  }
    //  printf("PARAM COUNT!!!!! = %d\n", param_count);
    //
    //  for(param = root->left_child; param != NULL; param = param->right_sibling){
    //    if(param->node_type == ARRAY_TYPE_N || param->return_type == ARRAY_TYPE_N){
    //      param->snode->offset = param_count * 4;
    //      param->snode->offset -= DEFAULT_ARRAY_PARAM_SIZE;
    //    }
    //    else{
    //     param->snode->offset = param_count-- * 4;
    //    }
    // }


      break;

    case FUNC_DECLARATION_N: // function declaraions
      //does hashtable exist with given lvl, siblvl (use find_hashtable)
      check_if_redef(root, symtab ,level, sibno);
      hash = find_hashtable(symtab->root, level, sibno);
      if(hash == NULL) {
        hash = make_insert_hashtable(symtab->root, level, sibno, MAX(level - 1, 0), getSibling(level) );

      }
      insert_into_symhashtable(hash, root); // will only insert if it is empty.
      insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) );
      break;

    case FUNCTION_N:
      check_if_declared(root, symtab ,level, sibno);
      insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) );
      break;

    case ID_N:      /* print the id */

        check_if_redef(root, symtab ,level, sibno);

      //if(root->return_type != 0) {  // a non-zero value means that it is a declaration, since only declarations
                                    // are assigned a return type when building the abstract syntax tree.
      if(root->isDecl){

        hash = find_hashtable(symtab->root, level, sibno);
        if(hash == NULL) {
          hash = make_insert_hashtable(symtab->root, level, sibno, MAX(level - 1, 0), getSibling(level) );
        }
        insert_into_symhashtable(hash, root);
      }
      else {  // don't know if previously declared
        check_if_declared(root, symtab , level, sibno);
      }
      insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) );
      break;

    case ARRAY_TYPE_N:             // check for return types!

        check_if_redef(root, symtab ,level, sibno);

      //cif(root->return_type != 0) {
      if(root->isDecl){
        hash = find_hashtable(symtab->root, level, sibno);
        if(hash == NULL) {
          hash = make_insert_hashtable(symtab->root, level, sibno, MAX(level - 1, 0), getSibling(level) );
          }
        insert_into_symhashtable(hash, root);
      }
      else {
        check_if_declared(root, symtab , level, sibno);
      }
      insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) );
      break;

    case RETURN_N:
      insert_scope_info(root, level, sibno, MAX(level - 1, 0), getSibling(level) );
      break;

    default:
      // printf("at default of switch\n");
      assert(symtab->root != NULL);
      hash = find_hashtable(symtab->root, level, sibno);
      if(hash == NULL) {
        hash = make_insert_hashtable(symtab->root, level, sibno, MAX(level - 1, 0), getSibling(level) );
      }
      //note: cannot use insert_scope_info here because siblings[level - 1] causes invalid read as level-1 can go negative
      break;
  }

  if(arraylen == level) {
    arraylen = arraylen + DELTA;
    siblings = realloc(siblings, sizeof(int) * arraylen);

    assert(siblings != NULL);

    for(int k=0; k < DELTA; k++) {
      siblings[arraylen - (DELTA-k)] = 0;
    }
  }

  /* Recurse on each child of the subtree root, with a depth one
     greater than the root's depth. */
  ast_node child;
  for (child = root->left_child; child != NULL; child = child->right_sibling)
    build_symbol_table(child, level, siblings[level], symtab);

  if(root->node_type == SEQ_N){//} || root->node_type == FORMAL_PARAMS_N){
    siblings[level]++;  // change sibling level after you're done printing all
                      // subtrees, i.e., after done recursing.
  }
}
Esempio n. 3
0
void redef_check(ast_node root, int level, int sibno, symboltable_t *symtab) {
  //calculate the scope for the variable/func declaration
  //calculate the parent for that variable/func declaration
  //need function to take as input
  //printf("here \n");
  symhashtable_t *hash;

  /* Depending on node types, go deeper, create sibling scopes, add to hashtable,
   * or take other appropriate action.
   */
  switch (root->node_type) {
    case SEQ_N:     // change main level when see a new sequence
      level++;
      break;

    case FORMAL_PARAMS_N:
      level++;
      break;

    case FUNC_DECLARATION_N: // function declaraions
      //does hashtable exist with given lvl, siblvl (use find_hashtable)
      if(root->snode != NULL)
        check_if_redef(root, symtab ,level, sibno);
      break;

    case FUNCTION_N:
      check_if_declared(root, symtab ,level, sibno);
      break;

    case ID_N:      /* print the id */
      if(root->snode != NULL)
        check_if_redef(root, symtab ,level, sibno);
      break;

    case ARRAY_TYPE_N:             // check for return types!
      if(root->snode != NULL)
        check_if_redef(root, symtab ,level, sibno);
      break;

    case RETURN_N:
      break;

    default:
      // printf("at default of switch\n");
      assert(symtab->root != NULL);
      break;
  }

  if(arraylen_trash == level) {
    arraylen_trash = arraylen_trash + DELTA;
    trash_array = realloc(trash_array, sizeof(int) * arraylen_trash);

    assert(trash_array != NULL);

    for(int k=0; k < DELTA; k++) {
      trash_array[arraylen_trash - (DELTA-k)] = 0;
    }
  }

  /* Recurse on each child of the subtree root, with a depth one
     greater than the root's depth. */
  ast_node child;
  for (child = root->left_child; child != NULL; child = child->right_sibling)
    redef_check(child, level, trash_array[level], symtab);

  if(root->node_type == SEQ_N){//} || root->node_type == FORMAL_PARAMS_N){
    trash_array[level]++;  // change sibling level after you're done printing all
                      // subtrees, i.e., after done recursing.
  }
}