📄 meridiandsl.cpp
字号:
switch (nextNode->val.a_val.a_type) { case INT_TYPE: { if (offset == -1) { return mk_int(ps, INT_MIN); } return mk_int(ps, (*curVect)[offset]->val.i_val); } case DOUBLE_TYPE: { if (offset == -1) { return mk_double(ps, -INFINITY); } return mk_double(ps, (*curVect)[offset]->val.d_val); } default: break; } return ps->empty_token(); } case ARRAY_MIN: { ASTNode* nextNode = eval(ps, cur_node->val.n_val.n_param_1, recurse_count + 1); if (nextNode->type != ARRAY_TYPE) { DSL_ERROR("Array type expected\n"); return ps->empty_token(); } vector<ASTNode*>* curVect = nextNode->val.a_val.a_vector; int offset = 0; if (arraySmallestOffset( nextNode->val.a_val.a_type, curVect, &offset) == -1) { return ps->empty_token(); } if (offset >= (int)(curVect->size())) { return ps->empty_token(); } // This should not be possible switch (nextNode->val.a_val.a_type) { case INT_TYPE: { if (offset == -1) { return mk_int(ps, INT_MAX); } return mk_int(ps, (*curVect)[offset]->val.i_val); } case DOUBLE_TYPE: { if (offset == -1) { return mk_double(ps, INFINITY); } return mk_double(ps, (*curVect)[offset]->val.d_val); } default: break; } return ps->empty_token(); } case ARRAY_UNION: { ASTNode* nextNode_1 = eval(ps, cur_node->val.n_val.n_param_1, recurse_count + 1); ASTNode* nextNode_2 = eval(ps, cur_node->val.n_val.n_param_2, recurse_count + 1); if (nextNode_1->type != ARRAY_TYPE) { DSL_ERROR("Array type expected\n"); return ps->empty_token(); } if (nextNode_1->type != nextNode_2->type) { DSL_ERROR("Arrays must be of the same type\n"); return ps->empty_token(); } if (nextNode_1->val.a_val.a_type == ADT_TYPE) { if (*(nextNode_1->val.a_val.a_adt_name) != *(nextNode_2->val.a_val.a_adt_name)) { DSL_ERROR("Arrays must be of the same type\n"); return ps->empty_token(); } } // Create return array ASTNode* retVar = ASTCreate(ps, ARRAY_TYPE, nextNode_1->val.a_val.a_adt_name, nextNode_1->val.a_val.a_type, 0); if (retVar->type == EMPTY_TYPE) { return ps->empty_token(); } vector<ASTNode*>* retVect = retVar->val.a_val.a_vector; if (uniqueAdd(ps, retVect, nextNode_1->val.a_val.a_vector) == -1) { return ps->empty_token(); } if (uniqueAdd(ps, retVect, nextNode_2->val.a_val.a_vector) == -1) { return ps->empty_token(); } return retVar; } default: { DSL_ERROR("Unexpected native function called\n"); } } return ps->empty_token();}void addGlobalModule(ParserState* ps) { string* adt_name = NULL; string* fields_1 = NULL; string* fields_2 = NULL; string* fields_3 = NULL; string* fields_4 = NULL; string* fields_5 = NULL; ASTNode* adt_fields = NULL; // Set struct name if ((adt_name = ps->get_var_table()->new_stack_string()) == NULL) return; *adt_name = "Node"; // Name of struct fields if ((fields_1 = ps->get_var_table()->new_stack_string()) == NULL) return; *fields_1 = "addr"; if ((fields_2 = ps->get_var_table()->new_stack_string()) == NULL) return; *fields_2 = "port"; if ((fields_3 = ps->get_var_table()->new_stack_string()) == NULL) return; *fields_3 = "rendvAddr"; if ((fields_4 = ps->get_var_table()->new_stack_string()) == NULL) return; *fields_4 = "rendvPort"; // Create fields AST adt_fields = mk_sep_list(ps, mk_new_var(ps, INT_TYPE, fields_1)); adt_fields->val.p_val.p_vector->push_back( mk_new_var(ps, INT_TYPE, fields_2)); adt_fields->val.p_val.p_vector->push_back( mk_new_var(ps, INT_TYPE, fields_3)); adt_fields->val.p_val.p_vector->push_back( mk_new_var(ps, INT_TYPE, fields_4)); // Add ADT to ps eval(ps, mk_adt(ps, adt_name, adt_fields), 0); // Set struct name if ((adt_name = ps->get_var_table()->new_stack_string()) == NULL) return; *adt_name = "Measurement"; // Name of struct fields if ((fields_1 = ps->get_var_table()->new_stack_string()) == NULL) return; *fields_1 = "addr"; if ((fields_2 = ps->get_var_table()->new_stack_string()) == NULL) return; *fields_2 = "port"; if ((fields_3 = ps->get_var_table()->new_stack_string()) == NULL) return; *fields_3 = "rendvAddr"; if ((fields_4 = ps->get_var_table()->new_stack_string()) == NULL) return; *fields_4 = "rendvPort"; if ((fields_5 = ps->get_var_table()->new_stack_string()) == NULL) return; //*fields_5 = "latency_ms"; *fields_5 = "distance"; // Create fields AST adt_fields = mk_sep_list(ps, mk_new_var(ps, INT_TYPE, fields_1)); adt_fields->val.p_val.p_vector->push_back( mk_new_var(ps, INT_TYPE, fields_2)); adt_fields->val.p_val.p_vector->push_back( mk_new_var(ps, INT_TYPE, fields_3)); adt_fields->val.p_val.p_vector->push_back( mk_new_var(ps, INT_TYPE, fields_4)); adt_fields->val.p_val.p_vector->push_back( mk_new_var_array(ps, DOUBLE_TYPE, fields_5, mk_int(ps, 0))); // Add ADT to ps eval(ps, mk_adt(ps, adt_name, adt_fields), 0); }int fillNodeIdentField( const char* in_string, const map<string, ASTNode*>* inMap, int32_t* val) { map<string, ASTNode*>::const_iterator findIt = inMap->find(in_string); if (findIt == inMap->end() || findIt->second->type != INT_TYPE) { return -1; } *val = findIt->second->val.i_val; return 0;}int createNodeIdent(ASTNode* in_ast, NodeIdentRendv* in_NodeIdent) { if (in_ast->type != VAR_ADT_TYPE) { return -1; } if (*(in_ast->val.adt_val.adt_type_name) != "Node") { return -1; } int32_t tmpVal; if (fillNodeIdentField("addr", in_ast->val.adt_val.adt_map, &tmpVal) == -1) { return -1; } in_NodeIdent->addr = (uint32_t)tmpVal; if (fillNodeIdentField("port", in_ast->val.adt_val.adt_map, &tmpVal) == -1) { return -1; } in_NodeIdent->port = (uint16_t)tmpVal; if (fillNodeIdentField("rendvAddr", in_ast->val.adt_val.adt_map, &tmpVal) == -1) { return -1; } in_NodeIdent->addrRendv = (uint32_t)tmpVal; if (fillNodeIdentField("rendvPort", in_ast->val.adt_val.adt_map, &tmpVal) == -1) { return -1; } in_NodeIdent->portRendv = (uint16_t)tmpVal; return 0;}// Returns empty on errorASTNode* createNodeIdent(ParserState* ps, const NodeIdentRendv& in_ident) { string adtName = "Node"; // Lookup ADT ASTNode* adtNode = NULL; if (ps->get_var_table()->lookup(adtName, &adtNode) == -1 || adtNode->type != ADT_TYPE) { DSL_ERROR("Cannot find specified ADT\n"); return ps->empty_token(); } ASTNode* retVar = ASTCreate(ps, ADT_TYPE, &adtName, VOID_TYPE, 0); if (retVar->type == EMPTY_TYPE) { return ps->empty_token(); } vector<ASTNode*>* tmpList = adtNode->val.adt_val.adt_param->val.p_val.p_vector; for (u_int i = 0; i < tmpList->size(); i++) { ASTNode* field_node = (*tmpList)[i]; string* curField = field_node->val.v_val.v_name; map<string, ASTNode*>::iterator it = retVar->val.adt_val.adt_map->find(*curField); if (it == retVar->val.adt_val.adt_map->end()) { DSL_ERROR("Cannot find required field type in Node\n"); return ps->empty_token(); } ASTNode* tmpNode = it->second; if (tmpNode->type != INT_TYPE) { DSL_ERROR("Field of unexpected type\n"); return ps->empty_token(); } if (*curField == "addr") { tmpNode->val.i_val = in_ident.addr; } else if (*curField == "port") { tmpNode->val.i_val = in_ident.port; } else if (*curField == "rendvAddr") { tmpNode->val.i_val = in_ident.addrRendv; } else if (*curField == "rendvPort") { tmpNode->val.i_val = in_ident.portRendv; } else { DSL_ERROR("Unexpected field\n"); return ps->empty_token(); } } return retVar;}// Returns empty on errorASTNode* createNodeIdentLat(ParserState* ps, const NodeIdentRendv& in_ident, const uint32_t* lat_us, u_int lat_size) { string adtName = "Measurement"; // Lookup ADT ASTNode* adtNode = NULL; if (ps->get_var_table()->lookup(adtName, &adtNode) == -1 || adtNode->type != ADT_TYPE) { DSL_ERROR("Cannot find specified ADT\n"); return ps->empty_token(); } ASTNode* retVar = ASTCreate(ps, ADT_TYPE, &adtName, VOID_TYPE, 0); if (retVar->type == EMPTY_TYPE) { return ps->empty_token(); } vector<ASTNode*>* tmpList = adtNode->val.adt_val.adt_param->val.p_val.p_vector; for (u_int i = 0; i < tmpList->size(); i++) { ASTNode* field_node = (*tmpList)[i]; string* curField = field_node->val.v_val.v_name; map<string, ASTNode*>::iterator it = retVar->val.adt_val.adt_map->find(*curField); if (it == retVar->val.adt_val.adt_map->end()) { DSL_ERROR( "Cannot find required field type in Measurement\n"); return ps->empty_token(); } ASTNode* tmpNode = it->second; if (tmpNode->type == INT_TYPE) { if (*curField == "addr") { tmpNode->val.i_val = in_ident.addr; } else if (*curField == "port") { tmpNode->val.i_val = in_ident.port; } else if (*curField == "rendvAddr") { tmpNode->val.i_val = in_ident.addrRendv; } else if (*curField == "rendvPort") { tmpNode->val.i_val = in_ident.portRendv; } else { DSL_ERROR("Unexpected field\n"); return ps->empty_token(); } } else if (tmpNode->type == ARRAY_TYPE && tmpNode->val.a_val.a_type == DOUBLE_TYPE) { //if (*curField == "latency_ms") { if (*curField == "distance") { //for (u_int j = 0; j < lat_us.size(); j++) { for (u_int j = 0; j < lat_size; j++) { ASTNode* tmpDoubleNode = ASTCreate(ps, DOUBLE_TYPE, NULL, VOID_TYPE, 0); if (tmpDoubleNode->type == EMPTY_TYPE) { return ps->empty_token(); } // Lat contains latency in us, where distance is in ms //tmpDoubleNode->val.d_val = (lat_us[j] / 1000.0); tmpDoubleNode->val.d_val = (*(lat_us + j) / 1000.0); tmpNode->val.a_val.a_vector->push_back(tmpDoubleNode); } } } else { DSL_ERROR("Unexpected field\n"); return ps->empty_token(); } } return retVar;}void jmp_eval(ParserState* ps) { // Evaluate global variables ps->allocateEvalCount(-1); // -1 means no limit // Global structs implemented in the language are added in here addGlobalModule(ps); // Add global structures and functions eval(ps, ps->get_start(), 0); ASTNode* main_node; if (ps->get_var_table()->lookup( *(ps->get_func_string()), &main_node) == -1) { DSL_ERROR("No main function found\n"); } else { // Set actual parameter main_node->val.f_val.f_actual_param = ps->get_param(); ps->allocateEvalCount(10000); ASTNode* this_node = eval(ps, main_node, 0); ps->setQueryReturn(this_node); } ps->set_parser_state(PS_DONE); setcontext(&global_env_thread);}ASTNode* eval(ParserState* ps, ASTNode* cur_node, int recurse_count) { if (recurse_count > MAX_RECURSE_COUNT) { DSL_ERROR("Maximum recurse count reached\n"); return ps->empty_token(); } if (ps->getEvalCount() != -1) { while (ps->getEvalCount() == 0) { ps->set_parser_state(PS_READY); swapcontext(ps->get_context(), &global_env_thread); } ps->decrementEvalCount(); } ps->set_parser_state(PS_RUNNING); // Determine what type of instruction is being evaluated switch(cur_node->type) { case EMPTY_TYPE: { //printf("Empty\n"); return ps->empty_token(); } case INT_TYPE: { //printf("int of value %d\n", cur_node->val.i_val); return cur_node; } case DOUBLE_TYPE: { //printf("double of value %0.2f\n", cur_node->val.d_val); return cur_node; } case VOID_TYPE: { DSL_ERROR("Cannot have a void type object (parser error)\n"); return cur_node; } case VAR_ADT_TYPE: { //printf("identifier reference named %s\n", // cur_node->val.adt_val.adt_type_name->c_str()); return cur_node; } case ARRAY_TYPE: { return cur_node; } case NEW_VAR_TYPE: { // Get array size by evaluating the expression int tmp_array_size = 0; if (cur_node->val.v_val.v_type == ARRAY_TYPE) { ASTNode* getArraySize = eval( ps, cur_node->val.v_val.v_array_size, recurse_count + 1); if (getArraySize->type != INT_TYPE) { return ps->empty_token(); } tmp_array_size = getArraySize->val.i_val; } ASTNode* newAst = variable_create(ps, cur_node->val.v_val.v_type, cur_node->val.v_val.v_adt_name, cur_node->val.v_val.v_array_type, //cur_node->val.v_val.v_array_size, tmp_array_size, cur_node->val.v_val.v_name, false); if (newAst->type == EMPTY_TYPE) { DSL_ERROR("Cannot create variable %s not found\n", cur_node->val.v_val.v_name->c_str()); } return newAst; } case NEW_VAR_ASSIGN_TYPE: { //printf("identifier declaration named %s with assignment\n", // cur_node->val.v_val.v_name->c_str()); ASTNode* evalAst = NULL; //if (cur_node->val.v_val.v_type == ADT_TYPE && if (cur_node->val.v_val.v_assign->type == SEP_TYPE) { vector<ASTNode*>* newArray = ps->get_var_table()->new_stack_vector(); if (newArray == NULL) { return ps->empty_token(); } vector<ASTNode*>* evalArray = cur_node->val.v_val.v_assign->val.p_val.p_vector; for (u_int i = 0; i < evalArray->size(); i++) { newArray->push_back( eval(ps, (*evalArray)[i], recurse_count + 1)); } evalAst = mk_sep_list(ps, newArray); } else { evalAst = eval(ps, cur_node->val.v_val.v_assign, recurse_count + 1); } if (evalAst->type == EMPTY_TYPE) { return evalAst; } // Create the actual variable after evaluation expression ASTNode* newAst = variable_create(ps, cur_node->val.v_val.v_type, cur_node->val.v_val.v_adt_name, cur_node->val.v_val.v_array_type, //cur_node->val.v_val.v_array_size, // Should always be 0 0, cur_node->val.v_val.v_name, false); if (newAst->type == EMPTY_TYPE) { DSL_ERROR("Cannot create variable %s not found\n", cur_node->val.v_val.v_name->c_str()); } // Assign the variable to the value generated by eval if (ps->get_var_table()->updateADT(newAst, evalAst) == -1) { DSL_ERROR("A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -