Skip to content

Instantly share code, notes, and snippets.

@edubart
Last active April 5, 2020 00:37
Show Gist options
  • Save edubart/17c463997961a6e7dc88e54e260eeab8 to your computer and use it in GitHub Desktop.
Save edubart/17c463997961a6e7dc88e54e260eeab8 to your computer and use it in GitHub Desktop.
c2nelua rudimentar experiment
local re = require 'relabel'
local file = require 'pl.file'
local stringx = require 'pl.stringx'
local grammar = [[
body <- {| line+ |}
line <- (extern / anyline)
anyline <- linerest
linerest<- [^;]* ';' sp
sp <- %s*
esp <- %s+
extern <-
('extern' esp ctype fname
lparen funcargs rparen) -> "function C.%2(%3): %1 <cimport'%2'> end"
linerest cnl
funcargs <- {~ (funcarg (comma funcarg)*)? ~}
funcarg <- (ctype restrict? (name / '' -> 'x')) -> '%2: %1'
ctype <- (
pointer /
struct /
primtype /
name /
varargs /
%{UnhandledCtype}
) sp
restrict <- '__'? 'restrict' sp
varargs <- {'...'} sp
pointer <-
('void' sp '*' sp) -> 'pointer' /
('const' esp)? {~ (primtype / struct / name) sp -> '' {'*'+} ~}
struct <-
'struct' sp name
primtype <-
'unsigned long long int' -> 'culonglong' /
'unsigned long long' -> 'culonglong' /
'unsigned long int' -> 'culong' /
'unsigned long' -> 'culong' /
'unsigned int' -> 'cuint' /
'unsigned short int' -> 'cushort' /
'unsigned short' -> 'cushort' /
'unsigned char' -> 'cuchar' /
'long long int' -> 'clonglong' /
'long long' -> 'clonglong' /
'long int' -> 'clong' /
'long double' -> 'clongdouble' /
'long' -> 'clong' /
'int' -> 'cint' /
'short int' -> 'cshort' /
'short' -> 'cshort' /
'signed char' -> 'cschar' /
'char' -> 'cchar' /
'float' -> 'float32' /
'double' -> 'float64' /
'intptr_t' -> 'isize' /
'int8_t' -> 'int8' /
'int16_t' -> 'int16' /
'int32_t' -> 'int32' /
'int64_t' -> 'int64' /
'uintptr_t' -> 'usize' /
'uint8_t' -> 'uint8' /
'uint16_t' -> 'uint16' /
'uint32_t' -> 'uint32' /
'uint64_t' -> 'uint64' /
'void' -> 'void' /
'ptrdiff_t' -> 'cptrdiff' /
'size_t' -> 'csize' /
'bool' -> 'boolean'
name <- '_'* {[_%w]+} sp
fname <- '_'* {[_%w]+} sp
comma <- ',' sp
lparen <- '(' sp
rparen <- ')' sp
cnl <- ''->nl
csp <- ''-> ' '
]]
local defs = {
nl = function() return '\n' end
}
local function sortlines(text)
local lines = stringx.split(text, '\n')
table.sort(lines)
return table.concat(lines, '\n')
end
local function convert(headerfile)
local source = file.read(headerfile)
if not source then
error('no header found')
end
local sourcegrammar = grammar:gsub('SOURCEFILE', '<'..headerfile..'>')
local pat = re.compile(sourcegrammar, defs)
local res, _, errpos = pat:match(source)
if not res then
error(string.format('failed: %s', source:sub(errpos, errpos+100)))
end
local text = table.concat(res)
--text = sortlines(text)
local outfile = headerfile:gsub('%.h', '.nelua')
file.write(outfile, text)
print(text)
end
-- first generate preprocessed C headers using this Makefile:
--[[
CC=gcc
CFLAGS=-std=c17 -E -P -xc -
CHEADERS= \
assert.h complex.h ctype.h errno.h \
fenv.h float.h inttypes.h iso646.h \
limits.h locale.h math.h setjmp.h \
signal.h stdalign.h stdarg.h stdatomic.h \
stdbool.h stddef.h stdint.h stdio.h \
stdlib.h stdnoreturn.h string.h \
tgmath.h threads.h time.h \
uchar.h wchar.h wctype.h
all: $(CHEADERS)
%.h:
echo '#include <$@>' | $(CC) $(CFLAGS) | sed "/^$$/d" > $@
clean:
rm -f *.h
]]
convert('stdlib.h')
convert('string.h')
convert('stdio.h')
convert('time.h')
convert('signal.h')
convert('locale.h')
convert('errno.h')
convert('ctype.h')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment