-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plan to rewrite the generator scripts. #111
Comments
mwe for the second program: import
compiler/[ast, parser, idents, astalgo, pathutils, condsyms, renderer,
options, nimconf, extccomp, modulegraphs], std/[os, strutils]
# need to run ./koch checksums
proc str(n: PNode): string =
case n.kind
of nkStrLit..nkTripleStrLit:
result = n.strVal
of nkIdent:
result = n.ident.s
of nkSym:
result = n.sym.name.s
of nkOpenSymChoice, nkClosedSymChoice:
result = n.sons[0].sym.name.s
else:
assert false
proc basename(n: PNode): PNode =
case n.kind
of nkIdent: result = n
of nkPragmaExpr:
result = basename(n[0])
of nkPostfix, nkPrefix:
result = basename(n[1])
of nkAccQuoted:
result = basename(n[0])
else:
assert false
proc eqIdent(a: string; b: string): bool =
result = cmpIgnoreStyle(a, b) == 0
proc eqIdent(a: PNode, b: string): bool =
result = cmpIgnoreStyle(a.basename.str, b) == 0
proc eqIdent(a, b: PNode): bool =
result = cmpIgnoreStyle(a.basename.str, b.basename.str) == 0
proc groupMatrixFieldsByRow(node: PNode) =
const MatN = 4 # assumes a 4x4 matrix
case node.kind
of nkTypeSection:
for child in node.items:
if child.kind == nkTypeDef and eqIdent(child[0], "Matrix"):
let reclist = child[2][2]
if reclist.len != MatN*MatN: return
for i in countdown(reclist.len-1, 0, MatN):
for j in countdown(i-1, i-MatN+1):
reclist[i].sons.insert(reclist[j][0])
for i in countdown(reclist.len-1, 0):
if (i + 1) mod 4 != 0:
reclist.sons.delete(i)
else:
discard
for child in node.items:
groupMatrixFieldsByRow(child)
proc main =
# Create a new configuration and module graph
let conf = newConfigRef()
let cache = newIdentCache()
let graph = newModuleGraph(cache, conf)
# Initialize defines and load configurations
condsyms.initDefines(conf.symbols)
conf.projectName = "stdinfile"
conf.projectFull = "stdinfile".AbsoluteFile
conf.projectPath = canonicalizePath(conf, getCurrentDir().AbsoluteFile).AbsoluteDir
conf.projectIsStdin = true
loadConfigs(DefaultConfig, cache, conf, graph.idgen)
# Initialize external compiler variables
extccomp.initVars(conf)
# Parse input file
let filename = "input.nim"
let node = parseString(readFile(filename), cache, conf)
# Apply postprocessing steps
node.groupMatrixFieldsByRow()
# Render the module to an output file
renderModule(node, filename, {renderDocComments})
main() |
Something similar was done in https://github.com/nim-lang/c2nim/blob/araq-gobject/gobject2nim.nim |
I was ignoring the easiest solution which is a wrapping macro like: https://github.com/nim-lang/opengl/blob/master/src/opengl/private/errors.nim Thanks to that you have the ability to influence the wrapper per project with defines: Maybe per #102 this can be used to make raylib accept int/float types instead of int32/float32 for people that don't care. There're helpful macros for this purpose as well: https://github.com/geekrelief/genit |
It's great that you're documenting the progress here via issues! |
Nah waste of time, instead the existing scripts were refactored. |
The scripts that are used to generate the wrapper have grown in complexity and are difficult to understand and modify. Experience has shown that trying to modify the produced nim code from a representation like, json, xml, etc, that the generators are using, leads to horrible, unmaintanable code. This is better done at the nim AST level. So to evolve the scripts, keep the maintenance cost down, make them easily extensive, the two separate tasks of parsing the C header definitions and outputting bindings, and making an idiomatic nim wrapper based on those bindings, should use two different programs. The bindings parser, can use the raylib_parser for a start, or eventually be ported to c2nim/furthark. It doesn't attempt to do any transformations and use the c types. This is necessary as upstream will not improve it to parse other headers than raylib.h correctly, it half works with rlgl.h and requires manual intervention. Another program the wrapper generator, makes use of the compiler as a library, and parses the bindings it traverses the nim ast and writes our wrapper in a file.
The text was updated successfully, but these errors were encountered: