Skip to content

Commit

Permalink
NIFC: support C++ reference types via a pointer qualifier (#530)
Browse files Browse the repository at this point in the history
* NIFC: support C++ reference types via a pointer qualifier

* only active when the backend is C++
  • Loading branch information
Araq authored Feb 13, 2025
1 parent a7d5ba5 commit 229266d
Show file tree
Hide file tree
Showing 8 changed files with 517 additions and 483 deletions.
10 changes: 7 additions & 3 deletions doc/nifc-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ CharLiteral ::= <according to NIF's spec>
StringLiteral ::= <according to NIF's spec>
IntBits ::= ('+' | '-') [0-9]+
Lvalue ::= Symbol | (deref Expr) |
Lvalue ::= Symbol | (deref Expr (cppref)?) |
(at Expr Expr) | # array indexing
(dot Expr Symbol Number) | # field access
(pat Expr Expr) | # pointer indexing
Expand All @@ -92,7 +92,7 @@ CallCanRaise ::= (onerr Stmt Expr+)
Expr ::= Number | CharLiteral | StringLiteral |
Lvalue |
(par Expr) | # wraps the expression in parentheses
(addr Lvalue) | # "address of" operation
(addr Lvalue (cppref)?) | # "address of" operation
(nil) | (false) | (true) |
(inf) | (neginf) | (nan) |
(and Expr Expr) | # "&&"
Expand Down Expand Up @@ -191,7 +191,7 @@ Type ::= Symbol |
(c IntBits IntQualifier*) | # character types
(bool IntQualifier*) |
(void) |
(ptr Type PtrQualifier*) | # pointer to a single object
(ptr Type PtrQualifier* (cppref)?) | # pointer to a single object
(flexarray Type) |
(aptr Type PtrQualifier*) | # pointer to an array of objects
ProcType
Expand Down Expand Up @@ -277,6 +277,10 @@ Notes:
- `var` is always a local variable, `gvar` is a global variable and `tvar` a thread local
variable.
- `SCOPE` indicates the construct introduces a new local scope for variables.
- `cppref` is a pragma that indicates that the pointer should be translated into a C++
reference (`T&`). The `(deref)` and `(addr)` operations are still mandatory then and
must be annotated with `(cppref)` too. `(cppref)` can be combined with `(ro)` to produce
a `const T&` reference.


Scopes
Expand Down
1 change: 1 addition & 0 deletions doc/tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
| atomic | TQC | `atomic` type qualifier for NIFC |
| ro | TQC | `readonly` (= `const`) type qualifier for NIFC |
| restrict | TQC | type qualifier for NIFC |
| cppref | TQC | type qualifier for NIFC that provides a C++ reference |
| i | TC, TN | `int` builtin type |
| u | TC, TN | `uint` builtin type |
| f | TC, TN | `float` builtin type |
Expand Down
20 changes: 10 additions & 10 deletions src/models/callconv_tags.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
type
CallConv* = enum
NoCallConv
Cdecl = (110, "cdecl") ## `cdecl` calling convention
Stdcall = (111, "stdcall") ## `stdcall` calling convention
Safecall = (112, "safecall") ## `safecall` calling convention
Syscall = (113, "syscall") ## `syscall` calling convention
Fastcall = (114, "fastcall") ## `fastcall` calling convention
Thiscall = (115, "thiscall") ## `thiscall` calling convention
Noconv = (116, "noconv") ## no explicit calling convention
Member = (117, "member") ## `member` calling convention
Nimcall = (118, "nimcall") ## `nimcall` calling convention
Cdecl = (111, "cdecl") ## `cdecl` calling convention
Stdcall = (112, "stdcall") ## `stdcall` calling convention
Safecall = (113, "safecall") ## `safecall` calling convention
Syscall = (114, "syscall") ## `syscall` calling convention
Fastcall = (115, "fastcall") ## `fastcall` calling convention
Thiscall = (116, "thiscall") ## `thiscall` calling convention
Noconv = (117, "noconv") ## no explicit calling convention
Member = (118, "member") ## `member` calling convention
Nimcall = (119, "nimcall") ## `nimcall` calling convention

proc rawTagIsCallConv*(raw: uint32): bool {.inline.} =
raw >= 110'u32 and raw <= 118'u32
raw >= 111'u32 and raw <= 119'u32

75 changes: 38 additions & 37 deletions src/models/nifc_tags.nim
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ type
CastC = (44, "cast")
ConvC = (45, "conv") ## type conversion
CallC = (46, "call") ## call operation
ErrvC = (245, "errv") ## error flag for `NIFC`
ErrvC = (246, "errv") ## error flag for `NIFC`

proc rawTagIsNifcExpr*(raw: uint32): bool {.inline.} =
raw <= 255'u32 and raw.uint8 in {2'u8, 3'u8, 4'u8, 5'u8, 6'u8, 7'u8, 8'u8, 9'u8, 10'u8, 11'u8, 12'u8, 13'u8, 14'u8, 15'u8, 16'u8, 17'u8, 18'u8, 19'u8, 20'u8, 21'u8, 22'u8, 24'u8, 29'u8, 30'u8, 31'u8, 32'u8, 33'u8, 34'u8, 35'u8, 36'u8, 37'u8, 38'u8, 39'u8, 40'u8, 41'u8, 42'u8, 43'u8, 44'u8, 45'u8, 46'u8, 245'u8}
raw <= 255'u32 and raw.uint8 in {2'u8, 3'u8, 4'u8, 5'u8, 6'u8, 7'u8, 8'u8, 9'u8, 10'u8, 11'u8, 12'u8, 13'u8, 14'u8, 15'u8, 16'u8, 17'u8, 18'u8, 19'u8, 20'u8, 21'u8, 22'u8, 24'u8, 29'u8, 30'u8, 31'u8, 32'u8, 33'u8, 34'u8, 35'u8, 36'u8, 37'u8, 38'u8, 39'u8, 40'u8, 41'u8, 42'u8, 43'u8, 44'u8, 45'u8, 46'u8, 246'u8}

type
NifcStmt* = enum
Expand All @@ -70,15 +70,15 @@ type
JmpS = (88, "jmp") ## jump/goto instruction
RetS = (89, "ret") ## `return` instruction
StmtsS = (91, "stmts") ## list of statements
ImpS = (129, "imp") ## import declaration
InclS = (131, "incl") ## `#include` statement or `incl` set operation
DiscardS = (139, "discard") ## `discard` statement
TryS = (140, "try") ## `try` statement
RaiseS = (141, "raise") ## `raise` statement
OnerrS = (142, "onerr") ## error handling statement
ImpS = (130, "imp") ## import declaration
InclS = (132, "incl") ## `#include` statement or `incl` set operation
DiscardS = (140, "discard") ## `discard` statement
TryS = (141, "try") ## `try` statement
RaiseS = (142, "raise") ## `raise` statement
OnerrS = (143, "onerr") ## error handling statement

proc rawTagIsNifcStmt*(raw: uint32): bool {.inline.} =
raw <= 255'u32 and raw.uint8 in {46'u8, 50'u8, 51'u8, 52'u8, 54'u8, 61'u8, 68'u8, 73'u8, 74'u8, 75'u8, 76'u8, 81'u8, 84'u8, 85'u8, 87'u8, 88'u8, 89'u8, 91'u8, 129'u8, 131'u8, 139'u8, 140'u8, 141'u8, 142'u8}
raw <= 255'u32 and raw.uint8 in {46'u8, 50'u8, 51'u8, 52'u8, 54'u8, 61'u8, 68'u8, 73'u8, 74'u8, 75'u8, 76'u8, 81'u8, 84'u8, 85'u8, 87'u8, 88'u8, 89'u8, 91'u8, 130'u8, 132'u8, 140'u8, 141'u8, 142'u8, 143'u8}

type
NifcType* = enum
Expand All @@ -88,19 +88,19 @@ type
ObjectT = (94, "object") ## object type declaration
EnumT = (95, "enum") ## enum type declaration
ProctypeT = (96, "proctype") ## proc type declaration (soon obsolete, use params instead)
IT = (100, "i") ## `int` builtin type
UT = (101, "u") ## `uint` builtin type
FT = (102, "f") ## `float` builtin type
CT = (103, "c") ## `char` builtin type
BoolT = (104, "bool") ## `bool` builtin type
VoidT = (105, "void") ## `void` return type
PtrT = (106, "ptr") ## `ptr` type contructor
ArrayT = (107, "array") ## `array` type constructor
FlexarrayT = (108, "flexarray") ## `flexarray` type constructor
AptrT = (109, "aptr") ## "pointer to array of" type constructor
IT = (101, "i") ## `int` builtin type
UT = (102, "u") ## `uint` builtin type
FT = (103, "f") ## `float` builtin type
CT = (104, "c") ## `char` builtin type
BoolT = (105, "bool") ## `bool` builtin type
VoidT = (106, "void") ## `void` return type
PtrT = (107, "ptr") ## `ptr` type contructor
ArrayT = (108, "array") ## `array` type constructor
FlexarrayT = (109, "flexarray") ## `flexarray` type constructor
AptrT = (110, "aptr") ## "pointer to array of" type constructor

proc rawTagIsNifcType*(raw: uint32): bool {.inline.} =
raw >= 92'u32 and raw <= 109'u32 and raw != 97'u32 and raw != 98'u32 and raw != 99'u32
raw <= 255'u32 and raw.uint8 in {92'u8, 93'u8, 94'u8, 95'u8, 96'u8, 101'u8, 102'u8, 103'u8, 104'u8, 105'u8, 106'u8, 107'u8, 108'u8, 109'u8, 110'u8}

type
NifcOther* = enum
Expand All @@ -115,40 +115,41 @@ type
ElifU = (78, "elif") ## pair of (condition, action)
ElseU = (79, "else") ## `else` action
OfU = (86, "of") ## `of` branch within a `case` statement
PragmasU = (125, "pragmas") ## begin of pragma section
PragmasU = (126, "pragmas") ## begin of pragma section

proc rawTagIsNifcOther*(raw: uint32): bool {.inline.} =
raw <= 255'u32 and raw.uint8 in {28'u8, 48'u8, 49'u8, 53'u8, 58'u8, 59'u8, 60'u8, 78'u8, 79'u8, 86'u8, 125'u8}
raw <= 255'u32 and raw.uint8 in {28'u8, 48'u8, 49'u8, 53'u8, 58'u8, 59'u8, 60'u8, 78'u8, 79'u8, 86'u8, 126'u8}

type
NifcPragma* = enum
NoPragma
InlineP = (119, "inline") ## `inline` proc annotation
NoinlineP = (120, "noinline") ## `noinline` proc annotation
AttrP = (121, "attr") ## general attribute annoation
VarargsP = (122, "varargs") ## `varargs` proc annotation
WasP = (123, "was")
SelectanyP = (124, "selectany")
AlignP = (126, "align")
BitsP = (127, "bits")
VectorP = (128, "vector")
NodeclP = (130, "nodecl") ## `nodecl` annotation
RaisesP = (143, "raises") ## proc annotation
ErrsP = (144, "errs") ## proc annotation
StaticP = (145, "static") ## `static` type or annotation
InlineP = (120, "inline") ## `inline` proc annotation
NoinlineP = (121, "noinline") ## `noinline` proc annotation
AttrP = (122, "attr") ## general attribute annoation
VarargsP = (123, "varargs") ## `varargs` proc annotation
WasP = (124, "was")
SelectanyP = (125, "selectany")
AlignP = (127, "align")
BitsP = (128, "bits")
VectorP = (129, "vector")
NodeclP = (131, "nodecl") ## `nodecl` annotation
RaisesP = (144, "raises") ## proc annotation
ErrsP = (145, "errs") ## proc annotation
StaticP = (146, "static") ## `static` type or annotation

proc rawTagIsNifcPragma*(raw: uint32): bool {.inline.} =
raw <= 255'u32 and raw.uint8 in {119'u8, 120'u8, 121'u8, 122'u8, 123'u8, 124'u8, 126'u8, 127'u8, 128'u8, 130'u8, 143'u8, 144'u8, 145'u8}
raw <= 255'u32 and raw.uint8 in {120'u8, 121'u8, 122'u8, 123'u8, 124'u8, 125'u8, 127'u8, 128'u8, 129'u8, 131'u8, 144'u8, 145'u8, 146'u8}

type
NifcTypeQualifier* = enum
NoQualifier
AtomicQ = (97, "atomic") ## `atomic` type qualifier for NIFC
RoQ = (98, "ro") ## `readonly` (= `const`) type qualifier for NIFC
RestrictQ = (99, "restrict") ## type qualifier for NIFC
CpprefQ = (100, "cppref") ## type qualifier for NIFC that provides a C++ reference

proc rawTagIsNifcTypeQualifier*(raw: uint32): bool {.inline.} =
raw >= 97'u32 and raw <= 99'u32
raw >= 97'u32 and raw <= 100'u32

type
NifcSym* = enum
Expand Down
Loading

0 comments on commit 229266d

Please sign in to comment.