VisitResult FunctionVisitor::Visit(FunctionNode* node) { node->Walk(this, false); std::string retTypeName; if(node->mReturnType) { retTypeName = std::string(node->mReturnType->mName.mText, node->mReturnType->mName.mLength); } else { retTypeName = "Void"; } Symbol* retType = find_symbol_by_name(retTypeName, dependencies_, library_); if(retTypeName != "Void") { retType = library_->GetPointerType(static_cast<Type*>(retType), node->mReturnType->mPointerCount); } Type* signatureType = library_->GetFunctionType(current_parameters_, static_cast<Type*>(retType)); node->mSignatureType = signatureType; current_parameters_.clear(); current_return_value_ = nullptr; return VisitResult::Stop; }
VisitResult FunctionVisitor::Visit(CastNode* node) { node->Walk(this, false); Type* type = static_cast<Type*>(find_symbol_by_name(std::string(node->mType->mName.mText, node->mType->mName.mLength), dependencies_, library_)); library_->GetPointerType(type, node->mType->mPointerCount); return VisitResult::Stop; }
VisitResult ExpressionVisitor::Visit(CastNode* node) { node->Walk(this, false); ValueNode* valNode = static_cast<ValueNode*>(node->mLeft.get()); Type* tocast = valNode->mResolvedType; std::string targetTypeName(node->mType->mName.mText, node->mType->mName.mLength); Type* targetType = static_cast<Type*>(find_symbol_by_name(targetTypeName, dependencies_, library_, symbol_stack_)); targetType = library_->GetPointerType(targetType, node->mType->mPointerCount); node->mResolvedType = static_cast<Type*>(targetType); switch(tocast->mMode) { case TypeMode::Class: if(tocast->mName == "Integer") { if(targetType->mName != "Integer" && targetType->mName != "Boolean" && targetType->mName != "Byte" && targetType->mName != "Float" && targetType->mMode != TypeMode::Pointer) { ErrorInvalidCast(tocast, targetType); } } else if(tocast->mName == "Boolean" || tocast->mName == "Byte" || tocast->mName == "Float") { if(targetType->mName != "Integer" && targetType->mName != "Boolean" && targetType->mName != "Byte" && targetType->mName != "Float") { ErrorInvalidCast(tocast, targetType); } } break; case TypeMode::Pointer: if(targetType->mMode != TypeMode::Pointer) { if(targetType->mName != "Integer" && targetType->mName != "Boolean") { ErrorInvalidCast(tocast, targetType); } } break; case TypeMode::Function: ErrorInvalidCast(tocast, targetType); } return VisitResult::Stop; }
static void command_find_by_name_cache_client(void * x) { CommandFindByNameArgs * args = (CommandFindByNameArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; Symbol * sym = NULL; int err = 0; if (id2frame(args->id, &ctx, &frame) < 0) ctx = id2ctx(args->id); if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->id); else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err == 0 && find_symbol_by_name(ctx, frame, args->ip, args->name, &sym) < 0) err = errno; list_cnt = 0; if (err == 0) { list_add(sym); if (!args->find_first) { while (find_next_symbol(&sym) == 0) list_add(sym); if (get_error_code(errno) != ERR_SYM_NOT_FOUND) err = errno; } } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); write_symbol_list(&c->out); write_stream(&c->out, MARKER_EOM); loc_free(args->name); }
VisitResult EvaluatorVisitor::Visit(VariableNode * node) { std::string varName(node->mName.mText, node->mName.mLength); auto& currentSymbols = symbol_stack_.back(); Variable* newVar; auto varSymbol = currentSymbols.find(varName); if(varSymbol != currentSymbols.end())//alright so we found something of the same name { node->mSymbol = static_cast<Variable*>(varSymbol->second); ErrorSameName(varName); } else { newVar = library_->CreateVariable(std::string(node->mName.mText, node->mName.mLength), !parent_type_ && !parent_function_); currentSymbols.insert(std::make_pair(varName, newVar)); } //search for type from dependencies and globals? auto& name = node->mType->mName; std::string typeName(name.mText, name.mLength); //find type newVar->mType = static_cast<Type*>(find_symbol_by_name(typeName, dependencies_, library_)); newVar->mType = library_->GetPointerType(newVar->mType, node->mType->mPointerCount); newVar->mParentFunction = parent_function_; newVar->mParentType = parent_type_; node->mSymbol = newVar; if(parent_type_) { if(parent_function_) { //same as function parent_function_->mLocals.push_back(newVar); } else { parent_type_->mMembers.push_back(newVar); parent_type_->mMembersByName.insert(std::make_pair(newVar->mName, newVar)); //just class } } else if(parent_function_) { parent_function_->mLocals.push_back(newVar); } node->Walk(this, false); return VisitResult::Stop; }
VisitResult FunctionVisitor::Visit(ParameterNode* node) { node->Walk(this, false); auto& name = node->mType->mName; std::string typeName(name.mText, name.mLength); //find type Type* foundType = static_cast<Type*>(find_symbol_by_name(typeName, dependencies_, library_)); foundType = library_->GetPointerType(foundType, node->mType->mPointerCount); current_parameters_.push_back(foundType); return VisitResult::Stop; }
VisitResult ExpressionVisitor::Visit(MemberAccessNode* node) { node->Walk(this, false); ValueNode* valNode = static_cast<ValueNode*>(node->mLeft.get()); switch(node->mOperator.mEnumTokenType) { case TokenType::Dot: { if(valNode->mResolvedType->mMode != TypeMode::Class) { ErrorInvalidMemberAccess(node); } break; } case TokenType::Arrow: { if(valNode->mResolvedType->mMode != TypeMode::Pointer) { ErrorInvalidMemberAccess(node); } break; } default: ErrorInvalidMemberAccess(node); } std::string leftExpression(valNode->mToken.mText, valNode->mToken.mLength); std::string rightExpression(node->mName.mText, node->mName.mLength); Variable* leftSide = static_cast<Variable*>(find_symbol_by_name(leftExpression, dependencies_, library_, symbol_stack_)); Variable* rightSide = nullptr;// = ;//find_symbol_by_name(rightExpression, dependencies_, library_, symbol_stack_); Type* lefttype = resolvePointers(leftSide->mType); auto rightIt = lefttype->mMembersByName.find(rightExpression); if(rightIt != lefttype->mMembersByName.end()) { rightSide = static_cast<Variable*>(rightIt->second); } node->mResolvedMember = rightSide; node->mResolvedType = rightSide->mType; return VisitResult::Stop; }
static ContextAddress find_module(Context * ctx, ELF_File * exe_file, ELF_File * module, ContextAddress r_map, ContextAddress r_brk) { #if ENABLE_Symbols Symbol * sym = NULL; int i = 0, n = 0; Symbol ** children = NULL; ContextAddress link = r_map; Symbol * sym_l_addr = NULL; Symbol * sym_l_next = NULL; Symbol * sym_l_tls_modid = NULL; if (find_symbol_by_name(ctx, STACK_NO_FRAME, r_brk, "link_map", &sym) < 0) str_exception(errno, "Cannot find loader symbol: link_map"); if (get_symbol_children(sym, &children, &n) < 0) exception(errno); for (i = 0; i < n; i++) { char * name = NULL; if (get_symbol_name(children[i], &name) < 0) exception(errno); if (name == NULL) continue; if (strcmp(name, "l_map_start") == 0) sym_l_addr = children[i]; else if (strcmp(name, "l_next") == 0) sym_l_next = children[i]; else if (strcmp(name, "l_tls_modid") == 0) sym_l_tls_modid = children[i]; } if (sym_l_addr == NULL || sym_l_next == NULL || sym_l_tls_modid == NULL) str_exception(ERR_OTHER, "Invalid 'link_map' fields"); while (link != 0) { ContextAddress l_tls_modid = 0; read_field(ctx, sym_l_tls_modid, link, &l_tls_modid); if (l_tls_modid != 0) { ContextAddress l_addr = 0; ELF_File * link_file = NULL; read_field(ctx, sym_l_addr, link, &l_addr); elf_map_to_link_time_address(ctx, l_addr, 0, &link_file, NULL); if (link_file != NULL) { if (link_file == module) return l_tls_modid; if (get_dwarf_file(link_file) == module) return l_tls_modid; } } read_field(ctx, sym_l_next, link, &link); } #endif return 0; }
VisitResult FunctionVisitor::Visit(VariableNode* node) { node->Walk(this, false); auto& name = node->mType->mName; std::string typeName(name.mText, name.mLength); //find type Type* foundType = static_cast<Type*>(find_symbol_by_name(typeName, dependencies_, library_)); if(foundType) { foundType = library_->GetPointerType(foundType, node->mType->mPointerCount); } else { ErrorSymbolNotFound(typeName); } //? not sure if this is needed node->mType->mSymbol = foundType; return VisitResult::Stop; }
VisitResult ExpressionVisitor::Visit(BinaryOperatorNode* node) { node->Walk(this, false); ValueNode* rhs = static_cast<ValueNode*>(node->mRight.get()); ValueNode* lhs = static_cast<ValueNode*>(node->mLeft.get()); switch(node->mOperator.mEnumTokenType) { case TokenType::Minus: { if((rhs->mResolvedType == lhs->mResolvedType) && (rhs->mResolvedType->mMode != TypeMode::Pointer)) { if(rhs->mResolvedType->mName == "Integer" || rhs->mResolvedType->mName == "Float" || rhs->mResolvedType->mName == "Byte") { node->mResolvedType = rhs->mResolvedType; } else { ErrorInvalidBinaryOperator(node); } } else if(rhs->mResolvedType->mMode == TypeMode::Pointer && lhs->mResolvedType->mName == "Integer") { node->mResolvedType = rhs->mResolvedType; } else if(lhs->mResolvedType->mMode == TypeMode::Pointer && rhs->mResolvedType->mName == "Integer") { node->mResolvedType = lhs->mResolvedType; } else if(lhs->mResolvedType->mMode == TypeMode::Pointer && rhs->mResolvedType->mMode == TypeMode::Pointer) { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Integer", dependencies_, library_, symbol_stack_)); } else { ErrorInvalidBinaryOperator(node); } break; } case TokenType::Plus: { if(rhs->mResolvedType == lhs->mResolvedType) { if(rhs->mResolvedType->mName == "Integer" || rhs->mResolvedType->mName == "Float" || rhs->mResolvedType->mName == "Byte") { node->mResolvedType = rhs->mResolvedType; } else { ErrorInvalidBinaryOperator(node); } } else if(rhs->mResolvedType->mMode == TypeMode::Pointer && lhs->mResolvedType->mName == "Integer") { node->mResolvedType = rhs->mResolvedType; } else if(lhs->mResolvedType->mMode == TypeMode::Pointer && rhs->mResolvedType->mName == "Integer") { node->mResolvedType = lhs->mResolvedType; } else { ErrorInvalidBinaryOperator(node); } break; } case TokenType::Asterisk: case TokenType::Divide: case TokenType::Modulo: { //if they're the same type and they're integer/float/byte if(rhs->mResolvedType == lhs->mResolvedType) { if(rhs->mResolvedType->mName == "Integer" || rhs->mResolvedType->mName == "Float" || rhs->mResolvedType->mName == "Byte") { node->mResolvedType = rhs->mResolvedType; } else { ErrorInvalidBinaryOperator(node); } } else { ErrorInvalidBinaryOperator(node); } break; } case TokenType::GreaterThan: case TokenType::GreaterThanOrEqualTo: case TokenType::Equality: case TokenType::Inequality: case TokenType::LessThanOrEqualTo: case TokenType::LessThan: { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Boolean", dependencies_, library_, symbol_stack_)); break; } case TokenType::LogicalAnd: case TokenType::LogicalOr: { if((rhs->mResolvedType->mName == "Boolean" || rhs->mResolvedType->mMode == TypeMode::Pointer) && (lhs->mResolvedType->mName == "Boolean" || lhs->mResolvedType->mMode == TypeMode::Pointer)) { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Boolean", dependencies_, library_, symbol_stack_)); } else { ErrorInvalidBinaryOperator(node); } break; } case TokenType::Assignment: { if(rhs->mResolvedType == lhs->mResolvedType) { if(lhs->mResolvedType->mName == "Function" || rhs->mResolvedType->mName == "Function") { ErrorInvalidBinaryOperator(node); } else { node->mResolvedType = lhs->mResolvedType; } } else { ErrorInvalidBinaryOperator(node); } break; } default: ErrorInvalidBinaryOperator(node); break; } return VisitResult::Stop; }
VisitResult ExpressionVisitor::Visit(ValueNode* node) { node->Walk(this, false); switch(node->mToken.mEnumTokenType) { case TokenType::StringLiteral: { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Byte", dependencies_, library_, symbol_stack_)); node->mResolvedType = library_->GetPointerType(node->mResolvedType, 1); break; } case TokenType::True: case TokenType::False: { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Boolean", dependencies_, library_, symbol_stack_)); break; } case TokenType::Null: { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Null", dependencies_, library_, symbol_stack_)); node->mResolvedType = library_->GetPointerType(node->mResolvedType, 1); break; } case TokenType::IntegerLiteral: { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Integer", dependencies_, library_, symbol_stack_)); break; } case TokenType::CharacterLiteral: { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Byte", dependencies_, library_, symbol_stack_)); break; } case TokenType::FloatLiteral: { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Float", dependencies_, library_, symbol_stack_)); break; } case TokenType::Identifier: { std::string name = std::string(node->mToken.mText, node->mToken.mLength); auto identifier = find_symbol_by_name(name, dependencies_, library_, symbol_stack_); if(identifier) { node->mResolvedType = identifier->mType; } else { ErrorSymbolNotFound(name); } //if(symbol_stack_.size()) //{ // auto fromStack = symbol_stack_.back().find(name); // if(fromStack != symbol_stack_.back().end()) // { // node->mResolvedType = static_cast<Type*>(fromStack->second); // } //} break; } } return VisitResult::Stop; }
VisitResult ExpressionVisitor::Visit(UnaryOperatorNode* node) { node->Walk(this, false); ValueNode* valNode = static_cast<ValueNode*>(node->mRight.get()); if(valNode->mResolvedType->mMode == TypeMode::Pointer) { switch(node->mOperator.mEnumTokenType) { case TokenType::Decrement: case TokenType::Increment: { node->mResolvedType = valNode->mResolvedType; break; } case TokenType::BitwiseAndAddressOf: { node->mResolvedType = library_->GetPointerType(valNode->mResolvedType, 1); break; } case TokenType::Asterisk: { node->mResolvedType = dereference(valNode->mResolvedType); break; } case TokenType::LogicalNot: { node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Boolean", dependencies_, library_, symbol_stack_)); break; } default: ErrorInvalidUnaryOperator(node); } } else if(valNode->mResolvedType->mName == "Integer" || valNode->mResolvedType->mName == "Float" || valNode->mResolvedType->mName == "Byte") { switch(node->mOperator.mEnumTokenType) { case TokenType::Plus: case TokenType::Minus: case TokenType::Decrement: case TokenType::Increment: { node->mResolvedType = valNode->mResolvedType; break; } case TokenType::BitwiseAndAddressOf: { node->mResolvedType = library_->GetPointerType(valNode->mResolvedType, 1); break; } default: ErrorInvalidUnaryOperator(node); } } else if(valNode->mResolvedType->mName == "Boolean") { switch(node->mOperator.mEnumTokenType) { case TokenType::BitwiseAndAddressOf: { node->mResolvedType = library_->GetPointerType(valNode->mResolvedType, 1); break; } case TokenType::LogicalNot: { node->mResolvedType = valNode->mResolvedType; break; } default: ErrorInvalidUnaryOperator(node); } } else { ErrorInvalidUnaryOperator(node); } return VisitResult::Stop; }