示例#1
0
int _zzt_board_limit_links(ZZTboard *brd, int max)
{
	int j, board_length;

	/* Fix link macro */
#define fixlink(link) if ((link) > max) (link) = 0;

	/* Fix board connections */
	fixlink(brd->info.board_n);
	fixlink(brd->info.board_s);
	fixlink(brd->info.board_e);
	fixlink(brd->info.board_w);

	/* Do the same for passages */
	if (!zztBoardDecompress(brd)) {
		fprintf(stderr, "Error decompressing board\n");
		return 0;
	}

	board_length = brd->bigboard->width * brd->bigboard->height;
	for (j = 0; j < board_length; j++) {
		if (brd->bigboard->tiles[j].type == ZZT_PASSAGE && brd->bigboard->tiles[j].param != NULL) {
			fixlink(brd->bigboard->tiles[j].param->data[2]);
		}
	}

	return 1;
}
示例#2
0
void procedure() {
    // assert: allocatedRegisters == 0

    // may be global variables but are anyway nicer like that
    int callBranches;
    int parameters;
    int localVariables;

    if (symbol == INTEGER) {
        getSymbol();

        if (symbol == ASTERISK)
            getSymbol();
    } else if (symbol == VOID)
        getSymbol();
    else
        syntaxError(PROCEDURE); // int expected!

    if (symbol == IDENTIFIER) {
        callBranches = setProcedureAddress();

        getSymbol();

        if (callBranches != codeLength)
            if (getOpcodeFromCode(callBranches) == BSR)
                fixlink(callBranches);
            else
                // procedure defined more than once!
                declarationError(PROCEDURE);

        if (symbol == LEFTPARENTHESIS) {
            getSymbol();

            parameters = 0;

            if (symbol != RIGHTPARENTHESIS) {
                declaration();

                parameters = 1;

                while (symbol == COMMA) {
                    getSymbol();

                    declaration();

                    parameters = parameters + 1;
                }

                // parameter offsets are only known here
                // when all parameters have been parsed!
                // thus enter offsets in local table now:

                // ...

                if (symbol == RIGHTPARENTHESIS)
                    getSymbol();
                else
                    syntaxError(PROCEDURE); // right parenthesis expected!
            } else
                getSymbol();
        } else
            syntaxError(PROCEDURE); // left parenthesis expected!

        if (symbol == SEMICOLON)
            getSymbol();
        else if (symbol == LEFTBRACES) {
            getSymbol();

            localVariables = 0;

            while (symbol == INT) {
                declaration();

                localVariables = localVariables + 1;

                if (symbol == SEMICOLON)
                    getSymbol();
                else
                    syntaxError(PROCEDURE); // semicolon expected!
            }

            // procedure prologue

            // save return address
            emit(PSH, LINK, SP, 4);

            // save caller's frame
            emit(PSH, FP, SP, 4);

            // allocate callee's frame
            emit(ADD, FP, ZR, SP);

            // allocate callee's local variables
            emit(SUBI, SP, SP, localVariables * 4);

            // create a fixup chain for return statements
            returnBranches = 0;

            while (symbol != RIGHTBRACES)
                statement();

            getSymbol();

            // procedure epilogue

            fixlink(returnBranches);

            // deallocate callee's frame and local variables
            emit(ADD, SP, ZR, FP);

            // restore caller's frame
            emit(POP, FP, SP, 4);

            // restore return address and deallocate parameters
            emit(POP, LINK, SP, parameters * 4 + 4);

            // return
            emit(RET, 0, 0, LINK);
        } else
            syntaxError(PROCEDURE); // semicolon or left braces expected!
    } else
        syntaxError(PROCEDURE); // identifier expected!

    // assert: allocatedRegisters == 0
}