summary refs log tree commit diff stats
path: root/nim/magicsys.pas
diff options
context:
space:
mode:
Diffstat (limited to 'nim/magicsys.pas')
-rw-r--r--nim/magicsys.pas124
1 files changed, 82 insertions, 42 deletions
diff --git a/nim/magicsys.pas b/nim/magicsys.pas
index 2f314065d..55ec0b002 100644
--- a/nim/magicsys.pas
+++ b/nim/magicsys.pas
@@ -8,8 +8,7 @@
 //
 unit magicsys;
 
-// This module declares built-in System types like int or string in the
-// system module.
+// Built-in types and compilerprocs are registered here.
 
 interface
 
@@ -17,44 +16,102 @@ interface
 
 uses
   nsystem,
-  ast, astalgo, hashes, msgs, platform, nversion, ntime, idents;
+  ast, astalgo, hashes, msgs, platform, nversion, ntime, idents, rodread;
 
 var // magic symbols in the system module:
-  notSym: PSym;              // 'not' operator (for bool)
-  countUpSym: PSym;          // countup iterator
-
   SystemModule: PSym;
-  intSetBaseType: PType;
-
-  compilerprocs: TStrTable;
 
+procedure registerSysType(t: PType);
 function getSysType(const kind: TTypeKind): PType;
-function getMatic(m: TMagic; const name: string): PSym;
+
 function getCompilerProc(const name: string): PSym;
+procedure registerCompilerProc(s: PSym);
 
 procedure InitSystem(var tab: TSymTab);
 procedure FinishSystem(const tab: TStrTable);
 
-procedure setSize(t: PType; size: int);
-
 implementation
 
 var
   gSysTypes: array [TTypeKind] of PType;
+  compilerprocs: TStrTable;
+
+procedure registerSysType(t: PType);
+begin
+  if gSysTypes[t.kind] = nil then gSysTypes[t.kind] := t;
+end;
+
+function newSysType(kind: TTypeKind; size: int): PType;
+begin
+  result := newType(kind, systemModule);
+  result.size := size;
+  result.align := size;
+end;
+
+function sysTypeFromName(const name: string): PType;
+var
+  s: PSym;
+begin
+  s := StrTableGet(systemModule.tab, getIdent(name));
+  if s = nil then rawMessage(errSystemNeeds, name);
+  if s.kind = skStub then loadStub(s); 
+  result := s.typ;
+end;
 
 function getSysType(const kind: TTypeKind): PType;
 begin
   result := gSysTypes[kind];
-  assert(result <> nil);
+  if result = nil then begin
+    case kind of
+      tyInt:     result := sysTypeFromName('int');
+      tyInt8:    result := sysTypeFromName('int8');
+      tyInt16:   result := sysTypeFromName('int16');
+      tyInt32:   result := sysTypeFromName('int32');
+      tyInt64:   result := sysTypeFromName('int64');
+      tyFloat:   result := sysTypeFromName('float');
+      tyFloat32: result := sysTypeFromName('float32');
+      tyFloat64: result := sysTypeFromName('float64');
+      tyBool:    result := sysTypeFromName('bool');
+      tyChar:    result := sysTypeFromName('char');
+      tyString:  result := sysTypeFromName('string');
+      tyCstring: result := sysTypeFromName('cstring');
+      tyPointer: result := sysTypeFromName('pointer');
+      tyAnyEnum: result := newSysType(tyAnyEnum, 1);
+      tyNil: result := newSysType(tyNil, ptrSize);
+      else InternalError('request for typekind: ' + typeKindToStr[kind]);
+    end;  
+    gSysTypes[kind] := result;
+  end;
+  if result.kind <> kind then 
+    InternalError('wanted: ' + typeKindToStr[kind] 
+      +{&} ' got: ' +{&} typeKindToStr[result.kind]);
+  if result = nil then InternalError('type not found: ' + typeKindToStr[kind]);
 end;
 
-
 function getCompilerProc(const name: string): PSym;
+var
+  ident: PIdent;
 begin
-  result := StrTableGet(compilerprocs, getIdent(name, getNormalizedHash(name)));
-  if result = nil then rawMessage(errSystemNeeds, name)
+  ident := getIdent(name, getNormalizedHash(name));
+  result := StrTableGet(compilerprocs, ident);
+  if result = nil then begin
+    result := StrTableGet(rodCompilerProcs, ident);
+    if result = nil then rawMessage(errSystemNeeds, name);
+    strTableAdd(compilerprocs, result);
+    if result.kind = skStub then loadStub(result);
+    // A bit hacky that this code is needed here, but it is the easiest 
+    // solution in order to avoid special cases for sfCompilerProc in the
+    // rodgen module. Another solution would be to always recompile the system
+    // module. But I don't want to do that as that would mean less testing of
+    // the new symbol file cache (and worse performance).
+  end;
 end;
 
+procedure registerCompilerProc(s: PSym);
+begin
+  strTableAdd(compilerprocs, s);
+end;
+(*
 function FindMagic(const tab: TStrTable; m: TMagic; const s: string): PSym;
 var
   ti: TIdentIter;
@@ -66,11 +123,6 @@ begin
   end
 end;
 
-function getMatic(m: TMagic; const name: string): PSym;
-begin
-  result := findMagic(systemModule.tab, m, name);
-end;
-
 function NewMagic(kind: TSymKind; const name: string;
   const info: TLineInfo): PSym;
 begin
@@ -84,7 +136,6 @@ function newMagicType(const info: TLineInfo; kind: TTypeKind;
 begin
   result := newType(kind, SystemModule);
   result.sym := magicSym;
-  assert(SystemModule <> nil);
 end;
 
 procedure setSize(t: PType; size: int);
@@ -93,15 +144,6 @@ begin
   t.size := size;
 end;
 
-
-//     not   -(unary)                         700
-//     *   /    div   mod                     600
-//     +   -                                  500
-//     &   ..                                 400
-//     ==   <=  <  >=  >  !=   in    not_in   300
-//     and                                    200
-//     or   xor                               100
-
 procedure addMagicSym(var tab: TSymTab; sym: PSym; sys: PSym);
 begin
   SymTabAdd(tab, sym);
@@ -132,13 +174,10 @@ begin
   s.typ := newMagicType(fakeInfo, tyAnyEnum, s);
   SymTabAdd(tab, s);
 end;
-
+*)
 procedure InitSystem(var tab: TSymTab);
-var
-  c: PSym;
-  typ: PType;
-begin
-  initStrTable(compilerprocs);
+begin (*
+  if SystemModule = nil then InternalError('systemModule == nil');
   fakeInfo := newLineInfo('system.nim', 1, 1);
   // symbols with compiler magic are pretended to be in system at line 1
 
@@ -209,25 +248,26 @@ begin
   intSetBaseType := newMagicType(fakeInfo, tyRange, nil);
   addSon(intSetBaseType, gSysTypes[tyInt]); // base type
   setSize(intSetBaseType, int(gSysTypes[tyInt].size));
-  intSetBaseType.n := newNode(nkRange);
-  intSetBaseType.n.info := fakeInfo;
+  intSetBaseType.n := newNodeI(nkRange, fakeInfo);
   addSon(intSetBaseType.n, newIntNode(nkIntLit, 0));
   addSon(intSetBaseType.n, newIntNode(nkIntLit, nversion.MaxSetElements-1));
   intSetBaseType.n.sons[0].info := fakeInfo;
   intSetBaseType.n.sons[1].info := fakeInfo;
   intSetBaseType.n.sons[0].typ := gSysTypes[tyInt];
-  intSetBaseType.n.sons[1].typ := gSysTypes[tyInt];
+  intSetBaseType.n.sons[1].typ := gSysTypes[tyInt]; *)
 end;
 
 procedure FinishSystem(const tab: TStrTable);
-begin
+begin (*
   notSym := findMagic(tab, mNot, 'not');
   if (notSym = nil) then
     rawMessage(errSystemNeeds, 'not');
 
   countUpSym := StrTableGet(tab, getIdent('countup'));
   if (countUpSym = nil) then
-    rawMessage(errSystemNeeds, 'countup');
+    rawMessage(errSystemNeeds, 'countup'); *)
 end;
 
+initialization
+  initStrTable(compilerprocs);
 end.