Skip to content

Commit

Permalink
Initial language server and client
Browse files Browse the repository at this point in the history
  • Loading branch information
DvvCz committed Aug 23, 2023
1 parent 87009b4 commit 885f54d
Show file tree
Hide file tree
Showing 13 changed files with 245 additions and 27 deletions.
75 changes: 73 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 5 additions & 7 deletions packages/ramattra-core/src/compiler/analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export type IRFunction =

type Scope = Map<string, IRExpr>;

export default function analyze(src: string): IREvent[] {
export function analyze(src: string): IREvent[] {
const ast = parse(src);

let scope: Scope = new Map();
Expand Down Expand Up @@ -77,13 +77,11 @@ export default function analyze(src: string): IREvent[] {
if (kind == "+") {
const [lhs, rhs] = [analyzeExpr(expr[1]), analyzeExpr(expr[2])];

if (lhs.type == "number" && rhs.type != "number")
throw `Cannot add a ${rhs.type} to a number`;

// Can append anything to a string.
if (lhs.type != rhs.type)
throw `Cannot perform ${kind} operation on expressions of differing types (${lhs.type} and ${rhs.type})`;

if (lhs.type != "string")
throw `Can only add strings`;
if (lhs.type != "string" && lhs.type != "number")
throw `Can only add numbers and strings`;

return { type: lhs.type, data: [kind, lhs, rhs] };
} else if (kind == "-" || kind == "*" || kind == "/") {
Expand Down
2 changes: 1 addition & 1 deletion packages/ramattra-core/src/compiler/assembler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { dedent } from "@ramattra/ramattra-util";
import analyze, { IRExpr, IRStmt } from "./analyzer.js";
import { analyze, IRExpr, IRStmt } from "./analyzer.js";
import optimize from "./optimizer.js";

export function assemble(src: string): string {
Expand Down
3 changes: 2 additions & 1 deletion packages/ramattra-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { parse } from "./compiler/parser.js";
export { assemble } from "./compiler/assembler.js";
export { assemble } from "./compiler/assembler.js";
export { analyze } from "./compiler/analyzer.js";
3 changes: 2 additions & 1 deletion packages/ramattra-language-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"private": true,
"main": "dist/server.js",
"scripts": {
"test": "vitest"
"test": "vitest",
"watch": "tsc --watch"
},
"dependencies": {
"vscode-languageserver": "^8.1.0",
Expand Down
73 changes: 60 additions & 13 deletions packages/ramattra-language-server/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,83 @@
import {
createConnection, TextDocuments, ProposedFeatures, TextDocumentSyncKind
createConnection, TextDocuments, TextDocumentSyncKind, Diagnostic, DiagnosticSeverity, CompletionItem, CompletionItemKind
} from "vscode-languageserver/node";

import {
TextDocument
} from "vscode-languageserver-textdocument";

import { analyze } from "@ramattra/ramattra-core";

// Creates the LSP connection
const connection = createConnection(ProposedFeatures.all);
const connection = createConnection();
const documents = new TextDocuments(TextDocument);

// Create a manager for open text documents
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
documents.onDidOpen((event) => {
connection.console.log(`[Server(${process.pid})] Document opened: ${event.document.uri}`);
});

// The workspace folder this server is operating on
let workspaceFolder: string | null;
connection.onCompletion((_pos): CompletionItem[] => {
return [
{
label: "TestingCompletion",
kind: CompletionItemKind.Text,
data: 1
}
];
});

documents.onDidOpen((event) => {
connection.console.log(`[Server(${process.pid}) ${workspaceFolder}] Document opened: ${event.document.uri}`);
connection.onCompletionResolve(
(item): CompletionItem => {
if (item.data == 1) {
item.detail = "TypeScript details";
item.documentation = "TypeScript documentation";
}

return item;
}
);

async function validateDocument(document: TextDocument) {
const text = document.getText();

const diagnostics: Diagnostic[] = [];

try {
analyze(text);
} catch (err) {
diagnostics.push({
severity: DiagnosticSeverity.Error,
range: {
start: document.positionAt(0),
end: document.positionAt(0)
},
message: `${err}`,
source: "Ramattra Language Server"
});
}

await connection.sendDiagnostics({ uri: document.uri, diagnostics })
}

documents.onDidChangeContent(async e => {
await validateDocument(e.document);
});

documents.listen(connection);

connection.onInitialize((params) => {
workspaceFolder = params.rootUri;
connection.console.log(`[Server(${process.pid}) ${workspaceFolder}] Started and initialize received`);
connection.onInitialize((_params) => {
connection.console.log(`[Server(${process.pid})] Started and initialize received`);

return {
capabilities: {
textDocumentSync: {
openClose: true,
change: TextDocumentSyncKind.None
change: TextDocumentSyncKind.Incremental
},
completionProvider: {
resolveProvider: true
}
}
};
});
connection.listen();
connection.listen();
20 changes: 20 additions & 0 deletions packages/ramattra-vscode/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": "0.2.0",
// List of configurations. Add new configurations or edit existing ones.
"configurations": [
{
"type": "extensionHost",
"request": "launch",
"name": "Launch Client",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceRoot}"
],
"autoAttachChildProcesses": true,
"sourceMaps": true,
"outFiles": [
"${workspaceRoot}/dist/**/*.js"
]
}
]
}
4 changes: 3 additions & 1 deletion packages/ramattra-vscode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ VSCode client for writing Ramattra code.
## Features

- [x] Syntax highlighting
- [ ] LSP Client
- [x] LSP Client

![Showcase](assets/showcase.png)
Binary file added packages/ramattra-vscode/assets/showcase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 9 additions & 1 deletion packages/ramattra-vscode/language-configuration.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
"comments": {
// symbol used for single line comment. Remove this entry if your language does not support line comments
// symbols used for start and end a block comment. Remove this entry if your language does not support block comments
"lineComment": "//"
"lineComment": "//",
"blockComment": [
"/*",
"*/"
]
},
// symbols used as brackets
"brackets": [
Expand Down Expand Up @@ -36,6 +40,10 @@
[
"\"",
"\""
],
[
"/*",
"*/"
]
],
// symbols that that can be used to surround a selection
Expand Down
5 changes: 5 additions & 0 deletions packages/ramattra-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"description": "Language server for ramattra",
"version": "0.1.0",
"private": true,
"repository": "https://github.com/DvvCz/Ramattra",
"main": "dist/extension.js",
"engines": {
"vscode": "^1.75.0"
Expand Down Expand Up @@ -37,7 +38,11 @@
"test": "vitest"
},
"dependencies": {
"vscode-languageclient": "^8.1.0",
"vscode-languageserver": "^8.1.0",
"vscode-languageserver-textdocument": "^1.0.8"
},
"devDependencies": {
"@types/vscode": "^1.81.0"
}
}
60 changes: 60 additions & 0 deletions packages/ramattra-vscode/src/extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import * as path from "path";
import { workspace, ExtensionContext } from "vscode";

import {
LanguageClient,
LanguageClientOptions,
ServerOptions,
TransportKind
} from "vscode-languageclient/node";

let client: LanguageClient;

export function activate(context: ExtensionContext) {
// The server is implemented in node
const serverModule = context.asAbsolutePath(
path.join("..", "ramattra-language-server", "dist", "server.js")
);

// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
const serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
}
};

// Options to control the language client
const clientOptions: LanguageClientOptions = {
documentSelector: [{ scheme: "file", language: "ramattra" }],
synchronize: {
// Notify the server about file changes to ".clientrc files contained in the workspace
fileEvents: workspace.createFileSystemWatcher("**/.clientrc")
}
};

// Create the language client and start the client.
client = new LanguageClient(
"ramattra-language-server",
"Ramattra Language Server",
serverOptions,
clientOptions
);

// Start the client. This will also launch the server
client.start();
}

export function deactivate(): Thenable<void> | undefined {
if (!client) {
return undefined;
}
return client.stop();
}
Loading

0 comments on commit 885f54d

Please sign in to comment.