summary refs log tree commit diff stats
path: root/compiler/cgen.nim
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2023-10-11 17:44:14 +0200
committerGitHub <noreply@github.com>2023-10-11 17:44:14 +0200
commit816589b6674e3af281766f1279420758dcacedc4 (patch)
tree3e4f825e29e2068466a35edc69cc27967b743687 /compiler/cgen.nim
parentecaccafa6c18e0b92cd5f75d3363d61c0866dec9 (diff)
downloadNim-816589b6674e3af281766f1279420758dcacedc4.tar.gz
NIR: Nim intermediate representation (#22777)
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.
Diffstat (limited to 'compiler/cgen.nim')
-rw-r--r--compiler/cgen.nim14
1 files changed, 8 insertions, 6 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index e9045b066..adee8f845 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -17,6 +17,8 @@ import
   lowerings, tables, sets, ndi, lineinfos, pathutils, transf,
   injectdestructors, astmsgs, modulepaths, backendpragmas
 
+from expanddefaults import caseObjDefaultBranch
+
 import pipelineutils
 
 when defined(nimPreviewSlimSystem):
@@ -499,8 +501,8 @@ proc resetLoc(p: BProc, loc: var TLoc) =
       # array passed as argument decayed into pointer, bug #7332
       # so we use getTypeDesc here rather than rdLoc(loc)
       let tyDesc = getTypeDesc(p.module, loc.t, descKindFromSymKind mapTypeChooser(loc))
-      if p.module.compileToCpp and isOrHasImportedCppType(typ): 
-        if lfIndirect in loc.flags: 
+      if p.module.compileToCpp and isOrHasImportedCppType(typ):
+        if lfIndirect in loc.flags:
           #C++ cant be just zeroed. We need to call the ctors
           var tmp = getTemp(p, loc.t)
           linefmt(p, cpsStmts,"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
@@ -508,7 +510,7 @@ proc resetLoc(p: BProc, loc: var TLoc) =
       else:
         linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
                 [addrLoc(p.config, loc), tyDesc])
-      
+
       # XXX: We can be extra clever here and call memset only
       # on the bytes following the m_type field?
       genObjectInit(p, cpsStmts, loc.t, loc, constructObj)
@@ -551,7 +553,7 @@ proc getTemp(p: BProc, t: PType, needsInit=false): TLoc =
   result = TLoc(r: "T" & rope(p.labels) & "_", k: locTemp, lode: lodeTyp t,
                 storage: OnStack, flags: {})
   if p.module.compileToCpp and isOrHasImportedCppType(t):
-    linefmt(p, cpsLocals, "$1 $2$3;$n", [getTypeDesc(p.module, t, dkVar), result.r, 
+    linefmt(p, cpsLocals, "$1 $2$3;$n", [getTypeDesc(p.module, t, dkVar), result.r,
       genCppInitializer(p.module, p, t)])
   else:
     linefmt(p, cpsLocals, "$1 $2;$n", [getTypeDesc(p.module, t, dkVar), result.r])
@@ -607,8 +609,8 @@ proc assignLocalVar(p: BProc, n: PNode) =
   # this need not be fulfilled for inline procs; they are regenerated
   # for each module that uses them!
   let nl = if optLineDir in p.config.options: "" else: "\n"
-  var decl = localVarDecl(p, n) 
-  if p.module.compileToCpp and isOrHasImportedCppType(n.typ): 
+  var decl = localVarDecl(p, n)
+  if p.module.compileToCpp and isOrHasImportedCppType(n.typ):
     decl.add genCppInitializer(p.module, p, n.typ)
   decl.add ";" & nl
   line(p, cpsLocals, decl)