diff options
| author | Paul Buetow <paul@buetow.org> | 2024-02-19 18:32:34 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2024-02-20 01:37:34 +0200 |
| commit | 24c8a46b870bbd7feb69a918e9a66a3011ef5c14 (patch) | |
| tree | e71e500b85306c482b2fb9209625716cd9b8decd /internal/generated/generate.raku | |
| parent | a112b65937d1ca5368de2791419a3451be9bc254 (diff) | |
initial play around with code generation from C to Go in Raku
Diffstat (limited to 'internal/generated/generate.raku')
| -rw-r--r-- | internal/generated/generate.raku | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/internal/generated/generate.raku b/internal/generated/generate.raku new file mode 100644 index 0000000..babb655 --- /dev/null +++ b/internal/generated/generate.raku @@ -0,0 +1,57 @@ +#!/usr/bin/env raku +# +# This Raku program takes a list of C struct and constant definitions and converts +# it to valid Go code. + +#use Grammar::Debugger; + +# Not quite C +grammar NQC { + rule TOP { <construct>* } + rule construct { <constant> | <statement> || <comment> } + rule constant { '#define' <identifier> <number> } + rule statement { <struct> ';' } + rule struct { 'struct' <identifier> '{' <member>+ %% ';' '}' } + rule member { <type> <identifier> <arraysize>? } + rule comment { <single-line-comment> | <multi-line-comment> } + rule single-line-comment { '//' <-[\n]>+ } + rule multi-line-comment { '/*' .*? '*/' } + token arraysize { '[' <identifier> ']' } + token type { 'char' | '__s32' | '__u32' | '__u64' } + token identifier { <[a..z A..Z 0..9 _]>+ } + token number { \d+ } +} + +class NQCToGoActions { + method TOP($/) { make "package types\n\n" ~ $<construct>.map(*.made).join('') } + method construct($/) { make $<constant>.made // $<statement>.made // '' } + method statement($/) { make "\n" ~ $<struct>.made ~ "\n"; } + method constant($/) { make 'const ' ~ $<identifier> ~ ' = ' ~ $<number> ~ "\n" } + + method struct($/) { + make 'type ' ~ $<identifier>.made ~ " struct \{\n\t" ~ + $<member>.map(*.made).join("\n\t") ~ "\n\}" + } + + method member($/) { + make $<identifier>.made ~ ' ' ~ ($<arraysize> ?? $<arraysize> !! '') ~ $<type>.made + } + + method type($/) { + make do given ~$/ { + when 'char' { 'byte' } + when '__s32' { 'int32' } + when '__u32' { 'uint32' } + when '__u64' { 'uint64' } + }; + } + + method identifier($/) { + # Convert identifier from snake_case (C) to CamelCase (Go) + make $/.Str.split('_').map(*.tc).join('') + } +} + +multi sub MAIN('nqctogo') { + NQC.parse($*IN.slurp, :actions(NQCToGoActions.new)).made.say; +} |
