コード例 #1
0
ファイル: flist.c プロジェクト: mingpen/OpenNT
extern data
list_start(
        arg_s           *parg,          /* arg entry causing call */
        callinfo_s      *pinfo,         /* info we need to pass around */
        long            *plength)       /* for varying length fields */
{
    /* take a type number and a buffer, and push them on the field list stack,
     *  emit field
     */
    list_s      *list;  /* new list */

    parg;
    plength;

    list = (list_s *)calloc(sizeof(list_s), 1);
    if (list == 0) {
        fatal("cannot allocate list structure\n");
    } /* if */

    list->type = type_create();
    list->next = list_stack;
    list->psym = pinfo->psym;
    list_stack = list;
    if (proc_arg_count_ptr) {
        /* we had previously been asked to stuff an arg count in a
         * LF_PROCEDURE, now we bind that request to this list.
         */
        list->pproccount = proc_arg_count_ptr;
        proc_arg_count_ptr = 0;
    } /* if */

    return type_get_index(list->type);
} /* list_start */
コード例 #2
0
ファイル: dcps_builtin.c プロジェクト: FlavioFalcao/tinq-core
static Endpoint_t *create_builtin_reader (Domain_t       *dp,
					  Builtin_Type_t type,
					  const char     *topic_name,
					  const char     *type_name)
{
	TopicType_t	*typep;
	Topic_t		*tp;
	Reader_t	*rp;
	DDS_TopicQos	qos_data;

	typep = type_create (dp, type_name, NULL);
	if (!typep)
		return (NULL);

	typep->flags = EF_LOCAL | EF_BUILTIN;
	typep->index = type;
	tp = topic_create (&dp->participant, NULL, topic_name, type_name, NULL);
	if (!tp)
		return (NULL);

	tp->entity.flags |= EF_ENABLED | EF_BUILTIN | EF_NOT_IGNORED;
	qos_data = qos_def_topic_qos;
	qos_data.durability.kind = DDS_TRANSIENT_LOCAL_DURABILITY_QOS;
	qos_data.reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;
	tp->qos = qos_topic_new (&qos_data);
	if (!tp->qos) {
		topic_delete (&dp->participant, tp, NULL, NULL);
		return (NULL);
	}

	rp = DDS_Subscriber_create_datareader (dp->builtin_subscriber,
					       (DDS_TopicDescription) tp,
					       DDS_DATAREADER_QOS_USE_TOPIC_QOS,
					       NULL, 0);
	if (!rp) {
		topic_delete (&dp->participant, tp, NULL, NULL);
		return (NULL);
	}
	dp->builtin_readers [type] = rp;

#ifdef RTPS_USED
	if (rtps_used)
		disc_populate_builtin (dp, type);
#endif
	return (&rp->r_ep);
}
コード例 #3
0
ファイル: type.c プロジェクト: timzchang/Compilers
// recursively copy all the way down.
struct type * type_copy(struct type *t){
	if(!t) return NULL;
	struct type * temp = type_create(t->kind, param_list_copy(t->params), type_copy(t->subtype), expr_copy(t->opt_expr));
	return temp;
}
コード例 #4
0
ファイル: expr.c プロジェクト: dmattia/C-minor-Compiler
struct type *expr_typecheck(struct expr *e) {
	if(!e) return type_create(TYPE_VOID, 0, 0, 0);
	struct param_list *param_ptr;
	struct expr *expr_ptr;
	struct type *left;
	struct type *right;
	switch(e->kind) {
		case EXPR_LIST:
			left = expr_typecheck(e->left);
			right = expr_typecheck(e->right);
			return type_create(TYPE_VOID, 0, 0, 0);
			break;
		case EXPR_ASSIGNMENT:
			left = expr_typecheck(e->left);
			right = expr_typecheck(e->right);
			while(left->kind == TYPE_ARRAY) left = left->subtype; 
			while(right->kind == TYPE_ARRAY) left = left->subtype; 
			if(type_equal(left, right) && left->kind != TYPE_FUNCTION) {
				return type_copy(left);
			} else {
				printf("Cannot assign ");
				type_print(right);
				printf(" to ");
				type_print(left);
				if(e->left->name) {
					printf(" %s\n", e->left->name);
				} else {
					printf("\n");
				}
				type_check_errors++;
				return left;
			}
			break;
		case EXPR_NOT_EQUALS:
		case EXPR_EQUALS:
			left = expr_typecheck(e->left);
			right = expr_typecheck(e->right);
			if(type_equal(left, right) && left->kind != TYPE_FUNCTION && left->kind != TYPE_ARRAY) {
				return type_create(TYPE_BOOLEAN, 0, 0, 0);
			} else {
				printf("Cannot perform logical equals operation on ");
				type_print(left);
				printf(" and ");
				type_print(right);
				printf("\n");
				type_check_errors++;
				return type_create(TYPE_BOOLEAN, 0, 0, 0);
			}
			break;
		case EXPR_LT:
		case EXPR_GT:
		case EXPR_LE:
		case EXPR_GE:
			left = expr_typecheck(e->left);
			right = expr_typecheck(e->right);
			if(left->kind == TYPE_INTEGER && right->kind == TYPE_INTEGER) {
				return type_create(TYPE_BOOLEAN, 0, 0, 0);
			} else {
				printf("Cannot perform boolean operations on ");
				type_print(left);
				printf(" and ");
				type_print(right);
				printf("\n");
				type_check_errors++;
				return type_create(TYPE_BOOLEAN, 0, 0, 0);
			}
			break;
		case EXPR_ADD:
		case EXPR_MINUS:
		case EXPR_TIMES:
		case EXPR_DIVIDES:
		case EXPR_MOD:
		case EXPR_POWER:
			left = expr_typecheck(e->left);
			right = expr_typecheck(e->right);
			if(left->kind == TYPE_INTEGER && right->kind == TYPE_INTEGER) {
				return type_create(TYPE_INTEGER, 0, 0, 0);
			} else {
				printf("Cannot perform arithmetic operations on ");
				type_print(left);
				printf(" and ");
				type_print(right);
				printf("\n");
				type_check_errors++;
				return type_create(TYPE_INTEGER, 0, 0, 0);
			}
			break;
		case EXPR_NEGATIVE:
			right = expr_typecheck(e->right);
			if(right->kind == TYPE_INTEGER) {
				return type_create(TYPE_INTEGER, 0, 0, 0);
			} else {
				printf("Cannot take the negative of ");
				type_print(right);	
				printf("\n");
				type_check_errors++;
				return type_create(TYPE_INTEGER, 0, 0, 0);
			}
			break;
		case EXPR_OR:
		case EXPR_AND:
			left = expr_typecheck(e->left);
			right = expr_typecheck(e->right);
			if(left->kind == TYPE_BOOLEAN && right->kind == TYPE_BOOLEAN) {
				return type_create(TYPE_BOOLEAN, 0, 0, 0);
			} else {
				printf("Cannot perform logical operations on ");
				type_print(left);
				printf(" and ");
				type_print(right);
				printf("\n");
				type_check_errors++;
				return type_create(TYPE_BOOLEAN, 0, 0, 0);
			}
			break;
		case EXPR_NOT:
			right = expr_typecheck(e->right);
			if(right->kind == TYPE_BOOLEAN) {
				return type_create(TYPE_BOOLEAN, 0, 0, 0);
			} else {
				printf("Cannot perform a logical not on ");
				type_print(right);	
				printf("\n");
				type_check_errors++;
				return type_create(TYPE_BOOLEAN, 0, 0, 0);
			}
			break;
		case EXPR_PRE_INCREMENT:
		case EXPR_PRE_DECREMENT:
			right = expr_typecheck(e->right);
			if(right->kind == TYPE_INTEGER) {
				return type_create(TYPE_INTEGER, 0, 0, 0);
			} else {
				printf("Cannot perform integer operations on ");
				type_print(right);	
				printf("\n");
				type_check_errors++;
				return type_create(TYPE_INTEGER, 0, 0, 0);
			}
			break;
		case EXPR_POST_INCREMENT:
		case EXPR_POST_DECREMENT:
			left = expr_typecheck(e->left);
			if(left->kind == TYPE_INTEGER) {
				return type_create(TYPE_INTEGER, 0, 0, 0);
			} else {
				printf("Cannot perform integer operations on ");
				type_print(left);	
				printf("\n");
				type_check_errors++;
				return type_create(TYPE_INTEGER, 0, 0, 0);
			}
			break;
		case EXPR_FUNCTION:
			param_ptr = e->left->symbol->type->params;
			expr_ptr = e->right;
			while(param_ptr) {
				if(!expr_ptr) {
					printf("Not enough arguments given for function %s\n", e->left->name);
					type_check_errors++;
					break;
				}
				if(!type_equal(param_ptr->type, expr_typecheck(expr_ptr->left))) {
					printf("Function %s requires a paramater of type ", e->left->name);
					type_print(param_ptr->type);
					printf(" but ");
					expr_print(expr_ptr->left);
					printf(" is of type ");
					type_print(expr_typecheck(expr_ptr->left));
					printf("\n");
					type_check_errors++;
					break;
				}
				param_ptr = param_ptr->next;
				expr_ptr = expr_ptr->right;
			}
			if(expr_ptr) {
				printf("Too many arguments given for function %s\n", e->left->name);
				type_check_errors++;
			}
			return e->left->symbol->type->subtype;
			break;
		case EXPR_BOOLEAN:
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_INT:
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_CHAR:
			return type_create(TYPE_CHARACTER, 0, 0, 0);
			break;
		case EXPR_STRING:
			return type_create(TYPE_STRING, 0, 0, 0);
			break;
		case EXPR_NAME:
			if (e->symbol) return e->symbol->type;
			return type_create(TYPE_VOID, 0, 0, 0);
			break;
		case EXPR_ARRAY:
			left = expr_typecheck(e->left);
			right = expr_typecheck(e->right);
			if(right->kind == TYPE_INTEGER) {
				return type_create(left->subtype->kind, 0, 0, 0);
			} else {
				printf("Cannot use ");
				type_print(right);
				printf(" as an array index. Must use an integer\n");
				type_check_errors++;
				return type_create(left->subtype->kind, 0, 0, 0);
			}
			break;
		case EXPR_ARRAY_LITERAL:
			left = expr_typecheck(e->right->left);
			return type_create(TYPE_ARRAY, 0, 0, left->subtype);
			break;
	}
	return type_create(TYPE_VOID, 0, 0, 0);
}
コード例 #5
0
ファイル: expr.c プロジェクト: cindyxinyiwang/cminor
struct type * expr_typecheck( struct expr *e ) {
	if (!e) return type_create(TYPE_VOID, 0, 0);
	struct type *L;
	struct type *R;
	switch (e->kind) {
		case EXPR_INT_VAL:
			return type_create(TYPE_INTEGER, 0, 0);
		case EXPR_NAME:
			return type_copy(e->symbol->type);
		case EXPR_STRING_VAL:
			return type_create(TYPE_STRING, 0, 0);
		case EXPR_CHAR_VAL:
			return type_create(TYPE_CHARACTER, 0, 0);
		case EXPR_BOOLEAN_VAL:
			return type_create(TYPE_BOOLEAN, 0, 0);
		case EXPR_ARRAY_VAL:
		{
			struct expr *vals = e->right;
			struct type *subtype = 0;
			int num_subtype = 0;
			while (vals) {
				struct type *cur_t = expr_typecheck(vals);
				if (!subtype) {
					subtype = cur_t;
				}
				if (!type_compare(subtype, cur_t)) {
					decl_has_error = 1;
					printf("type error: array of element type ");
					type_print(subtype);
					printf(" cannot have expression of type ");
					type_print(cur_t);
					printf("\n");
				}
				num_subtype++;
				vals = vals->next;
			}
			struct type *t = type_create(TYPE_ARRAY, 0, subtype);
			t->num_subtype = expr_create_integer_literal(num_subtype);
			return t;
		}
			//return type_copy(e->symbol->type);
		case EXPR_ARRAY_SUB:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot use ");
				type_print(R);
				printf(" as index to an array\n");
			}
			if (L->kind != TYPE_ARRAY) {
				decl_has_error = 1;
				printf("type error: access an ");
				type_print(R);
				printf(" as an array\n");
			}
			return type_copy(L->subtype);
		case EXPR_FUNCTION_VAL:
			// need to check function params!!!!!
			param_list_typecheck(e->right, e->symbol->params, e->name);
			return type_copy(e->symbol->type->subtype);
		case EXPR_ADD:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot add ");
				type_print(L);
				printf(" to a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_INTEGER, 0, 0);
		case EXPR_SUB:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if ( !(L->kind == TYPE_INTEGER && L->kind == TYPE_INTEGER) || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot subtract ");
				type_print(L);
				printf(" to a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_INTEGER, 0, 0);
		case EXPR_MUL:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot multiply ");
				type_print(L);
				printf(" to a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_INTEGER, 0, 0);
		case EXPR_DIV:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot divide ");
				type_print(L);
				printf(" to a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_INTEGER, 0, 0);
		case EXPR_MODULO:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot module ");
				type_print(L);
				printf(" to a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_INTEGER, 0, 0);
		case EXPR_EXPO:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot expo ");
				type_print(L);
				printf(" to a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_INTEGER, 0, 0);
		case EXPR_POST_DECREASE:
			L = expr_typecheck(e->left);
			if (L->kind != TYPE_INTEGER ) {
				decl_has_error = 1;
				printf("type error: cannot decrease a ");
				type_print(L);
				printf("\n");
			}
			return type_create(TYPE_INTEGER, 0, 0);
		case EXPR_POST_INCREASE:
			L = expr_typecheck(e->left);
			if (L->kind != TYPE_INTEGER ) {
				decl_has_error = 1;
				printf("type error: cannot add a ");
				type_print(L);
				printf("\n");
			}
			return type_create(TYPE_INTEGER, 0, 0);
		case EXPR_GE:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot make greater equal than compare ");
				type_print(L);
				printf(" with a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_BOOLEAN, 0, 0);		
		case EXPR_LE:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot make less equal compare ");
				type_print(L);
				printf(" with a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_BOOLEAN, 0, 0);		
		case EXPR_GT:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot make greater than compare ");
				type_print(L);
				printf(" with a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_BOOLEAN, 0, 0);		
		case EXPR_LT:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) {
				decl_has_error = 1;
				printf("type error: cannot make less than compare ");
				type_print(L);
				printf(" with a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_BOOLEAN, 0, 0);
		case EXPR_AND:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_BOOLEAN || R->kind != TYPE_BOOLEAN) {
				decl_has_error = 1;
				printf("type error: cannot and ");
				type_print(L);
				printf(" with a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_BOOLEAN, 0, 0);
		case EXPR_NOT:
			R = expr_typecheck(e->right);
			if (R->kind != TYPE_BOOLEAN) {
				decl_has_error = 1;
				printf("type error: cannot not a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_BOOLEAN, 0, 0);
		case EXPR_OR:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind != TYPE_BOOLEAN || R->kind != TYPE_BOOLEAN) {
				decl_has_error = 1;
				printf("type error: cannot or ");
				type_print(L);
				printf(" with a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_BOOLEAN, 0, 0);
		case EXPR_EQ:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind == TYPE_FUNCTION || R->kind == TYPE_FUNCTION
				|| L->kind == TYPE_ARRAY || R->kind == TYPE_ARRAY) {
				decl_has_error = 1;
				printf("type error: cannot compare equality ");
				type_print(L);
				printf(" with a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_BOOLEAN, 0, 0);
		case EXPR_NEQ:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind == TYPE_FUNCTION || R->kind == TYPE_FUNCTION
				|| L->kind == TYPE_ARRAY || R->kind == TYPE_ARRAY) {
				decl_has_error = 1;
				printf("type error: cannot compare non equality ");
				type_print(L);
				printf(" with a ");
				type_print(R);
				printf("\n");
			}
			return type_create(TYPE_BOOLEAN, 0, 0);
		case EXPR_ASSIGN:
			L = expr_typecheck(e->left);
			R = expr_typecheck(e->right);
			if (L->kind == TYPE_FUNCTION || R->kind == TYPE_FUNCTION) {
				decl_has_error = 1;
				printf("type error: cannot assign ");
				type_print(R);
				printf(" to a ");
				type_print(L);
				printf("\n");
			}
			if (!type_compare(L, R)) {
				decl_has_error = 1; 
				printf("type error: cannot assign ");
				type_print(R);
				printf(" to a ");
				type_print(L);
				printf("\n");
			}
			return type_copy(R);
	}
}
コード例 #6
0
ファイル: dcps_part.c プロジェクト: GerardoPardo/tinq-core
DDS_ReturnCode_t DDS_DomainParticipant_register_type (DDS_DomainParticipant dp,
						      DDS_TypeSupport       ts,
						      const char            *type_name)
{
	TopicType_t		*typep;
	TypeSupport_t		*pts;
	DDS_ReturnCode_t	ret;
#ifdef DDS_TYPECODE
	unsigned char		*vtc;
#endif

	ctrc_begind (DCPS_ID, DCPS_DP_R_TYPE, &dp, sizeof (dp));
	ctrc_contd (&ts, sizeof (ts));
	ctrc_contd (type_name, strlen (type_name));
	ctrc_endd ();

	prof_start (dcps_reg_type);

	/* Validate some required arguments. */
	if (!ts)
		return (DDS_RETCODE_BAD_PARAMETER);

	if (!domain_ptr (dp, 1, &ret))
		return (ret);

	if (!type_name &&
	    (type_name = DDS_TypeSupport_get_type_name (ts)) == NULL)
		return (DDS_RETCODE_BAD_PARAMETER);

	/* Search type name in participant type list. */
	typep = type_lookup (dp, type_name);
	if (typep) {
		if ((pts = typep->type_support) != NULL) {
#ifdef DDS_TYPECODE
			/* Type already learned from remote peers? */
			if (pts->ts_prefer >= MODE_V_TC) {
				vtc = (unsigned char *) pts->ts_vtc;
				if (!vtc_identical (ts, vtc)) {

					/* Oops: already present in domain but 
					   incompatible - notify later when
					   a topic is created. */
					typep->flags |= EF_INC_TYPE;
					type_promote_tc (dp, typep, ts, NULL);
				}
				else {
					typep->flags &= ~EF_INC_TYPE;
					type_promote_tc (dp, typep, ts, vtc);
				}

				/* Replace with real type support.*/
				xfree (typep->type_support);
				typep->type_support = (TypeSupport_t *) ts;
				vtc_free (vtc);
			}
			else

			/* Already defined: check compatibility. */
			if (ts->ts_prefer   != pts->ts_prefer ||
			    ts->ts_keys     != pts->ts_keys ||
			    ts->ts_fksize   != pts->ts_fksize ||
			    ts->ts_length   != pts->ts_length ||
			    ts->ts_mkeysize != pts->ts_mkeysize)
				return (DDS_RETCODE_PRECONDITION_NOT_MET);

			else if (ts->ts_prefer == MODE_CDR) {
				if (!xt_type_equal (ts->ts_cdr, pts->ts_cdr))
					return (DDS_RETCODE_PRECONDITION_NOT_MET);
			}
			else if (ts->ts_prefer == MODE_PL_CDR) {
				if (pts->ts_pl->builtin ||
				    ts->ts_pl->builtin ||
				    !xt_type_equal (ts->ts_pl->xtype, pts->ts_pl->xtype))
					return (DDS_RETCODE_PRECONDITION_NOT_MET);
			}
			else
#else
			if (pts != ts)
#endif
				return (DDS_RETCODE_PRECONDITION_NOT_MET);
		}
		else {
			typep->type_support = (TypeSupport_t *) ts;
			typep->type_support->ts_users++;
		}
	}
	else {
		/* Doesn't exist yet -- allocate new type context. */
		typep = type_create (dp, type_name, NULL);
		if (!typep) {
			warn_printf ("create_topic_type (%s): out of memory for topic type!\r\n", type_name);
			lock_release (dp->lock);
			return (DDS_RETCODE_OUT_OF_RESOURCES);
		}
		typep->type_support = (TypeSupport_t *) ts;
		typep->type_support->ts_users++;
	}
	typep->flags |= EF_LOCAL;
	typep->nrefs++;
	typep->nlrefs++;
	lock_release (dp->lock);
	prof_stop (dcps_reg_type, 1);
	return (DDS_RETCODE_OK);
}
コード例 #7
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);
}
コード例 #8
0
ファイル: expr.c プロジェクト: cjbara/cminorCompiler
struct type * expr_typecheck(struct expr *e) {
	if(!e) return type_create(TYPE_VOID, 0, 0, 0);
	struct type *L = expr_typecheck(e->left);
	struct type *R = expr_typecheck(e->right);
	switch(e->kind) {
		case EXPR_ASSIGNMENT:
			if(L->kind == TYPE_FUNCTION){
				printf("type error: cannot use assignment operator on function ");
				expr_print(e->left);
				error_count++;
			}
			if(R->kind == TYPE_FUNCTION){
				printf("type error: cannot use assignment operator on function ");
				expr_print(e->right);
				error_count++;
			}
			if(!type_compare(L, R)){
				printf("type error: cannot assign ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf(" to ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			}
			return L;
			break;
		case EXPR_GE:
			if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){
				printf("type error: cannot use operator >= to compare ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" and ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf(". This operator can only be used on two integers.\n");
				error_count++;
			}
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_LE:
			if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){
				printf("type error: cannot use operator <= to compare ");
				type_print(L);
				expr_print(e->left);
				printf(" and ");
				type_print(R);
				expr_print(e->right);
				printf(". This operator can only be used on two integers.\n");
				error_count++;
			}
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_GT:
			if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){
				printf("type error: cannot use operator > to compare ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" and ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf(". This operator can only be used on two integers.\n");
				error_count++;
			}
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_LT:
			if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){
				printf("type error: cannot use operator < to compare ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" and ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf(". This operator can only be used on two integers.\n");
				error_count++;
			}
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_EQ:
			if(L->kind == TYPE_ARRAY){
				printf("type error: cannot use operator == on array ");
				expr_print(e->left);
				printf("\n");
				error_count++;	
			} else if(L->kind == TYPE_FUNCTION){
				printf("type error: cannot use operator == on function ");
				expr_print(e->left);
				printf("\n");
				error_count++;	
			}
			if(R->kind == TYPE_ARRAY){
				printf("type error: cannot use operator == on array ");
				expr_print(e->right);
				printf("\n");
				error_count++;	
			} else if(R->kind == TYPE_FUNCTION){
				printf("type error: cannot use operator == on function ");
				expr_print(e->right);
				printf("\n");
				error_count++;	
			}
			if(L->kind != R->kind){
				printf("type error: cannot use operator == to compare ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" and ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_NE:
			if(L->kind == TYPE_ARRAY){
				printf("type error: cannot use operator != on array ");
				expr_print(e->left);
				printf("\n");
				error_count++;	
			} else if(L->kind == TYPE_FUNCTION){
				printf("type error: cannot use operator != on function ");
				expr_print(e->left);
				printf("\n");
				error_count++;	
			}
			if(R->kind == TYPE_ARRAY){
				printf("type error: cannot use operator != on array ");
				expr_print(e->right);
				printf("\n");
				error_count++;	
			} else if(R->kind == TYPE_FUNCTION){
				printf("type error: cannot use operator != on function ");
				expr_print(e->right);
				printf("\n");
				error_count++;	
			}
			if(L->kind != R->kind){
				printf("type error: cannot use operator != to compare ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" and ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_ADD:
			if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){
				printf("type error: cannot add ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" to ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_SUB:
				
			if((L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) && L->kind != TYPE_VOID){
				printf("type error: cannot subtract ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf(" from ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_MUL:
			if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){
				printf("type error: cannot multiply ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" with ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_DIV:
			if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){
				printf("type error: cannot divide ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf(" from ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_MOD:
			if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){
				printf("type error: cannot perform modular division ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" mod ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_POW:
			if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){
				printf("type error: cannot exponentiate ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" ^ ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_POSTFIX_PLUS:
			if(L->kind != TYPE_INTEGER){
				printf("type error: cannot increment ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			} 
			if(e->left->kind != EXPR_IDENT) {
				printf("type error: cannot increment non-variable ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			}	
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_POSTFIX_MINUS:
			if(L->kind != TYPE_INTEGER){
				printf("type error: cannot decrement ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			}
			if(e->left->kind != EXPR_IDENT) {
				printf("type error: cannot decrement non-variable ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			}	
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_LOGICAL_NOT:
			if(R->kind != TYPE_BOOLEAN){
				printf("type error: cannot negate non-boolean ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_LOGICAL_AND:
			if(L->kind != TYPE_BOOLEAN || R->kind != TYPE_BOOLEAN){
				printf("type error: cannot use && to compare non-boolean ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" and ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_LOGICAL_OR:
			if(L->kind != TYPE_BOOLEAN || R->kind != TYPE_BOOLEAN){
				printf("type error: cannot use && to compare non-boolean ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" and ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_INTEGER_LITERAL:
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_STRING_LITERAL:
			return type_create(TYPE_STRING, 0, 0, 0);
			break;
		case EXPR_CHAR_LITERAL:
			return type_create(TYPE_CHARACTER, 0, 0, 0);
			break;
		case EXPR_TRUE:
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_FALSE:
			return type_create(TYPE_BOOLEAN, 0, 0, 0);
			break;
		case EXPR_IDENT:
			return e->symbol->type;
			break;
		case EXPR_FCALL:
			if(L->kind != TYPE_FUNCTION) {
				printf("type error: cannot execute function call to non-function ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			}
			function_typecheck(e->left->name, e->right, e->left->symbol->type->params, 1, function_params(e)+1);
			return L->subtype;
			break;
		case EXPR_ARRCALL:
			if(L->kind != TYPE_ARRAY) {
				printf("type error: cannot index into non-array ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			} 
			//return the number of subtypes that the index requires
			int i;
			struct type *T = L;
			for(i = 0; i < array_call_subtypes(e->right); i++){
				T = T->subtype;
			}
			return T;
			break;
		case EXPR_ARRINDEX:
			if(L->kind != TYPE_INTEGER){
				printf("type error: cannot index an array using non-integer ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf("\n");
				error_count++;
			}
			return type_create(TYPE_INTEGER, 0, 0, 0);
			break;
		case EXPR_PARENS:
			return R;
			break;
		case EXPR_BLOCK:
			return type_create(TYPE_ARRAY, 0, R, exprs_in_block(e)-1);
			break;
		case EXPR_BLOCK_COMMA:
			if(L->kind != R->kind && R->kind != TYPE_VOID){
				printf("type error: cannot have ");
				type_print(L);
				printf(" ");
				expr_print(e->left);
				printf(" and ");
				type_print(R);
				printf(" ");
				expr_print(e->right);
				printf(" in the same expression list\n");
				error_count++;
				return type_create(TYPE_VOID,0,0,0);
			}
			return L;
			break;
		case EXPR_COMMA:
			return R;
			break;
	}
}
コード例 #9
0
ファイル: expr.c プロジェクト: atowneND/Cminor_Compiler
struct type *expr_typecheck(struct expr *e){
    if (e == NULL) {
        return type_create(TYPE_VOID,0,0,0);
    }
    struct type *l = malloc(sizeof(struct type));
    struct type *r = malloc(sizeof(struct type));
    switch (e->kind){
        case (EXPR_ADD):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot add ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_INTEGER,0,0,0);
            }
            break;
        case (EXPR_SUB):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot subtract ");
                type_print(l);
                literal_print(e->left);
                printf(" from ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_INTEGER,0,0,0);
            }
            break;
        case (EXPR_MUL):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot multiply ");
                type_print(l);
                literal_print(e->left);
                printf(" and ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_INTEGER,0,0,0);
            }
            break;
        case (EXPR_DIV):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot divide ");
                type_print(l);
                literal_print(e->left);
                printf(" by ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_INTEGER,0,0,0);
            }
            break;
        case (EXPR_INCREMENT):
            l = expr_typecheck(e->left);
            if (l->kind != TYPE_INTEGER){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot increment ");
                type_print(l);
                literal_print(e->left);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_INTEGER,0,0,0);
            }
            break;
        case (EXPR_DECREMENT):
            l = expr_typecheck(e->left);
            if (l->kind != TYPE_INTEGER){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot decrement ");
                type_print(l);
                literal_print(e->left);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_INTEGER,0,0,0);
            }
            break;
        case (EXPR_NOT):
            r = expr_typecheck(e->right);
            if (r->kind != TYPE_BOOLEAN){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot negate ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_BOOLEAN,0,0,0);
            }
            break;
        case (EXPR_POWER):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot raise ");
                type_print(l);
                literal_print(e->left);
                printf(" to power ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_INTEGER,0,0,0);
            }
            break;
        case (EXPR_MODULO):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot take modulus of ");
                type_print(l);
                literal_print(e->left);
                printf(" and ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_INTEGER,0,0,0);
            }
            break;
        case (EXPR_LESS_THAN):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_BOOLEAN,0,0,0);
            }
            break;
        case (EXPR_GREATER_THAN):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_BOOLEAN,0,0,0);
            }
            break;
        case (EXPR_LESS_THAN_OR_EQUAL):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_BOOLEAN,0,0,0);
            }
            break;
        case (EXPR_GREATER_THAN_OR_EQUAL):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_INTEGER) || (r->kind != TYPE_INTEGER)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_BOOLEAN,0,0,0);
            }
            break;
        case (EXPR_EQUIVALENCE_COMPARISON):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind == TYPE_FUNCTION) || (r->kind == TYPE_FUNCTION)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare equivalence of functions\n");
                e->type = 0;
            } else if ((l->kind == TYPE_ARRAY) || (r->kind == TYPE_ARRAY)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare equivalence of arrays\n");
                e->type = 0;
            } else if (l->kind != r->kind){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare equivalence of ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_BOOLEAN,0,0,0);
            }
            break;
        case (EXPR_NONEQUIVALENCE_COMPARISON):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind == TYPE_FUNCTION) || (r->kind == TYPE_FUNCTION)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare equivalence of functions\n");
                e->type = 0;
            } else if ((l->kind == TYPE_ARRAY) || (r->kind == TYPE_ARRAY)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare equivalence of arrays\n");
                e->type = 0;
            } else if (l->kind != r->kind){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare equivalence of ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_BOOLEAN,0,0,0);
            }
            break;
        case (EXPR_AND):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_BOOLEAN) || (r->kind != TYPE_BOOLEAN)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_BOOLEAN,0,0,0);
            }
            break;
        case (EXPR_OR):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            if ((l->kind != TYPE_BOOLEAN) || (r->kind != TYPE_BOOLEAN)){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot compare ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(TYPE_BOOLEAN,0,0,0);
            }
            break;
        case (EXPR_ASSIGNMENT):
            l = expr_typecheck(e->left);
            r = expr_typecheck(e->right);
            //if ((l->kind == TYPE_FUNCTION) || (r->kind == TYPE_FUNCTION)){
            if (l->kind == TYPE_FUNCTION){
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot assign a function\n");
                e->type = 0;
            } else if (l->kind != r->kind) {
                error_counter += 1;
                printf("Error #%i ",error_counter);
                printf("type error: cannot assign ");
                type_print(l);
                literal_print(e->left);
                printf(" to ");
                type_print(r);
                literal_print(e->right);
                printf("\n");
                e->type = 0;
            } else {
                e->type = type_create(l->kind,0,0,0);
            }
            break;
        case (EXPR_BOOLEAN_LITERAL):
            e->type = type_create(TYPE_BOOLEAN, 0, 0, 0);
            break;
        case (EXPR_INTEGER_LITERAL):
            e->type = type_create(TYPE_INTEGER, 0, 0, 0);
            break;
        case (EXPR_CHARACTER_LITERAL):
            e->type = type_create(TYPE_CHARACTER, 0, 0, 0);
            break;
        case (EXPR_STRING_LITERAL):
            e->type = type_create(TYPE_STRING, 0, 0, 0);
            break;
        case (EXPR_IDENTIFIER):
            e->type = e->symbol->type;
            break;
        case (EXPR_PARENTHESES):
            e->type = expr_typecheck(e->left);
            break;
        case (EXPR_FUNCTION_CALL):
            param_list_typecheck();
            e->type = e->left->symbol->type->subtype;
            break;
        case (EXPR_ARRAY_INDEX):
            e->type = type_create(TYPE_ARRAY, 0, 0, 0);
            break;
    }
    return e->type;
}
コード例 #10
0
ファイル: expr.c プロジェクト: tDeranek117/CSE-Notre-Dame
struct type * expr_typecheck(struct expr *e)
{
    if (!e)
        return type_create(TYPE_VOID, 0, 0);

    struct type *l, *r;

    switch(e->kind)
    {
    case EXPR_INTEGER_LITERAL:
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_BOOLEAN_LITERAL:
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_CHAR_LITERAL:
        return type_create(TYPE_CHARACTER, 0, 0);
    case EXPR_STRING_LITERAL:
        return type_create(TYPE_STRING, 0, 0);
    case EXPR_VARIABLE:
        return type_create(e->symbol->type->kind, 0, 0);
    case EXPR_FUNCTION_CALL:
        param_list_typecheck(e->symbol->type->params, e->right, 0);
        return type_create(e->symbol->type->subtype->kind, 0, 0);
    case EXPR_ADD:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: cannot add type ", e->line);
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" to type ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_UNARY:
        r = expr_typecheck(e->right);
        if (r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: ", e->line);
            printf("unary operator (-) cannot be applied to type ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            error_count++;
        }
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_ASSIGN:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind == TYPE_FUNCTION || r->kind == TYPE_FUNCTION)
        {
            printf("type error: line %d: ", e->line);
            printf("= operator not compatible with functions\n");
            error_count++;
        }
        else if (!(type_compare(l, r)))
        {
            printf("type error: line %d: cannot assign type ", e->line);
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf(" to type ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(l->kind, 0, 0);
    case EXPR_LIST:
        l = expr_typecheck(e->left);
        expr_typecheck(e->right);
        return l;
    case EXPR_LIST_OUTER:
        r = expr_typecheck(e->right);
        return r;;
    case EXPR_SUB:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: cannot subtract type ", e->line);
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" from type ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_MUL:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: cannot multiply type ", e->line);
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" and type ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_DIV:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: cannot divide type ", e->line);
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" by type ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_MOD:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: cannot modulus type ", e->line);
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" with type ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_POW:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: cannot exponentiate type ", e->line);
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" by type ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_INCR:
        r = expr_typecheck(e->right);
        if (r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: ", e->line);
            printf("++ operator not compatible with type ");
            type_print(e->symbol->type);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;

        }
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_DECR:
        r = expr_typecheck(e->right);
        if (r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: ", e->line);
            printf("-- operator not compatible with type ");
            type_print(e->symbol->type);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_INTEGER, 0, 0);
    case EXPR_NOT:
        r = expr_typecheck(e->right);
        if (r->kind != TYPE_BOOLEAN)
        {
            printf("type error: line %d: ", e->line);
            printf("! operator requires boolean type boolean type operand (found ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf(" )\n" );
            error_count++;
        }
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_LT:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: ", e->line);
            printf("< operator not compatible with types ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_LE:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: ", e->line);
            printf("<= operator not compatible with types ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_GT:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: ", e->line);
            printf("> operator not compatible with types ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_GE:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_INTEGER || r->kind != TYPE_INTEGER)
        {
            printf("type error: line %d: ", e->line);
            printf(">= operator not compatible with types ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_EQ:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind == TYPE_ARRAY
                || l->kind == TYPE_FUNCTION
                || r->kind == TYPE_ARRAY
                || r->kind == TYPE_FUNCTION)
        {
            printf("type error: line %d: ", e->line);
            printf("== operator not compatible with types ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        else if (!type_compare(l, r))
        {
            printf("type error: line %d: ", e->line);
            printf("cannot use == operator on non-matching types ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_NE:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind == TYPE_ARRAY
                || l->kind == TYPE_FUNCTION
                || r->kind == TYPE_ARRAY
                || r->kind == TYPE_FUNCTION)
        {
            printf("type error: line %d:", e->line);
            printf("!= operator not compatible with types ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        else if (!type_compare(l, r))
        {
            printf("type error: line %d:", e->line);
            printf("cannot use != operator on non-matching types ");
            printf(" (");
            expr_print(e->left);
            printf(")");
            type_print(l);
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_AND:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_BOOLEAN || r->kind != TYPE_BOOLEAN)
        {
            printf("type error: line %d: ", e->line);
            printf("&& operator not compatible with types ");
            type_print(l);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_OR:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_BOOLEAN || r->kind != TYPE_BOOLEAN)
        {
            printf("type error: line %d: ", e->line);
            printf("|| operator not compatible with types ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf(" and ");
            type_print(r);
            printf(" (");
            expr_print(e->right);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(TYPE_BOOLEAN, 0, 0);
    case EXPR_ARRAY_MEMBER:
        l = expr_typecheck(e->left);
        r = expr_typecheck(e->right);
        if (l->kind != TYPE_ARRAY && l->kind != TYPE_STRING)
        {
            printf("type error: line %d: ", e->line);
            printf("[] operator cannot follow a variable of type ");
            type_print(l);
            printf(" (");
            expr_print(e->left);
            printf(")");
            printf("\n");
            error_count++;
        }
        return type_create(type_array_type(e), 0, 0);
    case EXPR_INDEX:
        if (e->left)
        {
            l = expr_typecheck(e->left->right);
            if (l->kind != TYPE_INTEGER)
            {
                printf("type error: line %d: ", e->line);
                printf("an array index cannot be type ");
                type_print(l);
                printf(" (");
                expr_print(e->left->right);
                printf(")");
                printf("\n");
                error_count++;
            }
            expr_typecheck(e->right);
        }
        else
        {
            r = expr_typecheck(e->right);
            if (r->kind != TYPE_INTEGER)
            {
                printf("type error: line %d: ", e->line);
                printf("an array index cannot be type ");
                type_print(r);
                printf(" (");
                expr_print(e->right);
                printf(")");
                printf("\n");
                error_count++;
            }
        }
        return type_create(TYPE_INTEGER, 0, 0);
    default:
        fprintf(stderr, "cminor: ERROR! Illegal expr type found!\n");
        exit(1);
    }
}