From 0932e2f65b3403e271734aa3a25e97a4251498a1 Mon Sep 17 00:00:00 2001 From: araq Date: Tue, 26 Aug 2025 21:24:15 +0200 Subject: [PATCH 1/3] WIP: 'feature' pragma --- doc/tags.md | 1 + src/hexer/nifcgen.nim | 2 +- src/models/nimony_tags.nim | 3 +- src/models/tags.nim | 186 +++++++++++++++++++------------------ 4 files changed, 98 insertions(+), 94 deletions(-) diff --git a/doc/tags.md b/doc/tags.md index ec69dcafa..60774a12a 100644 --- a/doc/tags.md +++ b/doc/tags.md @@ -211,6 +211,7 @@ | `(assume X)` | NimonyPragma, NimonyStmt | `assume` pragma | | `(assert X)` | NimonyPragma, NimonyStmt | `assert` pragma | | `(build X)`; `(build STR STR STR)` | NimonyPragma, NifIndexKind | `build` pragma | +| `(feature STR)` | NimonyPragma | `feature` pragma | | `(string)` | NimonyPragma | `string` pragma | | `(view)` | NimonyPragma | `view` pragma | | `(quoted X+)` | NimonyExpr, NiflerKind | name in backticks | diff --git a/src/hexer/nifcgen.nim b/src/hexer/nifcgen.nim index b985b937c..c6a9b2b68 100644 --- a/src/hexer/nifcgen.nim +++ b/src/hexer/nifcgen.nim @@ -783,7 +783,7 @@ proc parsePragmas(c: var EContext; n: var Cursor): CollectedPragmas = inc n of RequiresP, EnsuresP, StringP, RaisesP, ErrorP, AssumeP, AssertP, ReportP, TagsP, DeprecatedP, SideEffectP, KeepOverflowFlagP, SemanticsP, - BaseP, FinalP, PragmaP, CursorP, PassiveP, PluginP: + BaseP, FinalP, PragmaP, CursorP, PassiveP, PluginP, FeatureP: skip n continue of BuildP, EmitP, PushP, PopP, PassLP: diff --git a/src/models/nimony_tags.nim b/src/models/nimony_tags.nim index 2f7989b7c..f142f8808 100644 --- a/src/models/nimony_tags.nim +++ b/src/models/nimony_tags.nim @@ -310,6 +310,7 @@ type AssumeP = (ord(AssumeTagId), "assume") ## `assume` pragma AssertP = (ord(AssertTagId), "assert") ## `assert` pragma BuildP = (ord(BuildTagId), "build") ## `build` pragma + FeatureP = (ord(FeatureTagId), "feature") ## `feature` pragma StringP = (ord(StringTagId), "string") ## `string` pragma ViewP = (ord(ViewTagId), "view") ## `view` pragma InjectP = (ord(InjectTagId), "inject") ## `inject` pragma @@ -333,7 +334,7 @@ type PassLP = (ord(PassLTagId), "passL") ## `passL` pragma adds options to the backend linker proc rawTagIsNimonyPragma*(raw: TagEnum): bool {.inline.} = - raw in {CursorTagId, EmitTagId, UnionTagId, InlineTagId, NoinlineTagId, ClosureTagId, VarargsTagId, SelectanyTagId, AlignTagId, BitsTagId, NodeclTagId, RaisesTagId, UntypedTagId, MagicTagId, ImportcTagId, ImportcppTagId, DynlibTagId, ExportcTagId, HeaderTagId, ThreadvarTagId, GlobalTagId, DiscardableTagId, NoreturnTagId, BorrowTagId, NoSideEffectTagId, NodestroyTagId, PluginTagId, BycopyTagId, ByrefTagId, NoinitTagId, RequiresTagId, EnsuresTagId, AssumeTagId, AssertTagId, BuildTagId, StringTagId, ViewTagId, InjectTagId, GensymTagId, ErrorTagId, ReportTagId, TagsTagId, DeprecatedTagId, SideEffectTagId, KeepOverflowFlagTagId, SemanticsTagId, InheritableTagId, BaseTagId, PureTagId, FinalTagId, PragmaTagId, PackedTagId, PassiveTagId, PushTagId, PopTagId, PassLTagId} + raw in {CursorTagId, EmitTagId, UnionTagId, InlineTagId, NoinlineTagId, ClosureTagId, VarargsTagId, SelectanyTagId, AlignTagId, BitsTagId, NodeclTagId, RaisesTagId, UntypedTagId, MagicTagId, ImportcTagId, ImportcppTagId, DynlibTagId, ExportcTagId, HeaderTagId, ThreadvarTagId, GlobalTagId, DiscardableTagId, NoreturnTagId, BorrowTagId, NoSideEffectTagId, NodestroyTagId, PluginTagId, BycopyTagId, ByrefTagId, NoinitTagId, RequiresTagId, EnsuresTagId, AssumeTagId, AssertTagId, BuildTagId, FeatureTagId, StringTagId, ViewTagId, InjectTagId, GensymTagId, ErrorTagId, ReportTagId, TagsTagId, DeprecatedTagId, SideEffectTagId, KeepOverflowFlagTagId, SemanticsTagId, InheritableTagId, BaseTagId, PureTagId, FinalTagId, PragmaTagId, PackedTagId, PassiveTagId, PushTagId, PopTagId, PassLTagId} type NimonySym* = enum diff --git a/src/models/tags.nim b/src/models/tags.nim index 633a7e056..354196582 100644 --- a/src/models/tags.nim +++ b/src/models/tags.nim @@ -214,6 +214,7 @@ type AssumeTagId AssertTagId BuildTagId + FeatureTagId StringTagId ViewTagId QuotedTagId @@ -520,96 +521,97 @@ const ("assume", 209), ("assert", 210), ("build", 211), - ("string", 212), - ("view", 213), - ("quoted", 214), - ("hderef", 215), - ("ddot", 216), - ("haddr", 217), - ("newref", 218), - ("newobj", 219), - ("tup", 220), - ("tupconstr", 221), - ("setconstr", 222), - ("tabconstr", 223), - ("ashr", 224), - ("baseobj", 225), - ("hconv", 226), - ("dconv", 227), - ("callstrlit", 228), - ("infix", 229), - ("prefix", 230), - ("hcall", 231), - ("compiles", 232), - ("declared", 233), - ("defined", 234), - ("astToStr", 235), - ("instanceof", 236), - ("proccall", 237), - ("high", 238), - ("low", 239), - ("typeof", 240), - ("unpack", 241), - ("fields", 242), - ("fieldpairs", 243), - ("enumtostr", 244), - ("ismainmodule", 245), - ("defaultobj", 246), - ("defaulttup", 247), - ("defaultdistinct", 248), - ("delay", 249), - ("expr", 250), - ("do", 251), - ("arrat", 252), - ("tupat", 253), - ("plusset", 254), - ("minusset", 255), - ("mulset", 256), - ("xorset", 257), - ("eqset", 258), - ("leset", 259), - ("ltset", 260), - ("inset", 261), - ("card", 262), - ("emove", 263), - ("destroy", 264), - ("dup", 265), - ("copy", 266), - ("wasmoved", 267), - ("sinkh", 268), - ("trace", 269), - ("errv", 270), - ("staticstmt", 271), - ("bind", 272), - ("mixin", 273), - ("using", 274), - ("asm", 275), - ("defer", 276), - ("index", 277), - ("public", 278), - ("private", 279), - ("inject", 280), - ("gensym", 281), - ("error", 282), - ("report", 283), - ("tags", 284), - ("deprecated", 285), - ("sideEffect", 286), - ("keepOverflowFlag", 287), - ("semantics", 288), - ("inheritable", 289), - ("base", 290), - ("pure", 291), - ("final", 292), - ("pragma", 293), - ("internalTypeName", 294), - ("internalFieldPairs", 295), - ("failed", 296), - ("is", 297), - ("envp", 298), - ("packed", 299), - ("passive", 300), - ("push", 301), - ("pop", 302), - ("passL", 303) + ("feature", 212), + ("string", 213), + ("view", 214), + ("quoted", 215), + ("hderef", 216), + ("ddot", 217), + ("haddr", 218), + ("newref", 219), + ("newobj", 220), + ("tup", 221), + ("tupconstr", 222), + ("setconstr", 223), + ("tabconstr", 224), + ("ashr", 225), + ("baseobj", 226), + ("hconv", 227), + ("dconv", 228), + ("callstrlit", 229), + ("infix", 230), + ("prefix", 231), + ("hcall", 232), + ("compiles", 233), + ("declared", 234), + ("defined", 235), + ("astToStr", 236), + ("instanceof", 237), + ("proccall", 238), + ("high", 239), + ("low", 240), + ("typeof", 241), + ("unpack", 242), + ("fields", 243), + ("fieldpairs", 244), + ("enumtostr", 245), + ("ismainmodule", 246), + ("defaultobj", 247), + ("defaulttup", 248), + ("defaultdistinct", 249), + ("delay", 250), + ("expr", 251), + ("do", 252), + ("arrat", 253), + ("tupat", 254), + ("plusset", 255), + ("minusset", 256), + ("mulset", 257), + ("xorset", 258), + ("eqset", 259), + ("leset", 260), + ("ltset", 261), + ("inset", 262), + ("card", 263), + ("emove", 264), + ("destroy", 265), + ("dup", 266), + ("copy", 267), + ("wasmoved", 268), + ("sinkh", 269), + ("trace", 270), + ("errv", 271), + ("staticstmt", 272), + ("bind", 273), + ("mixin", 274), + ("using", 275), + ("asm", 276), + ("defer", 277), + ("index", 278), + ("public", 279), + ("private", 280), + ("inject", 281), + ("gensym", 282), + ("error", 283), + ("report", 284), + ("tags", 285), + ("deprecated", 286), + ("sideEffect", 287), + ("keepOverflowFlag", 288), + ("semantics", 289), + ("inheritable", 290), + ("base", 291), + ("pure", 292), + ("final", 293), + ("pragma", 294), + ("internalTypeName", 295), + ("internalFieldPairs", 296), + ("failed", 297), + ("is", 298), + ("envp", 299), + ("packed", 300), + ("passive", 301), + ("push", 302), + ("pop", 303), + ("passL", 304) ] From 4b7dd9118b1c1618e7661bd516653cfa30546e71 Mon Sep 17 00:00:00 2001 From: araq Date: Wed, 27 Aug 2025 08:15:25 +0200 Subject: [PATCH 2/3] progress --- src/nimony/sem.nim | 17 ++++++++++++++++- src/nimony/semdata.nim | 3 ++- vendor/errorcodes | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/nimony/sem.nim b/src/nimony/sem.nim index 18d8f2801..cc8b6faa4 100644 --- a/src/nimony/sem.nim +++ b/src/nimony/sem.nim @@ -13,7 +13,7 @@ from std/os import changeFileExt, getCurrentDir include nifprelude import nimony_model, symtabs, builtintypes, decls, symparser, asthelpers, programs, sigmatch, magics, reporters, nifconfig, nifindexes, - intervals, xints, typeprops, + intervals, xints, typeprops, features, semdata, sembasics, semos, expreval, semborrow, enumtostr, derefs, sizeof, renderer, semuntyped, contracts, vtables_frontend, module_plugins, deferstmts, pragmacanon @@ -1333,6 +1333,21 @@ proc semPragma(c: var SemContext; n: var Cursor; crucial: var CrucialPragma; kin else: buildErr c, n.info, "`magic` pragma takes a string literal" c.dest.addParRi() + of FeatureP: + c.dest.add parLeToken(FeatureP, n.info) + inc n + if hasParRi and n.kind in {StringLit, Ident}: + let feature = parseFeature(pool.strings[n.litId]) + if feature == InvalidFeature: + buildErr c, n.info, "unknown `feature`" + else: + c.features.incl feature + takeToken c, n + elif n.exprKind == ErrX: + c.dest.addSubtree n + else: + buildErr c, n.info, "`feature` pragma takes a string literal" + c.dest.addParRi() of ErrorP, ReportP, DeprecatedP: crucial.flags.incl pk c.dest.add parLeToken(pk, n.info) diff --git a/src/nimony/semdata.nim b/src/nimony/semdata.nim index de57a4933..2f4f65e46 100644 --- a/src/nimony/semdata.nim +++ b/src/nimony/semdata.nim @@ -9,7 +9,7 @@ import std / [tables, sets, os, syncio, formatfloat, assertions] include nifprelude import nimony_model, symtabs, builtintypes, decls, symparser, - programs, magics, reporters, nifconfig, nifindexes + programs, magics, reporters, nifconfig, nifindexes, features import ".." / gear2 / modnames @@ -92,6 +92,7 @@ type instantiatedProcs*: Table[(SymId, string), SymId] thisModuleSuffix*: string moduleFlags*: set[ModuleFlag] + features*: set[Feature] processedModules*: Table[string, SymId] # suffix to sym usedTypevars*: int phase*: SemPhase diff --git a/vendor/errorcodes b/vendor/errorcodes index 56e26eea5..9f3e79794 160000 --- a/vendor/errorcodes +++ b/vendor/errorcodes @@ -1 +1 @@ -Subproject commit 56e26eea527282ec01d85bee1071e9659e71bcf4 +Subproject commit 9f3e7979499529ad5d1023e2559c6c98a119ccc8 From 78147613f0353194606a0dc8018b1f63bb5366a4 Mon Sep 17 00:00:00 2001 From: araq Date: Sun, 31 Aug 2025 17:51:36 +0200 Subject: [PATCH 3/3] added missing file --- src/nimony/features.nim | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/nimony/features.nim diff --git a/src/nimony/features.nim b/src/nimony/features.nim new file mode 100644 index 000000000..51adccd78 --- /dev/null +++ b/src/nimony/features.nim @@ -0,0 +1,19 @@ +# Nimony +# (c) Copyright 2024 Andreas Rumpf +# +# See the file "license.txt", included in this +# distribution, for details about the copyright. + + +type + Feature* = enum ## A feature is a language mode that is purely frontend-related. + ## A `CheckMode` is something Hexer needs to know about too. + InvalidFeature + NotnilFeature + +proc parseFeature*(s: string): Feature = + case s + of "notnil": NotnilFeature + else: InvalidFeature + +