mirror of
https://github.com/Museum-of-Art-and-Digital-Entertainment/macross.git
synced 2024-11-23 02:33:48 +00:00
665 lines
16 KiB
C
665 lines
16 KiB
C
/*
|
|
* Copyright (c) 1987 Fujitsu
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*/
|
|
/* WARNING: this file has not yet been separated into 6502 and non-6052 parts */
|
|
/*
|
|
encode.c -- Routines to encode expressions for Macross object files.
|
|
|
|
Chip Morningstar -- Lucasfilm Ltd.
|
|
|
|
8-November-1985
|
|
*/
|
|
|
|
#include "macrossTypes.h"
|
|
#include "macrossGlobals.h"
|
|
#include "y.tab.h"
|
|
#include "encode.h"
|
|
#include "debugPrint.h"
|
|
#include "errorStuff.h"
|
|
#include "parserMisc.h"
|
|
#include "semanticMisc.h"
|
|
#include "slinkyExpressions.h"
|
|
|
|
#define nullEncode(thing) if (thing==NULL) return(TRUE);
|
|
#define byteOp(op) ((op)-256)
|
|
|
|
bool encodingFunction;
|
|
|
|
bool
|
|
encodeByte(byte aByte)
|
|
{
|
|
if (expressionBufferSize < EXPRESSION_BUFFER_LIMIT) {
|
|
expressionBuffer[expressionBufferSize++] = aByte;
|
|
return(TRUE);
|
|
} else {
|
|
error(EXPRESSION_TOO_BIG_TO_FIT_IN_OBJECT_ERROR);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
bool
|
|
encodeBigword(int bigword)
|
|
{
|
|
int i;
|
|
for (i=0; i<sizeof(int); ++i) {
|
|
if (!encodeByte(bigword & 0xFF))
|
|
return(FALSE);
|
|
bigword >>= 8;
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
bool
|
|
encodeAssignmentTerm(binopTermType *assignmentTerm)
|
|
{
|
|
nullEncode(assignmentTerm);
|
|
if ((assignmentKindType)assignmentTerm->binop != ASSIGN_ASSIGN) {
|
|
error(FUNNY_ASSIGNMENT_KIND_IN_OBJECT_EXPRESSION_ERROR);
|
|
return(FALSE);
|
|
}
|
|
return(
|
|
encodeByte(BINOP_TAG) &&
|
|
encodeByte(byteOp(ASSIGN)) &&
|
|
encodeIdentifier(assignmentTerm->leftArgument) &&
|
|
encodeExpression(assignmentTerm->rightArgument)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeBinopTerm(binopTermType *binopTerm)
|
|
{
|
|
nullEncode(binopTerm);
|
|
return (
|
|
encodeByte(BINOP_TAG) &&
|
|
encodeByte(byteOp(binopTerm->binop)) &&
|
|
encodeExpression(binopTerm->leftArgument) &&
|
|
encodeExpression(binopTerm->rightArgument)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeCondition(conditionType condition)
|
|
{
|
|
return(
|
|
encodeByte(CONDITION_CODE_TAG) &&
|
|
encodeByte(condition)
|
|
);
|
|
}
|
|
|
|
int
|
|
functionNumber(functionDefinitionType *function)
|
|
{
|
|
if (function->ordinal == -1) {
|
|
function->ordinal = externalFunctionCount++;
|
|
if (externalFunctionList == NULL) {
|
|
externalFunctionList = endOfExternalFunctionList =
|
|
function;
|
|
} else {
|
|
endOfExternalFunctionList->nextExternalFunction =
|
|
function;
|
|
endOfExternalFunctionList = function;
|
|
}
|
|
}
|
|
return(function->ordinal);
|
|
}
|
|
|
|
bool
|
|
encodeFunctionCall(functionCallTermType *functionCall)
|
|
{
|
|
functionDefinitionType *theFunction;
|
|
int functionOrdinal;
|
|
symbolInContextType *workingContext;
|
|
operandListType *parameterList;
|
|
|
|
nullEncode(functionCall);
|
|
workingContext = getWorkingContext(functionCall->functionName);
|
|
if (isFunction(workingContext)) {
|
|
if (!encodeByte(FUNCTION_CALL_TAG))
|
|
return(FALSE);
|
|
theFunction = (functionDefinitionType *)workingContext->
|
|
value->value;
|
|
if (!encodeBigword(functionNumber(theFunction)))
|
|
return(FALSE);
|
|
} else if (isBuiltInFunction(workingContext)) {
|
|
functionOrdinal = workingContext->value->value;
|
|
if (builtInFunctionTable[functionOrdinal].isSpecialFunction)
|
|
return(encodeValue((*builtInFunctionTable[
|
|
functionOrdinal].functionEntry)(functionCall->
|
|
parameters, NO_FIXUP)));
|
|
if (!encodeByte(BUILTIN_FUNCTION_CALL_TAG))
|
|
return(FALSE);
|
|
if (builtInFunctionTable[functionOrdinal].ordinal < 0) {
|
|
error(BUILT_IN_FUNCTION_NOT_AVAILABLE_IN_OBJECT_ERROR,
|
|
builtInFunctionTable[functionOrdinal].
|
|
functionName);
|
|
return(FALSE);
|
|
} else if (!encodeBigword(builtInFunctionTable[
|
|
functionOrdinal].ordinal)) {
|
|
return(FALSE);
|
|
}
|
|
} else {
|
|
error(NOT_A_FUNCTION_ERROR, symbName(functionCall->
|
|
functionName));
|
|
return(FALSE);
|
|
}
|
|
parameterList = functionCall->parameters;
|
|
if (!encodeByte(countParameters(parameterList)))
|
|
return(FALSE);
|
|
while (parameterList != NULL)
|
|
if (!encodeOperand(parameterList))
|
|
return(FALSE);
|
|
else
|
|
parameterList = parameterList->nextOperand;
|
|
return(TRUE);
|
|
}
|
|
|
|
bool
|
|
encodeHere(void)
|
|
{
|
|
return(encodeByte(HERE_TAG));
|
|
}
|
|
|
|
bool
|
|
encodeIdentifier(symbolTableEntryType *identifier)
|
|
{
|
|
symbolInContextType *workingContext;
|
|
environmentType *saveEnvironment;
|
|
bool result;
|
|
|
|
nullEncode(identifier);
|
|
|
|
if (symbName(identifier)[0] == '$') {
|
|
error(TEMP_SYMBOL_IN_OBJECT_ERROR, symbName(identifier));
|
|
return(FALSE);
|
|
}
|
|
if (encodingFunction) {
|
|
return(encodeByte(IDENTIFIER_TAG) &&
|
|
encodeBigword(identifier->ordinal));
|
|
}
|
|
if ((workingContext = getWorkingContext(identifier)) == NULL) {
|
|
error(UNDEFINED_SYMBOL_ERROR, symbName(identifier));
|
|
return(FALSE);
|
|
}
|
|
if (workingContext->usage == FUNCTION_SYMBOL || workingContext->usage
|
|
== BUILT_IN_FUNCTION_SYMBOL) {
|
|
error(FUNCTION_IS_NOT_A_VALUE_ERROR, symbName(identifier));
|
|
return(FALSE);
|
|
}
|
|
if (workingContext->value == NULL) {
|
|
error(UNDEFINED_SYMBOL_ERROR, symbName(identifier));
|
|
return(FALSE);
|
|
}
|
|
if (workingContext->value->kindOfValue == UNDEFINED_VALUE) {
|
|
if (workingContext->attributes & GLOBAL_ATT) {
|
|
return(encodeByte(IDENTIFIER_TAG) &&
|
|
encodeBigword(identifier->ordinal));
|
|
} else {
|
|
error(UNDEFINED_SYMBOL_ERROR, symbName(identifier));
|
|
return(FALSE);
|
|
}
|
|
}
|
|
if (workingContext->value->kindOfValue == RELOCATABLE_VALUE) {
|
|
return(encodeByte(IDENTIFIER_TAG) &&
|
|
encodeBigword(identifier->ordinal));
|
|
}
|
|
if (workingContext->value->kindOfValue == FAIL) {
|
|
error(UNASSIGNED_SYMBOL_ERROR, symbName(identifier));
|
|
return(FALSE);
|
|
}
|
|
if (workingContext->value->kindOfValue == OPERAND_VALUE) {
|
|
saveEnvironment = currentEnvironment;
|
|
if (workingContext->usage == ARGUMENT_SYMBOL) {
|
|
currentEnvironment = currentEnvironment->
|
|
previousEnvironment;
|
|
}
|
|
result = encodeOperand(workingContext->value->value);
|
|
currentEnvironment = saveEnvironment;
|
|
return(result);
|
|
}
|
|
if (workingContext->value->kindOfValue == BLOCK_VALUE) {
|
|
error(BLOCK_OPERAND_IN_OBJECT_EXPRESSION_ERROR);
|
|
return(FALSE);
|
|
}
|
|
return(encodeValue(workingContext->value));
|
|
}
|
|
|
|
bool
|
|
encodeNumber(numberTermType number)
|
|
{
|
|
return(
|
|
encodeByte(NUMBER_TAG) &&
|
|
encodeBigword(number)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeRelocatableNumber(numberTermType number)
|
|
{
|
|
return(
|
|
encodeByte(RELOCATABLE_TAG) &&
|
|
encodeBigword(number)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeOperand(operandType *operand)
|
|
{
|
|
switch (operand->kindOfOperand) {
|
|
case EXPRESSION_OPND:
|
|
case IMMEDIATE_OPND:
|
|
case INDIRECT_OPND:
|
|
case POST_INDEXED_Y_OPND:
|
|
case PRE_INDEXED_X_OPND:
|
|
case X_INDEXED_OPND:
|
|
case Y_INDEXED_OPND:
|
|
return(encodeExpression(operand->theOperand.expressionUnion));
|
|
|
|
case A_REGISTER_OPND:
|
|
case X_REGISTER_OPND:
|
|
case Y_REGISTER_OPND:
|
|
error(REGISTER_OPERAND_IN_OBJECT_EXPRESSION_ERROR);
|
|
return(FALSE);
|
|
|
|
case X_SELECTED_OPND:
|
|
case Y_SELECTED_OPND:
|
|
case PRE_SELECTED_X_OPND:
|
|
error(SELECTION_OPERAND_IN_OBJECT_EXPRESSION_ERROR);
|
|
return(FALSE);
|
|
|
|
case STRING_OPND:
|
|
return(encodeString(operand->theOperand.stringUnion));
|
|
|
|
case BLOCK_OPND:
|
|
error(BLOCK_OPERAND_IN_OBJECT_EXPRESSION_ERROR);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
bool
|
|
encodePostopTerm(postOpTermType *postopTerm)
|
|
{
|
|
nullEncode(postopTerm);
|
|
return(
|
|
encodeByte(POSTOP_TAG) &&
|
|
encodeByte(byteOp(postopTerm->postOp)) &&
|
|
encodeExpression(postopTerm->postOpArgument)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodePreopTerm(preOpTermType *preopTerm)
|
|
{
|
|
nullEncode(preopTerm);
|
|
return(
|
|
encodeByte(PREOP_TAG) &&
|
|
encodeByte(byteOp(preopTerm->preOp)) &&
|
|
encodeExpression(preopTerm->preOpArgument)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeString(stringType *string)
|
|
{
|
|
if (!encodeByte(STRING_TAG))
|
|
return(FALSE);
|
|
while (*string != '\0') {
|
|
if (!encodeByte(*string++))
|
|
return(FALSE);
|
|
}
|
|
return(encodeByte('\0'));
|
|
}
|
|
|
|
bool
|
|
encodeUnopTerm(unopTermType *unopTerm)
|
|
{
|
|
nullEncode(unopTerm);
|
|
return(
|
|
encodeByte(UNOP_TAG) &&
|
|
encodeByte(byteOp(unopTerm->unop)) &&
|
|
encodeExpression(unopTerm->unopArgument)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeValue(valueType *value)
|
|
{
|
|
switch (value->kindOfValue) {
|
|
case ABSOLUTE_VALUE:
|
|
return(encodeNumber(value->value));
|
|
|
|
case RELOCATABLE_VALUE:
|
|
return(encodeRelocatableNumber(value->value));
|
|
|
|
case OPERAND_VALUE:
|
|
return(encodeOperand(value->value));
|
|
|
|
case STRING_VALUE:
|
|
return(encodeString(value->value));
|
|
|
|
case CONDITION_VALUE:
|
|
return(encodeCondition(value->value));
|
|
|
|
case DATA_VALUE:
|
|
case BSS_VALUE:
|
|
case STRUCT_VALUE:
|
|
case FIELD_VALUE:
|
|
case MACRO_VALUE:
|
|
case UNDEFINED_VALUE:
|
|
case FUNCTION_VALUE:
|
|
case BLOCK_VALUE:
|
|
case BUILT_IN_FUNCTION_VALUE:
|
|
case ARRAY_VALUE:
|
|
case FAIL:
|
|
error(WRONG_KIND_OF_VALUE_IN_OBJECT_EXPRESSION_ERROR,
|
|
valueKindString(value->kindOfValue));
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
bool
|
|
encodeExpression(expressionType *expression)
|
|
{
|
|
nullEncode(expression);
|
|
switch (expression->kindOfTerm) {
|
|
|
|
case ARRAY_EXPR:
|
|
error(ARRAY_TERM_IN_OBJECT_EXPRESSION_ERROR);
|
|
return(FALSE);
|
|
break;
|
|
|
|
case ASSIGN_EXPR:
|
|
return(encodeAssignmentTerm(expression->expressionTerm.binopUnion));
|
|
break;
|
|
|
|
case BINOP_EXPR:
|
|
return(encodeBinopTerm(expression->expressionTerm.binopUnion));
|
|
break;
|
|
|
|
case CONDITION_CODE_EXPR:
|
|
return(encodeCondition(expression->expressionTerm.conditionTypeUnion));
|
|
break;
|
|
|
|
case FUNCTION_CALL_EXPR:
|
|
return(encodeFunctionCall(expression->expressionTerm.functionCallUnion));
|
|
break;
|
|
|
|
case HERE_EXPR:
|
|
return(encodeHere());
|
|
break;
|
|
|
|
case IDENTIFIER_EXPR:
|
|
return(encodeIdentifier(expression->expressionTerm.identifierUnion));
|
|
break;
|
|
|
|
case NUMBER_EXPR:
|
|
return(encodeNumber(expression->expressionTerm.numberUnion));
|
|
break;
|
|
|
|
case POSTOP_EXPR:
|
|
return(encodePostopTerm(expression->expressionTerm.postOpUnion));
|
|
break;
|
|
|
|
case PREOP_EXPR:
|
|
return(encodePreopTerm(expression->expressionTerm.preOpUnion));
|
|
break;
|
|
|
|
case SUBEXPRESSION_EXPR:
|
|
encodeExpression(expression->expressionTerm.expressionUnion);
|
|
break;
|
|
|
|
case STRING_EXPR:
|
|
return(encodeString(expression->expressionTerm.stringUnion));
|
|
break;
|
|
|
|
case UNOP_EXPR:
|
|
return(encodeUnopTerm(expression->expressionTerm.unopUnion));
|
|
break;
|
|
|
|
case VALUE_EXPR:
|
|
return(encodeValue(expression->expressionTerm.valueUnion));
|
|
break;
|
|
|
|
default:
|
|
botch("encodeExpression: funny expression kind %d\n",
|
|
expression->kindOfTerm);
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool
|
|
encodeAssertStatement(assertStatementBodyType *assertStatement)
|
|
{
|
|
return(
|
|
encodeByte(ASSERT_TAG) &&
|
|
encodeExpression(assertStatement->condition) &&
|
|
encodeExpression(assertStatement->message)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeFreturnStatement(freturnStatementBodyType *freturnStatement)
|
|
{
|
|
return(
|
|
encodeByte(FRETURN_TAG) &&
|
|
encodeExpression(freturnStatement)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeMdefineStatement(defineStatementBodyType *mdefineStatement)
|
|
{
|
|
return(
|
|
encodeByte(MDEFINE_TAG) &&
|
|
encodeIdentifier(mdefineStatement->theSymbol) &&
|
|
encodeExpression(mdefineStatement->theValue)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeMdoUntilStatement(mdoUntilStatementBodyType *mdoUntilStatement)
|
|
{
|
|
return(
|
|
encodeByte(MDOUNTIL_TAG) &&
|
|
encodeExpression(mdoUntilStatement->mdoUntilCondition) &&
|
|
encodeBlock(mdoUntilStatement->mdoUntilLoop)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeMdoWhileStatement(mdoWhileStatementBodyType *mdoWhileStatement)
|
|
{
|
|
return(
|
|
encodeByte(MDOWHILE_TAG) &&
|
|
encodeExpression(mdoWhileStatement->mdoWhileCondition) &&
|
|
encodeBlock(mdoWhileStatement->mdoWhileLoop)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeMforStatement(mforStatementBodyType *mforStatement)
|
|
{
|
|
return(
|
|
encodeByte(MFOR_TAG) &&
|
|
encodeExpression(mforStatement->initExpression) &&
|
|
encodeExpression(mforStatement->testExpression) &&
|
|
encodeExpression(mforStatement->incrExpression) &&
|
|
encodeBlock(mforStatement->forLoop)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeMifStatement(mifStatementBodyType *mifStatement)
|
|
{
|
|
return(
|
|
encodeByte(MIF_TAG) &&
|
|
encodeExpression(mifStatement->mifCondition) &&
|
|
encodeBlock(mifStatement->mifConsequence) &&
|
|
encodeBlock(mifStatement->mifContinuation.mifBlockUnion)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeMswitchStatement(mswitchStatementBodyType *mswitchStatement)
|
|
{
|
|
caseListType *caseList;
|
|
caseType *theCase;
|
|
expressionListType *tagExpressionList;
|
|
|
|
if (!(encodeByte(MSWITCH_TAG) && encodeExpression(mswitchStatement->
|
|
switchExpression)))
|
|
return(FALSE);
|
|
for (caseList=mswitchStatement->cases; caseList!=NULL; caseList=caseList->
|
|
nextCase) {
|
|
theCase = caseList->theCase;
|
|
for (tagExpressionList=theCase->caseTags; tagExpressionList!=NULL;
|
|
tagExpressionList=tagExpressionList->nextExpression) {
|
|
if (!encodeExpression(tagExpressionList->theExpression))
|
|
return(FALSE);
|
|
}
|
|
if (!encodeBlock(theCase->caseBody))
|
|
return(FALSE);
|
|
}
|
|
return(encodeByte(END_TAG));
|
|
}
|
|
|
|
bool
|
|
encodeMvariableStatement(mvariableStatementBodyType *mvariableStatement)
|
|
{
|
|
int length;
|
|
|
|
if ((length=expressionListLength(mvariableStatement->theValue) > 1) ||
|
|
mvariableStatement->theDimension!=NULL) {
|
|
error(ARRAY_MVARIABLE_IN_OBJECT_FUNCTION_ERROR);
|
|
return(FALSE);
|
|
}
|
|
if (!(encodeByte(MVARIABLE_TAG) && encodeIdentifier(mvariableStatement->
|
|
theSymbol)))
|
|
return(FALSE);
|
|
if (length == 1)
|
|
return(encodeExpression(mvariableStatement->theValue->
|
|
theExpression));
|
|
else
|
|
return(encodeExpression(NULL));
|
|
}
|
|
|
|
bool
|
|
encodeMwhileStatement(mwhileStatementBodyType *mwhileStatement)
|
|
{
|
|
return(
|
|
encodeByte(MWHILE_TAG) &&
|
|
encodeExpression(mwhileStatement->mwhileCondition) &&
|
|
encodeBlock(mwhileStatement->mwhileLoop)
|
|
);
|
|
}
|
|
|
|
bool
|
|
encodeStatement(statementType *statement)
|
|
{
|
|
switch(statement->kindOfStatement) {
|
|
|
|
case ALIGN_STATEMENT:
|
|
case BLOCK_STATEMENT:
|
|
case BYTE_STATEMENT:
|
|
case CONSTRAIN_STATEMENT:
|
|
case DBYTE_STATEMENT:
|
|
case DEFINE_STATEMENT:
|
|
case DO_UNTIL_STATEMENT:
|
|
case DO_WHILE_STATEMENT:
|
|
case EXTERN_STATEMENT:
|
|
case FUNCTION_STATEMENT:
|
|
case IF_STATEMENT:
|
|
case INCLUDE_STATEMENT:
|
|
case INSTRUCTION_STATEMENT:
|
|
case LONG_STATEMENT:
|
|
case MACRO_STATEMENT:
|
|
case ORG_STATEMENT:
|
|
case REL_STATEMENT:
|
|
case START_STATEMENT:
|
|
case STRING_STATEMENT:
|
|
case STRUCT_STATEMENT:
|
|
case TARGET_STATEMENT:
|
|
case UNDEFINE_STATEMENT:
|
|
case VARIABLE_STATEMENT:
|
|
case WHILE_STATEMENT:
|
|
case WORD_STATEMENT:
|
|
error(ILLEGAL_STATEMENT_IN_OBJECT_FILE_FUNCTION_ERROR,
|
|
statementKindString(statement->kindOfStatement));
|
|
return(FALSE);
|
|
|
|
case ASSERT_STATEMENT:
|
|
return(encodeAssertStatement(statement->statementBody.assertUnion));
|
|
|
|
case FRETURN_STATEMENT:
|
|
return(encodeFreturnStatement(statement->statementBody.freturnUnion));
|
|
|
|
case GROUP_STATEMENT:
|
|
return(encodeBlock(statement->statementBody.groupUnion));
|
|
|
|
case MDEFINE_STATEMENT:
|
|
return(encodeMdefineStatement(statement->statementBody.defineUnion));
|
|
|
|
case MDO_UNTIL_STATEMENT:
|
|
return(encodeMdoUntilStatement(statement->statementBody.mdoUntilUnion));
|
|
|
|
case MDO_WHILE_STATEMENT:
|
|
return(encodeMdoWhileStatement(statement->statementBody.mdoWhileUnion));
|
|
|
|
case MFOR_STATEMENT:
|
|
return(encodeMforStatement(statement->statementBody.mforUnion));
|
|
|
|
case MIF_STATEMENT:
|
|
return(encodeMifStatement(statement->statementBody.mifUnion));
|
|
|
|
case MSWITCH_STATEMENT:
|
|
return(encodeMswitchStatement(statement->statementBody.mswitchUnion));
|
|
|
|
case MVARIABLE_STATEMENT:
|
|
return(encodeMvariableStatement(statement->statementBody.mvariableUnion));
|
|
|
|
case MWHILE_STATEMENT:
|
|
return(encodeMwhileStatement(statement->statementBody.mwhileUnion));
|
|
|
|
case NULL_STATEMENT:
|
|
return(TRUE);
|
|
|
|
case PERFORM_STATEMENT:
|
|
return(encodeExpression(statement->statementBody.expressionUnion));
|
|
|
|
default:
|
|
botch("encodeStatementBody doesn't know kind %d\n",
|
|
statement->kindOfStatement);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
bool
|
|
encodeBlock(blockType *block)
|
|
{
|
|
if (!encodeByte(BLOCK_TAG))
|
|
return(FALSE);
|
|
while (block != NULL) {
|
|
if (!encodeStatement(block))
|
|
return(FALSE);
|
|
block = block->nextStatement;
|
|
}
|
|
return(encodeByte(END_TAG));
|
|
}
|