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; }
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 }