Commit 0dff195779e5a8b7e5f9f6d278a2c4a6a2cebb7b
Merge branch 'master' of gitlab.3dicc.com:3dicc/squeaknim
Showing
2 changed files
with
24 additions
and
14 deletions
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