コード例 #1
0
ファイル: stmt.c プロジェクト: alexmwu/cminor
void stmt_typecheck(struct stmt *s, struct type *ret, int *returned) {
  if(!s) return;
  switch(s -> kind) {
    struct type *expr;
    struct expr *curr;
    case STMT_DECL:
      decl_typecheck(s -> decl);
      break;
    case STMT_EXPR:
      // need to typecheck, but don't need type
      type_delete(expr_typecheck(s -> expr));
      break;
    case STMT_IF_ELSE:
      expr = expr_typecheck(s -> expr);
      if(expr -> kind != TYPE_BOOLEAN) {
        fprintf(stderr, "TYPE_ERROR: cannot use a(n) ");
        type_fprint(stderr, expr);
        fprintf(stderr, " as the if statement expression (currently ");
        expr_fprint(stderr, s -> expr);
        fprintf(stderr, ") requires a boolean\n");
        type_error_count++;
      }
      stmt_typecheck(s -> body, ret, returned);
      stmt_typecheck(s -> else_body, ret, returned);
      type_delete(expr);
      break;
    case STMT_FOR:
      type_delete(expr_typecheck(s -> init_expr));
      expr = expr_typecheck(s -> expr);
      // need to check that the middle
      // expression is actually there
      if(expr && expr -> kind != TYPE_BOOLEAN) {
        fprintf(stderr, "TYPE_ERROR: cannot use a ");
        type_fprint(stderr, expr);
        fprintf(stderr, " as the middle expression requires a boolean (or an empty expression)\n");
        type_error_count++;
      }
      type_delete(expr);
      type_delete(expr_typecheck(s -> next_expr));
      stmt_typecheck(s -> body, ret, returned);
      break;
    case STMT_WHILE:
      break;
    case STMT_PRINT:
      curr = s -> expr;
      while(curr) {
        expr = expr_typecheck(curr);
        // pass type through new symbol
        if(!type_is_atomic(expr)) {
          fprintf(stderr, "TYPE_ERROR: cannot print (print ");
          expr_fprint(stderr, s -> expr);
          fprintf(stderr, ") a non-atomic value (");
          type_fprint(stderr, expr);
          fprintf(stderr, ")\n");
          type_error_count++;
        }
        switch(expr -> kind) {
          case TYPE_BOOLEAN:
            curr -> print_type = 1;
            break;
          case TYPE_CHARACTER:
            curr -> print_type = 2;
            break;
          case TYPE_INTEGER:
            curr -> print_type = 3;
            break;
          case TYPE_STRING:
            curr -> print_type = 4;
            break;
          case TYPE_ARRAY:
            curr -> print_type = 0;
            fprintf(stderr, "Bad entry into switch on type_kind in stmt_typecheck (case STMT_PRINT)\n");
            exit(1);
            break;
          case TYPE_ARRAY_DECL:
            curr -> print_type = 0;
            fprintf(stderr, "Bad entry into switch on type_kind in stmt_typecheck (case STMT_PRINT)\n");
            exit(1);
            break;
          case TYPE_FUNCTION:
            curr -> print_type = 0;
            fprintf(stderr, "Bad entry into switch on type_kind in stmt_typecheck (case STMT_PRINT)\n");
            exit(1);
            break;
          case TYPE_VOID:
            curr -> print_type = 0;
            fprintf(stderr, "Bad entry into switch on type_kind in stmt_typecheck (case STMT_PRINT)\n");
            exit(1);
            break;
        }
        type_delete(expr);
        curr = curr -> next;
      }
      break;
    case STMT_RET:
      // always set to 1
      *returned = 1;
      expr = expr_typecheck(s -> expr);
      if(!s -> expr) {
        type_delete(expr);
        expr = type_create(TYPE_VOID, 0, 0, 0);
      }
      if(!type_compare(expr, ret)) {
        fprintf(stderr, "TYPE_ERROR: the return statement (return ");
        expr_fprint(stderr, s -> expr);
        fprintf(stderr, ") does not match the function return type (");
        type_fprint(stderr, ret);
        fprintf(stderr, ")\n");
        type_error_count++;
      }
      type_delete(expr);
      break;
    case STMT_BLOCK:
      stmt_typecheck(s -> body, ret, returned);
      break;
  }
  stmt_typecheck(s -> next, ret, returned);
}
コード例 #2
0
void decl_typecheck(struct decl *d){
	if(!d)return;
	if(d->value){
		if(d->type->kind!=TYPE_ARRAY){
			struct type* t;
			t = expr_typecheck(d->value);
			if(d->type-> kind != t->kind){
				printf("Cannot assign ");
				expr_print(d->value);
				printf(" to ");
				type_print(d->type);
				printf("\n");
				get_incrementError(2);
			}
		}else
		{
			if(d->value->kind!=EXPR_ARRAY_LIST){
				printf("Cannot assign ");
				expr_print(d->value);
				printf(" to array %s\n",d->name);
				get_incrementError(2);
			}
			else{
				struct type* aux_type = d->type;
				int lenght = 1;
				if(aux_type->expression){
					while(aux_type->kind == TYPE_ARRAY){
				 		 if(aux_type->expression && aux_type->expression->kind!= EXPR_INTEGER_LITERAL){
						  printf("Array %s must have a literal value as index\n",d->name);
						  lenght = 99999;
						  break;	
						}
						else{
						  lenght*=aux_type->expression->literal_value;
						}
						aux_type = aux_type->subtype;
			     	
					}
				}
				else{
					lenght = 99999;
					while(aux_type->kind == TYPE_ARRAY)aux_type = aux_type->subtype;
			   	}


				resolve_array_values(d->value,aux_type,d->name);	
				if(const_expr > lenght){
					get_incrementError(2);
					printf("Too many arguments on inicialization of array %s\n",d->name);
				}
			}
		}
	}
	
	if(d->symbol->kind == SYMBOL_GLOBAL)
	{
		const_expr = 0;
		expr_constant(d->value);
		if(const_expr>0){
		  get_incrementError(1);
		  printf("Tried to assign not constant variable in the declaration of %s\n",d->name);
		}
				
	}
		
	if(d->code)stmt_typecheck(d->code,d->type->subtype);
	decl_typecheck(d->next);

}
コード例 #3
0
ファイル: stmt.c プロジェクト: kmeranda/Compiler
void stmt_typecheck( struct stmt *s, struct decl * current_function ) {
	if (!s) { return; }
	struct type * T = expr_typecheck(s->expr);
	switch (s -> kind) {
		case STMT_IF_ELSE:				
			T = expr_typecheck(s->expr);
			if(T->kind != TYPE_BOOLEAN){
				printf("type error: if condition is of type ");
				type_print(T);
				printf(" (");
				expr_print(s->expr);
				printf("), where a boolean value is required\n");
				error_count++;
			}
			stmt_typecheck(s->body,current_function);
			stmt_typecheck(s->else_body,current_function);
			break;
		// decl can't be a function decl if outside of global scope
		case STMT_DECL: 
			if(s->decl->type->kind == TYPE_FUNCTION){
				printf("type error: cannot declare a function (%s) nested in another function (%s)\n",s->decl->name,current_function->name);
				error_count++;
			}
			decl_typecheck(s->decl);
			break;
		case STMT_EXPR:
			expr_typecheck(s->expr);
			break;
		case STMT_FOR:
			expr_typecheck(s->init_expr);
			T = expr_typecheck(s->expr);
			if(T->kind != TYPE_BOOLEAN && T->kind != TYPE_VOID){
				printf("type error: for loop conditional is of type ");
				type_print(T);
				printf(" (");
				expr_print(s->expr);
				printf("), where a boolean value is required\n");
				error_count++;
			}
			expr_typecheck(s->next_expr);
			stmt_typecheck(s->body,current_function);
			break;
		case STMT_PRINT:
			expr_typecheck(s->expr);
			break;
		// check that value being returned matches the subtype of the function it is called in (the return values must match)
		case STMT_RETURN:
			if(current_function->type->subtype->kind != expr_typecheck(s->expr)->kind){
				printf("type error: cannot return ");
				type_print(expr_typecheck(s->expr));
				printf(" in function (%s) that returns ",current_function->name);
				type_print(current_function->type->subtype);
				printf("\n");
				error_count++;
			}
			break;
		case STMT_BLOCK:
			stmt_typecheck(s->body,current_function);
			break;
		case STMT_EMPTY:
			// do nothing
			break;
	}
	stmt_typecheck(s->next,current_function);
}