Skip to content
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

Nim 0.19/devel compatibility #42

Closed
wants to merge 10 commits into from
4 changes: 2 additions & 2 deletions docs/docbuild.nim
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ proc fixupHrefs(file: string) =

proc getGitHash(): string =
result = execProcess("git rev-parse HEAD")
if not result.isNil and result.len > 0:
if result.len > 0:
result = result.replace("\L", "").replace("\r", "")

proc buildDocs*(outDir, godotNimDir, godotBin: string) =
Expand Down Expand Up @@ -112,7 +112,7 @@ proc buildDocs*(outDir, godotNimDir, godotBin: string) =
var gitHash: string
withDir(godotBinAbs.parentDir()):
gitHash = getGitHash()
if gitHash.isNil or gitHash.len == 0:
if gitHash.len == 0:
raise newException(Exception,
"Godot executable is not under Git repository")

Expand Down
9 changes: 3 additions & 6 deletions godot/core/variants.nim
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,9 @@ proc newVariant*(r: cdouble): Variant {.inline.} =

proc newVariant*(s: string): Variant {.inline.} =
new(result, variantFinalizer)
if s.isNil:
initGodotVariant(result.godotVariant)
else:
var godotStr = s.toGodotString()
initGodotVariant(result.godotVariant, godotStr)
godotStr.deinit()
var godotStr = s.toGodotString()
initGodotVariant(result.godotVariant, godotStr)
godotStr.deinit()

import basis, nodepaths
import planes, quats, rect2, aabb, rids
Expand Down
95 changes: 52 additions & 43 deletions godot/godotapigen.nim
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Copyright 2018 Xored Software, Inc.

import streams, json, os, strutils, times, sets, tables
import streams, json, os, strutils, times, sets, tables, options
import sequtils, algorithm
import compiler.ast, compiler.renderer, compiler.idents, compiler.astalgo

when (NimMajor, NimMinor, NimPatch) >= (0, 19, 0):
var gic* = newIdentCache()

proc getIdent(ident: string): PIdent =
getIdent(gic, ident)

proc ident(ident: string): PNode =
result = newNode(nkIdent)
result.ident = getIdent(ident)
Expand Down Expand Up @@ -139,19 +145,19 @@ proc findCommonRoot(typeRegistry: Table[string, GodotType],

var idx = 0
while true:
var curType: string
var curType = none(string)
var allEqual = true
for chain in chains:
if idx >= chain.len:
allEqual = false
break
if curType.isNil:
curType = chain[idx]
elif curType != chain[idx]:
if curType.isNone:
curType = some(chain[idx])
elif curType.get != chain[idx]:
allEqual = false
break
if allEqual:
result = curType
result = curType.get
else:
break
inc idx
Expand Down Expand Up @@ -224,7 +230,7 @@ proc newRefTypeNode(typeSection: PNode, typ, base, doc: string,
inherit.add(ident(base))
objTy.add(inherit)

if not doc.isNil:
if doc.len > 0:
let recList = newNode(nkRecList)
let docNode = newNode(nkCommentStmt)
docNode.comment = doc
Expand Down Expand Up @@ -275,7 +281,7 @@ type
godotName: string
typ: GodotType
args: seq[MethodArg]
returnType: string
returnType: Option[string]
isVirtual: bool
isBase: bool
isDiscardable: bool
Expand Down Expand Up @@ -428,15 +434,15 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
newCStringLit(meth.godotName))
)
let vars = newNode(nkVarSection)
var varargsName: string
var varargsName = none(string)
var isVarargs: bool
var staticArgsLen: int
var argLenNode = newIntLit(0)
let argsName = ident("argsToPassToGodot")
if meth.args.len > 0:
for idx, arg in meth.args:
if arg.kind == ArgKind.VarArgs:
varargsName = arg.name
varargsName = some(arg.name)
isVarargs = true
vars.add(newIdentDefs(ident("callError"), ident("VariantCallError")))
elif arg.kind == ArgKind.Bound:
Expand All @@ -450,13 +456,13 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
ident("array"), ident("MAX_ARG_COUNT"),
if isVarargs: newNode(nkPtrTy).addChain(ident("GodotVariant"))
else: ident("pointer"))))
staticArgsLen = if varargsName.isNil: meth.args.len
staticArgsLen = if varargsName.isSome: meth.args.len
Copy link

@adrianperreault adrianperreault Mar 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo? Should it be if varargsName.isNone?

else: meth.args.len - 1
if not varargsName.isNil:
if varargsName.isSome:
argLenNode = newCall("cint",
infix(newIntLit(staticArgsLen),
ident("+"),
newDotExpr(ident(varargsName), ident("len"))))
newDotExpr(ident(varargsName.get), ident("len"))))
argsAlloc.add(newCall("godotAlloc", newCall("cint", infix(
newCall("sizeof", ident("Variant")), ident("*"),
newNode(nkPar).addChain(argLenNode))))
Expand All @@ -477,12 +483,12 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
else: ident(arg.name)
if arg.kind == ArgKind.VarArgs:
argName = newNode(nkBracketExpr).addChain(
ident(varargsName),
ident(varargsName.get),
infix(ident("idx"), ident("-"), newIntLit(staticArgsLen)))
let argIdx = if arg.kind == ArgKind.VarArgs: ident("idx") else: newIntLit(idx)
let isStandardType = arg.typ in standardTypes
let isWrappedType = arg.typ in wrapperTypes
let convArg = if not varargsName.isNil:
let convArg = if varargsName.isSome:
getInternalPtr(newCall("toVariant", argName), "Variant")
elif isWrappedType: getInternalPtr(argName, arg.typ)
elif isStandardType: newCall("unsafeAddr", argName)
Expand All @@ -493,7 +499,7 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
raise newException(ValueError,
"Non-standard type $# for varargs params of method $# of type $#" %
[arg.typ, meth.godotName, meth.typ.godotName])
if not isStandardType and varargsName.isNil:
if not isStandardType and varargsName.isNone:
if arg.typ == "string":
argConversions.add(newNode(nkVarSection).addChain(
newIdentDefs(ident("argToPassToGodot" & $idx), newEmptyNode(),
Expand Down Expand Up @@ -560,31 +566,32 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
var isStringRet: bool
var isWrapperRet: bool
let retValIdent = if not isVarargs: ident("ptrCallVal") else: ident(retName)
if not meth.returnType.isNil and not isVarargs:
if meth.returnType.isSome and not isVarargs:
let returnType = meth.returnType.get
var addrToAssign = newCall("addr", retValIdent)
if meth.returnType in smallIntTypes:
if returnType in smallIntTypes:
isConversionRet = true
body.add(newNode(nkVarSection).addChain(newIdentDefs(
retValIdent, ident("int64"),
)))
elif meth.returnType in float32Types:
elif returnType in float32Types:
isConversionRet = true
body.add(newNode(nkVarSection).addChain(newIdentDefs(
retValIdent, ident("float64"),
)))
elif meth.returnType in wrapperTypes:
elif returnType in wrapperTypes:
isWrapperRet = true
body.add(newNode(nkVarSection).addChain(newIdentDefs(
retValIdent, ident("Godot" & meth.returnType),
retValIdent, ident("Godot" & returnType),
)))
elif meth.returnType in standardTypes:
elif returnType in standardTypes:
addrToAssign = newCall("addr", ident("result"))
elif meth.returnType == "string":
elif returnType == "string":
isStringRet = true
body.add(newNode(nkVarSection).addChain(newIdentDefs(
retValIdent, ident("GodotString"),
)))
elif meth.returnType != "void":
elif returnType != "void":
isObjRet = true
body.add(newNode(nkVarSection).addChain(newIdentDefs(
retValIdent, newNode(nkPtrTy).addChain(ident("GodotObject")),
Expand All @@ -594,7 +601,7 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
if not isVarargs:
body.add(theCall)
else:
if not meth.returnType.isNil:
if meth.returnType.isSome:
isVariantRet = true
let callStmt = newNode(nkLetSection).addChain(
newIdentDefs(
Expand All @@ -603,14 +610,14 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
newNode(nkEmpty), theCall))
body.add(callStmt)

if varargsName.isNil:
if varargsName.isNone:
for idx, arg in meth.args:
if arg.typ == "string":
body.add(newCall("deinit", ident("argToPassToGodot" & $idx)))

if meth.args.len > 0 and not varargsName.isNil:
if meth.args.len > 0 and varargsName.isSome:
body.add(freeCall)
if not varargsName.isNil:
if varargsName.isSome:
let errCheck = newIfStmt(
infix(newDotExpr(ident("callError"), ident("error")), ident("!="),
newDotExpr(ident("VariantCallErrorType"), ident("OK"))),
Expand Down Expand Up @@ -638,11 +645,11 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
elif isConversionRet:
body.add(newNode(nkAsgn).addChain(
ident("result"),
newCall(meth.returnType, retValIdent)))
newCall(meth.returnType.get, retValIdent)))
elif isWrapperRet:
body.add(newNode(nkAsgn).addChain(
ident("result"),
newCall("new" & meth.returnType, retValIdent)))
newCall("new" & meth.returnType.get, retValIdent)))
elif isObjRet:
body.add(newNode(nkAsgn).addChain(ident("result"),
newCall(newBracketExpr(ident("asNimGodotObject"),
Expand All @@ -655,8 +662,8 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
let procType = if meth.isVirtual: nkMethodDef
else: nkProcDef
var params = newSeqOfCap[PNode](meth.args.len + 2)
if not meth.returnType.isNil:
params.add(ident(meth.returnType))
if meth.returnType.isSome:
params.add(ident(meth.returnType.get))
else:
params.add(newNode(nkEmpty))
if not meth.typ.isSingleton:
Expand Down Expand Up @@ -684,7 +691,7 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string],
if meth.isVirtual and meth.isBase and meth.typ.name != "PhysicsBody":
# Nim doesn't like `base` on PhysicsBody methods - wtf
pragma.add(ident("base"))
if meth.isDiscardable and not meth.returnType.isNil:
if meth.isDiscardable and meth.returnType.isSome:
pragma.add(ident("discardable"))
procDecl.sons[4] = pragma
tree.add(procDecl)
Expand Down Expand Up @@ -729,8 +736,8 @@ proc getMethodInfo(methodObj: JsonNode, types: Table[string, GodotType],
nimName = nimName & "Impl"

let returnType = if methodObj["return_type"].str != "void":
toNimType(types, methodObj["return_type"].str)
else: nil
some(toNimType(types, methodObj["return_type"].str))
else: none(string)
const discardableMethods = toSet(["emit_signal"])
result = MethodInfo(
name: ident(nimName),
Expand Down Expand Up @@ -764,13 +771,13 @@ proc makeProperty(types: Table[string, GodotType], tree: PNode,

let getter = findMethod(obj, propertyObj["getter"].str)
let nimType = if getter.isNil: toNimType(types, propertyObj["type"].str)
else: getMethodInfo(getter, types, typ).returnType
else: getMethodInfo(getter, types, typ).returnType.get("void")
let getterInfo = MethodInfo(
name: getterName,
typ: typ,
godotName: propertyObj["getter"].str,
args: @[],
returnType: nimType
args: newSeq[MethodArg](),
returnType: some(nimType)
)
let setterInfo = MethodInfo(
name: setterName,
Expand All @@ -779,10 +786,12 @@ proc makeProperty(types: Table[string, GodotType], tree: PNode,
args: @[MethodArg(name: "val", typ: nimType)]
)
if "index" in propertyObj and propertyObj["index"] != newJInt(-1):
getterInfo.args = @[MethodArg(defaultVal: newJString($propertyObj["index"]),
typ: "int", kind: ArgKind.Bound)] & getterInfo.args
setterInfo.args = @[MethodArg(defaultVal: newJString($propertyObj["index"]),
typ: "int", kind: ArgKind.Bound)] & setterInfo.args
getterInfo.args =
@[MethodArg(defaultVal: newJString($propertyObj["index"]),
typ: "int", kind: ArgKind.Bound)] & getterInfo.args
setterInfo.args =
@[MethodArg(defaultVal: newJString($propertyObj["index"]),
typ: "int", kind: ArgKind.Bound)] & setterInfo.args
generateMethod(tree, methodBindRegistry, getterInfo, withImplementation)
generateMethod(tree, methodBindRegistry, setterInfo, withImplementation)

Expand Down Expand Up @@ -920,7 +929,7 @@ proc genApi*(targetDir: string, apiJsonFile: string) =
let className = godotClassName.replace("_", "")
var baseClassName = obj["base_class"].str
baseClassName = toNimType(baseClassName.replace("_", ""))
if baseClassName.isNil or baseClassName.len == 0:
if baseClassName.len == 0:
baseClassName = "NimGodotObject"
var doc = ""
for attr in classAttributes:
Expand Down
5 changes: 1 addition & 4 deletions godot/internal/godotstrings.nim
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ proc `$`*(self: GodotString): string =

proc toGodotString*(s: string): GodotString {.inline.} =
## Converts the Nim string into ``GodotString``
if s.isNil:
initGodotString(result)
else:
initGodotString(result, cstring(s), cint(s.len + 1))
initGodotString(result, cstring(s), cint(s.len + 1))

proc toGodotString*(s: cstring): GodotString {.inline.} =
## Converts the cstring into ``GodotString``
Expand Down
Loading