📄 meridiandsl.cpp
字号:
return in_state->empty_token(); } thisNode->type = FOR_LOOP_TYPE; thisNode->val.for_val.for_node_1 = a; thisNode->val.for_val.for_node_2 = b; thisNode->val.for_val.for_node_3 = c; thisNode->val.for_val.for_node_4 = d; return thisNode;}ASTNode* mk_rpc(ParserState* in_state, ASTNode* dest, string* func_name, ASTNode* paramAST) { ASTNode* thisNode = in_state->get_var_table()->new_stack_ast(); if (thisNode == NULL) { return in_state->empty_token(); } thisNode->type = RPC_TYPE; thisNode->val.rpc_val.rpc_dest = dest; thisNode->val.rpc_val.rpc_func_name = func_name; // Func names should have global scope, so we can just pass the ptr thisNode->val.rpc_val.rpc_param = paramAST; return thisNode; }ASTNode* unmarshal_ast(ParserState* ps, BufferWrapper* bw) { ASTNode* in_node = ps->get_var_table()->new_stack_ast(); if (in_node == NULL) { return ps->empty_token(); } in_node->type = (ASTType)(ntohl(bw->retrieve_int())); switch (in_node->type) { case EMPTY_TYPE: { // Do nothing } break; case INT_TYPE: { in_node->val.i_val = ntohl(bw->retrieve_int()); } break; case DOUBLE_TYPE: { char* buf = const_cast<char*>(bw->retrieve_buf(sizeof(double))); if (bw->error()) { return ps->empty_token(); } XDR xdrsDecode; xdrmem_create(&xdrsDecode, buf, sizeof(double), XDR_DECODE); if (xdr_double(&xdrsDecode, &(in_node->val.d_val)) == 0) { return ps->empty_token(); } } break; case STRING_TYPE: { u_int string_size = ntohl(bw->retrieve_uint()); in_node->val.s_val = ps->get_var_table()->new_stack_string(); if (in_node->val.s_val == NULL) { return ps->empty_token(); } const char* buf = bw->retrieve_buf(string_size); if (bw->error()) { return ps->empty_token(); } in_node->val.s_val->append(buf, string_size); } break; case ARRAY_TYPE: { in_node->val.a_val.a_type = (ASTType)(ntohl(bw->retrieve_int())); // Retrieve string size u_int string_size = ntohl(bw->retrieve_uint()); if (string_size > 0 ) { string* tmp_string = ps->get_var_table()->new_stack_string(); if (tmp_string == NULL) { return ps->empty_token(); } // Retrieve string const char* buf = bw->retrieve_buf(string_size); if (bw->error()) { return ps->empty_token(); } tmp_string->append(buf, string_size); in_node->val.a_val.a_adt_name = tmp_string; } // Retrieve vector size u_int vector_size = ntohl(bw->retrieve_uint()); in_node->val.a_val.a_vector = ps->get_var_table()->new_stack_vector(); if (in_node->val.a_val.a_vector == NULL) { return ps->empty_token(); } for (u_int i = 0; i < vector_size; i++) { ASTNode* nextNode = unmarshal_ast(ps, bw); if (nextNode->type == EMPTY_TYPE) { return ps->empty_token(); } in_node->val.a_val.a_vector->push_back(nextNode); } } break; case VAR_ADT_TYPE: { // Retrieve string size u_int string_size = ntohl(bw->retrieve_uint()); string* tmp_string = ps->get_var_table()->new_stack_string(); if (tmp_string == NULL) { return ps->empty_token(); } // Retrieve string const char* buf = bw->retrieve_buf(string_size); if (bw->error()) { return ps->empty_token(); } tmp_string->append(buf, string_size); in_node->val.adt_val.adt_type_name = tmp_string; // Get map size u_int map_size = ntohl(bw->retrieve_uint()); // Create map in_node->val.adt_val.adt_map = ps->get_var_table()->new_stack_map(); if (in_node->val.adt_val.adt_map == NULL) { return ps->empty_token(); } for (u_int i = 0; i < map_size; i++) { u_int map_string_size = ntohl(bw->retrieve_uint()); // Retrieve string const char* map_buf = bw->retrieve_buf(map_string_size); if (bw->error()) { return ps->empty_token(); } string map_string(map_buf, map_string_size); ASTNode* map_node = unmarshal_ast(ps, bw); if (map_node->type == EMPTY_TYPE) { return ps->empty_token(); } (*(in_node->val.adt_val.adt_map))[map_string] = map_node; } } break; case SEP_TYPE: { // Retrieve vector size u_int vector_size = ntohl(bw->retrieve_uint()); // Create new stack vector in_node->val.p_val.p_vector = ps->get_var_table()->new_stack_vector(); if (in_node->val.p_val.p_vector == NULL) { return ps->empty_token(); } for (u_int i = 0; i < vector_size; i++) { ASTNode* nextNode = unmarshal_ast(ps, bw); if (nextNode->type == EMPTY_TYPE) { return ps->empty_token(); } in_node->val.p_val.p_vector->push_back(nextNode); } } break; default: DSL_ERROR("Cannot marshal non-base type AST\n"); return ps->empty_token(); } // Check if we encountered any error if (bw->error()) { return ps->empty_token(); } return in_node;}int marshal_ast(const ASTNode* in_node, RealPacket* in_packet) { // Append the type of the AST in_packet->append_int(htonl(in_node->type)); switch (in_node->type) { case EMPTY_TYPE: { // Do nothing } break; case INT_TYPE: { in_packet->append_int(htonl(in_node->val.i_val)); } break; case DOUBLE_TYPE: { // I don't know how to encode DOUBLEs, so I'm going to use XDR XDR xdrsEncode; char buf[sizeof(double)]; xdrmem_create(&xdrsEncode, buf, sizeof(double), XDR_ENCODE); double tmpDouble = in_node->val.d_val; // For const reasons //if (xdr_double(&xdrsEncode, &(in_node->val.d_val)) == 0) { if (xdr_double(&xdrsEncode, &(tmpDouble)) == 0) { return -1; } in_packet->append_str(buf, sizeof(double)); } break; case STRING_TYPE: { u_int string_size = in_node->val.s_val->size(); in_packet->append_uint(htonl(string_size)); in_packet->append_str(in_node->val.s_val->c_str(), string_size); } break; case ARRAY_TYPE: { // Array entries type in_packet->append_int(htonl(in_node->val.a_val.a_type)); // String length and adt string if (in_node->val.a_val.a_type == ADT_TYPE) { u_int string_size = in_node->val.a_val.a_adt_name->size(); in_packet->append_uint(htonl(string_size)); in_packet->append_str(in_node->val.a_val.a_adt_name->c_str(), string_size); } else { in_packet->append_uint(htonl(0)); } // Vector length and entries in vector u_int vector_size = in_node->val.a_val.a_vector->size(); in_packet->append_uint(htonl(vector_size)); for (u_int i = 0; i < vector_size; i++) { if (marshal_ast( (*(in_node->val.a_val.a_vector))[i], in_packet) == -1) { DSL_ERROR("Error marshaling ast #%d\n", i); return -1; } } } break; case VAR_ADT_TYPE: { // String length and adt string u_int string_size = in_node->val.adt_val.adt_type_name->size(); in_packet->append_uint(htonl(string_size)); in_packet->append_str(in_node->val.adt_val.adt_type_name->c_str(), string_size); // NOTE: adt_param does NOT need to me marshalled, as it is // used in ADT_TYPE, not VAR_ADT_TYPE // Map size and entries in map u_int map_size = in_node->val.adt_val.adt_map->size(); in_packet->append_uint(htonl(map_size)); map<string, ASTNode*>::iterator map_it = in_node->val.adt_val.adt_map->begin(); for (; map_it != in_node->val.adt_val.adt_map->end(); map_it++) { u_int map_str_size = (map_it->first).size(); in_packet->append_uint(htonl(map_str_size)); in_packet->append_str((map_it->first).c_str(), map_str_size); if (marshal_ast(map_it->second, in_packet) == -1) { DSL_ERROR("Error marshaling ast\n"); return -1; } } } break; case SEP_TYPE: { // Vector length and entries in vector (note unsigned int) u_int vector_size = in_node->val.p_val.p_vector->size(); in_packet->append_uint(htonl(vector_size)); for (u_int i = 0; i < vector_size; i++) { if (marshal_ast( (*(in_node->val.p_val.p_vector))[i], in_packet) == -1) { return -1; } } } break; default: DSL_ERROR("Cannot marshal non-base type AST\n"); return -1; } // See if any error occured during packet construction if (!(in_packet->completeOkay())) { DSL_ERROR("marshal_ast: packet too small for ast\n"); return -1; } return 0; }int arrayLargestOffset(ASTType type, const vector<ASTNode*>* curVect, int* offset) { // Empty INT or DOUBLE array gets offset of -1 if ((type == INT_TYPE || type == DOUBLE_TYPE) && curVect->size() == 0) { *offset = -1; return 0; } if (type == INT_TYPE) { int maxValue = INT_MIN; *offset = 0; for (u_int i = 0; i < curVect->size(); i++) { ASTNode* curVectNode = (*curVect)[i]; if (curVectNode->type != INT_TYPE) { DSL_ERROR("Ill-formed array\n"); return -1; } if (curVectNode->val.i_val > maxValue) { maxValue = curVectNode->val.i_val; *offset = i; } } return 0; } else if (type == DOUBLE_TYPE) { double maxValue = -INFINITY; *offset = 0; for (u_int i = 0; i < curVect->size(); i++) { ASTNode* curVectNode = (*curVect)[i]; if (curVectNode->type != DOUBLE_TYPE) { DSL_ERROR("Ill-formed array\n"); return -1; } if (curVectNode->val.d_val > maxValue) { maxValue = curVectNode->val.d_val; *offset = i; } } return 0; } DSL_ERROR("Array type must be int or double\n"); return -1; }int arraySmallestOffset(ASTType type, const vector<ASTNode*>* curVect, int* offset) { // Empty INT or DOUBLE array gets offset of -1 if ((type == INT_TYPE || type == DOUBLE_TYPE) && curVect->size() == 0) { *offset = -1; return 0; } if (type == INT_TYPE) { int minValue = INT_MAX; *offset = 0; for (u_int i = 0; i < curVect->size(); i++) { ASTNode* curVectNode = (*curVect)[i]; if (curVectNode->type != INT_TYPE) { DSL_ERROR("Ill-formed array\n"); return -1; } if (curVectNode->val.i_val < minValue) { minValue = curVectNode->val.i_val; *offset = i; } } return 0; } else if (type == DOUBLE_TYPE) { double minValue = INFINITY; *offset = 0; for (u_int i = 0; i < curVect->size(); i++) { ASTNode* curVectNode = (*curVect)[i]; if (curVectNode->type != DOUBLE_TYPE) { DSL_ERROR("Ill-formed array\n"); return -1; } if (curVectNode->val.d_val < minValue) { minValue = curVectNode->val.d_val; *offset = i; } } return 0; } DSL_ERROR("Array type must be int or double\n"); return -1; }int uniqueAdd(ParserState* ps, vector<ASTNode*>* retVect, const ASTNode* in_node) { for (u_int i = 0; i < retVect->size(); i++) { if (ADTEqual(in_node, (*retVect)[i])) { return 0; } } ASTNode* tmpNode = ADTCreateAndCopy(ps, in_node); if (tmpNode->type == EMPTY_TYPE) { return -1; } retVect->push_back(tmpNode); return 0; }int uniqueAdd(ParserState* ps, vector<ASTNode*>* retVect, const vector<ASTNode*>* in_vect) { for (u_int i = 0; i < in_vect->size(); i++) { if (uniqueAdd(ps, retVect, (*in_vect)[i]) == -1) { return -1; } } return 0;}int unmarshal_packet(ParserState& ps, BufferWrapper& bw) { // Actual program text size uLongf prog_size = ntohl(bw.retrieve_uint());#define MAX_PROGRAM_SIZE 10000 if (prog_size > MAX_PROGRAM_SIZE) { DSL_ERROR("unmarshal_packet: received program size too large\n"); return -1; } // Compressed size store in packet u_int comp_prog_size = ntohl(bw.retrieve_uint()); //const char* buf = bw.retrieve_buf(prog_size); const char* buf = bw.retrieve_buf(comp_prog_size); if (bw.error()) { return -1; } // Retrieve function name that will be called u_int string_size = ntohl(bw.retrieve_uint()); const char* func_name = bw.retrieve_buf(string_size); if (bw.error()) { return -1; } ps.set_func_string(func_name); // Set func name to be called ps.set_param(unmarshal_ast(&ps, &bw)); // Unmarshal parameters // Allocate temp buffer char* tmpCompBuf = (char*)malloc(prog_size); if (tmpCompBuf == NULL) { DSL_ERROR("Cannot allocate temporary decompress buffer\n"); return -1; } if (uncompress((Bytef*)tmpCompBuf, (uLongf*)&prog_size, (Bytef*)buf, comp_prog_size) != Z_OK) { DSL_ERROR("zlib decompression failed\n"); free(tmpCompBuf); return -1; } // Copy program over to separate buffer if (ps.input_buffer.create_buffer(prog_size) == -1) { DSL_ERROR("Cannot create buffer\n"); free(tmpCompBuf); return -1; } //memcpy(ps.input_buffer.get_raw_buf(), buf, prog_size); memcpy(ps.input_buffer.get_raw_buf(), tmpCompBuf, prog_size); free(tmpCompBuf); // Done with buffer //ps.input_buffer.delete_buffer(); return 0;}ASTNode* evalNativeFunctions( ParserState* ps, ASTNode* cur_node, int recurse_count) { switch (cur_node->val.n_val.n_type) { case ROUND: { ASTNode* nextNode = eval(ps, cur_node->val.n_val.n_param_1, recurse_count + 1); if (nextNode->type != DOUBLE_TYPE) { DSL_ERROR("Double type expected\n"); return ps->empty_token(); } ASTNode* ret = mk_int(ps, lrint(nextNode->val.d_val));/* if (ret == NULL) { DSL_ERROR("Out of memory\n"); ret = ps->empty_token(); }*/ return ret; } case CEIL: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -