toolcall-3.json•6.5 kB
{"jsonrpc": "2.0", "method": "initialize", "params": {"clientInfo": {"name": "Llama Agent", "version": "0.1"}, "protocolVersion": "2024-11-05", "capabilities": { "tools": { "subscribe": true, "listChanged": true }, "resource": { "subscribe": true, "listChanged": true } }}, "id": 1}{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}, "id": 8899}{"id": 1111,"method":"tools/call","params":{"name":"code-to-tree","arguments": {"lang":"c++","code":"#include <algorithm>\n#include <cctype>\n#include <concepts>\n#include <functional>\n#include <iostream>\n#include <map>\n#include <memory>\n#include <numeric>\n#include <optional>\n#include <sstream>\n#include <stdexcept>\n#include <string>\n#include <tuple>\n#include <type_traits>\n#include <variant>\n#include <vector>\n\nenum class TokenType {\n Integer,\n Identifier,\n Plus,\n Minus,\n Star,\n Slash,\n LParen,\n RParen,\n Comma,\n End\n};\n\nstruct Token {\n TokenType type;\n std::string_view text;\n};\n\nclass Lexer {\n std::string_view input;\n size_t pos = 0;\n\npublic: \n explicit Lexer(std::string_view in) : input(in) {}\n Token next() {\n while (pos < input.size() && std::isspace(input[pos]))\n pos++;\n if (pos >= input.size())\n return {TokenType::End, \"\"};\n char c = input[pos];\n if (std::isdigit(c)) {\n size_t start = pos;\n while (pos < input.size() && std::isdigit(input[pos]))\n pos++;\n return {TokenType::Integer, input.substr(start, pos - start)};\n }\n if (std::isalpha(c)) {\n size_t start = pos;\n while (pos < input.size() && std::isalnum(input[pos]))\n pos++;\n return {TokenType::Identifier, input.substr(start, pos - start)};\n }\n ++pos;\n switch (c) {\n case '+':\n return {TokenType::Plus, \"+\"};\n case '-':\n return {TokenType::Minus, \"-\"};\n case '*':\n return {TokenType::Star, \"*\"};\n case '/':\n return {TokenType::Slash, \"/\"};\n case '(':\n return {TokenType::LParen, \"(\"};\n case ')':\n return {TokenType::RParen, \")\"};\n case ',':\n return {TokenType::Comma, \",\"};\n default: \n throw std::runtime_error(\"Unknown character\");\n }\n }\n};\n\nstruct ASTInt {\n int value;\n};\nstruct ASTVar {\n std::string name;\n};\nstruct ASTCall;\nstruct ASTBinary;\n\nusing ASTNode = std::variant<ASTInt, ASTVar, std::unique_ptr<ASTCall>,\n std::unique_ptr<ASTBinary>>;\n\nstruct ASTCall {\n std::string callee;\n std::vector<ASTNode> args;\n};\n\nstruct ASTBinary {\n char op;\n ASTNode left;\n ASTNode right;\n};\n\ntemplate <typename F>\nconcept ParserFunc = requires(F f, Lexer &lx) {\n { f(lx) } -> std::convertible_to<std::optional<ASTNode>>;\n};\n\nclass Parser {\n Lexer lex;\n Token cur;\n\npublic: \n explicit Parser(std::string_view in) : lex(in), cur(lex.next()) {}\n void consume(TokenType t) {\n if (cur.type != t)\n throw std::runtime_error(\"Unexpected token\");\n cur = lex.next();\n }\n bool match(TokenType t) {\n if (cur.type == t) {\n cur = lex.next();\n return true;\n }\n return false;\n }\n ASTNode parseExpression() { return parseAddSub(); }\n\nprivate: \n ASTNode parsePrimary() {\n if (match(TokenType::Integer)) {\n int v = std::stoi(std::string(cur.text));\n return ASTInt{v};\n }\n if (match(TokenType::Identifier)) {\n std::string name(cur.text);\n if (match(TokenType::LParen)) {\n std::vector<ASTNode> args;\n if (!match(TokenType::RParen)) {\n do {\n args.push_back(parseExpression());\n } while (match(TokenType::Comma));\n consume(TokenType::RParen);\n }\n return std::make_unique<ASTCall>(\n ASTCall{std::move(name), std::move(args)});\n }\n return ASTVar{std::move(name)};\n }\n if (match(TokenType::LParen)) {\n auto expr = parseExpression();\n consume(TokenType::RParen);\n return expr;\n }\n throw std::runtime_error(\"Invalid primary\");\n }\n ASTNode parseMulDiv() {\n auto node = parsePrimary();\n while (cur.type == TokenType::Star || cur.type == TokenType::Slash) {\n char op = cur.text[0];\n cur = lex.next();\n auto right = parsePrimary();\n node = std::make_unique<ASTBinary>(ASTBinary{op, node, right});\n }\n return node;\n }\n ASTNode parseAddSub() {\n auto node = parseMulDiv();\n while (cur.type == TokenType::Plus || cur.type == TokenType::Minus) {\n char op = cur.text[0];\n cur = lex.next();\n auto right = parseMulDiv();\n node = std::make_unique<ASTBinary>(ASTBinary{op, node, right});\n }\n return node;\n }\n};\n\nstruct EvalContext {\n std::map<std::string, int> vars;\n std::map<std::string, std::function<int(std::vector<int>)>> funcs;\n};\n\nint evaluate(const ASTNode &node, EvalContext &ctx) {\n return std::visit(\n [&](auto &&x) -> int {\n using T = std::decay_t<decltype(x)>;\n if constexpr (std::is_same_v<T, ASTInt>)\n return x.value;\n if constexpr (std::is_same_v<T, ASTVar>)\n return ctx.vars.at(x.name);\n if constexpr (std::is_same_v<T, std::unique_ptr<ASTCall>>) {\n std::vector<int> args;\n for (auto &a : x->args)\n args.push_back(evaluate(a, ctx));\n return ctx.funcs[x->callee](args);\n }\n if constexpr (std::is_same_v<T, std::unique_ptr<ASTBinary>>) {\n int l = evaluate(x->left, ctx);\n int r = evaluate(x->right, ctx);\n switch (x->op) {\n case '+':\n return l + r;\n case '-':\n return l - r;\n case '*':\n return l * r;\n case '/':\n return l / r;\n }\n }\n throw std::runtime_error(\"Unknown node\");\n },\n node);\n}\n\nint main() {\n std::string input;\n std::cout << \"Enter expression: \";\n std::getline(std::cin, input);\n\n Parser parser(input);\n ASTNode ast = parser.parseExpression();\n\n EvalContext ctx;\n ctx.vars[\"x\"] = 10;\n ctx.vars[\"y\"] = 5;\n ctx.funcs[\"max\"] = [](std::vector<int> v) {\n return *std::max_element(v.begin(), v.end());\n };\n ctx.funcs[\"min\"] = [](std::vector<int> v) {\n return *std::min_element(v.begin(), v.end());\n };\n\n int result = evaluate(ast, ctx);\n std::cout << \"Result: \" << result << std::endl;\n\n return 0;\n}"}}}