-
Notifications
You must be signed in to change notification settings - Fork 23
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
user defined quote literals, eg: -12.3E+4022'dec128 ; -128'i8 is transformed as i8("-128")
#228
Comments
Pretty nice but please work out how backwards compat can work. Having to patch existing macros is not acceptable. Been there, done that, it's expensive and a desaster for the ecosystem. |
It is my intent to have a PR for this placed before the end of February 2021. Perhaps sooner as I already have it working; I just need to write more test cases to confirm it handles more border conditions and errors gracefully. However my solution takes a somewhat different tack: rather than combine all numeric literals into a single token for later parsing, my solution leaves the current literals as-is and adds a new one: In the parser, when the new token is seen it attempts to run the var a = 1234.56E7m # or 1234.56E7'm into var A = "1234.56E7".m My motive is to allow this function to enable the IEEE 745 decimal library (#308) I'm writing to also use this. Specifically "m" will be the suffix (a convention used in C# and a few other languages.) One of my goals to have this fully convert/resolve at compile-time. The Because this adds a token, other files such as docgen.nim etc will also need update, but those updates will be minimal. These changes do not modify the AST structure in any way, so macros should behave the same. I will also make updates to documentation. Admittedly, my solution is not as "pure" and comprehensive as yours. But it could be an intermediate place to make it more pure with another later PR. |
nim-lang/Nim#17489 will soon be merged. This RFC has been implemented. |
summary
-128'i8
) become regular user defined literals (UDL) that the parser represents as a litteral-call expressioni8("-128")
, with ASTnkLitCall(nkIdent("i8"), nkStrLit("-128"))
; which has same semantics asnkCall
nkCharLit .. nkFloat64Lit
get replaced by a singlenkLit
kind, andTNode
is simplified as follows:(or if
nkFloat128Lit
is still needed, toarray[2,uint64]
instead ofuint64
)value
fromuint64
to the appropriate type as specified bytyp : PType
(then casting back touint64
)details
123'i8
) into litteral-call expressions as follows:'
that are in some set (eg: numbers +-
+ letters; precise set TBD); eg-123e-12
) is delayed until it's needed (eg for cgen, or vm)benefits
remove edge case where T.low can't be used as a litteral for signed types T, eg
-128'i8
, see -128'i8 gives: Error: number out of range: '128'i8' timotheecour/Nim#125; because it'd be parsed as:i8("-128")
repr
(and runnableExamples rendering etc) would preserve original source code formatting (refs runnableExamples should preserve source code doc comments, strings, and (maybe) formatting Nim#8871) in particalbinary/octal/1_000_000
; it'd also make it easier fornimpretty
andnim doc
parsing becomes lazier, leading to potentially faster compile times in case some large chunk of code is statically disabled, eg via
when defined cpp: let a = 12.3'f32
=>12.3
won't need to be parsed into a floatno more redundancy between the type (eg
tyInt32
) and the literal (egnkInt32Lit
) since we now just have the type + a single kind nkLit; AST is simplified, user macros and compiler code have lessTNodeKind
kinds to deal withparser backward compatibility when new literals are introduced
suppose we implement these new literal handling in 1.3.7, then any nim version after that will be backward compatible using since, eg:
the "generalized" literal handling could also be backported to older nim (eg 1.2.2) using a simple hack: turn unrecognized literals (eg 1.2'f80) into an error PNode, but not a parser error, so that
since 1.3.7:
would work and not give parser erroreverything becomes user defined, so
dec128
(https://forum.nim-lang.org/t/6310#38884) can be written via:the builtin literals are not special builtins anymore, and require symbols defined in system.nim, eg:
with
-0x12e4567'bar
, ifbar
isn't defined in scope, it gives a regular CT error (bar
not defined)examples
all these types can be implemented as library solution and preserve nice native looking syntax, and also, would render as numerical types, not strings (pending updating syntax highlighters, including github linguist, as evidenced by ugly highlighting in this post)
note
I originally suggested an initial concept of this in RFC: represent all litterals as string compilerdev#7 but then realized it could be generalized to support arbitrary user defined literals and simplify the AST thanks to parser transformation, so that builtin literals (eg
123'i8
) are no longer builtin and naturally extend to other user defined literalsliterals without quote (quote as in
1'i8
) can be handled uniformly as literals with quote by a fake litteral-call, eg:openLitteral
preserves the same semantics asconst b = 1234
, in that the type is not bound but kept open so that this remains valid:VM
likewise for VM:
TFullReg
could be simplified as:with following benefits:
The text was updated successfully, but these errors were encountered: