Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/senselogic/GENERIS
Versatile Go code generator.
https://github.com/senselogic/GENERIS
code-generator conditional-compilation conversion generics golang html-templating style
Last synced: 14 days ago
JSON representation
Versatile Go code generator.
- Host: GitHub
- URL: https://github.com/senselogic/GENERIS
- Owner: senselogic
- License: gpl-3.0
- Created: 2019-03-10T19:33:31.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2022-02-22T21:26:01.000Z (over 2 years ago)
- Last Synced: 2024-07-31T20:51:43.469Z (3 months ago)
- Topics: code-generator, conditional-compilation, conversion, generics, golang, html-templating, style
- Language: D
- Homepage:
- Size: 311 KB
- Stars: 43
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
- awesome-go - generis - Code generation tool providing generics, free-form macros, conditional compilation and HTML templating. (Generators / Search and Analytic Databases)
- awesome-go-extra - GENERIS - 03-10T19:33:31Z|2022-02-22T21:26:01Z| (Generators / Utility/Miscellaneous)
README
![](https://github.com/senselogic/GENERIS/blob/master/LOGO/generis.png)
# Generis
Versatile Go code generator.
## Description
Generis is a lightweight code preprocessor adding the following features to the Go language :
* Generics.
* Free-form macros.
* Conditional compilation.
* HTML templating.
* Allman style conversion.## Sample
```go
package main;// -- IMPORTS
import (
"html"
"io"
"log"
"net/http"
"net/url"
"strconv"
);// -- DEFINITIONS
#define DebugMode
#as true// ~~
#define HttpPort
#as 8080// ~~
#define WriteLine( {{text}} )
#as log.Println( {{text}} )// ~~
#define local {{variable}} : {{type}};
#as var {{variable}} {{type}};// ~~
#define DeclareStack( {{type}}, {{name}} )
#as
// -- TYPEStype {{name}}Stack struct
{
ElementArray []{{type}};
}// -- INQUIRIES
func ( stack * {{name}}Stack ) IsEmpty(
) bool
{
return len( stack.ElementArray ) == 0;
}// -- OPERATIONS
func ( stack * {{name}}Stack ) Push(
element {{type}}
)
{
stack.ElementArray = append( stack.ElementArray, element );
}// ~~
func ( stack * {{name}}Stack ) Pop(
) {{type}}
{
local
element : {{type}};element = stack.ElementArray[ len( stack.ElementArray ) - 1 ];
stack.ElementArray = stack.ElementArray[ : len( stack.ElementArray ) - 1 ];
return element;
}
#end// ~~
#define DeclareStack( {{type}} )
#as DeclareStack( {{type}}, {{type:PascalCase}} )// -- TYPES
DeclareStack( string )
DeclareStack( int32 )// -- FUNCTIONS
func HandleRootPage(
response_writer http.ResponseWriter,
request * http.Request
)
{
local
boolean : bool;
local
natural : uint;
local
integer : int;
local
real : float64;
local
escaped_html_text,
escaped_url_text,
text : string;
local
integer_stack : Int32Stack;boolean = true;
natural = 10;
integer = 20;
real = 30.0;
text = "text";
escaped_url_text = "&escaped text?";
escaped_html_text = "";integer_stack.Push( 10 );
integer_stack.Push( 20 );
integer_stack.Push( 30 );#write response_writer
<%= request.URL.Path %>
<% if ( boolean ) { %>
<%= "URL : " + request.URL.Path %>
<%@ natural %>
<%# integer %>
<%& real %>
<%~ text %>
<%^ escaped_url_text %>
<%= escaped_html_text %>
<%= "<%% ignored %%>" %>
<%% ignored %%>
<% } %>
Stack :
<% for !integer_stack.IsEmpty() { %>
<%# integer_stack.Pop() %>
<% } %>
#end
}// ~~
func main()
{
http.HandleFunc( "/", HandleRootPage );#if DebugMode
WriteLine( "Listening on http://localhost:HttpPort" );
#endlog.Fatal(
http.ListenAndServe( ":HttpPort", nil )
);
}
```## Syntax
### #define directive
Constants and generic code can be defined with the following syntax :
```go
#define old code
#as new code#define old code
#as
new
code
#end#define
old
code
#as new code#define
old
code
#as
new
code
#end
```#### #define parameter
The `#define` directive can contain one or several parameters :
```go
{{variable name}} : hierarchical code (with properly matching brackets and parentheses)
{{variable name#}} : statement code (hierarchical code without semicolon)
{{variable name$}} : plain code
{{variable name:boolean expression}} : conditional hierarchical code
{{variable name#:boolean expression}} : conditional statement code
{{variable name$:boolean expression}} : conditional plain code
```They can have a boolean expression to require they match specific conditions :
```go
HasText text
HasPrefix prefix
HasSuffix suffix
HasIdentifier text
false
true
!expression
expression && expression
expression || expression
( expression )
```The `#define` directive must not start or end with a parameter.
#### #as parameter
The `#as` directive can use the value of the `#define` parameters :
```go
{{variable name}}
{{variable name:filter function}}
{{variable name:filter function:filter function:...}}
```Their value can be changed through one or several filter functions :
```go
LowerCase
UpperCase
MinorCase
MajorCase
SnakeCase
PascalCase
CamelCase
RemoveComments
RemoveBlanks
PackStrings
PackIdentifiers
ReplacePrefix old_prefix new_prefix
ReplaceSuffix old_suffix new_suffix
ReplaceText old_text new_text
ReplaceIdentifier old_identifier new_identifier
AddPrefix prefix
AddSuffix suffix
RemovePrefix prefix
RemoveSuffix suffix
RemoveText text
RemoveIdentifier identifier
```### #if directive
Conditional code can be defined with the following syntax :
```go
#if boolean expression
#if boolean expression
...
#else
...
#end
#else
#if boolean expression
...
#else
...
#end
#end
```The boolean expression can use the following operators :
```go
false
true
!expression
expression && expression
expression || expression
( expression )
```### #write directive
Templated HTML code can be sent to a stream writer using the following syntax :
```html
#write writer expression
<% code %>
<%@ natural expression %>
<%# integer expression %>
<%& real expression %>
<%~ text expression %>
<%= escaped text expression %>
<%! removed content %>
<%% ignored tags %%>
#end
```## Limitations
* There is no operator precedence in boolean expressions.
* The `--join` option requires to end the statements with a semicolon.
* The `#writer` directive is only available for the Go language.## Installation
Install the [DMD 2 compiler](https://dlang.org/download.html) (using the MinGW setup option on Windows).
Build the executable with the following command line :
```bash
dmd -m64 generis.d
```## Command line
```
generis [options]
```### Options
```
--prefix # : set the command prefix
--parse INPUT_FOLDER/ : parse the definitions of the Generis files in the input folder
--process INPUT_FOLDER/ OUTPUT_FOLDER/ : reads the Generis files in the input folder and writes the processed files in the output folder
--trim : trim the HTML templates
--join : join the split statements
--create : create the output folders if needed
--watch : watch the Generis files for modifications
--pause 500 : time to wait before checking the Generis files again
--tabulation 4 : set the tabulation space count
--extension .go : generate files with this extension
```### Examples
```bash
generis --process GS/ GO/
```Reads the Generis files in the `GS/` folder and writes Go files in the `GO/` folder.
```bash
generis --process GS/ GO/ --create
```Reads the Generis files in the `GS/` folder and writes Go files in the `GO/` folder,
creating the output folders if needed.```bash
generis --process GS/ GO/ --create --watch
```Reads the Generis files in the `GS/` folder and writes Go files in the `GO/` folder,
creating the output folders if needed and watching the Generis files for modifications.```bash
generis --process GS/ GO/ --trim --join --create --watch
```Reads the Generis files in the `GS/` folder and writes Go files in the `GO/` folder,
trimming the HTML templates, joining the split statements, creating the output folders if needed
and watching the Generis files for modifications.## Version
2.0
## Author
Eric Pelzer ([email protected]).
## License
This project is licensed under the GNU General Public License version 3.
See the [LICENSE.md](LICENSE.md) file for details.