mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
In `semExprWithType`: `if result.typ.kind in {tyVar, tyLent}: result =
newDeref(result)` derefed `var`/`lent`. Since it is not done for `sink`,
we need to skip `tySink` in the corresponding procs
(cherry picked from commit f56568d851)
170 lines
6.0 KiB
Nim
170 lines
6.0 KiB
Nim
#
|
|
#
|
|
# The Nim Compiler
|
|
# (c) Copyright 2012 Andreas Rumpf
|
|
#
|
|
# See the file "copying.txt", included in this
|
|
# distribution, for details about the copyright.
|
|
#
|
|
|
|
# Built-in types and compilerprocs are registered here.
|
|
|
|
import
|
|
ast, astalgo, msgs, platform, idents,
|
|
modulegraphs, lineinfos
|
|
|
|
export createMagic
|
|
|
|
proc nilOrSysInt*(g: ModuleGraph): PType = g.sysTypes[tyInt]
|
|
|
|
proc newSysType(g: ModuleGraph; kind: TTypeKind, size: int): PType =
|
|
result = newType(kind, g.idgen, g.systemModule)
|
|
result.size = size
|
|
result.align = size.int16
|
|
|
|
proc getSysSym*(g: ModuleGraph; info: TLineInfo; name: string): PSym =
|
|
result = systemModuleSym(g, getIdent(g.cache, name))
|
|
if result == nil:
|
|
localError(g.config, info, "system module needs: " & name)
|
|
result = newSym(skError, getIdent(g.cache, name), g.idgen, g.systemModule, g.systemModule.info, {})
|
|
result.typ = newType(tyError, g.idgen, g.systemModule)
|
|
|
|
proc getSysMagic*(g: ModuleGraph; info: TLineInfo; name: string, m: TMagic): PSym =
|
|
result = nil
|
|
let id = getIdent(g.cache, name)
|
|
for r in systemModuleSyms(g, id):
|
|
if r.magic == m:
|
|
# prefer the tyInt variant:
|
|
if r.typ.returnType != nil and r.typ.returnType.kind == tyInt: return r
|
|
result = r
|
|
if result != nil: return result
|
|
localError(g.config, info, "system module needs: " & name)
|
|
result = newSym(skError, id, g.idgen, g.systemModule, g.systemModule.info, {})
|
|
result.typ = newType(tyError, g.idgen, g.systemModule)
|
|
|
|
proc sysTypeFromName*(g: ModuleGraph; info: TLineInfo; name: string): PType =
|
|
result = getSysSym(g, info, name).typ
|
|
|
|
proc getSysType*(g: ModuleGraph; info: TLineInfo; kind: TTypeKind): PType =
|
|
template sysTypeFromName(s: string): untyped = sysTypeFromName(g, info, s)
|
|
result = g.sysTypes[kind]
|
|
if result == nil:
|
|
case kind
|
|
of tyVoid: result = sysTypeFromName("void")
|
|
of tyInt: result = sysTypeFromName("int")
|
|
of tyInt8: result = sysTypeFromName("int8")
|
|
of tyInt16: result = sysTypeFromName("int16")
|
|
of tyInt32: result = sysTypeFromName("int32")
|
|
of tyInt64: result = sysTypeFromName("int64")
|
|
of tyUInt: result = sysTypeFromName("uint")
|
|
of tyUInt8: result = sysTypeFromName("uint8")
|
|
of tyUInt16: result = sysTypeFromName("uint16")
|
|
of tyUInt32: result = sysTypeFromName("uint32")
|
|
of tyUInt64: result = sysTypeFromName("uint64")
|
|
of tyFloat: result = sysTypeFromName("float")
|
|
of tyFloat32: result = sysTypeFromName("float32")
|
|
of tyFloat64: result = sysTypeFromName("float64")
|
|
of tyFloat128: result = sysTypeFromName("float128")
|
|
of tyBool: result = sysTypeFromName("bool")
|
|
of tyChar: result = sysTypeFromName("char")
|
|
of tyString: result = sysTypeFromName("string")
|
|
of tyCstring: result = sysTypeFromName("cstring")
|
|
of tyPointer: result = sysTypeFromName("pointer")
|
|
of tyNil: result = newSysType(g, tyNil, g.config.target.ptrSize)
|
|
else: internalError(g.config, "request for typekind: " & $kind)
|
|
g.sysTypes[kind] = result
|
|
if result.kind != kind:
|
|
if kind == tyFloat64 and result.kind == tyFloat: discard # because of aliasing
|
|
else:
|
|
internalError(g.config, "wanted: " & $kind & " got: " & $result.kind)
|
|
if result == nil: internalError(g.config, "type not found: " & $kind)
|
|
|
|
proc resetSysTypes*(g: ModuleGraph) =
|
|
g.systemModule = nil
|
|
g.compilerprocs = initStrTable()
|
|
g.exposed = initStrTable()
|
|
for i in low(g.sysTypes)..high(g.sysTypes):
|
|
g.sysTypes[i] = nil
|
|
|
|
proc getFloatLitType*(g: ModuleGraph; literal: PNode): PType =
|
|
# for now we do not cache these:
|
|
result = newSysType(g, tyFloat, size=8)
|
|
result.n = literal
|
|
|
|
proc skipIntLit*(t: PType; id: IdGenerator): PType {.inline.} =
|
|
if t.n != nil and t.kind in {tyInt, tyFloat}:
|
|
result = copyType(t, id, t.owner)
|
|
result.n = nil
|
|
else:
|
|
result = t
|
|
|
|
proc addSonSkipIntLit*(father, son: PType; id: IdGenerator) =
|
|
let s = son.skipIntLit(id)
|
|
father.add(s)
|
|
propagateToOwner(father, s)
|
|
|
|
proc makeVarType*(owner: PSym; baseType: PType; idgen: IdGenerator; kind = tyVar): PType =
|
|
if baseType.kind == kind:
|
|
result = baseType
|
|
else:
|
|
result = newType(kind, idgen, owner)
|
|
addSonSkipIntLit(result, baseType, idgen)
|
|
|
|
proc getCompilerProc*(g: ModuleGraph; name: string): PSym =
|
|
let ident = getIdent(g.cache, name)
|
|
result = strTableGet(g.compilerprocs, ident)
|
|
if result == nil:
|
|
result = loadCompilerProc(g, name)
|
|
|
|
proc registerCompilerProc*(g: ModuleGraph; s: PSym) =
|
|
strTableAdd(g.compilerprocs, s)
|
|
|
|
proc registerNimScriptSymbol*(g: ModuleGraph; s: PSym) =
|
|
# Nimscript symbols must be al unique:
|
|
let conflict = strTableGet(g.exposed, s.name)
|
|
if conflict == nil:
|
|
strTableAdd(g.exposed, s)
|
|
else:
|
|
localError(g.config, s.info,
|
|
"symbol conflicts with other .exportNims symbol at: " & g.config$conflict.info)
|
|
|
|
proc getNimScriptSymbol*(g: ModuleGraph; name: string): PSym =
|
|
strTableGet(g.exposed, getIdent(g.cache, name))
|
|
|
|
proc resetNimScriptSymbols*(g: ModuleGraph) = g.exposed = initStrTable()
|
|
|
|
proc getMagicEqSymForType*(g: ModuleGraph; t: PType; info: TLineInfo): PSym =
|
|
case t.kind
|
|
of tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
|
|
tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64:
|
|
result = getSysMagic(g, info, "==", mEqI)
|
|
of tyEnum:
|
|
result = getSysMagic(g, info, "==", mEqEnum)
|
|
of tyBool:
|
|
result = getSysMagic(g, info, "==", mEqB)
|
|
of tyRef, tyPtr, tyPointer:
|
|
result = getSysMagic(g, info, "==", mEqRef)
|
|
of tyString:
|
|
result = getSysMagic(g, info, "==", mEqStr)
|
|
of tyChar:
|
|
result = getSysMagic(g, info, "==", mEqCh)
|
|
of tySet:
|
|
result = getSysMagic(g, info, "==", mEqSet)
|
|
of tyProc:
|
|
result = getSysMagic(g, info, "==", mEqProc)
|
|
else:
|
|
result = nil
|
|
globalError(g.config, info,
|
|
"can't find magic equals operator for type kind " & $t.kind)
|
|
|
|
proc makePtrType*(baseType: PType; idgen: IdGenerator): PType =
|
|
result = newType(tyPtr, idgen, baseType.owner)
|
|
addSonSkipIntLit(result, baseType, idgen)
|
|
|
|
proc makeAddr*(n: PNode; idgen: IdGenerator): PNode =
|
|
if n.kind == nkHiddenAddr:
|
|
result = n
|
|
else:
|
|
result = newTree(nkHiddenAddr, n)
|
|
result.typ() = makePtrType(n.typ.skipTypes({tySink}), idgen)
|