/*
    analyzing all arguments of the function call
*/
void analyze_args(Exprs args, char* procName, char* callee, int paramNum)
{
    Expr first = args->first;
    Exprs rest = args->rest;
    if(first && getParamType(callee, paramNum)!=-1)
    {
        analyze_expr(first, procName);
        analyze_arg(first, callee, paramNum, procName);
    }
    else if(first && getParamType(callee, paramNum)==-1)
    {
        printf("function call %s has more number of parameter.\n",
                                                    callee);
        errorNum++;
        return;
    }
    if(rest == 0 && getParamType(callee, paramNum+1)!=-1)
    {
        printf("function call %s has less number of parameter.\n",
                                                    callee);
        errorNum++;
    }
    if(rest)
        analyze_args(rest, procName, callee, paramNum+1);

}
/*
    analyzing assignment statement,
    if any variable is not declared report an error
    check the type of left and right
*/
void analyze_assign(Assign assign, char* procName)
{
    analyze_expr(assign.expr, procName);
    getExprType(assign.expr, procName);
    int r = checkType(procName, assign.id, 
        getExprType(assign.expr, procName));

    int j = getArrayType(getType(procName,assign.id)) == 
        getExprType(assign.expr, procName) ? 1:0;

    if(getType(procName,assign.id)==FLOAT_TYPE && 
        getExprType(assign.expr, procName)==INT_TYPE ||
         getType(procName,assign.id)==FLOAT_TYPE && 
          getExprType(assign.expr, procName)==INT_ARRAY_TYPE)
        r = 1;
    if(r == 0 && j == 0)
    {
        printf("wrong assign type of %s.\n", assign.id);
        errorNum++;
    }
    if(r == -1)
    {
        printf("no declaration of %s.\n", assign.id);
        errorNum++;
    }
}
/*
    analyzing expression list for array
*/
void analyze_exprs(Exprs exprs, char* procName)
{
    Expr first = exprs->first;
    Exprs rest = exprs->rest;
    if(first)
        analyze_expr(first, procName);
    if(rest)
        analyze_exprs(rest, procName);
}
/*
    analyzing expressions of each statement
*/
void analyze_expr(Expr expr, char* procName)
{
    switch (expr->kind) {
        case EXPR_ID:
            if(inDeclared(procName, expr->id) != 1)
            {
                printf("no declaration of %s in line %d.\n", 
                                   expr->id, expr->lineno);
                errorNum++;
            }
            Type type = getType(procName, expr->id);
            if(type == INT_ARRAY_TYPE||type == FLOAT_ARRAY_TYPE||
                type == BOOL_ARRAY_TYPE)
            {
                printf("use array name wrongly.\n");
                errorNum++;
            }
            break;
        case EXPR_CONST:
            break;
        case EXPR_BINOP:
            analyze_expr(expr->e1, procName);
            analyze_expr(expr->e2, procName);
            break;
        case EXPR_UNOP:
            analyze_expr(expr->e1, procName);
            break;
        case EXPR_RELOP:
            analyze_expr(expr->e1, procName);
            analyze_expr(expr->e2, procName);
            break;
        case EXPR_ARRAY:
            if(inDeclared(procName, expr->id) != 1)
            {
                printf("no declaration of %s in line %d.\n", 
                                   expr->id, expr->lineno);
                errorNum++;
            }
            analyze_exprs(expr->es,procName);
            break;
    }
}
/*
    analyzing while statements of procedure
    check if the condition expression is bool type
*/
void analyze_while(While while_stmt, char* procName)
{
    analyze_expr(while_stmt.cond, procName);
    if(getExprType(while_stmt.cond, procName)!=BOOL_TYPE)
    {
        printf("condition expression type is not bool in");
        printf(" line %d.\n", while_stmt.cond->lineno);
        errorNum++;
    }
    if(while_stmt.body){
        analyze_stmts(while_stmt.body, procName);
    }
}
/*
    analyzing condition statements of procedure
    check if the condition expression is bool type
*/
void analyze_cond(Cond cond_stmt, char* procName)
{
    analyze_expr(cond_stmt.cond, procName);
    if(getExprType(cond_stmt.cond, procName)!= BOOL_TYPE)
    {
        printf("condition expression type is not ");
        printf("bool in line %d.\n", cond_stmt.cond->lineno);
        errorNum++;
    }
    analyze_stmts(cond_stmt.then_branch, procName);
    if (cond_stmt.else_branch) 
    {
        analyze_stmts(cond_stmt.else_branch, procName);
    }
}
Esempio n. 7
0
void TRANS_tree(bool check_statement, TRANS_TREE **result, int *count)
{
	#ifdef DEBUG
	int i;
	#endif

	tree_length = 0;
	current = JOB->current;
	level = 0;

	TRY
	{
		analyze_expr(0, RS_NONE);
		JOB->current = current;
	}
	CATCH
	{
		JOB->current = current;
		PROPAGATE();
	}
	END_TRY

	#ifdef DEBUG
		printf("\n");
		for (i = 0; i < tree_length; i++)
		{
			printf("[%d] ", i);
			READ_dump_pattern(&tree[i]);
		}
	#endif

	if (check_statement && (!is_statement()))
		THROW("This expression cannot be a statement");

	if (result)
	{
		ALLOC(result, sizeof(PATTERN) * tree_length);
		memcpy(*result, tree, sizeof(PATTERN) * tree_length);
		*count = tree_length;
	}
}
Esempio n. 8
0
static void analyze_array()
{
	int i;

	check_last_first(1);

	for(i = 0; i < MAX_ARRAY_DIM; i++)
	{
		analyze_expr(0, RS_NONE);
		
		if (!PATTERN_is(*current, RS_COMMA))
			break;
			
		current++;
	}

	if (!PATTERN_is(*current, RS_RSQR))
		THROW(E_MISSING, "',' or ')'");
	current++;

	add_operator(RS_LSQR, i + 2);
}
Esempio n. 9
0
static void analyze_expr(short priority, short op_main)
{
	short op, op_curr, op_not;
	short prio;
	short nparam;

	inc_level();

	op_curr = op_main;
	op_not = RS_NONE;
	nparam = (op_main == RS_NONE || op_main == RS_UNARY) ? 0 : 1;

	if (PATTERN_is(*current, RS_NEW))
		THROW("Cannot use NEW operator there");

READ_OPERAND:

	//analyze_expr_check_first(op_curr);

	analyze_single(op_curr);
	nparam++;

	if (nparam > MAX_PARAM_OP)
		THROW("Expression too complex. Too many operands");

READ_OPERATOR:

	if (!PATTERN_is_reserved(*current))
		goto OPERATOR_END;

	op = PATTERN_index(*current);

	if (!RES_is_operator(op))
		goto OPERATOR_END;

	if (op == RS_AND || op == RS_OR)
		if (PATTERN_is(current[1], RS_IF))
			goto OPERATOR_END;

	current++;
	
	if (op == RS_NOT && PATTERN_is_reserved(*current))
	{
		op_not = PATTERN_index(*current);
		if (RES_is_operator(op_not) && RES_can_have_not_before(op_not))
		{
			op = op_not + 1;
			current++;
		}
	}
	
	if (priority)
		prio = priority;
	else if (op_curr == RS_NONE)
		prio = 0;
	else
		prio = RES_priority(op_curr);

	if (op_curr == RS_NONE)
	{
		if (RES_is_binary(op) || RES_is_n_ary(op))
		{
			op_curr = op;
			goto READ_OPERAND;
		}
	}

	if (op_curr == op)
	{
		if (!(RES_is_binary(op) && nparam == 2))
			goto READ_OPERAND;
	}

	if (RES_priority(op) > prio)
	{
		if (op == RS_LSQR)
			analyze_array();
		else if (op == RS_LBRA)
			analyze_call();
		else
			analyze_expr(RES_priority(op), op);

		goto READ_OPERATOR;
	}

	if (RES_priority(op) == prio)
	{
		add_operator(op_curr, nparam);

		if (op == RS_LSQR)
		{
			analyze_array();
			goto READ_OPERATOR;
		}
		else if (op == RS_LBRA)
		{
			analyze_call();
			goto READ_OPERATOR;
		}
		else
		{
			if (RES_is_only(op_curr) || RES_is_only(op))
				THROW("Ambiguous expression. Please use brackets");

			nparam = 1;
			op_curr = op;
			goto READ_OPERAND;
		}
	}

	if (RES_priority(op) < prio)
	{
		if ((op_main != RS_NONE) || (priority > 0))
		{
			add_operator(op_curr, nparam);
			current--;
			if (op_not != RS_NONE)
				current--;
			goto END;
		}

		add_operator(op_curr, nparam);

		if (op == RS_LSQR)
		{
			analyze_array();
			nparam = 1;
			op_curr = op_main;
			goto READ_OPERATOR;
		}
		else if (op == RS_LBRA)
		{
			analyze_call();
			nparam = 1;
			op_curr = op_main;
			goto READ_OPERATOR;
		}
		else
		{
			nparam = 1;
			op_curr = op;
			goto READ_OPERAND;
		}
	}

	dec_level();
	return;

OPERATOR_END:

	add_operator(op_curr, nparam);

END:

	dec_level();
	return;

}
Esempio n. 10
0
static void analyze_call()
{
	static PATTERN *byref_pattern[MAX_PARAM_FUNC];

	int i, nparam_post = 0;
	PATTERN subr_pattern = NULL_PATTERN;
	PATTERN last_pattern = get_last_pattern(1);
	SUBR_INFO *info;
	bool optional = TRUE;
	uint64_t byref = 0;
	PATTERN *save;

	/*
	get_pattern_subr(last_pattern, &subr);
	*/
	if (PATTERN_is_subr(last_pattern))
	{
		subr_pattern = last_pattern;
		remove_last_pattern();
		optional = FALSE;
	}
	else if (PATTERN_is_identifier(last_pattern))
	{
		check_last_first(1);
	}
	else if (PATTERN_is_string(last_pattern) || PATTERN_is_number(last_pattern))
		THROW(E_SYNTAX);

	/* N.B. Le cas où last_pattern = "." n'a pas de test spécifique */

	if (PATTERN_type(subr_pattern) == RT_SUBR && PATTERN_index(subr_pattern) == SUBR_VarPtr)
	{
		if (!PATTERN_is_identifier(current[0]) || !PATTERN_is(current[1], RS_RBRA))
			THROW("Syntax error. VarPtr() takes only one identifier");
		
		add_pattern(*current);
		current += 2;
		add_subr(subr_pattern, 1);
	}
	else
	{
		for (;;)
		{
			if (PATTERN_is(*current, RS_RBRA))
			{
				current++;
				break;
			}
	
			if (nparam_post > 0)
			{
				if (!PATTERN_is(*current, RS_COMMA))
					THROW(E_MISSING, "',' or ')'");
				current++;
			}
	
			#if 0
			if (FALSE) /*(PATTERN_is(*current, RS_AMP))*/
			{
				current++;
				output[nparam_post] = current;
				has_output = TRUE;
			}
			else
			{
				output[nparam_post] = NULL;
			}
			#endif
			
			if (optional && (PATTERN_is(*current, RS_COMMA) || PATTERN_is(*current, RS_RBRA)))
			{
				add_reserved_pattern(RS_OPTIONAL);
			}
			else if (optional && PATTERN_is(*current, RS_3PTS) && PATTERN_is(current[1], RS_RBRA))
			{
				current++;
				add_reserved_pattern(RS_3PTS);
				nparam_post--;
			}
			else
			{
				if (PATTERN_is(*current, RS_AT) || PATTERN_is(*current, RS_BYREF))
				{
					current++;
					BYREF_SET(byref, nparam_post);
					byref_pattern[nparam_post] = current;
				}
	
				analyze_expr(0, RS_NONE);
			}
	
			nparam_post++;

			if (nparam_post >= MAX_PARAM_FUNC)
				THROW("Too many arguments");
		}

		last_pattern = get_last_pattern(1);
		if (PATTERN_is(last_pattern, RS_OPTIONAL))
			THROW("Syntax error. Needless arguments");
		
		/*
		while (nparam_post > 0)
		{
			if (get_last_pattern(1) != PATTERN_make(RT_RESERVED, RS_OPTIONAL))
				break;
	
			remove_last_pattern();
			nparam_post--;
		}
		*/
	
		if (PATTERN_is_null(subr_pattern))
		{
			add_operator_output(RS_LBRA, nparam_post, byref);
			
			save = current;
			
			for (i = nparam_post - 1; i >= 0; i--)
			{
				if (BYREF_TEST(byref, i))
				{
					current = byref_pattern[i];
					analyze_expr(0, RS_NONE);
					//if (!is_statement())
					//	THROW("The &1 argument cannot be passed by reference", TRANS_get_num_desc(i + 1));
					add_pattern(PATTERN_make(RT_RESERVED, RS_AT));
				}
			}
			
			current = save;
		}
		else
		{
			info = &COMP_subr_info[PATTERN_index(subr_pattern)];
	
			if (nparam_post < info->min_param)
				THROW("Not enough arguments to &1()", info->name);
			else if (nparam_post > info->max_param)
				THROW("Too many arguments to &1()", info->name);
			else if (byref)
				THROW("Subroutine arguments cannot be passed by reference");
	
			add_subr(subr_pattern, nparam_post);
		}
	}

}
Esempio n. 11
0
static void analyze_single(int op)
{
	PATTERN *pattern;
	bool jump_newline;

	jump_newline = PATTERN_is_newline(*current);
	if (jump_newline)
	{
		add_pattern(PATTERN_make(RT_NEWLINE, 0));
		JOB->line++;
		current++;
	}

	if (op == RS_PT && !PATTERN_is_identifier(*current))
		THROW("The '.' operator must be followed by an identifier");
	else if (op == RS_EXCL && !PATTERN_is_string(*current))
		THROW("The '!' operator must be followed by an identifier");

	/* ( expr ) */

	if (PATTERN_is(*current, RS_LBRA))
	{
		int old_length = tree_length;
		PATTERN last;

		current++;
		analyze_expr(0, RS_NONE);

		if (!PATTERN_is(*current, RS_RBRA))
			THROW(E_MISSING, "')'");
		current++;

		if (tree_length == (old_length + 1))
		{
			last = get_last_pattern(1);
			if (PATTERN_is_string(last))
				change_last_pattern(1, PATTERN_make(RT_TSTRING, PATTERN_index(last)));
		}
	}

	/* [ expr, expr, ... ] */

	else if (PATTERN_is(*current, RS_LSQR))
	{
		current++;
		analyze_make_array();
	}

	/* - expr | NOT expr */

	else if (PATTERN_is(*current, RS_MINUS) || PATTERN_is(*current, RS_NOT))
	{
		pattern = current;
		current++;

		analyze_expr(RES_priority(RS_NOT), RS_UNARY);
		add_operator(PATTERN_index(*pattern), 1);
	}

	// . symbol

	else if (PATTERN_is(*current, RS_PT) && PATTERN_is_identifier(current[1]))
	{
		add_operator(PATTERN_index(current[0]), 0);
		add_pattern(PATTERN_set_flag(current[1], RT_POINT));
		current += 2;
	}

	// . [ ... ]

	else if (PATTERN_is(*current, RS_PT) && PATTERN_is(current[1], RS_LSQR))
	{
		add_operator(PATTERN_index(current[0]), 0);
		//add_pattern(PATTERN_set_flag(RS_RSQR, RT_POINT));
		current += 2;
		analyze_array();
	}

	// ! symbol

	else if (PATTERN_is(*current, RS_EXCL) && PATTERN_is_string(current[1]))
	{
		add_operator(RS_PT, 0);
		add_pattern(PATTERN_set_flag(current[1], RT_POINT));
		add_operator(RS_EXCL, 0);
		current += 2;
	}

	/* NULL, TRUE, FALSE, ME, PARENT, LAST, ERROR */
	/* number, string or symbol */

	else if (PATTERN_is(*current, RS_NULL)
					|| PATTERN_is(*current, RS_ME)
					|| PATTERN_is(*current, RS_LAST)
					|| PATTERN_is(*current, RS_TRUE)
					|| PATTERN_is(*current, RS_FALSE)
					|| PATTERN_is(*current, RS_PINF)
					|| PATTERN_is(*current, RS_MINF)
					|| PATTERN_is(*current, RS_ERROR)
					|| (!PATTERN_is_reserved(*current) && !PATTERN_is_newline(*current) && !PATTERN_is_end(*current)))
	{
		add_pattern(*current);

		if (PATTERN_is_identifier(*current))
		{
			/*if ((op == RS_NONE || op == RS_UNARY) && (PATTERN_is_identifier(*current)))
				change_last_pattern(1, PATTERN_set_flag(get_last_pattern(1), RT_FIRST));*/
			if (op == RS_PT)
			{
				change_last_pattern(1, PATTERN_set_flag(get_last_pattern(1), RT_POINT));
				check_last_first(2);
			}
		}

		current++;
	}

	else if (PATTERN_is(*current, RS_SUPER))
	{
		add_pattern(*current);
		current++;
		if (!PATTERN_is(*current, RS_PT)
				&& !PATTERN_is(*current, RS_EXCL)
				&& !PATTERN_is(*current, RS_LBRA)
				&& !PATTERN_is(*current, RS_LSQR))
			THROW("SUPER cannot be used alone");
	}

	else
	{
		if (jump_newline)
		{
			current--;
			JOB->line--;
		}

		THROW_UNEXPECTED(current);
	}
}
Esempio n. 12
0
static void analyze_make_array()
{
	int n = 0;
	bool checked = FALSE;
	bool collection = FALSE;

	/*if (PATTERN_is(*current, RS_RSQR))
	{
		current++;
		add_pattern(PATTERN_make(RT_RESERVED, RS_NULL));
		return;
	}*/

	if (!PATTERN_is(*current, RS_RSQR))
	{
		for(;;)
		{
			n++;
			/*if (n > MAX_PARAM_OP)
				THROW("Too many arguments");*/
			analyze_expr(0, RS_NONE);
			
			if (!checked)
			{
				collection = PATTERN_is(*current, RS_COLON);
				checked = TRUE;
			}
			
			if (collection)
			{
				if (!PATTERN_is(*current, RS_COLON))
					THROW(E_MISSING, "':'");
				current++;
				n++;
				/*if (n > MAX_PARAM_OP)
					THROW("Too many arguments");*/
				analyze_expr(0, RS_NONE);
			}
			
			if (!PATTERN_is(*current, RS_COMMA))
				break;

			current++;

			if (collection)
			{
				if (n == (MAX_PARAM_OP - 1))
				{
					add_operator(RS_COLON, MAX_PARAM_OP + 1);
					n = 0;
				}
			}
			else
			{
				if (n == MAX_PARAM_OP)
				{
					add_operator(RS_RSQR, MAX_PARAM_OP + 1);
					n = 0;
				}
			}
		}
	}

	if (!PATTERN_is(*current, RS_RSQR))
		THROW(E_MISSING, "']'");
	current++;

	add_operator(collection ? RS_COLON : RS_RSQR, n);
}
/*
    analyzing write statements of procedure
*/
void analyze_write(Stmt stmt, char* procName)
{
    getExprType(stmt->info.write, procName);
    analyze_expr(stmt->info.write, procName);
}