diff --git a/compiler/ccgreset.nim b/compiler/ccgreset.nim index bd0e2a58a3..47b6a1e15e 100644 --- a/compiler/ccgreset.nim +++ b/compiler/ccgreset.nim @@ -95,11 +95,11 @@ proc specializeResetT(p: BProc, accessor: Rope, typ: PType) = lineCg(p, cpsStmts, "$1 = 0;$n", [accessor]) else: raiseAssert "unexpected set type kind" - of {tyNone, tyEmpty, tyNil, tyUntyped, tyTyped, tyGenericInvocation, + of tyNone, tyEmpty, tyNil, tyUntyped, tyTyped, tyGenericInvocation, tyGenericParam, tyOrdinal, tyRange, tyOpenArray, tyForward, tyVarargs, tyUncheckedArray, tyProxy, tyBuiltInTypeClass, tyUserTypeClass, tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot, - tyAnything, tyStatic, tyFromExpr, tyConcept, tyVoid, tyIterable}: + tyAnything, tyStatic, tyFromExpr, tyConcept, tyVoid, tyIterable: discard proc specializeReset(p: BProc, a: TLoc) = diff --git a/compiler/nir/ast2ir.nim b/compiler/nir/ast2ir.nim new file mode 100644 index 0000000000..0fa145264f --- /dev/null +++ b/compiler/nir/ast2ir.nim @@ -0,0 +1,37 @@ +# +# +# The Nim Compiler +# (c) Copyright 2023 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +import std / [assertions, tables] +import ".." / [ast, types, options, lineinfos, msgs] +import .. / ic / bitabs + +import nirtypes, nirinsts, nirlineinfos + +type + Context = object + conf: ConfigRef + lastFileKey: FileIndex + lastFileVal: LitId + strings: BiTable[string] + man: LineInfoManager + +proc toLineInfo(i: TLineInfo; c: var Context): PackedLineInfo = + var val: LitId + if c.lastFileKey == i.fileIndex: + val = c.lastFileVal + else: + val = c.strings.getOrIncl(toFullPath(c.conf, i.fileIndex)) + # remember the entry: + c.lastFileKey = i.fileIndex + c.lastFileVal = val + result = pack(c.man, val, int32 i.line, int32 i.col) + +proc astToIr*(n: PNode; dest: var Tree; c: var Context) = + let info = toLineInfo(n.info, c) + diff --git a/compiler/nir/cir.nim b/compiler/nir/cir.nim index 6a1d9d9b36..90a3035ddb 100644 --- a/compiler/nir/cir.nim +++ b/compiler/nir/cir.nim @@ -1,78 +1,78 @@ -# -# -# The Nim Compiler -# (c) Copyright 2023 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -# We produce C code as a list of tokens. - -import std / assertions -import .. / ic / bitabs - -type - Token = LitId # indexing into the tokens BiTable[string] - - PredefinedToken = enum - IgnoreMe = "" - EmptyToken = "" - DeclPrefix = "" # the next token is the name of a definition - CurlyLe = "{" - CurlyRi = "}" - ParLe = "(" - ParRi = ")" - BracketLe = "[" - BracketRi = "]" - NewLine = "\n" - Semicolon = ";" - Comma = ", " - Space = " " - Colon = ":" - Dot = "." - Arrow = "->" - Star = "*" - Amp = "&" - AsgnOpr = " = " - ScopeOpr = "::" - ConstKeyword = "const " - StaticKeyword = "static " - NimString = "NimString" - StrLitPrefix = "(NimChar*)" - StrLitNamePrefix = "Qstr" - LoopKeyword = "while (true) " - WhileKeyword = "while (" - IfKeyword = "if (" - ElseKeyword = "else " - SwitchKeyword = "switch (" - CaseKeyword = "case " - DefaultKeyword = "default:" - BreakKeyword = "break" - NullPtr = "nullptr" - IfNot = "if (!(" - ReturnKeyword = "return " - -const - ModulePrefix = Token(int(ReturnKeyword)+1) - -proc fillTokenTable(tab: var BiTable[string]) = - for e in EmptyToken..high(PredefinedToken): - let id = tab.getOrIncl $e - assert id == LitId(e) - -type - GeneratedCode* = object - code: seq[LitId] - tokens: BiTable[string] - -proc initGeneratedCode*(): GeneratedCode = - result = GeneratedCode(code: @[], tokens: initBiTable[string]()) - fillTokenTable(result.tokens) - -proc add*(g: var GeneratedCode; t: PredefinedToken) {.inline.} = - g.code.add Token(t) - -proc add*(g: var GeneratedCode; s: string) {.inline.} = - g.code.add g.tokens.getOrIncl(s) - +# +# +# The Nim Compiler +# (c) Copyright 2023 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +# We produce C code as a list of tokens. + +import std / assertions +import .. / ic / bitabs + +type + Token = LitId # indexing into the tokens BiTable[string] + + PredefinedToken = enum + IgnoreMe = "" + EmptyToken = "" + DeclPrefix = "" # the next token is the name of a definition + CurlyLe = "{" + CurlyRi = "}" + ParLe = "(" + ParRi = ")" + BracketLe = "[" + BracketRi = "]" + NewLine = "\n" + Semicolon = ";" + Comma = ", " + Space = " " + Colon = ":" + Dot = "." + Arrow = "->" + Star = "*" + Amp = "&" + AsgnOpr = " = " + ScopeOpr = "::" + ConstKeyword = "const " + StaticKeyword = "static " + NimString = "NimString" + StrLitPrefix = "(NimChar*)" + StrLitNamePrefix = "Qstr" + LoopKeyword = "while (true) " + WhileKeyword = "while (" + IfKeyword = "if (" + ElseKeyword = "else " + SwitchKeyword = "switch (" + CaseKeyword = "case " + DefaultKeyword = "default:" + BreakKeyword = "break" + NullPtr = "nullptr" + IfNot = "if (!(" + ReturnKeyword = "return " + +const + ModulePrefix = Token(int(ReturnKeyword)+1) + +proc fillTokenTable(tab: var BiTable[string]) = + for e in EmptyToken..high(PredefinedToken): + let id = tab.getOrIncl $e + assert id == LitId(e) + +type + GeneratedCode* = object + code: seq[LitId] + tokens: BiTable[string] + +proc initGeneratedCode*(): GeneratedCode = + result = GeneratedCode(code: @[], tokens: initBiTable[string]()) + fillTokenTable(result.tokens) + +proc add*(g: var GeneratedCode; t: PredefinedToken) {.inline.} = + g.code.add Token(t) + +proc add*(g: var GeneratedCode; s: string) {.inline.} = + g.code.add g.tokens.getOrIncl(s) + diff --git a/compiler/nir/nirinsts.nim b/compiler/nir/nirinsts.nim index e285d6efb5..e12973c450 100644 --- a/compiler/nir/nirinsts.nim +++ b/compiler/nir/nirinsts.nim @@ -68,6 +68,10 @@ type Eq, Le, Lt, + Cast, + NumberConv, + CheckedObjConv, + ObjConv, Emit, ProcDecl diff --git a/compiler/nir/nirtypes.nim b/compiler/nir/nirtypes.nim index c3e2e4db01..aef5264c70 100644 --- a/compiler/nir/nirtypes.nim +++ b/compiler/nir/nirtypes.nim @@ -176,6 +176,10 @@ proc nominalType*(tree: var TypeGraph; kind: NirTypeKind; name: string): TypeId result = TypeId tree.nodes.len tree.nodes.add TypeNode(x: toX(kind, tree.names.getOrIncl(name))) +proc getFloat128Type*(tree: var TypeGraph): TypeId = + result = TypeId tree.nodes.len + tree.nodes.add TypeNode(x: toX(FloatTy, 128'u32)) + proc addBuiltinType*(g: var TypeGraph; id: TypeId) = g.nodes.add g[id] diff --git a/compiler/nir/types2ir.nim b/compiler/nir/types2ir.nim new file mode 100644 index 0000000000..55593682be --- /dev/null +++ b/compiler/nir/types2ir.nim @@ -0,0 +1,237 @@ +# +# +# The Nim Compiler +# (c) Copyright 2023 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +import std / [assertions, tables] +import ".." / [ast, types, options] +import nirtypes + +type + Context = object + processed: Table[ItemId, TypeId] + g: TypeGraph + conf: ConfigRef + +template cached(c: var Context; t: PType; body: untyped) = + result = c.processed.getOrDefault(t.itemId) + if result.int == 0: + body + c.processed[t.itemId] = result + +proc typeToIr*(c: var Context; t: PType): TypeId + +proc collectFieldTypes(c: var Context; n: PNode; dest: var seq[TypeId]) = + case n.kind + of nkRecList: + for i in 0.. 0: + result = typeToIr(c, t.lastSon) + else: + result = TypeId(-1) + of tyFromExpr: + if t.n != nil and t.n.typ != nil: + result = typeToIr(c, t.n.typ) + else: + result = TypeId(-1) + of tyArray: + cached(c, t): + var n = toInt64(lengthOrd(c.conf, t)) + if n <= 0: n = 1 # make an array of at least one element + let elemType = typeToIr(c, t[1]) + let a = openType(c.g, ArrayTy) + c.g.addType(elemType) + c.g.addArrayLen uint64(n) + result = sealType(c.g, a) + of tyPtr, tyRef: + cached(c, t): + let e = t.lastSon + if e.kind == tyUncheckedArray: + let elemType = typeToIr(c, e.lastSon) + let a = openType(c.g, AArrayPtrTy) + c.g.addType(elemType) + result = sealType(c.g, a) + else: + let elemType = typeToIr(c, t.lastSon) + let a = openType(c.g, APtrTy) + c.g.addType(elemType) + result = sealType(c.g, a) + of tyVar, tyLent: + cached(c, t): + let elemType = typeToIr(c, t.lastSon) + let a = openType(c.g, APtrTy) + c.g.addType(elemType) + result = sealType(c.g, a) + of tySet: + let s = int(getSize(c.conf, t)) + case s + of 1: result = UInt8Id + of 2: result = UInt16Id + of 4: result = UInt32Id + of 8: result = UInt64Id + else: + # array[U8, s] + cached(c, t): + let a = openType(c.g, ArrayTy) + c.g.addType(UInt8Id) + c.g.addArrayLen uint64(s) + result = sealType(c.g, a) + of tyPointer: + let a = openType(c.g, APtrTy) + c.g.addBuiltinType(VoidId) + result = sealType(c.g, a) + of tyObject: + cached(c, t): + result = objectToIr(c, t) + of tyTuple: + cached(c, t): + result = tupleToIr(c, t) + of tyProc: + cached(c, t): + result = procToIr(c, t) + of tyVarargs, tyOpenArray: + cached(c, t): + # object (a: ArrayPtr[T], len: int) + result = TypeId(-1) + of tyString: + cached(c, t): + # a string a pair of `len, p` with convoluted `p`: + result = TypeId(-1) + of tySequence: + cached(c, t): + result = TypeId(-1) + of tyCstring: + cached(c, t): + let a = openType(c.g, AArrayPtrTy) + c.g.addBuiltinType Char8Id + result = sealType(c.g, a) + of tyUncheckedArray: + # We already handled the `ptr UncheckedArray` in a special way. + cached(c, t): + let elemType = typeToIr(c, t.lastSon) + let a = openType(c.g, LastArrayTy) + c.g.addType(elemType) + result = sealType(c.g, a) + of tyNone, tyEmpty, tyUntyped, tyTyped, tyTypeDesc, + tyNil, tyGenericInvocation, tyProxy, tyBuiltInTypeClass, + tyUserTypeClass, tyUserTypeClassInst, tyCompositeTypeClass, + tyAnd, tyOr, tyNot, tyAnything, tyConcept, tyIterable, tyForward: + result = TypeId(-1)