void encodeSubscripts (bcSubscript *subscript, outputWriter *ow) { while (subscript != 0) { if (subscript->type == BYTECODE_SUBSCRIPT_LIST) { OUT_CHAR(ow, '['); } else { OUT_CHAR(ow, '{'); } encodeBytecode(subscript->bc, ow); if (subscript->type == BYTECODE_SUBSCRIPT_LIST) { OUT_CHAR(ow, ']'); } else { OUT_CHAR(ow, '}'); } subscript = subscript->next; } }
void builtInSame (int numArgs, macroArgument *args, environment *env, outputWriter *ow) { if (!(numArgs == 2)) { issueError(ERRMAC_WRONG_NUM_ARGS, "same"); return; } if (args[0].value.needCopy || args[1].value.needCopy) { OUT_CHAR(ow, '0'); } else { if (valueAreSame(args[0].value.value, args[1].value.value)) { OUT_CHAR(ow, '1'); } else { OUT_CHAR(ow, '0'); } } }
void outCharXfer(char c) { // If we're sending a character that needs escaping, then escape it. OUT_CHAR(c); if (c == CMD_TOKEN) OUT_CHAR(ESCAPED_CMD); }
void encodeDynstring (dynstring *ds, outputWriter *ow) { int i; OUT_CHAR(ow, metaChar); OUT_CHAR(ow, '\''); for (i = 0; i < ds->length; ++i) { char c = ds->data[i]; if (c == '\'' || c == quoteChar) OUT_CHAR(ow, quoteChar); OUT_CHAR(ow, c); } OUT_CHAR(ow, '\''); }
void builtInEqual (int numArgs, macroArgument *args, environment *env, outputWriter *ow) { if (!(numArgs == 2)) { issueError(ERRMAC_WRONG_NUM_ARGS, "equal"); return; } if (valueAreEqual(args[0].value.value, args[1].value.value)) { OUT_CHAR(ow, '1'); } else { OUT_CHAR(ow, '0'); } }
void specifyVar(uint u_varIndex, volatile void* pv_data, uint u_size, BOOL b_isWriteable, char* psz_format, char* psz_name, char* psz_desc) { uint u_len; // Make sure this variable exists ASSERTM("specifyVar:indexTooHigh", u_varIndex < NUM_XFER_VARS); // Make sure the data isn't NULL ASSERTM("specifyVar:nullData", pv_data != NULL); // Make sure the size is valid ASSERTM("specifyVar:invalidSize", (u_size > 0) && (u_size <= 256)); // Update data structure xferVar[u_varIndex].pu8_data = (uint8_t*) pv_data; xferVar[u_varIndex].u8_size = u_size - 1; assignBit(u_varIndex, b_isWriteable); // Send a command OUT_CHAR(CMD_TOKEN); // Send a specification: The spec code, index, then length outCharXfer(b_isWriteable ? CMD_SEND_RECEIVE_VAR : CMD_SEND_ONLY); outCharXfer(u_varIndex); // Include the space taken by the three NULL characters, minus one since a // length of 1 is sent as 0, plus one for the variable size byte. u_len = strlen(psz_format) + strlen(psz_name) + strlen(psz_desc) + 3 - 1 + 1; // Allow a maximum string length of 255. outCharXfer(u_len <= 255 ? u_len : 255); // Send the size of this variable, minus 1 since a size of 1 is sent as a 0. outCharXfer(u_size - 1); // Send the strings u_len = 1; do { if (u_len++ > 256) return; outCharXfer(*psz_format); } while (*psz_format++); do { if (u_len++ > 256) return; outCharXfer(*psz_name); } while (*psz_name++); do { if (u_len++ > 256) return; outCharXfer(*psz_desc); } while (*psz_desc++); }
void sendVar(uint u_varIndex) { XFER_VAR* pXferVar; uint8_t u8_size; uint8_t* pu8_data; // Make sure this variable exists ASSERTM("sendVar:indexTooHigh", u_varIndex < NUM_XFER_VARS); // Note: The MS C compiler flags the statement // XFER_VAR* pXferVar = xferVar + u_varIndex; // as an error. It's OK in MS C++. Apparently, the C compiler doesn't // support the newer C99 syntax. Therefore, u8_size and pu8_data are // also declared above. pXferVar = xferVar + u_varIndex; ASSERTM("sendVar:indexNotSpecified", pXferVar->pu8_data != NULL); // Make sure it's read/write (PC only) #ifndef __PIC__ ASSERTM("sendVar:notWriteable", isVarWriteable(u_varIndex)); #endif // Send a command OUT_CHAR(CMD_TOKEN); // Send short/long var info u8_size = pXferVar->u8_size; if ((u8_size + 1) > SHORT_VAR_MAX_LEN) { // Send a long var: The long var code, index, then length outCharXfer(CMD_LONG_VAR); outCharXfer(u_varIndex); outCharXfer(u8_size); } else { // Send a short var outCharXfer((u_varIndex << VAR_SIZE_BITS) | u8_size); } // Send data pu8_data = pXferVar->pu8_data; do { outCharXfer(*pu8_data++); } while (u8_size--); }
void encodeValue (value *theValue, outputWriter *ow) { assert(theValue != 0); switch (theValue->type) { case VALUE_UNDEFINED : return; case VALUE_INTERNAL : OUT_STRING(ow, "<internal>", 10); break; case VALUE_BUILT_IN : OUT_STRING(ow, "<builtIn>", 9); break; case VALUE_SCALAR : encodeDynstring(&theValue->v.scalar.scalar, ow); break; case VALUE_LIST : { int i; OUT_CHAR(ow, metaChar); OUT_STRING(ow, "list(", 5); if (valueListLength(theValue) > 0) { encodeValue(valueListGetElement(theValue, 0), ow); for (i = 1; i < valueListLength(theValue); ++i) { OUT_CHAR(ow, ','); encodeValue(valueListGetElement(theValue, i), ow); } } OUT_CHAR(ow, ')'); } break; case VALUE_HASH : { value *aValue, *keyValue; char *aKey; hstate state; OUT_CHAR(ow, metaChar); OUT_STRING(ow, "hash(", 5); state = hash_state(theValue->v.hash.hash); if ((aValue = (value*)hash_next(&state, &aKey)) != 0) { keyValue = valueNewScalarFromCString(aKey); encodeValue(keyValue, ow); OUT_CHAR(ow, ','); encodeValue(aValue, ow); while ((aValue = (value*)hash_next(&state, &aKey)) != 0) { OUT_CHAR(ow, ','); keyValue = valueNewScalarFromCString(aKey); encodeValue(keyValue, ow); OUT_CHAR(ow, ','); encodeValue(aValue, ow); } } OUT_CHAR(ow, ')'); } break; case VALUE_LAMBDA : { int i; OUT_CHAR(ow, metaChar); OUT_STRING(ow, "lambda(", 7); for (i = 0; i < theValue->v.lambda.numParams; ++i) { encodeDynstring(&theValue->v.lambda.paramNames[i], ow); OUT_CHAR(ow, ','); } encodeBytecode(theValue->v.lambda.code, ow); OUT_CHAR(ow, ')'); } break; case VALUE_ENVIRONMENT : OUT_STRING(ow, "<environment>", 13); break; case VALUE_BYTECODE : OUT_STRING(ow, "<bytecode>", 10); break; case VALUE_WHATSIT : OUT_STRING(ow, "<whatsit>", 9); break; default : assert(0); } }
void encodeBytecode (bytecode *bc, outputWriter *ow) { while (bc != 0) { switch (bc->type) { case BYTECODE_STRING : case BYTECODE_QUOTED_STRING : encodeDynstring(&bc->v.string.string, ow); break; case BYTECODE_EVAL : OUT_CHAR(ow, metaChar); OUT_CHAR(ow, '{'); encodeBytecode(bc->v.eval.bc, ow); OUT_CHAR(ow, '}'); break; case BYTECODE_ARITH : OUT_CHAR(ow, metaChar); OUT_CHAR(ow, '['); encodeBytecode(bc->v.arith.bc, ow); OUT_CHAR(ow, ']'); break; case BYTECODE_ASSIGNMENT : { bcSubscript *subscript; OUT_CHAR(ow, metaChar); OUT_CHAR(ow, '<'); if (bc->v.assignment.modify) OUT_CHAR(ow, '&'); encodeBytecode(bc->v.assignment.varName, ow); encodeSubscripts(bc->v.assignment.subscript, ow); OUT_CHAR(ow, '='); encodeBytecode(bc->v.assignment.newValue, ow); OUT_CHAR(ow, '>'); } break; case BYTECODE_MACRO : { bcSubscript *subscript; OUT_CHAR(ow, metaChar); OUT_CHAR(ow, '<'); if (bc->v.macro.flags & BYTECODE_MACRO_BYREF) OUT_CHAR(ow, '&'); if (bc->v.macro.flags & BYTECODE_MACRO_SUBVALUE) OUT_CHAR(ow, '('); encodeBytecode(bc->v.macro.nameOrValue, ow); if (bc->v.macro.flags & BYTECODE_MACRO_SUBVALUE) OUT_CHAR(ow, ')'); encodeSubscripts(bc->v.macro.subscript, ow); if (bc->v.macro.numArgs >= 0) { bcArgument *argument; OUT_CHAR(ow, '('); for (argument = bc->v.macro.arguments; argument != 0; argument = argument->next) { encodeBytecode(argument->bc, ow); if (argument->next != 0) { OUT_CHAR(ow, ','); } } OUT_CHAR(ow, ')'); } OUT_CHAR(ow, '>'); } break; } bc = bc->next; } }