diff --git a/design/pdl-compiler.md b/design/pdl-compiler.md new file mode 100644 index 0000000..364961d --- /dev/null +++ b/design/pdl-compiler.md @@ -0,0 +1,102 @@ +# PDL Compiler Specification + +Given one or more PDL files representing a protocol, the compiler shall generate +a Go package named "protocol", which shall contain types for message and type +definitions, as well as encoding and decoding methods. + +## Static Section + +The compiler shall write a static section alongside the generated code. It +shall contain this text: + +```go +// Table is a KTV table with an undefined schema. +type Table map[uint16] any + +// Message is any message that can be sent along this protocol. +type Message interface { + codec.Encodable + codec.Decodable + + // Method returns the method code of the message. + Method() uint16 +} +``` + +## Preamble + +At the start of each file but after the package name, the compiler shall emit +this text: + +```go +/* # Do not edit this package by hand! + * + * This file was automatically generated by the Holanet PDL compiler. The + * source file is located at + * Please edit that file instead, and re-compile it to this location. + * + * HOPP, TAPE, METADAPT, PDL/0 (c) 2025 holanet.xyz + */ +``` + +Where `` is the path of the protocol definition file relative to the +generated file. + +## Message Definitions + +For each defined message, the compiler shall generate a Go type named +`MessageName`, where `Name` is the name of the message as written in its +definition. The message shall be encodable, and shall have `Encode` and `Decode` +methods as described below. + +All messages shall satisfy a `Message` interface, which is defined in the +static section. + +## Type Definitions + +For each defined type, the compiler shall generate a Go type with the same name +as written in its definition. The Go type shall be encodable, and shall have +`Encode` and `Decode` methods as described below. + +## Encoding and Decoding Methods + +Each encodable type shall be given an `Encode` method and a `Decode` method, +which will take in a `codec.Encoder` and a `codec.Decoder` respectively. Both +return an `(int, error)` pair describing the amount of bytes written and an +error if the write stopped early. `Encode` will encode the data within the +message to the given encoder, and `Decode` will decode data from the given +decoder and place it in the type's value. The methods shall not retain or close +any encoders or decoders they are given. Both methods shall have pointer +receivers. In effect, these methods will satisfy `codec.Encodable` and +`codec.Decodable`. + +## Connection + +The compiler shall generate a `Conn` struct which embeds a `hopp.Conn`, which +is the real "porcelain" of the generated code. It shall provide methods to +create and accept transactions. Each transaction shall be a struct which embeds +a `hopp.Trans`, and shall have methods for sending and receiving messages. + +### Sending + +To send a message along a transaction, the program shall: + +1. Obtain the method code from the message +3. Obtain a writer from the connection using the method code +4. Wrap the writer in a `codec.Encoder` +5. Use the encoder to encode the message +6. Close the writer + +### Receiving + +To receiving a message from a transaction, the program shall: + +1. Obtain a method code and reader from the connection +2. Wrap the reader in a `codec.Decoder` +3. Switch on the method code, and decode the correct message using the decoder +4. Return the message to the caller as a value + +The recieve function must return the message as a value instead of a pointer in +order to avoid making an allocation. Because of this, the return value must be +`any` instead of `Message`. The caller must then use a type switch to figure out +what message was sent. diff --git a/design/pdl.md b/design/pdl.md index b39da72..dfbc6cf 100644 --- a/design/pdl.md +++ b/design/pdl.md @@ -108,80 +108,3 @@ Below is an EBNF description of the language. -> -> ``` - -## Go Code Generation - -Given one or more PDL files representing a protocol, the compiler shall generate -a Go package named "protocol", which shall contain types for message and type -definitions, as well as encoding and decoding methods. - -### Static Section - -The compiler shall write a static section alongside the generated code. It -shall contain this text: - -```go -// Table is a KTV table with an undefined schema. -type Table map[uint16] any - -// Message is any message that can be sent along this protocol. -type Message interface { - codec.Encodable - codec.Decodable - - // Method returns the method code of the message. - Method() uint16 -} -``` - -### Preamble - -At the start of each file but after the package name, the compiler shall emit -this text: - -```go -/* # Do not edit this package by hand! - * - * This file was automatically generated by the Holanet PDL compiler. The - * source file is located at - * Please edit that file instead, and re-compile it to this location. - * - * HOPP, TAPE, METADAPT, PDL/0 (c) 2025 holanet.xyz - */ -``` - -Where `` is the path of the protocol definition file relative to the -generated file. - -### Message Definitions - -For each defined message, the compiler shall generate a Go type named -`MessageName`, where `Name` is the name of the message as written in its -definition. The message shall be encodable, and shall have `Encode` and `Decode` -methods as described below. - -All messages shall satisfy a `Message` interface, which is defined in the -static section. - -### Type Definitions - -For each defined type, the compiler shall generate a Go type with the same name -as written in its definition. The Go type shall be encodable, and shall have -`Encode` and `Decode` methods as described below. - -### Encoding and Decoding Methods - -Each encodable type shall be given an `Encode` method and a `Decode` method, -which will take in a `codec.Encoder` and a `codec.Decoder` respectively. Both -return an `(int, error)` pair describing the amount of bytes written and an -error if the write stopped early. `Encode` will encode the data within the -message to the given encoder, and `Decode` will decode data from the given -decoder and place it in the type's value. The methods shall not retain or close -any encoders or decoders they are given. Both methods shall have pointer -receivers. In effect, these methods will satisfy `codec.Encodable` and -`codec.Decodable`. - -### Connection - -The compiler shall generate a `Conn` struct which embeds a `hopp.Conn`, which -is the real "porcelain" of the generated code. Any