diff options
Diffstat (limited to 'rod/ccgutils.nim')
-rwxr-xr-x | rod/ccgutils.nim | 96 |
1 files changed, 53 insertions, 43 deletions
diff --git a/rod/ccgutils.nim b/rod/ccgutils.nim index c7733c5ff..f1d66ca94 100755 --- a/rod/ccgutils.nim +++ b/rod/ccgutils.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -10,21 +10,58 @@ # This module declares some helpers for the C code generator. import - ast, astalgo, ropes, lists, nhashes, strutils, types, msgs + ast, astalgo, ropes, lists, nhashes, strutils, types, msgs, wordrecg, + platform -proc toCChar*(c: Char): string -proc makeCString*(s: string): PRope -proc makeLLVMString*(s: string): PRope -proc TableGetType*(tab: TIdTable, key: PType): PObject -proc GetUniqueType*(key: PType): PType -# implementation +proc whichPragma*(n: PNode): TSpecialWord = + var key = if n.kind == nkExprColonExpr: n.sons[0] else: n + if key.kind == nkIdent: result = whichKeyword(key.ident) + +proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode = + case n.kind + of nkStmtList: + for i in 0 .. < n.len: + result = getPragmaStmt(n[i], w) + if result != nil: break + of nkPragma: + for i in 0 .. < n.len: + if whichPragma(n[i]) == w: return n[i] + else: nil + +proc stmtsContainPragma*(n: PNode, w: TSpecialWord): bool = + result = getPragmaStmt(n, w) != nil + +proc hashString*(s: string): biggestInt = + # has to be the same algorithm as system.hashString! + if CPU[targetCPU].bit == 64: + # we have to use the same bitwidth + # as the target CPU + var b = 0'i64 + for i in countup(0, len(s) - 1): + b = b +% Ord(s[i]) + b = b +% `shl`(b, 10) + b = b xor `shr`(b, 6) + b = b +% `shl`(b, 3) + b = b xor `shr`(b, 11) + b = b +% `shl`(b, 15) + result = b + else: + var a = 0'i32 + for i in countup(0, len(s) - 1): + a = a +% Ord(s[i]).int32 + a = a +% `shl`(a, 10'i32) + a = a xor `shr`(a, 6'i32) + a = a +% `shl`(a, 3'i32) + a = a xor `shr`(a, 11'i32) + a = a +% `shl`(a, 15'i32) + result = a var gTypeTable: array[TTypeKind, TIdTable] proc initTypeTables() = for i in countup(low(TTypeKind), high(TTypeKind)): InitIdTable(gTypeTable[i]) -proc GetUniqueType(key: PType): PType = +proc GetUniqueType*(key: PType): PType = var t: PType k: TTypeKind @@ -32,33 +69,7 @@ proc GetUniqueType(key: PType): PType = result = key if key == nil: return k = key.kind - case k # - # case key.Kind of - # tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString, - # tyInt..tyFloat128, tyProc, tyAnyEnum: begin end; - # tyNone, tyForward: - # InternalError('GetUniqueType: ' + typeToString(key)); - # tyGenericParam, tyGeneric, tyAbstract, tySequence, - # tyOpenArray, tySet, tyVar, tyRef, tyPtr, tyArrayConstr, - # tyArray, tyTuple, tyRange: begin - # // we have to do a slow linear search because types may need - # // to be compared by their structure: - # if IdTableHasObjectAsKey(gTypeTable, key) then exit; - # for h := 0 to high(gTypeTable.data) do begin - # t := PType(gTypeTable.data[h].key); - # if (t <> nil) and sameType(t, key) then begin result := t; exit end - # end; - # IdTablePut(gTypeTable, key, key); - # end; - # tyObject, tyEnum: begin - # result := PType(IdTableGet(gTypeTable, key)); - # if result = nil then begin - # IdTablePut(gTypeTable, key, key); - # result := key; - # end - # end; - # tyGenericInst, tyAbstract: result := GetUniqueType(lastSon(key)); - # end; + case k of tyObject, tyEnum: result = PType(IdTableGet(gTypeTable[k], key)) if result == nil: @@ -78,7 +89,7 @@ proc GetUniqueType(key: PType): PType = return t IdTablePut(gTypeTable[k], key, key) -proc TableGetType(tab: TIdTable, key: PType): PObject = +proc TableGetType*(tab: TIdTable, key: PType): PObject = var t: PType # returns nil if we need to declare this type result = IdTableGet(tab, key) @@ -91,13 +102,13 @@ proc TableGetType(tab: TIdTable, key: PType): PObject = if sameType(t, key): return tab.data[h].val -proc toCChar(c: Char): string = +proc toCChar*(c: Char): string = case c of '\0'..'\x1F', '\x80'..'\xFF': result = '\\' & toOctal(c) of '\'', '\"', '\\': result = '\\' & c else: result = $(c) -proc makeCString(s: string): PRope = +proc makeCString*(s: string): PRope = # BUGFIX: We have to split long strings into many ropes. Otherwise # this could trigger an InternalError(). See the ropes module for # further information. @@ -117,9 +128,8 @@ proc makeCString(s: string): PRope = add(res, '\"') app(result, toRope(res)) -proc makeLLVMString(s: string): PRope = - const - MaxLineLength = 64 +proc makeLLVMString*(s: string): PRope = + const MaxLineLength = 64 var res: string result = nil res = "c\"" @@ -135,4 +145,4 @@ proc makeLLVMString(s: string): PRope = add(res, "\\00\"") app(result, toRope(res)) -InitTypeTables() \ No newline at end of file +InitTypeTables() |