Пример #1
0
int check_continue(is_continue* node)
{
	int errors = 0;


	if (errors == 0)
	{
		if (node->label)
			node->scope = scope_get_by_name(symtab, node->label->name, t_symbol_loop);
		else
			node->scope = scope_get_by_name(symtab, NULL, t_symbol_loop);

		if (!node->scope)
		{
			errors++;

			if (node->label)
				pretty_error(node->line, "continue stmt label \"%s\" is undefined", node->label->name);
			else
				pretty_error(node->line, "continue stmt outside of loop");		

		} else
			node->scope->symbol->data.loop_data.continued = true;
	}

	return errors;
}
Пример #2
0
int check_ternary_op(is_ternary_op* node)
{
	char *typeA, *typeB;
	int errors = 0;

	errors += check_expr(node->if_expr);
	if (errors == 0 && !type_native_assign_able(t_type_native_bool, node->if_expr->s_type))
	{
		errors++;
		typeA = string_type_decl(node->if_expr->s_type);

		pretty_error(node->line, "ternary conditional is not boolean (is of type %s)", typeA);

		free(typeA);
	}

	errors += check_expr(node->then_expr);
	errors += check_expr(node->else_expr);
	if (errors == 0 && !type_type_equal(node->then_expr->s_type, node->else_expr->s_type))
	{
		errors++;
		typeA = string_type_decl(node->then_expr->s_type);
		typeB = string_type_decl(node->else_expr->s_type);

		pretty_error(node->line, "ternary results are not of the same type (are of types %s and %s)", typeA, typeB);

		free(typeA);
		free(typeB);
	}

	if (errors == 0)
		node->s_type = duplicate_type_decl(node->then_expr->s_type);

	return errors;
}
Пример #3
0
int check_incr_op(is_incr_op* node)
{
	is_type_native type;
	char* typeA;
	int errors = 0;

	errors += check_var(node->var);
	if (errors == 0)
	{
		if (node->var->s_type->type != t_type_decl_array_decl)
		{
			type = operators_incr_op[node->var->s_type->data.type_object->type];
			if (type == ERROR)
			{
				errors++;
				pretty_error(node->line, "increment operation with %s type is invalid",
					typeA = string_type_decl(node->var->s_type));

				free(typeA);
			} else if (!node->var->initialized)
			{
				errors++;
				pretty_error(node->line, "variable used in a increment op without being initialized ");
			} else
				node->s_type = duplicate_type_decl(node->var->s_type);

		} else
		{
			errors++;
			pretty_error(node->line, "increment operations are invalid between array types");
		}
	}

	return errors;
}
Пример #4
0
int check_break(is_break* node)
{
	int errors = 0;
	SCOPE *scope_loop, *scope_switch, *aux;

	if (errors == 0)
	{
		node->scope = NULL;

		if (node->label)
		{
			scope_loop = scope_get_by_name(symtab, node->label->name, t_symbol_loop);
			scope_switch = scope_get_by_name(symtab, node->label->name, t_symbol_switch);
		} else
		{
			scope_loop = scope_get_by_name(symtab, NULL, t_symbol_loop);
			scope_switch = scope_get_by_name(symtab, NULL, t_symbol_switch);
		}

		if (scope_loop == NULL)
		{
			node->scope = scope_switch;
			node->type = t_break_switch;
		} else if (scope_switch == NULL)
		{
			node->scope = scope_loop;
			node->type = t_break_loop;
		} else
		{
			for (aux = scope_loop; aux != NULL; aux = aux->parent)
			{
				if (aux == scope_switch) /* switch is higher on the scope stack */
				{
					node->scope = scope_loop; /* we want the lowest */
					node->type = t_break_loop;
					break;
				}
			}

			if (node->scope == NULL)
			{
				node->scope = scope_switch;
				node->type = t_break_switch;
			}
		}

		if (!node->scope)
		{
			errors++;

			if (node->label)
				pretty_error(node->line, "break stmt label \"%s\" is undefined", node->label->name);
			else
				pretty_error(node->line, "break stmt outside of loop or switch");
		}
	}

	return errors;
}
Пример #5
0
int check_func_call(is_func_call* node)
{
	is_expr_list* arg;
	int errors = 0;
	int i;
	char *typeA, *typeB;

	node->symbol = scope_lookup(symtab, node->id->name, t_symbol_func);
	if (!node->symbol)
	{
		pretty_error(node->line, "undefined function \"%s\"", node->id->name);
		errors++;
	} else
	{
		errors += check_func_call_arg_list(node->args);

		if (errors == 0)
		{
			if ((node->args == NULL && node->symbol->data.func_data.nArgs != 0) ||
				(node->args != NULL && node->args->length != node->symbol->data.func_data.nArgs))
			{
				pretty_error(node->line, "too %s arguments for \"%s\", got %d expected %d (declaration is here: %d)",
					node->args->length > node->symbol->data.func_data.nArgs ? "many" : "few",
					node->id->name,
					node->args->length,
					node->symbol->data.func_data.nArgs,
					node->symbol->line);

				errors++;
			} else
			{
				for (i = 0, arg = node->args; arg != NULL; i++, arg = arg->next)
				{
					if (!type_type_assign_able(node->symbol->data.func_data.args[i]->type, arg->node->s_type))
					{
						errors++;
						pretty_error(node->line, "invalid parameter \"%d\" (%s) of function %s (got %s expected %s)",
							i,
							node->symbol->data.func_data.args[i]->id->name,
							node->id->name,
							typeA = string_type_decl(arg->node->s_type),
							typeB = string_type_decl(node->symbol->data.func_data.args[i]->type)
						);

						free(typeA);
						free(typeB);
					}
				}

				if (errors == 0)
					node->s_type = duplicate_type_decl(node->symbol->data.func_data.type);
			}
		}
	}

	return errors;
}
Пример #6
0
int check_binary_op(is_binary_op* node)
{
	int errors = 0;
	char *typeA, *typeB;
	is_type_native type;

	switch (node->type)
	{
		case t_binary_op_assign:
			errors += check_assign_op(node->data.assign);
			if (errors == 0)
				node->s_type = duplicate_type_decl(node->data.assign->s_type);
		break;

		default:
			errors += check_expr(node->data.operands.left);
			errors += check_expr(node->data.operands.right);

			if (errors == 0)
			{
				if (node->data.operands.left->s_type->type == t_type_decl_array_decl ||
					node->data.operands.right->s_type->type == t_type_decl_array_decl)
				{
					errors++;
					pretty_error(node->line, "binary operations are invalid between array types");
				} else
				{
					type = operators_binary[node->type][node->data.operands.left->s_type->data.type_object->type][node->data.operands.right->s_type->data.type_object->type];
					if (type == ERROR)
					{
						errors++;
						pretty_error(node->line, "invalid binary operation between %s and %s",
							typeA = string_type_decl(node->data.operands.left->s_type),
							typeB = string_type_decl(node->data.operands.right->s_type)
						);
						free(typeA);
						free(typeB);
					}
				}
			}

			/* only valid for objects not arrays*/
			if (errors == 0)
				node->s_type = insert_type_decl_object(insert_type_object(type));
		break;
	}

	return errors;
}
Пример #7
0
int check_while(is_while* node, is_label* label)
{
	int errors = 0;
	char *string;

	int mylabel = ++label_counter; /* setting label for use with loops and break/continue */
	
	if (label)
		node->scope = scope_new(symbol_new_loop(label->name, node->line, mylabel), false);
	else
		node->scope = scope_new(symbol_new_loop(NULL, node->line, mylabel), false);
		
	scope_push(node->scope);
		errors += check_expr(node->cond);
		if (errors == 0)
		{
			if (!type_native_assign_able(t_type_native_bool, node->cond->s_type))
			{
				errors++;
				pretty_error(node->line, "invalid while condition: expected boolean, got %s", string = string_type_decl(node->cond->s_type));
				free(string);
			}
		}

		errors += check_stmt(node->body);
		node->terminates = node->body->terminates;
	scope_pop();
	
	return errors;
}
Пример #8
0
int check_do_while(is_do_while* node, is_label* label)
{
	int errors = 0;

	int mylabel = ++label_counter; /* setting label for use with loops and break/continue */

	if (label)
		node->scope = scope_new(symbol_new_loop(label->name, node->line, mylabel), false);
	else
		node->scope = scope_new(symbol_new_loop(NULL, node->line, mylabel), false);
		
	scope_push(node->scope);
		errors += check_stmt(node->body);
		if (errors == 0)
			node->terminates = node->body->terminates;

		errors += check_expr(node->cond);
		if (errors == 0)
		{
			if (!type_native_assign_able(t_type_native_bool, node->cond->s_type))
			{
				errors++;
				pretty_error(node->line, "invalid do..while condition (must be boolean)");
			}
		}
	scope_pop();
	return errors;
}
Пример #9
0
int check_stmt_list(is_stmt_list* node)
{
	int errors = 0;

	if (node)
	{
		errors += check_stmt(node->node);
		errors += check_stmt_list(node->next);

		if (node->node)
			node->terminated = node->node->terminates;
		else
			node->terminated = false;

		if (node->next)
		{
			node->length = node->next->length+1;
			
			if (node->terminated)
				pretty_error(node->line, "dead code after incoditional jump stmt");
			else
				node->terminated = node->next->terminated;
		} else
			node->length = 1;
	}

	return errors;
}
Пример #10
0
int check_unary_op(is_unary_op* node)
{
	is_type_native type;
	char* typeA;
	int errors = 0;

	switch (node->type)
	{
		case t_unary_op_operation:
			errors += check_expr(node->data.operation.expr);
			if (errors == 0)
			{
				if (node->data.operation.expr->s_type->type != t_type_decl_array_decl)
				{
					type = operators_unary[node->data.operation.op][node->data.operation.expr->s_type->type];
					if (type == ERROR)
					{
						errors++;
						pretty_error(node->line, "unary operation with %s type is invalid",
							typeA = string_type_decl(node->data.operation.expr->s_type));
						free(typeA);
					} else
						node->s_type = duplicate_type_decl(node->data.operation.expr->s_type);
				} else
				{
					errors++;
					pretty_error(node->line, "unary operations are invalid between array types");
				}
			}
		break;

		case t_unary_op_incr_op:
			errors += check_incr_op(node->data.incr);
			if (errors == 0)
			{
				node->s_type = duplicate_type_decl(node->data.incr->s_type);
				node->data.incr->used = true;
			}
		break;	
	}

	return errors;
}
Пример #11
0
int check_label(is_id* node)
{
	int errors = 0;
	SCOPE* scope;

	scope = scope_get_by_name(symtab, node->name, t_symbol_loop);
	if (scope != NULL)
	{
		errors++;
		pretty_error(node->line, "ambiguous label \"%s\"", node->name); 
	}	

	return errors;
}
Пример #12
0
int check_class_def(is_class_def* node)
{
	int errors = 0;
	SYMBOL* symbol;

	symbol = scope_lookup(symtab, node->id->name, t_symbol_class);
	if (symbol)
	{
		errors++;
		pretty_error(node->line, "class \"%s\" is already defined (previous declaration was here: %d)", node->id->name, symbol->line);
	} else
		scope_insert(symtab, symbol = symbol_new_class(node->id->name, node->line));

	node->scope = scope_new(symbol, true);

	/*
		FIXME:
		this should be in application and not in class def,
		because theoretically class should be able to access other classes
	*/
	scope_push(node->scope);
		errors += check_class_stmt_list(node->body, true);

		if (errors == 0)
		{
			symbol = scope_lookup(symtab, "main", t_symbol_func);
			if (!symbol)
			{
				errors++;
				pretty_error(node->line, "missing main entry point");
			}
		}
		errors += check_class_stmt_list(node->body, false);
	scope_pop();

	return errors;
}
Пример #13
0
int check_dims_sized(is_dims_sized* node)
{
	int errors = 0;

	errors += check_expr(node);
	if (errors == 0)
	{
		if (!type_native_assign_able(t_type_native_int, node->s_type))
		{
			errors++;
			pretty_error(node->line, "invalid array size (must be convertible to int)");
		}
	}

	return errors;
}
Пример #14
0
int check_return(is_return* node)
{
	int errors = 0;
	SCOPE* scope;

	is_type_decl *type = NULL, *typeR;
	char *typeA, *typeB;

	if (node->value)
	{
		errors += check_expr(node->value);
		typeR = node->value->s_type;
	} else
	{
		type = new_type_decl_void(node->line);
		typeR = type;
	}

	if (errors == 0)
	{
		scope = scope_get_by_name(symtab, NULL, t_symbol_func);
		node->symbol = scope->symbol;
		if (!type_type_equal(typeR, node->symbol->data.func_data.type))
		{
			typeA = string_type_decl(typeR);

			typeB = string_type_decl(node->symbol->data.func_data.type);

			errors++;
			pretty_error(node->line, "invalid return type %s should be of type %s",
				typeA,
				typeB
			);

			free(typeA);
			free(typeB);
		}
	}

	if (type)
		free_type_decl(type);

	return errors;
}
Пример #15
0
int check_for(is_for* node, is_label* label)
{
	int errors = 0, cond_errors;
	char* typeA;

	int mylabel = ++label_counter; /* setting label for use with loops and break/continue */

	if (label)
		node->scope = scope_new(symbol_new_loop(label->name, node->line, mylabel), false);
	else
		node->scope = scope_new(symbol_new_loop(NULL, node->line, mylabel), false);
		
	scope_push(node->scope);
		if (node->init)
			errors += check_for_init(node->init);

		if (node->cond)
		{
			cond_errors = check_for_cond(node->cond);
			if (cond_errors == 0)
			{
				if (!type_native_assign_able(t_type_native_bool, node->cond->s_type))
				{
					cond_errors++;
					pretty_error(node->line, "for conditional is not boolean (is of type %s)", typeA = string_type_decl(node->cond->s_type));
					free(typeA);
				}
			}
			errors += cond_errors;
		}
	
		if (node->inc)
			errors += check_for_inc(node->inc);

		errors += check_stmt(node->body);

		if (errors == 0)
			node->terminates = (node->body ? node->body->terminates : true);
	scope_pop();
 
	return errors;
}
Пример #16
0
int check_switch(is_switch* node)
{
	int errors = 0;
	int mylabel = ++label_counter; /* setting label for use with break */
	char *type;

	if (node->label)
		errors += check_label(node->label);

	errors += check_expr(node->expr);

	if (errors == 0)
	{
		if (node->expr->s_type->type == t_type_decl_array_decl)
		{
			errors++;

			type = string_type_decl(node->expr->s_type);
			pretty_error(node->line, "switch statement expression must be of object type (got %s)", type);
			free(type);
		}
	}

	if (errors == 0)
	{
		if (node->label)
			node->scope = scope_new(symbol_new_switch(node->label->name, node->line, mylabel, node->expr->s_type->data.type_object, symtab->framepos++), false);
		else
			node->scope = scope_new(symbol_new_switch(NULL, node->line, mylabel, node->expr->s_type->data.type_object, symtab->framepos++), false);

		scope_push(node->scope);
			check_switch_stmt_list(node->list, node);

			if (errors == 0)
				node->terminates = (node->list ? node->list->terminates : true);
		scope_pop();
 	}

	return errors;
}
Пример #17
0
int check_if(is_if* node)
{
	int errors = 0;
	char* typeA;

	errors += check_expr(node->cond);
	if (errors == 0 && !type_native_assign_able(t_type_native_bool, node->cond->s_type))
	{
		errors++;
		pretty_error(node->line, "if conditional is not boolean (is of type %s)", typeA = string_type_decl(node->cond->s_type));
		free(typeA);
	}	

	errors += check_stmt(node->then_body);
	node->terminates = node->then_body->terminates && node->else_body != NULL;
	if (node->else_body)
	{
		errors += check_stmt(node->else_body);
		node->terminates &= node->else_body->terminates;
	}

	return errors;
}
Пример #18
0
int check_func_def_arg(is_func_def_arg* node)
{
	int errors = 0;
	SYMBOL* symbol;

	errors += check_type_decl(node->type);
	if (errors == 0)
	{
		symbol = scope_local_lookup(symtab, node->id->name, t_symbol_var);
		if (symbol)
		{
			pretty_error(node->line, "argument \"%s\" colides with already defined variable (previous declaration was here: %d)",
				node->id->name, symbol->line);
			errors++;
		} else
		{
			symbol = scope_insert(symtab, symbol_new_var(node->id->name, node->line, node->type, false, symtab->framepos++));
			symbol->data.var_data.initialized = true;
		}
	}

	return errors;
}
Пример #19
0
/**
 * Report an error that occurs during evaluation.
 */
static void eval_error(struct eval_state *state) {
	pretty_error(state->cmdline->stderr_colors,
	             "'%s': %s\n", state->ftwbuf->path, strerror(errno));
	state->ret = -1;
}
Пример #20
0
int check_func_def(is_func_def* node, bool first_pass)
{
	SYMBOL* symbol;
	SCOPE* tempscope;
	int label;
	int errors = 0;
	is_type_decl *tmpType = NULL;

	if (first_pass)
	{
		errors += check_type_decl(node->type);

		symbol = scope_lookup(symtab, node->id->name, t_symbol_func);
		if (symbol)
		{
			pretty_error(node->line, "symbol \"%s\" is already defined (previous declaration was here: %d)", node->id->name, symbol->line);
			errors++;
		} else
		{
			tempscope = scope_new(NULL, false);
			scope_push(tempscope);
				errors += check_func_def_args(node->args);
			scope_pop();
			
			if (strcmp(node->id->name, "main") == 0)
			{
				label = 0;

				if (node->args) /* no args is valid */
				{
					if (node->args->length == 1) /* main may must not have more than two arguments */
					{
						tmpType = insert_type_decl_array(insert_array_decl(insert_type_object(t_type_native_string), new_dims_empty_list(0, 1))); /* must be an array of Strings */

						if (!type_type_equal(tmpType,node->args->node->type))
						{
							errors++;
							pretty_error(node->line, "main function arguments do not match any valid prototypes");
						}

						free_type_decl(tmpType);
					} else
					{
						errors++;
						pretty_error(node->line, "main function arguments do not match any valid prototypes");
					}
				}

				tmpType = insert_type_decl_object(insert_type_object(t_type_native_int)); /* return value must be int or void */

				if (!type_type_equal(tmpType,node->type))
				{
					free_type_decl(tmpType);

					tmpType = new_type_decl_void(0); /* check for void */

					if (!type_type_equal(tmpType,node->type)) /* none; errors occurred */
					{
						errors++;
						pretty_error(node->line, "main function return type does not match any valid types (nor int nor void)");
					}
				}
				
				free_type_decl(tmpType);
			} else
				label = ++label_counter;

			symbol = symbol_new_func(node->id->name, node->line, node->type, node->args, label);
			scope_delete(tempscope);

			scope_insert(symtab, symbol);

			node->scope = scope_new(symbol, false);
		}
	} else
	{
		scope_push(node->scope);
			errors += check_func_def_args(node->args); /* this will not give errors */
			errors += check_stmt_list(node->body);
			
			if ((!node->body || !node->body->terminated) &&
				!(node->type->type == t_type_decl_type_object && node->type->data.type_object->type == t_type_native_void))
			{
				pretty_error(node->line, "reached end of non void function");
				errors++;		
			}
		scope_pop();
	}

	return errors;
}
Пример #21
0
int check_assign_op(is_assign_op* node)
{
	int errors = 0;
	char* typeA, *typeB;
	is_type_native type;
	SYMBOL* symbol;

	errors += check_var(node->var);
	errors += check_expr(node->expr);

	if (errors == 0)
	{
		switch (node->type)
		{
			case t_assign_op_eq:
				if (!type_type_assign_able(node->var->s_type, node->expr->s_type))
				{
					errors++;
					pretty_error(node->line, "invalid assignment from %s to %s",
						typeA = string_type_decl(node->expr->s_type),
						typeB = string_type_decl(node->var->s_type)
					);
					free(typeA);
					free(typeB);
				} else
				{
					if (node->var->type == t_var_id)
					{
						symbol = scope_lookup(symtab, node->var->data.id->name, t_symbol_var);
						symbol->data.var_data.initialized = true;
					}

					node->s_type = duplicate_type_decl(node->var->s_type);
				}
			break;

			default:
				if (node->var->s_type->type == t_type_decl_array_decl || node->expr->s_type->type == t_type_decl_array_decl)
				{
					errors++;
					pretty_error(node->line, "assignment operations are invalid between array types");
				} else
				{
					type = operators_binary[node->type][node->var->s_type->data.type_object->type][node->expr->s_type->data.type_object->type];
					if (type == ERROR)
					{
						errors++;
						pretty_error(node->line, "assignment operation invalid between %s and %s",
							typeA = string_type_decl(node->var->s_type),
							typeB = string_type_decl(node->expr->s_type)
						);
						free(typeA);
						free(typeB);
					} else
						node->s_type = insert_type_decl_object(insert_type_object(type));
				}
			break;
		}
	}

	return errors;
}
Пример #22
0
int check_switch_stmt(is_switch_stmt* node, is_switch* root)
{
	int errors = 0;
	char *typeA, *typeB;
	is_switch_stmt_list* temp;

	switch (node->type)
	{
		case t_switch_stmt_default:
			for (temp = root->list; temp->node != node; temp = temp->next)
			{
				if (temp->node->type == t_switch_stmt_default)
				{
					errors++;
					pretty_error(node->line, "duplicate default label inside of switch (previous declaration was here %d)",
						temp->node->line);
				}
			}
			
			if (node->list)
				errors += check_stmt_list(node->list);
		break;

		case t_switch_stmt_case:
			check_constant(node->constant);
			
			if (errors == 0)
			{
				node->s_type = duplicate_type_decl(node->constant->s_type);

	 			if (!type_type_equal(root->expr->s_type, node->s_type))
				{
					errors++;
					typeA = string_type_decl(root->expr->s_type);
					typeB = string_type_decl(node->s_type);

					pretty_error(node->line, "case stmt must by of type %s (but got %s)",
						typeA, typeB);

					free(typeA);
					free(typeB);
				}
			}

			if (errors == 0)
			{
				for (temp = root->list; temp->node != node; temp = temp->next)
				{
					if (temp->node->type != t_switch_stmt_default &&
						constant_constant_equal(temp->node->constant, node->constant))
					{
						errors++;
						pretty_error(node->line, "duplicate case inside of switch (previous declaration was here %d)",
							temp->node->line);
					}
				}
			}

			if (node->list)
				errors += check_stmt_list(node->list);
		break;
	}

	return errors;
}
Пример #23
0
int check_expr(is_expr* node)
{
	char *typeA, *typeB; 
	int errors = 0;

	switch (node->type)
	{
		case t_expr_var:
			errors += check_var(node->data.var);

			if (errors == 0)
			{
				node->s_type = duplicate_type_decl(node->data.var->s_type);

				if (!node->data.var->initialized)
				{
					errors++;
					pretty_error(node->line, "variable used without being initialized");
				}
			}
		break;

		case t_expr_new_op:
			errors += check_new_op(node->data.new_op);
			if (errors == 0)
				node->s_type = duplicate_type_decl(node->data.new_op->s_type);
		break;

		case t_expr_type_cast:
			errors += check_expr(node->data.type_cast.expr);
			errors += check_type_decl(node->data.type_cast.type);

			if (errors == 0)
			{
				if (!type_type_cast_able(node->data.type_cast.type, node->data.type_cast.expr->s_type))
				{
					errors++;
					typeA = string_type_decl(node->data.type_cast.type);
					typeB = string_type_decl(node->data.type_cast.expr->s_type);

					pretty_error(node->line, "invalid typecast from %s to %s", typeA, typeB);
					free(typeA); free(typeB);
				} else
					node->s_type = duplicate_type_decl(node->data.type_cast.type);
			}
		break;

		case t_expr_constant:
			errors += check_constant(node->data.constant);
			if (errors == 0)
				node->s_type = duplicate_type_decl(node->data.constant->s_type);
		break;

		case t_expr_func_call:
			errors += check_func_call(node->data.func_call);
			if (errors == 0)
				node->s_type = duplicate_type_decl(node->data.func_call->s_type);
		break;

		case t_expr_operation:
			errors += check_expr_op(node->data.operation);
			if (errors == 0)
				node->s_type = duplicate_type_decl(node->data.operation->s_type);
		break;
	}

	return errors;
}
Пример #24
0
int check_var(is_var* node)
{
	int errors = 0;
	char *typeA;

	switch (node->type)
	{
		case t_var_id:
			node->symbol = scope_lookup(symtab, node->data.id->name, t_symbol_var);
			if (!node->symbol)
			{
				errors++;
				pretty_error(node->line, "undefined variable \"%s\"", node->data.id->name);
				node->initialized = false;
			} else
			{
				node->initialized = node->symbol->data.var_data.initialized;
				node->s_type = duplicate_type_decl(node->symbol->data.var_data.type);
			}
		break;

		case t_var_new_op:
			errors += check_new_op(node->data.new_op);
			node->s_type = duplicate_type_decl(node->data.new_op->s_type);
			node->initialized = true;
		break;

		case t_var_array:
			errors += check_var(node->data.array.var);
			errors += check_dims_sized(node->data.array.dims);

			if (errors == 0)
			{
				if (node->data.array.var->s_type->type == t_type_decl_array_decl)
				{
					node->s_type = decapsulate_type_decl(node->data.array.var->s_type);
				} else
				{
					errors++;
					pretty_error(node->line, "subscript of unsuscriptable type (%s)",
						typeA = string_type_decl(node->data.array.var->s_type)
					);
					free(typeA);
				}
			}
			node->initialized = true;
		break;

		case t_var_func_call:
			errors += check_func_call(node->data.func_call.call);
			errors += check_dims_sized(node->data.array.dims);

			if (errors == 0)
			{
				if (node->data.func_call.call->s_type->type == t_type_decl_array_decl)
				{
					node->s_type = decapsulate_type_decl(node->data.func_call.call->s_type);
				} else
				{
					errors++;
					pretty_error(node->line, "subscript of unsuscriptable type (%s)",
						typeA = string_type_decl(node->data.func_call.call->s_type)
					);
					free(typeA);
				}
			}
			node->initialized = true;
		break;
	}

	/* todo propagate node->initialized */
	return errors;
}
Пример #25
0
int check_var_defs(is_var_defs* node, bool first_pass)
{
	int errors = 0;

	SYMBOL *symbol;

	is_type_decl *type = NULL;

	is_var_def_list *it;

	errors += check_type_decl(node->type);
	errors += check_var_def_list(node->list);

	for (it = node->list; it != NULL; it = it->next)
	{
		symbol = scope_local_lookup(symtab, it->node->left->id->name, t_symbol_var);
		if (symbol)
		{
			errors++;
			pretty_error(it->node->line, "symbol \"%s\" is already defined (previous declaration was here: %d)", it->node->left->id->name, symbol->line);
		} else
		{
			if (it->node->left->empty->size != 0)
			{
				if (node->type->type != t_type_decl_array_decl)
				{
					/* create a new type_decl (array) with it->node->left->data.empty->size dimensions */
					type = insert_type_decl_array(insert_array_decl(insert_type_object(node->type->data.type_object->type), new_dims_empty_list(node->type->line, it->node->left->empty->size)));
				} else
				{
					/* type is already a type_decl_array, only dims update is needed */
					type = duplicate_type_decl(node->type);
					type->data.array->dims->size += it->node->left->empty->size;
				}

			} else /* no dims updates are needed; even if the type is "dimmed" this is only a copy of the type */
				type = duplicate_type_decl(node->type);

			if (first_pass)
				symbol = scope_insert(symtab, symbol_new_var(it->node->left->id->name, node->line, type, true, globalpos++));
			else
				symbol = scope_insert(symtab, symbol_new_var(it->node->left->id->name, node->line, type, false, symtab->framepos++));

			it->node->left->symbol = symbol;

			if (it->node->var_init) /* check initialization if it exists */
			{
				if (type_var_init_assign_able(type, (type->type == t_type_decl_array_decl ? type->data.array->dims->size : 0), it->node->var_init))
					/* if initialization is valid */
					symbol->data.var_data.initialized = true;
				else
				{
					errors++;
					pretty_error(it->node->line, "variable \"%s\" initalization is invalid", it->node->left->id->name);
				}
			}
		}

		free_type_decl(type);
	}
	
	return errors;
}