summary refs log tree commit diff stats
path: root/changelogs/changelog_0_18_1.md
diff options
context:
space:
mode:
Diffstat (limited to 'changelogs/changelog_0_18_1.md')
0 files changed, 0 insertions, 0 deletions
8' href='#n38'>38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125




























































































































                                                                                
#
#
#           The Nimrod Compiler
#        (c) Copyright 2009 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## Converts Nimrod types to LLVM types.

import llvm

proc intFromSize(size: int): TypeRef =
  case size
  of 8: result = llvm.Int64Type()
  of 4: result = llvm.Int32Type()
  of 2: result = llvm.Int16Type()
  of 1: result = llvm.Int8Type()
  else: InternalError("unknown type size")

type
  TPending = TTypeHandleMap

proc convertProcType(m: BModule, t: PType, pending: var TPending): TypeRef =
  
  
proc simpleType(m: BModule, t: PType): TypeRef =
  case t.kind
  of tyBool, tyChar, tyInt8: result = llvm.Int8Type()
  of tyEnum:
    if firstOrd(t) < 0: 
      result = llvm.Int32Type()
    else: 
      case int(getSize(t))
      of 1: result = llvm.Int8Type()
      of 2: result = llvm.Int16Type()
      of 4: result = llvm.Int32Type()
      of 8: result = llvm.Int64Type()
      else: internalError(t.sym.info, "convertTypeAux")
  of tyInt: result = intFromSize(getSize(t))
  of tyInt16: result = llvm.Int16Type()
  of tyInt32: result = llvm.Int32Type()
  of tyInt64: result = llvm.Int64Type()
  of tyFloat, tyFloat64: result = llvm.DoubleType()
  of tyFloat32: result = llvm.FloatType()
  of tyCString, tyPointer, tyNil: result = llvm.PointerType(llvm.Int8Type())
  else: result = nil
  
proc convertTypeAux(m: BModule, t: PType, pending: var TPending): TypeRef =
  case t.kind
  of tyDistinct, tyRange:
    result = convertTypeAux(m, t.sons[0], pending)
  of tyArray: 
    result = m.typeCache[t]
    if result == nil:
      var handle = pending[t]
      if handle == nil:
        handle = llvm.CreateTypeHandle(llvm.OpaqueType())
        pending[t] = handle
        result = llvm.ArrayType(ResolveTypeHandle(handle), int32(lengthOrd(t)))
        var elemConcrete = convertTypeAux(m, elemType(t), pending)
        # this may destroy the types!
        refineType(ResolveTypeHandle(handle), elemConcrete)
        
        # elemConcrete is potentially invalidated, but handle
        # (a PATypeHolder) is kept up-to-date
        elemConcrete = ResolveTypeHandle(handle)

        
      else:
        # we are pending!
        result = ResolveTypeHandle(handle)
      # now we have the correct type:
      m.typeCache[t] = result
  of tyOpenArray:
  
  of tySeq:
  
  of tyObject: 
  of tyTuple: 
    
  of tyProc:
  else: result = simpleType(m, t)

proc CreateTypeHandle*(PotentiallyAbstractTy: TypeRef): TypeHandleRef{.cdecl, 
    dynlib: libname, importc: "LLVMCreateTypeHandle".}
proc RefineType*(AbstractTy: TypeRef, ConcreteTy: TypeRef){.cdecl, 
    dynlib: libname, importc: "LLVMRefineType".}
proc ResolveTypeHandle*(TypeHandle: TypeHandleRef): TypeRef{.cdecl, 
    dynlib: libname, importc: "LLVMResolveTypeHandle".}
proc DisposeTypeHandle*(TypeHandle: TypeHandleRef){.cdecl, dynlib: libname, 
    importc: "LLVMDisposeTypeHandle".}    


proc `!`*(m: BModule, t: PType): TypeRef =
  ## converts a Nimrod type to an LLVM type. Since this is so common, we use
  ## an infix operator for this.
  result = simpleType(m, t)
  if result == nil:
    var cl: TTypeMap
    init(cl)
    result = convertTypeAux(m, t, cl)

proc FunctionType*(ReturnType: TypeRef, ParamTypes: ptr TypeRef,
                   ParamCount: int32, IsVarArg: int32): TypeRef {.
    cdecl, dynlib: libname, importc: "LLVMFunctionType".}
    

proc VoidType*(): TypeRef{.cdecl, dynlib: libname, importc: "LLVMVoidType".}
proc LabelType*(): TypeRef{.cdecl, dynlib: libname, importc: "LLVMLabelType".}
proc OpaqueType*(): TypeRef{.cdecl, dynlib: libname, importc: "LLVMOpaqueType".}
  # Operations on type handles  
proc CreateTypeHandle*(PotentiallyAbstractTy: TypeRef): TypeHandleRef{.cdecl, 
    dynlib: libname, importc: "LLVMCreateTypeHandle".}
proc RefineType*(AbstractTy: TypeRef, ConcreteTy: TypeRef){.cdecl, 
    dynlib: libname, importc: "LLVMRefineType".}
proc ResolveTypeHandle*(TypeHandle: TypeHandleRef): TypeRef{.cdecl, 
    dynlib: libname, importc: "LLVMResolveTypeHandle".}
proc DisposeTypeHandle*(TypeHandle: TypeHandleRef){.cdecl, dynlib: libname, 
    importc: "LLVMDisposeTypeHandle".}

    
#  m!typ, m!a[i]