Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIFC: support C++ reference types via a pointer qualifier #530

Merged
merged 2 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading