# # # The Nim Compiler # (c) Copyright 2015 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # # This include file implements the semantic checking for magics. # included from sem.nim proc semAddrArg(c: PContext; n: PNode; isUnsafeAddr = false): PNode = let x = semExprWithType(c, n) if x.kind == nkSym: x.sym.flags.incl(sfAddrTaken) if isAssignable(c, x, isUnsafeAddr) notin {arLValue, arLocalLValue}: # Do not suggest the use of unsafeAddr if this expression already is a # unsafeAddr if isUnsafeAddr: localError(c.config, n.info, errExprHasNoAddress) else: localError(c.config, n.info, errExprHasNoAddress & "; maybe use 'unsafeAddr'") result = x proc semTypeOf(c: PContext; n: PNode): PNode = var m = BiggestInt 1 # typeOfIter if n.len == 3: let mode = semConstExpr(c, n[2]) if mode.kind != nkIntLit: localError(c.config, n.info, "typeof: cannot evaluate 'mode' parameter at compile-time") else: m = mode.intVal result = newNodeI(nkTypeOfExpr, n.info) let typExpr = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {}) result.add typExpr result.typ = makeTypeDesc(c, typExpr.typ) type SemAsgnMode = enum asgnNormal, noOverloadedSubscript, noOverloadedAsgn proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode proc skipAddr(n: PNode): PNode {.inline.} = (if n.kind == nkHiddenAddr: n.sons[0] else: n) proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode = result = newNodeI(nkBracketExpr, n.info) for i in 1..pre { line-height: 125%; } td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
discard """
  file: "tstmtexp.nim"
  line: 8
  errormsg: "expression '5' is of type 'int literal(5)' and has to be discarded"
"""
# Test 3

1+4
a.getNode(2)) let # altough we use VM callback here, it is not # executed like 'normal' VM callback idx = vm.registerCallback("bindSymImpl", bindSymWrapper) # dummy node to carry idx information to VM idxNode = newIntTypeNode(nkIntLit, idx, c.graph.getSysType(TLineInfo(), tyInt)) result = copyNode(n) for x in n: result.add x result.add n # info node result.add idxNode proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode proc semOf(c: PContext, n: PNode): PNode = if sonsLen(n) == 3: n.sons[1] = semExprWithType(c, n.sons[1]) n.sons[2] = semExprWithType(c, n.sons[2], {efDetermineType}) #restoreOldStyleType(n.sons[1]) #restoreOldStyleType(n.sons[2]) let a = skipTypes(n.sons[1].typ, abstractPtrs) let b = skipTypes(n.sons[2].typ, abstractPtrs) let x = skipTypes(n.sons[1].typ, abstractPtrs-{tyTypeDesc}) let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc}) if x.kind == tyTypeDesc or y.kind != tyTypeDesc: localError(c.config, n.info, "'of' takes object types") elif b.kind != tyObject or a.kind != tyObject: localError(c.config, n.info, "'of' takes object types") else: let diff = inheritanceDiff(a, b) # | returns: 0 iff `a` == `b` # | returns: -x iff `a` is the x'th direct superclass of `b` # | returns: +x iff `a` is the x'th direct subclass of `b` # | returns: `maxint` iff `a` and `b` are not compatible at all if diff <= 0: # optimize to true: message(c.config, n.info, hintConditionAlwaysTrue, renderTree(n)) result = newIntNode(nkIntLit, 1) result.info = n.info result.typ = getSysType(c.graph, n.info, tyBool) return result elif diff == high(int): if commonSuperclass(a, b) == nil: localError(c.config, n.info, "'$1' cannot be of this subtype" % typeToString(a)) else: message(c.config, n.info, hintConditionAlwaysFalse, renderTree(n)) result = newIntNode(nkIntLit, 0) result.info = n.info result.typ = getSysType(c.graph, n.info, tyBool) else: localError(c.config, n.info, "'of' takes 2 arguments") n.typ = getSysType(c.graph, n.info, tyBool) result = n proc semUnown(c: PContext; n: PNode): PNode = proc unownedType(c: PContext; t: PType): PType = case t.kind of tyTuple: var elems = newSeq[PType](t.len) var someChange = false for i in 0..= 0: result = newIntNode(nkIntLit, size) result.info = n.info result.typ = n.typ else: localError(c.config, n.info, "cannot evaluate 'sizeof' because its type is not defined completely, type: " & n[1].typ.typeToString) result = n of mAlignOf: # this is 100% analog to mSizeOf, could be made more dry. let align = getAlign(c.config, n[1].typ) if align == szUnknownSize: result = n elif align >= 0: result = newIntNode(nkIntLit, align) result.info = n.info result.typ = n.typ else: localError(c.config, n.info, "cannot evaluate 'alignof' because its type is not defined completely, type: " & n[1].typ.typeToString) result = n of mOffsetOf: var dotExpr: PNode block findDotExpr: if n[1].kind == nkDotExpr: dotExpr = n[1] elif n[1].kind == nkCheckedFieldExpr: dotExpr = n[1][0] else: illFormedAst(n, c.config) assert dotExpr != nil let value = dotExpr[0] let member = dotExpr[1] discard computeSize(c.config, value.typ) result = newIntNode(nkIntLit, member.sym.offset) result.info = n.info result.typ = n.typ of mArrGet: result = semArrGet(c, n, flags) of mArrPut: result = semArrPut(c, n, flags) of mAsgn: if n[0].sym.name.s == "=": result = semAsgnOpr(c, n) else: result = semShallowCopy(c, n, flags) of mIsPartOf: result = semIsPartOf(c, n, flags) of mTypeTrait: result = semTypeTraits(c, n) of mAstToStr: result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, c.graph) result.typ = getSysType(c.graph, n.info, tyString) of mInstantiationInfo: result = semInstantiationInfo(c, n) of mOrd: result = semOrd(c, n) of mOf: result = semOf(c, n) of mHigh, mLow: result = semLowHigh(c, n, n[0].sym.magic) of mShallowCopy: result = semShallowCopy(c, n, flags) of mNBindSym: if dynamicBindSym notin c.features: result = semBindSym(c, n) else: result = semDynamicBindSym(c, n) of mProcCall: result = n result.typ = n[1].typ of mDotDot: result = n of mRoof: localError(c.config, n.info, "builtin roof operator is not supported anymore") of mPlugin: let plugin = getPlugin(c.cache, n[0].sym) if plugin.isNil: localError(c.config, n.info, "cannot find plugin " & n[0].sym.name.s) result = n else: result = plugin(c, n) of mNewFinalize: # Make sure the finalizer procedure refers to a procedure if n[^1].kind == nkSym and n[^1].sym.kind notin {skProc, skFunc}: localError(c.config, n.info, "finalizer must be a direct reference to a procedure") result = n of mDestroy: result = n let t = n[1].typ.skipTypes(abstractVar) if t.destructor != nil: result.sons[0] = newSymNode(t.destructor) of mUnown: result = semUnown(c, n) else: result = n