Commit 0dff195779e5a8b7e5f9f6d278a2c4a6a2cebb7b

Authored by Göran Krampe
2 parents d25d32db e454a5e9

Merge branch 'master' of gitlab.3dicc.com:3dicc/squeaknim

src/squeaknim.nim
... ... @@ -88,24 +88,33 @@ template writeExternalLibrary*() =
88 88 "!$1 class methodsFor: 'primitives' stamp: 'SqueakNim'!\C",
89 89 gPrefix & capitalize(dllName), capitalize(dllName))
90 90  
91   -template writeSmallTalkCode*(filename: string) =
92   - ## You need to invoke this template to write the produced SmallTalk code to
  91 +template writeSmalltalkCode*(filename: string) =
  92 + ## You need to invoke this template to write the produced Smalltalk code to
93 93 ## a file.
94 94 static:
95 95 writeFile(filename, stCode)
96 96  
97   -proc mapTypeToC(symbolicType: NimNode): string {.compileTime.} =
98   - if symbolicType.kind == nnkEmpty: return "void"
  97 +proc mapTypeToC(symbolicType: NimNode; isResultType: bool): string {.compileTime.} =
  98 + if symbolicType.kind == nnkEmpty and isResultType: return "void"
99 99 let t = symbolicType.getType
100 100 if symbolicType.kind == nnkSym and t.typeKind == ntyObject:
101 101 return gPrefix & $symbolicType
102 102 case t.typeKind
103 103 of ntyPtr, ntyVar:
  104 + if t.typeKind == ntyVar and isResultType:
  105 + quit "cannot wrap 'var T' as a result type"
104 106 expectKind t, nnkBracketExpr
105   - result = mapTypeToC(t[1]) & "*"
  107 + let base = t[1]
  108 + if base.getType.typeKind == ntyArray:
  109 + expectKind base, nnkBracketExpr
  110 + result = mapTypeToC(base[2], isResultType) & "*"
  111 + else:
  112 + result = mapTypeToC(base, isResultType) & "*"
106 113 of ntyArray:
  114 + if isResultType:
  115 + quit "cannot wrap array as a result type"
107 116 expectKind t, nnkBracketExpr
108   - result = mapTypeToC(t[2]) & "*"
  117 + result = mapTypeToC(t[2], isResultType) & "*"
109 118 of ntyCString: result = "char*"
110 119 of ntyPointer: result = "void*"
111 120 of ntyInt: result = intType
... ... @@ -145,7 +154,7 @@ macro exportSt*(body: stmt): stmt =
145 154 else:
146 155 st.add(": " & ident)
147 156 # return type:
148   - var apicall = "<cdecl: " & mapTypeToC(params[0]) & " '" &
  157 + var apicall = "<cdecl: " & mapTypeToC(params[0], true) & " '" &
149 158 procName & "' ("
150 159 var counter = 0
151 160 # parameter types:
... ... @@ -158,14 +167,14 @@ macro exportSt*(body: stmt): stmt =
158 167 if counter > 0:
159 168 apicall.add(" ")
160 169 st.addf(" $1: $1", name)
161   - apicall.add(mapTypeToC(typ))
  170 + apicall.add(mapTypeToC(typ, false))
162 171 inc counter
163 172 apicall.add(") module: '" & dllName & "'>\C" &
164 173 "\t^self externalCallFailed\C!\C\C")
165 174 stCode.add(st & "\C\t\"Generated by NimSqueak\"\C\t" & apicall)
166 175  
167   -macro wrapObject*(typ: stmt): stmt =
168   - ## Declares a SmallTalk wrapper class.
  176 +macro wrapObject*(typ: stmt; wrapFields=false): stmt =
  177 + ## Declares a Smalltalk wrapper class.
169 178 var t = typ.getType()
170 179 if t.typeKind == ntyTypeDesc:
171 180 expectKind t, nnkBracketExpr
... ... @@ -177,9 +186,10 @@ macro wrapObject*(typ: stmt): stmt =
177 186 t = t[1]
178 187 expectKind t, nnkRecList
179 188 var fields = ""
180   - for i in 0.. < t.len:
181   - expectKind t[i], nnkSym
182   - fields.addf "\t\t($# '$#')\C", $t[i], mapTypeToC(t[i])
  189 + if $wrapFields == "true":
  190 + for i in 0.. < t.len:
  191 + expectKind t[i], nnkSym
  192 + fields.addf "\t\t($# '$#')\C", $t[i], mapTypeToC(t[i], false)
183 193  
184 194 let st = ("ExternalStructure subclass: #$1\C" &
185 195 "\tinstanceVariableNames: ''\C" &
... ...
tests/Test1.nim
... ... @@ -29,4 +29,4 @@ proc foo*(a, b: Vector3, c: int): cstring {.exportSt.} =
29 29 result = "x plus y plus c " & $(a.x + b.y + c.float)
30 30  
31 31 # Write the Smalltalk code to file
32   -writeSmallTalkCode("Test1.st")
  32 +writeSmalltalkCode("Test1.st")
... ...