mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 13:33:22 +00:00
Theoretical Benefits / Plans: - Typed assembler-like language. - Allows for a CPS transformation. - Can replace the existing C backend by a new C backend. - Can replace the VM. - Can do more effective "not nil" checking and static array bounds checking. - Can be used instead of the DFA. - Easily translatable to LLVM. - Reasonably easy to produce native code from. - Tiny memory consumption. No pointers, no cry. **In very early stages of development.** Todo: - [x] Map Nim types to IR types. - [ ] Map Nim AST to IR instructions: - [x] Map bitsets to bitops. - [ ] Implement string cases. - [ ] Implement range and index checks. - [x] Implement `default(T)` builtin. - [x] Implement multi string concat. - [ ] Write some analysis passes. - [ ] Write a backend. - [x] Integrate into the compilation pipeline.
79 lines
1.8 KiB
Nim
79 lines
1.8 KiB
Nim
#
|
|
#
|
|
# The Nim Compiler
|
|
# (c) Copyright 2023 Andreas Rumpf
|
|
#
|
|
# See the file "copying.txt", included in this
|
|
# distribution, for details about the copyright.
|
|
#
|
|
|
|
# We produce C code as a list of tokens.
|
|
|
|
import std / assertions
|
|
import .. / ic / bitabs
|
|
|
|
type
|
|
Token = LitId # indexing into the tokens BiTable[string]
|
|
|
|
PredefinedToken = enum
|
|
IgnoreMe = "<unused>"
|
|
EmptyToken = ""
|
|
DeclPrefix = "" # the next token is the name of a definition
|
|
CurlyLe = "{"
|
|
CurlyRi = "}"
|
|
ParLe = "("
|
|
ParRi = ")"
|
|
BracketLe = "["
|
|
BracketRi = "]"
|
|
NewLine = "\n"
|
|
Semicolon = ";"
|
|
Comma = ", "
|
|
Space = " "
|
|
Colon = ":"
|
|
Dot = "."
|
|
Arrow = "->"
|
|
Star = "*"
|
|
Amp = "&"
|
|
AsgnOpr = " = "
|
|
ScopeOpr = "::"
|
|
ConstKeyword = "const "
|
|
StaticKeyword = "static "
|
|
NimString = "NimString"
|
|
StrLitPrefix = "(NimChar*)"
|
|
StrLitNamePrefix = "Qstr"
|
|
LoopKeyword = "while (true) "
|
|
WhileKeyword = "while ("
|
|
IfKeyword = "if ("
|
|
ElseKeyword = "else "
|
|
SwitchKeyword = "switch ("
|
|
CaseKeyword = "case "
|
|
DefaultKeyword = "default:"
|
|
BreakKeyword = "break"
|
|
NullPtr = "nullptr"
|
|
IfNot = "if (!("
|
|
ReturnKeyword = "return "
|
|
|
|
const
|
|
ModulePrefix = Token(int(ReturnKeyword)+1)
|
|
|
|
proc fillTokenTable(tab: var BiTable[string]) =
|
|
for e in EmptyToken..high(PredefinedToken):
|
|
let id = tab.getOrIncl $e
|
|
assert id == LitId(e)
|
|
|
|
type
|
|
GeneratedCode* = object
|
|
code: seq[LitId]
|
|
tokens: BiTable[string]
|
|
|
|
proc initGeneratedCode*(): GeneratedCode =
|
|
result = GeneratedCode(code: @[], tokens: initBiTable[string]())
|
|
fillTokenTable(result.tokens)
|
|
|
|
proc add*(g: var GeneratedCode; t: PredefinedToken) {.inline.} =
|
|
g.code.add Token(t)
|
|
|
|
proc add*(g: var GeneratedCode; s: string) {.inline.} =
|
|
g.code.add g.tokens.getOrIncl(s)
|
|
|