Skip to content

Commit

Permalink
fixing zig bugs with enum; c+go best practices
Browse files Browse the repository at this point in the history
  • Loading branch information
sjml committed Nov 14, 2024
1 parent ff8de8d commit e285707
Show file tree
Hide file tree
Showing 15 changed files with 105 additions and 106 deletions.
2 changes: 1 addition & 1 deletion beschi/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(self, protocol: Protocol, tab: str = DEFAULT_INDENT):

self.protocol = protocol
self.tab: str = tab
self.native_tab: str = tab
self.native_tab: str = tab # so can still access in case it gets overridden

self.type_mapping: dict[str, str] = {}
self.type_mapping["string"] = "string"
Expand Down
4 changes: 2 additions & 2 deletions beschi/writers/go.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class GoWriter(Writer):
@classmethod
def get_additional_args(cls, parser: argparse.ArgumentParser):
group = parser.add_argument_group(cls.language_name)
group.add_argument("--go-no-rename", action="store_const", const=True, default=False, help="don't rename data members to Uppercase or namespace to lowercase")
group.add_argument("--go-no-rename", action="store_const", const=True, default=False, help="don't rename data members to Uppercase or namespace to snake_case")

def __init__(self, p: Protocol, extra_args: dict[str,any] = {}):
self.rename = not extra_args["go_no_rename"]
Expand Down Expand Up @@ -320,7 +320,7 @@ def generate(self) -> str:
if self.protocol.namespace:
subs.append(("Beschi", self.protocol.namespace))
if self.rename:
subs.append(("beschi", self.protocol.namespace.lower()))
subs.append(("beschi", TextUtil.convert_to_lower_snake_case(self.protocol.namespace)))

self.add_boilerplate(subs)
self.write_line()
Expand Down
5 changes: 2 additions & 3 deletions beschi/writers/zig.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ def deserializer(self, var: Variable, accessor: str, parent_is_simple: bool, sim
self.write_line(f"const {accessor}_{var.name} = (try readNumber({self.type_mapping[var.vartype]}, offset + {simple_offset}, buffer)).value;")
elif var.vartype in self.protocol.enums:
e = self.protocol.enums[var.vartype]
self.write_line(f"const {accessor}_{var.name}_check = (try readNumber({self.type_mapping[e.encoding]}, offset + {simple_offset}, buffer)).value;")
self.write_line(f"")
self.write_line(f"const {accessor}_{var.name} = (try readNumber({var.vartype}, offset + {simple_offset}, buffer)).value;")
else:
self.write_line(f"const {accessor}_{var.name}_read = {var.vartype}.fromBytes({simple_offset}, buffer);")
self.write_line(f"const {accessor}_{var.name}_read = {var.vartype}.fromBytes(offset + {simple_offset}, buffer);")
self.write_line(f"const {accessor}_{var.name} = {accessor}_{var.name}_read.value;")
else:
if var.is_list:
Expand Down
4 changes: 1 addition & 3 deletions docs/dev/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ This file is a rough todo list for the tool itself.
- I still like this idea in the larger sense; feels like a very pragmatic thing to have. In current projects though I'm not quibbling over a few bytes, and the effort of implementing and testing this across all generated languages would be high.

## "immediate" todo
- make multiple message stream a bit smarter (below)
- docstrings in various languages?
- add "IsValid" function to languages where it makes sense:
- check that numbers are in the appropriate range (like JavaScript where everything is everything)
- in languages with strong types enforced by a compiler, skip
Expand Down Expand Up @@ -58,7 +56,7 @@ This file is a rough todo list for the tool itself.
## testing framework
- comparison (size/perf) to flatbuffers/capnproto/etc?
- I'm willing to bet that beschi will lose in performance, but hopefully not by much. There should be a noticeable win in buffer size, though. Enough to justify this project? Eeeeeeh?
- I'm willing to bet that beschi will lose in performance, but hopefully not by much. There should be at lest a small win in buffer size, though. Enough to justify this project? Eeeeeeh?
- And if it's behind in both memory size AND performance, I still like the client-code ergonomics, so maybe not a total loss.
- is there some way to test it with big-endian architecture too so we can be sure it's consistent?
- qemu or something?
Expand Down
2 changes: 1 addition & 1 deletion docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Beschi is a little fast and loose with how it does does code generation. This al

* I make no claims that the generated code is optimal or necessarily even good. It passes [a test suite](./../test/), and I've used it "in production" for personal projects; it seems to work pretty well, but I'm not an expert programmer in all the target languages, so am very open to feedback if there's something that could be improved.
* The test suite is not completely exhaustive. It tests some pathological inputs like infinite inclusion loops and deeply nested structures (for some definition of "deep") but you could probably devise a protocol that would make it fall over. Let me know if you do!
* It makes efforts to generate code that follows the best practices of each language as much as possible, but that code probably won't win any awards from the linters. The test suite runs with warnings as high as possible, but there are a few very specific warnings in each language that it suppresses.
* It makes efforts to generate code that follows the best practices of each language as much as possible, but that code probably won't win any awards from the linters. The test suite runs with warnings as high as recommended by compilers (clang used to run with `-Weverything` but [even they don't recommend that](https://clang.llvm.org/docs/UsersManual.html#diagnostics-enable-everything)), and there are a few very specific warnings in each language that it suppresses.
* It always produces *valid* code (if it does not, that is a bug), but it may not be formatted to your (or `gofmt`'s) liking. If you have strong opinions on that sort of thing, consider running it through a code formatter after generation.
* Beschi makes no attempt to limit variable names other than disallowing whitespace and making sure the protocol itself is valid. That means you could name a data member something that is a reserved word in a target language and it would cause compilation problems. Or you could use emoji for all your struct names because you're only working in Swift and find that nothing works in C. If you call something "return" or "💩" you probably won't be happy, so don't do that; stay happy.
* You cannot at present define more than 255 message types in a single namespace. This is because the identifier tag is a single byte. It hasn't proven to be a limitation for me so far, and it could obviously be expanded if needed.
Expand Down
9 changes: 5 additions & 4 deletions test/_harnesses/c/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
]
# actually, complain about everything
if CC == "clang":
FLAGS += ["-Wall", "-Wextra"]
FLAGS += ["-Weverything"] # clang recommends against this, but lets stay overly pedantic and find as much as possible... for now
# FLAGS += ["-Wall", "-Wextra"] # the recommended setting from clang
else:
# assuming that non-clang is GCC
FLAGS += ["-Wall"]
FLAGS += ["-Wall", "-Wextra"]
FLAGS += [
"-Werror", # loudly
"-Werror", # complain loudly
"-O0", "-g", # have as much debug info as we can
]
SILENCE_WARNINGS = [ # turn off these very specific warnings, though
Expand All @@ -40,7 +41,7 @@
"-std=c99", # c99 is the baseline
]
CSILENCE_WARNINGS = [
"declaration-after-statement", # should not be a problem with > c99, but both LLVM and GCC still warn on it
"declaration-after-statement", # should not be a problem with >= c99, but both LLVM and GCC still warn on it
]
[CFLAGS.append(f"-Wno-{sw}") for sw in CSILENCE_WARNINGS]

Expand Down
82 changes: 41 additions & 41 deletions test/_harnesses/go/basic/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"os"
"path/filepath"

"messages/comprehensivemessage"
"messages/comprehensive_message"
)

var ok bool = true
Expand All @@ -19,7 +19,7 @@ func softAssert(condition bool, label string) {
}

func main() {
var example comprehensivemessage.TestingMessage
var example comprehensive_message.TestingMessage
example.B = 250
example.Tf = true
example.I16 = -32000
Expand All @@ -30,8 +30,8 @@ func main() {
example.Ui64 = 18000000000000000000
example.F = 3.1415927410125732421875
example.D = 2.718281828459045090795598298427648842334747314453125
example.Ee = comprehensivemessage.EnumeratedBeta
example.Es = comprehensivemessage.SpecifiedNegative
example.Ee = comprehensive_message.EnumeratedBeta
example.Es = comprehensive_message.SpecifiedNegative
example.S = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
example.V2.X = 256.512
example.V2.Y = 1024.768
Expand All @@ -42,13 +42,13 @@ func main() {
example.C.G = 128
example.C.B = 0
example.Il = []int16{-1000, 500, 0, 750, 2000}
example.El = []comprehensivemessage.Specified{
comprehensivemessage.SpecifiedNegative,
comprehensivemessage.SpecifiedNegative,
comprehensivemessage.SpecifiedPositive,
comprehensivemessage.SpecifiedZero,
comprehensivemessage.SpecifiedPositive,
comprehensivemessage.SpecifiedZero,
example.El = []comprehensive_message.Specified{
comprehensive_message.SpecifiedNegative,
comprehensive_message.SpecifiedNegative,
comprehensive_message.SpecifiedPositive,
comprehensive_message.SpecifiedZero,
comprehensive_message.SpecifiedPositive,
comprehensive_message.SpecifiedZero,
}
example.Sl = []string{
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
Expand All @@ -59,79 +59,79 @@ func main() {
"用ねぼ雪入文モ段足リフケ報通ンさーを応細めい気川ヤセ車不古6治ニフサコ悩段をご青止ぽっ期年ト量報驚テルユ役1家埋詰軟きぎ。",
"لآخر نشجب ونستنكر هؤلاء الرجال المفتونون بنشوة اللحظة الهائمون في رغبات",
}
var v21 comprehensivemessage.Vec2
var v21 comprehensive_message.Vec2
v21.X = 10.0
v21.Y = 15.0
var v22 comprehensivemessage.Vec2
var v22 comprehensive_message.Vec2
v22.X = 20.0
v22.Y = 25.0
var v23 comprehensivemessage.Vec2
var v23 comprehensive_message.Vec2
v23.X = 30.0
v23.Y = 35.0
var v24 comprehensivemessage.Vec2
var v24 comprehensive_message.Vec2
v24.X = 40.0
v24.Y = 45.0
example.V2l = []comprehensivemessage.Vec2{v21, v22, v23, v24}
var v31 comprehensivemessage.Vec3
example.V2l = []comprehensive_message.Vec2{v21, v22, v23, v24}
var v31 comprehensive_message.Vec3
v31.X = 10.0
v31.Y = 15.0
v31.Z = 17.5
var v32 comprehensivemessage.Vec3
var v32 comprehensive_message.Vec3
v32.X = 20.0
v32.Y = 25.0
v32.Z = 27.5
var v33 comprehensivemessage.Vec3
var v33 comprehensive_message.Vec3
v33.X = 30.0
v33.Y = 35.0
v33.Z = 37.5
var v34 comprehensivemessage.Vec3
var v34 comprehensive_message.Vec3
v34.X = 40.0
v34.Y = 45.0
v34.Z = 47.5
example.V3l = []comprehensivemessage.Vec3{v31, v32, v33, v34}
var c1 comprehensivemessage.Color
example.V3l = []comprehensive_message.Vec3{v31, v32, v33, v34}
var c1 comprehensive_message.Color
c1.R = 255
c1.G = 0
c1.B = 0
var c2 comprehensivemessage.Color
var c2 comprehensive_message.Color
c2.R = 0
c2.G = 255
c2.B = 0
var c3 comprehensivemessage.Color
var c3 comprehensive_message.Color
c3.R = 0
c3.G = 0
c3.B = 255
example.Cl = []comprehensivemessage.Color{c1, c2, c3}
example.Cl = []comprehensive_message.Color{c1, c2, c3}
example.Cx.Identifier = 127
example.Cx.Label = "ComplexDataObject"
example.Cx.BackgroundColor = c1
example.Cx.TextColor = c2
example.Cx.Spectrum = []comprehensivemessage.Color{c3, c2, c1}
example.Cx.Ranges = []comprehensivemessage.Specified{
comprehensivemessage.SpecifiedNegative,
comprehensivemessage.SpecifiedPositive,
example.Cx.Spectrum = []comprehensive_message.Color{c3, c2, c1}
example.Cx.Ranges = []comprehensive_message.Specified{
comprehensive_message.SpecifiedNegative,
comprehensive_message.SpecifiedPositive,
}
var cx1 comprehensivemessage.ComplexData
var cx1 comprehensive_message.ComplexData
cx1.Identifier = 255
cx1.Label = "Complex1"
cx1.BackgroundColor = c3
cx1.TextColor = c1
cx1.Spectrum = []comprehensivemessage.Color{c3, c2, c1, c2, c3}
cx1.Ranges = []comprehensivemessage.Specified{
comprehensivemessage.SpecifiedZero,
comprehensivemessage.SpecifiedPositive,
cx1.Spectrum = []comprehensive_message.Color{c3, c2, c1, c2, c3}
cx1.Ranges = []comprehensive_message.Specified{
comprehensive_message.SpecifiedZero,
comprehensive_message.SpecifiedPositive,
}
var cx2 comprehensivemessage.ComplexData
var cx2 comprehensive_message.ComplexData
cx2.Identifier = 63
cx2.Label = "Complex2"
cx2.BackgroundColor = c1
cx2.TextColor = c3
cx2.Spectrum = []comprehensivemessage.Color{c1, c2, c3, c2, c1}
cx2.Ranges = []comprehensivemessage.Specified{
comprehensivemessage.SpecifiedNegative,
comprehensivemessage.SpecifiedZero,
cx2.Spectrum = []comprehensive_message.Color{c1, c2, c3, c2, c1}
cx2.Ranges = []comprehensive_message.Specified{
comprehensive_message.SpecifiedNegative,
comprehensive_message.SpecifiedZero,
}
example.Cxl = []comprehensivemessage.ComplexData{cx1, cx2}
example.Cxl = []comprehensive_message.ComplexData{cx1, cx2}

readPathPtr := flag.String("read", "", "path to message file for verification")
generatePathPtr := flag.String("generate", "", "path to message file for generation")
Expand All @@ -157,7 +157,7 @@ func main() {
}
defer dat.Close()

input, err := comprehensivemessage.TestingMessageFromBytes(dat)
input, err := comprehensive_message.TestingMessageFromBytes(dat)
softAssert(err == nil, "parsing test message")

softAssert(input.B == example.B, "byte")
Expand Down
6 changes: 3 additions & 3 deletions test/_harnesses/go/broken/broken.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"os"
"path/filepath"

"messages/brokenmessages"
"messages/broken_messages"
)

var ok bool = true
Expand All @@ -19,7 +19,7 @@ func softAssert(condition bool, label string) {
}

func main() {
var broken brokenmessages.TruncatedMessage
var broken broken_messages.TruncatedMessage
broken.X = 1.0
broken.Y = 2.0

Expand All @@ -46,7 +46,7 @@ func main() {
}
defer dat.Close()

_, err = brokenmessages.FullMessageFromBytes(dat)
_, err = broken_messages.FullMessageFromBytes(dat)

softAssert(err != nil, "reading broken message")
softAssert(err.Error() == "Could not read msg.Z at offset 8 (EOF)", "broken error message")
Expand Down
5 changes: 3 additions & 2 deletions test/_harnesses/go/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import builder_util

from beschi.writer import TextUtil


class GoBuilder(builder_util.Builder):
def __init__(self) -> None:
super().__init__("go")
self.lib_src_dirs = [f"messages/{ln.lower()}" for ln in self.libnames]
self.local_libfiles = [os.path.join(lsd, lf.lower()) for lsd, lf in zip(self.lib_src_dirs, self.libfiles)]
self.lib_src_dirs = [f"messages/{TextUtil.convert_to_lower_snake_case(ln)}" for ln in self.libnames]
self.local_libfiles = [os.path.join(lsd, TextUtil.convert_to_lower_snake_case(lf)) for lsd, lf in zip(self.lib_src_dirs, self.libfiles)]



Expand Down
Loading

0 comments on commit e285707

Please sign in to comment.