From 66d70ca82dd2f9ac31ba81771d187a69b1051874 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 4 Mar 2015 23:06:08 +0100 Subject: [PATCH] squeaknim doesn't depend on strutils anymore; generates proper sections --- src/squeaknim.nim | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/src/squeaknim.nim b/src/squeaknim.nim index f96b9b5..3d79585 100644 --- a/src/squeaknim.nim +++ b/src/squeaknim.nim @@ -1,5 +1,63 @@ -import macros, strutils +import macros +# Note: Since we combine -d:useNimRtl with this module, we cannot use strutils. +# So we use our own helper procs here: + +proc toUpper(c: char): char = + result = if c in {'a'..'z'}: chr(c.ord - 'a'.ord + 'A'.ord) else: c + +proc capitalize(s: string): string {.noSideEffect.} = + result = toUpper(s[0]) & substr(s, 1) + +proc invalidFormatString() {.noinline.} = + raise newException(ValueError, "invalid format string") + +proc addf(s: var string, formatstr: string, a: varargs[string, `$`]) = + ## The same as ``add(s, formatstr % a)``, but more efficient. + const PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\128'..'\255', '_'} + var i = 0 + var num = 0 + while i < len(formatstr): + if formatstr[i] == '$': + case formatstr[i+1] # again we use the fact that strings + # are zero-terminated here + of '#': + if num >% a.high: invalidFormatString() + add s, a[num] + inc i, 2 + inc num + of '$': + add s, '$' + inc(i, 2) + of '1'..'9', '-': + var j = 0 + inc(i) # skip $ + var negative = formatstr[i] == '-' + if negative: inc i + while formatstr[i] in {'0'..'9'}: + j = j * 10 + ord(formatstr[i]) - ord('0') + inc(i) + let idx = if not negative: j-1 else: a.len-j + if idx >% a.high: invalidFormatString() + add s, a[idx] + else: + invalidFormatString() + else: + add s, formatstr[i] + inc(i) + +proc `%`(formatstr: string, a: openArray[string]): string = + result = newStringOfCap(formatstr.len + a.len shl 4) + addf(result, formatstr, a) + +proc `%`(formatstr, a: string): string = + result = newStringOfCap(formatstr.len + a.len) + addf(result, formatstr, [a]) + +proc format(formatstr: string, a: varargs[string, `$`]): string = + result = newStringOfCap(formatstr.len + a.len) + addf(result, formatstr, a) + const pragmaPos = 4 @@ -29,7 +87,7 @@ template writeExternalLibrary*() = category: '$1'! !$1 class methodsFor: 'primitives' stamp: 'SqueakNim'! -""", capitalize(dllName)) +""", gPrefix & capitalize(dllName)) template writeSmallTalkCode*(filename: string) = ## You need to invoke this template to write the produced SmallTalk code to @@ -72,7 +130,11 @@ macro exportSt*(body: stmt): stmt = # # ^self externalCallFailed. result = body - result[pragmaPos].add(ident"exportc", ident"dynlib", ident"cdecl") + when defined(cpp): + result[pragmaPos].add(ident"exportc", ident"dynlib", ident"cdecl", + newColonExpr(ident"codegenDecl", newLit"""extern "C" $# $#$#""")) + else: + result[pragmaPos].add(ident"exportc", ident"dynlib", ident"cdecl") let params = result[paramPos] let procName = $result[0] var st = procName @@ -101,7 +163,7 @@ macro exportSt*(body: stmt): stmt = apicall.add(mapTypeToC(typ)) inc counter apicall.add(") module: '" & dllName & "'>\n" & - "\t^self externalCallFailed.\n") + "\t^self externalCallFailed.\n!\n\n") stCode.add(st & "\n\t\"Generated by NimSqueak\"\n\t" & apicall) macro wrapObject*(typ: stmt): stmt = -- libgit2 0.22.2