Skip to content

Commit

Permalink
feat: betwixt-labs#56 Python support
Browse files Browse the repository at this point in the history
- added Python generator
- added Python runtime
  • Loading branch information
liquidiert committed Nov 5, 2023
1 parent cf3ac79 commit 43d9bd1
Show file tree
Hide file tree
Showing 28 changed files with 2,886 additions and 170 deletions.
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/Compiler/bin/Debug/net7.0/bebopc.dll",
"args": [],
"program": "${workspaceFolder}/bin/compiler/Debug/artifacts/bebopc.dll",
"args": ["--config", "bebop.json"],
"cwd": "${workspaceFolder}/Compiler",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
Expand Down
7 changes: 6 additions & 1 deletion Compiler/CommandLineFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ public class CommandLineFlags
"--ts ./my/output/HelloWorld.ts", true)]
public string? TypeScriptOutput { get; private set; }

[CommandLineFlag("py", "Generate Python source code to the specified file",
"--py ./my/output/HelloWorld.py", true)]
public string? PythonOutput { get; private set; }

[CommandLineFlag("namespace", "When this option is specified generated code will use namespaces",
"--cs --namespace [package]")]
public string? Namespace { get; private set; }
Expand Down Expand Up @@ -277,7 +281,8 @@ public class CommandLineFlags
["cs"] = TempoServices.Both,
["dart"] = TempoServices.Both,
["rust"] = TempoServices.Both,
["ts"] = TempoServices.Both
["ts"] = TempoServices.Both,
["py"] = TempoServices.Both
};

/// <summary>
Expand Down
6 changes: 5 additions & 1 deletion Core/Generators/GeneratorUtils.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Runtime.Serialization;
using System;
using System.Collections.Generic;
using System.Text;
using Core.Generators.CPlusPlus;
using Core.Generators.CSharp;
using Core.Generators.Dart;
using Core.Generators.Rust;
using Core.Generators.TypeScript;
using Core.Generators.Python;
using Core.Meta;
using Core.Meta.Extensions;

Expand Down Expand Up @@ -121,6 +123,7 @@ public static string BaseClassName(this Definition definition)
{ "dart", s => new DartGenerator(s) },
{ "rust", s => new RustGenerator(s) },
{ "ts", s => new TypeScriptGenerator(s) },
{ "py", s => new PythonGenerator(s) }
};

public static Dictionary<string, string> ImplementedGeneratorNames = new()
Expand All @@ -130,6 +133,7 @@ public static string BaseClassName(this Definition definition)
{ "dart", "Dart" },
{ "rust", "Rust" },
{ "ts", "TypeScript" },
{ "py", "Python" }
};

/// <summary>
Expand Down
506 changes: 506 additions & 0 deletions Core/Generators/Python/PythonGenerator.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Core/Generators/TypeScript/TypeScriptGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public string CompileDecode(Definition definition)
}

/// <summary>
/// Generate the body of the <c>decode</c> function for the given <see cref=MessageDefinition"/>,
/// Generate the body of the <c>decode</c> function for the given <see cref="MessageDefinition"/>,
/// </summary>
/// <param name="definition">The message definition to generate code for.</param>
/// <returns>The generated TypeScript <c>decode</c> function body.</returns>
Expand Down
1 change: 1 addition & 0 deletions Laboratory/Integration/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ schema.ts
bebop.hpp
*.enc
Rust/src/schema.rs
Python/src/schema.py
target
21 changes: 21 additions & 0 deletions Laboratory/Integration/Python/src/decode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from schema import Library
from lib import make_lib
import sys
import json

with open(sys.argv[1], "rb") as buffer_file:
buffer = buffer_file.read()

de = Library.decode(buffer)
ex = make_lib()

eq = json.loads(repr(de)) == json.loads(repr(ex))

if not eq:
print("decoded:")
print(repr(de))
print()
print("expected:")
print(repr(ex))

sys.exit(0 if eq else 1)
6 changes: 6 additions & 0 deletions Laboratory/Integration/Python/src/encode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from lib import make_lib
from schema import Library
import sys

with open("py.enc", "wb+") as enc_file:
enc_file.write(bytearray(Library.encode(make_lib())))
48 changes: 48 additions & 0 deletions Laboratory/Integration/Python/src/lib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from schema import Library, Instrument, Album, StudioAlbum, LiveAlbum, Song, Musician
from datetime import datetime

def make_lib():
giant_steps_song = Song()
giant_steps_song.title = "Giant Steps"
giant_steps_song.year = 1959
giant_steps_song.performers = [
Musician(name="John Coltrane", plays=Instrument.PIANO)
]

a_night_in_tunisia_song = Song()
a_night_in_tunisia_song.title = "A Night in Tunisia"
a_night_in_tunisia_song.year = 1942
a_night_in_tunisia_song.performers = [
Musician(name="Dizzy Gillespie", plays=Instrument.TRUMPET),
Musician(name="Count Basie", plays=Instrument.PIANO),
]

groovin_high_song = Song()
groovin_high_song.title = "Groovin' High"

adams_apple_album = LiveAlbum()
adams_apple_album.venueName = "Tunisia"
adams_apple_album.concertDate = datetime.fromtimestamp(528205479)

unnamed_song = Song()
unnamed_song.year = 1965
unnamed_song.performers = [
Musician(name="Carmell Jones", plays=Instrument.TRUMPET),
Musician(name="Joe Henderson", plays=Instrument.SAX),
Musician(name="Teddy Smith", plays=Instrument.CLARINET)
]

brilliant_corners_album = LiveAlbum()
brilliant_corners_album.venueName = "Night's Palace"
brilliant_corners_album.tracks = [
unnamed_song
]

return Library(albums={
"Giant Steps": Album.fromStudioAlbum(StudioAlbum(tracks=[
giant_steps_song, a_night_in_tunisia_song, groovin_high_song
])),
"Adam's Apple": Album.fromLiveAlbum(adams_apple_album),
"Milestones": Album.fromStudioAlbum(StudioAlbum(tracks=[])),
"Brilliant Corners": Album.fromLiveAlbum(brilliant_corners_album)
})
6 changes: 5 additions & 1 deletion Laboratory/Integration/run_test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const shell = require("shelljs");
const cxx = shell.env["CXX"] || "g++";
const aout = process.platform === "win32" ? "a.exe" : "./a.out";
const py = process.platform === "win32" ? "py" : "python3";

shell.echo("Compiling schema...");
if (shell.exec("dotnet run --project ../../Compiler --files schema.bop --cs schema.cs --ts schema.ts --cpp schema.hpp --rust Rust/src/schema.rs").code !== 0) {
if (shell.exec("dotnet run --project ../../Compiler --files schema.bop --cs schema.cs --ts schema.ts --cpp schema.hpp --rust Rust/src/schema.rs --py Python/src/schema.py").code !== 0) {
shell.echo("Error: bebopc failed");
shell.exit(1);
}
Expand All @@ -18,6 +19,8 @@ if (shell.exec(`${cxx} --std=c++17 encode.cpp`).code !== 0) {
shell.exec(`${aout} > cpp.enc`);
shell.rm("-f", aout);
shell.exec("cargo run --manifest-path Rust/Cargo.toml --example encode > rs.enc");
shell.exec(`${py} Python/src/encode.py`)


// Files can have some variance and still be equivalent because of ordering in maps and C# dates.
// Perform full matrix testing because it seems like a good idea
Expand All @@ -34,6 +37,7 @@ const languages = [
{name: "C#", cmd: "dotnet run decode", file: "cs.enc"},
{name: "TypeScript", cmd: "npx ts-node decode.ts", file: "ts.enc"},
{name: "C++", cmd: aout, file: "cpp.enc"},
{name: "Python", cmd: `${py} Python/src/decode.py`, file: "py.enc"},
];

var failed = false;
Expand Down
Loading

0 comments on commit 43d9bd1

Please sign in to comment.