21 std::ostringstream ss;
22 ss <<
"fn " << fn->name <<
"(";
23 for (
size_t i = 0; i < fn->params.size(); ++i)
27 ss << fn->params[i].name <<
": ";
28 if (fn->params[i].type)
30 ss << fn->params[i].type->name;
31 if (fn->params[i].type->isPointer)
33 for (
int dim : fn->params[i].type->arrayDimensions)
34 ss <<
"[" << dim <<
"]";
40 ss <<
" -> " << fn->returnType->name;
41 if (fn->returnType->isPointer)
48 std::ostringstream ss;
49 ss <<
"struct " << st->name <<
" {";
50 for (
size_t i = 0; i < st->fields.size(); ++i)
54 ss <<
" " << st->fields[i].name <<
": ";
55 if (st->fields[i].type)
57 ss << st->fields[i].type->name;
58 if (st->fields[i].type->isPointer)
66 return "var " + vd->name;
106 return it->second.diagnostics;
112 if (it ==
documents.end() || !it->second.program)
117std::optional<std::string>
LSP::getHover(
const std::string &uri,
size_t line,
size_t column)
120 if (it ==
documents.end() || !it->second.program)
140 return sit->second.signature.empty() ? name : sit->second.signature;
146 if (it ==
documents.end() || !it->second.program)
158 if (!sig.empty() && node->
line > 0)
169 AST::Node *decl = sit->second.declaration;
170 if (!decl || decl->
line == 0)
182 if (!node || node->
line == 0)
184 if (node->
line == line && node->
column <= col)
189AST::Node *walkExpr(AST::Expression *expr,
size_t line,
size_t col)
194 if (
auto *e =
dynamic_cast<AST::BinaryExpr *
>(expr))
196 if (
auto *n = walkExpr(e->left.get(), line, col))
198 if (
auto *n = walkExpr(e->right.get(), line, col))
203 if (
auto *n = walkExpr(e->operand.get(), line, col))
208 if (
auto *n = walkExpr(e->operand.get(), line, col))
213 if (
auto *n = walkExpr(e->target.get(), line, col))
215 if (
auto *n = walkExpr(e->value.get(), line, col))
220 for (
const auto &arg : e->arguments)
221 if (
auto *n = walkExpr(arg.get(), line, col))
226 if (
auto *n = walkExpr(e->array.get(), line, col))
228 if (
auto *n = walkExpr(e->index.get(), line, col))
233 for (
const auto &elem : e->elements)
234 if (
auto *n = walkExpr(elem.get(), line, col))
239 if (
auto *n = walkExpr(e->object.get(), line, col))
244 if (
auto *n = walkExpr(e->object.get(), line, col))
249 for (
const auto &fv : e->fieldValues)
250 if (
auto *n = walkExpr(fv.second.get(), line, col))
254 return candidate(expr, line, col);
264 for (
const auto &child : s->statements)
265 if (
auto *n = walkStmt(child.get(), line, col))
270 if (
auto *n = walkExpr(s->expression.get(), line, col))
275 if (
auto *n = walkExpr(s->expression.get(), line, col))
280 if (
auto *n = walkExpr(s->initializer.get(), line, col))
282 return candidate(s, line, col);
286 if (
auto *n = walkExpr(s->value.get(), line, col))
289 else if (
auto *s =
dynamic_cast<AST::IfStmt *
>(stmt))
291 if (
auto *n = walkExpr(s->condition.get(), line, col))
293 if (
auto *n = walkStmt(s->thenBranch.get(), line, col))
295 if (
auto *n = walkStmt(s->elseBranch.get(), line, col))
300 if (
auto *n = walkExpr(s->condition.get(), line, col))
302 if (
auto *n = walkStmt(s->body.get(), line, col))
307 if (
auto *n = walkStmt(s->initializer.get(), line, col))
309 if (
auto *n = walkExpr(s->condition.get(), line, col))
311 if (
auto *n = walkExpr(s->increment.get(), line, col))
313 if (
auto *n = walkStmt(s->body.get(), line, col))
318 if (
auto *n = walkExpr(s->expr.get(), line, col))
320 for (
const auto &c : s->cases)
322 if (
auto *n = walkExpr(c.value.get(), line, col))
324 for (
const auto &cs : c.statements)
325 if (
auto *n = walkStmt(cs.get(), line, col))
328 for (
const auto &ds : s->defaultStmts)
329 if (
auto *n = walkStmt(ds.get(), line, col))
335 if (
auto *n = walkStmt(s->body.get(), line, col))
337 return candidate(s, line, col);
341 return candidate(s, line, col);
345 if (
auto *n = walkStmt(s->declaration.get(), line, col))
350 if (
auto *n = walkStmt(s->block.get(), line, col))
354 return candidate(stmt, line, col);
362 for (
const auto &stmt : doc.
program->statements)
363 if (
auto *n = walkStmt(stmt.get(), line, col))
377 return e->structName;
389 for (
size_t i = 0; i < doc.
source.size(); ++i)
390 if (doc.
source[i] ==
'\n')
399 auto tryRegister = [&](
const std::string &name,
AST::Node *node) {
407 for (
const auto &stmt : doc.
program->statements)
410 tryRegister(fn->name, fn);
412 tryRegister(st->name, st);
413 else if (
auto *vd =
dynamic_cast<AST::VarDecl *
>(stmt.get()))
414 tryRegister(vd->name, vd);
418 tryRegister(fn->name, fn);
419 else if (
auto *st =
dynamic_cast<AST::StructDecl *
>(ex->declaration.get()))
420 tryRegister(st->name, st);
421 else if (
auto *vd =
dynamic_cast<AST::VarDecl *
>(ex->declaration.get()))
422 tryRegister(vd->name, vd);
439 doc.
diagnostics.push_back({err->message, err->line, err->column, err->line, err->column + 1});
445 doc.
diagnostics.push_back({err->message, err->line, err->column, err->line, err->column + 1});
450 catch (
const std::runtime_error &e)
452 std::cerr << e.what();
456 std::cerr <<
"Caught unknown exception";
AST::Node * walkForNode(const DocumentState &doc, size_t line, size_t col)
std::optional< Location > getDefinition(const std::string &uri, size_t line, size_t column)
void buildGlobalSymbols(DocumentState &doc)
void openDocument(const std::string &uri, const std::string &text)
void closeDocument(const std::string &uri)
AST::Node * findNodeAtPosition(const std::string &uri, size_t line, size_t column)
void compile(DocumentState &doc)
std::vector< Diagnostic > getDiagnostics(const std::string &uri) const
std::string symbolNameAt(AST::Node *node) const
std::optional< std::string > getHover(const std::string &uri, size_t line, size_t column)
void changeDocument(const std::string &uri, const std::string &newText)
std::unordered_map< std::string, DocumentState > documents
void computeLineOffsets(DocumentState &doc)
std::vector< Token > tokenize()
std::optional< Error > getError() const
std::unique_ptr< AST::Program > parse()
std::optional< Error > getError() const
The Phasor Programming Language and Runtime.
static std::string buildSignature(AST::Node *node)
static size_t toLexerLine(size_t lspLine)
static size_t toLexerCol(size_t lspCol)
Array Access Expression Node.
Array Literal Expression Node.
Assignment Expression Node.
Expression Statement Node.
Field Access Expression Node.
Function Declaration Node.
Identifier Expression Node.
Member Access Expression Node.
Struct Instance Expression Node.
Unsafe Block Statement Node.
Variable Declaration Node.
std::unordered_map< std::string, SymbolInfo > globalSymbols
std::vector< size_t > lineStartOffsets
std::unique_ptr< AST::Program > program
std::vector< Diagnostic > diagnostics