https://gcc.gnu.org/g:d1c3cfa3296ae5010c514d67f57acf144a299c7a

commit r16-1277-gd1c3cfa3296ae5010c514d67f57acf144a299c7a
Author: Gaius Mulley <gaiusm...@gmail.com>
Date:   Sat Jun 7 16:25:19 2025 +0100

    [PR modula2/119650, PR modula2/117203]: WriteString and Delete are missing 
from base libraries
    
    This patch introduces a Write procedure for an array of char,
    the string and char datatype.  It uses the m2r10 style of
    naming the module on the datatype.  This uncovered a bug
    in the import handling inside Quadident.  It also includes
    an Unlink procedure from a new module FileSysOp and a String
    interface to this module.
    
    gcc/m2/ChangeLog:
    
            PR modula2/119650
            PR modula2/117203
            * gm2-compiler/P2Build.bnf (CheckModuleQualident): New
            procedure.
            (Qualident): Rewrite.
            * gm2-compiler/P3Build.bnf (PushTFQualident): New procedure.
            (CheckModuleQualident): Ditto.
            (Qualident): Rewrite.
            * gm2-compiler/PCBuild.bnf (PushTFQualident): New procedure.
            (CheckModuleQualident): Ditto.
            (Qualident): Rewrite.
            * gm2-compiler/PHBuild.bnf (PushTFQualident): New procedure.
            (CheckModuleQualident): Ditto.
            (Qualident): Rewrite.
            * gm2-libs/ARRAYOFCHAR.def: New file.
            * gm2-libs/ARRAYOFCHAR.mod: New file.
            * gm2-libs/CFileSysOp.def: New file.
            * gm2-libs/CHAR.def: New file.
            * gm2-libs/CHAR.mod: New file.
            * gm2-libs/FileSysOp.def: New file.
            * gm2-libs/FileSysOp.mod: New file.
            * gm2-libs/String.def: New file.
            * gm2-libs/String.mod: New file.
            * gm2-libs/StringFileSysOp.def: New file.
            * gm2-libs/StringFileSysOp.mod: New file.
    
    libgm2/ChangeLog:
    
            PR modula2/119650
            PR modula2/117203
            * libm2pim/Makefile.am (M2MODS): Add ARRAYOFCHAR,
            CHAR.mod, StringFileSysOp.mod and String.mod.
            (M2DEFS): Add ARRAYOFCHAR, CHAR.mod,
            StringFileSysOp.mod and String.mod.
            (libm2pim_la_SOURCES): Add CFileSysOp.c.
            * libm2pim/Makefile.in: Regenerate.
            * libm2pim/CFileSysOp.cc: New file.
    
    gcc/testsuite/ChangeLog:
    
            PR modula2/119650
            * gm2/iso/fail/CHAR.mod: New test.
            * gm2/iso/run/pass/CHAR.mod: New test.
            * gm2/iso/run/pass/importself.mod: New test.
            * gm2/pimlib/run/pass/testwrite.mod: New test.
            * gm2/pimlib/run/pass/testwritechar.mod: New test.
    
    Signed-off-by: Gaius Mulley <gaiusm...@gmail.com>

Diff:
---
 gcc/m2/gm2-compiler/P2Build.bnf                    |  79 +++++++----
 gcc/m2/gm2-compiler/P3Build.bnf                    |  99 +++++++++-----
 gcc/m2/gm2-compiler/PCBuild.bnf                    |  97 +++++++++-----
 gcc/m2/gm2-compiler/PHBuild.bnf                    |  86 +++++++++---
 gcc/m2/gm2-libs/ARRAYOFCHAR.def                    |  41 ++++++
 gcc/m2/gm2-libs/ARRAYOFCHAR.mod                    |  56 ++++++++
 gcc/m2/gm2-libs/CFileSysOp.def                     |  56 ++++++++
 gcc/m2/gm2-libs/CHAR.def                           |  40 ++++++
 gcc/m2/gm2-libs/CHAR.mod                           |  48 +++++++
 gcc/m2/gm2-libs/FileSysOp.def                      |  44 +++++++
 gcc/m2/gm2-libs/FileSysOp.mod                      |  98 ++++++++++++++
 gcc/m2/gm2-libs/String.def                         |  35 +++++
 gcc/m2/gm2-libs/String.mod                         |  51 ++++++++
 gcc/m2/gm2-libs/StringFileSysOp.def                |  40 ++++++
 gcc/m2/gm2-libs/StringFileSysOp.mod                |  63 +++++++++
 gcc/testsuite/gm2/iso/fail/CHAR.mod                |   7 +
 gcc/testsuite/gm2/iso/run/pass/CHAR.mod            |   7 +
 gcc/testsuite/gm2/iso/run/pass/importself.mod      |  14 ++
 gcc/testsuite/gm2/pimlib/run/pass/testwrite.mod    |   8 ++
 .../gm2/pimlib/run/pass/testwritechar.mod          |  13 ++
 libgm2/libm2pim/CFileSysOp.cc                      | 145 +++++++++++++++++++++
 libgm2/libm2pim/Makefile.am                        |  20 ++-
 libgm2/libm2pim/Makefile.in                        |  27 +++-
 23 files changed, 1059 insertions(+), 115 deletions(-)

diff --git a/gcc/m2/gm2-compiler/P2Build.bnf b/gcc/m2/gm2-compiler/P2Build.bnf
index b9a6daa70b2e..c28e630422f7 100644
--- a/gcc/m2/gm2-compiler/P2Build.bnf
+++ b/gcc/m2/gm2-compiler/P2Build.bnf
@@ -46,7 +46,8 @@ see <https://www.gnu.org/licenses/>.  *)
 IMPLEMENTATION MODULE P2Build ;
 
 FROM M2LexBuf IMPORT currentstring, currenttoken, GetToken, InsertToken,
-                     InsertTokenAndRewind, GetTokenNo, MakeVirtual2Tok ;
+                     InsertTokenAndRewind, GetTokenNo, MakeVirtual2Tok,
+                    MakeVirtualTok ;
 
 FROM M2MetaError IMPORT MetaErrorStringT0, MetaErrorT1 ;
 FROM NameKey IMPORT NulName, Name, makekey, MakeKey ;
@@ -128,13 +129,13 @@ FROM SymbolTable IMPORT MakeGnuAsm, PutGnuAsmVolatile, 
PutGnuAsm, PutGnuAsmInput
                         PutGnuAsmOutput, PutGnuAsmTrash, PutGnuAsmVolatile,
                         MakeRegInterface,
                         PutRegInterface, GetRegInterface,
-                        GetSymName, GetType, MakeConstLit,
+                        GetSymName, GetType, MakeConstLit, IsProcType,
                         NulSym,
-                        StartScope, EndScope,
+                        StartScope, EndScope, GetCurrentModule,
                         PutIncluded,
                         PutExceptionFinally, PutExceptionBlock, 
GetCurrentScope,
                         IsVarParam, IsProcedure, IsDefImp, IsModule,
-                        IsRecord, IsAModula2Type,
+                        IsRecord, IsAModula2Type, IsImported,
                         RequestSym ;
 
 IMPORT M2Error ;
@@ -450,6 +451,54 @@ BEGIN
    Expect(realtok, stopset0, stopset1, stopset2)
 END Real ;
 
+
+(*
+   CheckModuleQualident - check to see if the beginning ident of the qualident 
is an
+                          imported module.
+*)
+
+PROCEDURE CheckModuleQualident (stopset0: SetOfStop0;
+                                stopset1: SetOfStop1;
+                               stopset2: SetOfStop2) ;
+VAR
+   name         : Name ;
+   init,
+   nextLevel,
+   tok, tokstart: CARDINAL ;
+BEGIN
+   PopTtok (name, tokstart) ;
+   tok := tokstart ;
+   init := RequestSym (tok, name) ;
+   IF IsImported (GetCurrentModule (), init) AND (IsDefImp (init) OR IsModule 
(init))
+   THEN
+      WHILE IsDefImp (init) OR IsModule (init) DO
+         Expect (periodtok, stopset0, stopset1, stopset2 + 
SetOfStop2{identtok}) ;
+         StartScope (init) ;
+         Ident (stopset0, stopset1, stopset2) ;
+        PopTtok (name, tok) ;
+         nextLevel := RequestSym (tok, name) ;
+         EndScope ;
+        init := nextLevel
+      END ;
+      IF tok#tokstart
+      THEN
+         tok := MakeVirtualTok (tokstart, tokstart, tok)
+      END ;
+      IF IsProcedure (init) OR IsProcType (init)
+      THEN
+         PushTtok (init, tok)
+      ELSE
+         Annotate ("%1s(%1d)|%1s(%1d)||qualident|type") ;
+         PushTFtok (init, GetType (init), tok) ;
+      END ;
+      PutIncluded (init)
+   ELSE
+      PushTFtok (init, GetType (init), tok) ;
+      Annotate ("%1s(%1d)|%1s(%1d)||qualident|type")
+   END
+END CheckModuleQualident ;
+
+
 % module P2Build end
 END P2Build.
 % rules
@@ -609,28 +658,10 @@ ImplementationOrProgramModule := ImplementationModule | 
ProgramModule =:
 
 Number := Integer | Real =:
 
-Qualident :=                                                               % 
VAR name: Name ;
-                                                                               
  Type, Sym, tok: CARDINAL ; %
-             Ident
+Qualident := Ident
                                                                            % 
IF IsAutoPushOn()
                                                                              
THEN
-                                                                               
 PopTtok(name, tok) ;
-                                                                               
 Sym := RequestSym (tok, name) ;
-                                                                               
 IF IsDefImp(Sym) OR IsModule(Sym)
-                                                                               
 THEN
-                                                                               
    Expect(periodtok, stopset0, stopset1, stopset2 + SetOfStop2{identtok}) ;
-                                                                               
    StartScope(Sym) ;
-                                                                               
    Qualident(stopset0, stopset1, stopset2) ;
-                                                                               
    (* should we test for lack of ident? *)
-                                                                               
    PopTFtok(Sym, Type, tok) ;
-                                                                               
    PushTFtok(Sym, Type, tok) ;
-                                                                               
    Annotate("%1s(%1d)|%1s(%1d)||qualident|type") ;
-                                                                               
    EndScope ;
-                                                                               
    PutIncluded(Sym)
-                                                                               
 ELSE
-                                                                               
    PushTFtok(Sym, GetType(Sym), tok) ;
-                                                                               
    Annotate("%1s(%1d)|%1s(%1d)||qualident|type")
-                                                                               
 END
+                                                                               
CheckModuleQualident (stopset0, stopset1, stopset2)
                                                                              
ELSE (* just parse qualident *) %
              { "." Ident }                                                 % 
END %
            =:
diff --git a/gcc/m2/gm2-compiler/P3Build.bnf b/gcc/m2/gm2-compiler/P3Build.bnf
index 4f6ffb772211..0033d33e446a 100644
--- a/gcc/m2/gm2-compiler/P3Build.bnf
+++ b/gcc/m2/gm2-compiler/P3Build.bnf
@@ -166,14 +166,14 @@ FROM SymbolTable IMPORT MakeGnuAsm, PutGnuAsmVolatile, 
PutGnuAsm, PutGnuAsmInput
                         MakeRegInterface,
                         PutRegInterface,
                         IsRegInterface, IsGnuAsmVolatile, IsGnuAsm,
-                        GetCurrentModule,
+                        GetCurrentModule, IsInnerModule,
                         GetSymName, GetType, SkipType,
                         NulSym,
                         StartScope, EndScope,
                         PutIncluded,
                         IsVarParam, IsProcedure, IsDefImp, IsModule, 
IsProcType,
                         IsRecord,
-                        RequestSym, IsExported,
+                        RequestSym, IsExported, IsImported,
                         GetSym, GetLocalSym ;
 
 FROM M2Batch IMPORT IsModuleKnown ;
@@ -468,6 +468,69 @@ BEGIN
    Expect(realtok, stopset0, stopset1, stopset2)
 END Real ;
 
+
+(*
+   PushTFQualident - push the result of the Qualident
+                     to the stack.  It checks to see if init
+                    is a procedure or proc type and if so
+                    it does not push the return type.
+*)
+
+PROCEDURE PushTFQualident (tok, tokstart: CARDINAL;
+                           init: CARDINAL) ;
+BEGIN
+   IF tok#tokstart
+   THEN
+      tok := MakeVirtualTok (tokstart, tokstart, tok)
+   END ;
+   IF IsProcedure (init) OR IsProcType (init) OR IsModule (init) OR IsDefImp 
(init)
+   THEN
+      PushTtok (init, tok) ;
+      Annotate ("%1s(%1d)||qualident procedure/proctype") ;
+   ELSE
+      Annotate ("%1s(%1d)|%1s(%1d)||qualident|type") ;
+      PushTFtok (init, GetType (init), tok) ;
+   END
+END PushTFQualident ;
+
+
+(*
+   CheckModuleQualident - check to see if the beginning ident of the qualident 
is an
+                          imported module.
+*)
+
+PROCEDURE CheckModuleQualident (stopset0: SetOfStop0;
+                                stopset1: SetOfStop1;
+                               stopset2: SetOfStop2) ;
+VAR
+   name         : Name ;
+   init,
+   nextLevel,
+   tok, tokstart: CARDINAL ;
+BEGIN
+   PopTtok (name, tokstart) ;
+   tok := tokstart ;
+   init := RequestSym (tok, name) ;
+   IF (IsImported (GetCurrentModule (), init) AND IsDefImp (init)) OR
+      IsModule (init)
+   THEN
+      WHILE IsDefImp (init) OR IsModule (init) DO
+         Expect (periodtok, stopset0, stopset1, stopset2 + 
SetOfStop2{identtok}) ;
+         StartScope (init) ;
+         Ident (stopset0, stopset1, stopset2) ;
+        PopTtok (name, tok) ;
+         nextLevel := RequestSym (tok, name) ;
+         EndScope ;
+        CheckCanBeImported (init, nextLevel) ;
+        init := nextLevel
+      END ;
+      PushTFQualident (tok, tokstart, init) ;
+      PutIncluded (init)
+   ELSE
+      PushTFQualident (tok, tokstart, init)
+   END
+END CheckModuleQualident ;
+
 % module P3Build end
 BEGIN
    BlockState := InitState ()
@@ -643,37 +706,11 @@ Number := Integer | Real =:
 --  IsAutoPushOff then we just consume tokens.
 --
 
-Qualident :=                                                               % 
VAR name          : Name ;
-                                                                               
  init, ip1,
-                                                                               
  tokstart, tok : CARDINAL ; %
-             Ident
+Qualident := Ident
                                                                            % 
IF IsAutoPushOn()
                                                                              
THEN
-                                                                               
 PopTtok(name, tokstart) ;
-                                                                               
tok := tokstart ;
-                                                                               
 init := RequestSym (tok, name) ;
-                                                                               
 WHILE IsDefImp (init) OR IsModule (init) DO
-                                                                               
    Expect (periodtok, stopset0, stopset1, stopset2 + SetOfStop2{identtok}) ;
-                                                                               
    StartScope (init) ;
-                                                                               
    Ident (stopset0, stopset1, stopset2) ;
-                                                                               
    PopTtok (name, tok) ;
-                                                                               
    ip1 := RequestSym (tok, name) ;
-                                                                               
    PutIncluded(ip1) ;
-                                                                               
    EndScope ;
-                                                                               
    CheckCanBeImported(init, ip1) ;
-                                                                               
    init := ip1
-                                                                               
 END ;
-                                                                               
IF tok#tokstart
-                                                                               
THEN
-                                                                               
   tok := MakeVirtualTok (tokstart, tokstart, tok)
-                                                                               
END ;
-                                                                               
 IF IsProcedure(init) OR IsProcType(init)
-                                                                               
 THEN
-                                                                               
    PushTtok(init, tok)
-                                                                               
 ELSE
-                                                                               
    PushTFtok(init, GetType(init), tok) ;
-                                                                               
 END
-                                                                             
ELSE %
+                                                                               
CheckModuleQualident (stopset0, stopset1, stopset2)
+                                                                             
ELSE (* just parse qualident *) %
              { "." Ident }                                                 % 
END %
            =:
 
diff --git a/gcc/m2/gm2-compiler/PCBuild.bnf b/gcc/m2/gm2-compiler/PCBuild.bnf
index a05a55f2612f..ddbe2f1b2fc0 100644
--- a/gcc/m2/gm2-compiler/PCBuild.bnf
+++ b/gcc/m2/gm2-compiler/PCBuild.bnf
@@ -65,7 +65,7 @@ FROM M2Quads IMPORT Top, PushT, PopT, PushTF, PopTF, 
PopNothing, OperandT, Opera
                     PushTFA,
                     PushTFn, PopTFn, PushTFtok, PopTtok, PopTFtok, PushTtok, 
PushTFntok,
                     PushT, PushTF, IsAutoPushOn, PushAutoOff, PushAutoOn, 
PopAuto,
-                    DupFrame,
+                    DupFrame, Annotate,
                     BuildTypeForConstructor, BuildConstructor, 
BuildConstructorEnd,
                     PopConstructor,
                     NextConstructorField, SilentBuildConstructor,
@@ -118,6 +118,7 @@ FROM SymbolTable IMPORT MakeGnuAsm, PutGnuAsmVolatile, 
PutGnuAsm, PutGnuAsmInput
                         PutIncluded,
                         IsVarParam, IsProcedure, IsDefImp, IsModule,
                         IsRecord, IsProcType,
+                        GetCurrentModule, IsInnerModule, IsImported,
                         RequestSym,
                         GetSym, GetLocalSym ;
 
@@ -412,6 +413,68 @@ BEGIN
    Expect(realtok, stopset0, stopset1, stopset2)
 END Real ;
 
+
+(*
+   PushTFQualident - push the result of the Qualident
+                     to the stack.  It checks to see if init
+                    is a procedure or proc type and if so
+                    it does not push the return type.
+*)
+
+PROCEDURE PushTFQualident (tok, tokstart: CARDINAL;
+                           init: CARDINAL) ;
+BEGIN
+   IF tok#tokstart
+   THEN
+      tok := MakeVirtualTok (tokstart, tokstart, tok)
+   END ;
+   IF IsProcedure (init) OR IsProcType (init)
+   THEN
+      PushTtok (init, tok) ;
+      Annotate ("%1s(%1d)||qualident procedure/proctype") ;
+   ELSE
+      Annotate ("%1s(%1d)|%1s(%1d)||qualident|type") ;
+      PushTFtok (init, GetType (init), tok) ;
+   END
+END PushTFQualident ;
+
+
+(*
+   CheckModuleQualident - check to see if the beginning ident of the qualident 
is an
+                          imported module.
+*)
+
+PROCEDURE CheckModuleQualident (stopset0: SetOfStop0;
+                                stopset1: SetOfStop1;
+                               stopset2: SetOfStop2) ;
+VAR
+   name         : Name ;
+   init,
+   nextLevel,
+   tok, tokstart: CARDINAL ;
+BEGIN
+   PopTtok (name, tokstart) ;
+   tok := tokstart ;
+   init := RequestSym (tok, name) ;
+   IF IsImported (GetCurrentModule (), init) AND (IsDefImp (init) OR IsModule 
(init))
+   THEN
+      WHILE IsDefImp (init) OR IsModule (init) DO
+         Expect (periodtok, stopset0, stopset1, stopset2 + 
SetOfStop2{identtok}) ;
+         StartScope (init) ;
+         Ident (stopset0, stopset1, stopset2) ;
+        PopTtok (name, tok) ;
+         nextLevel := RequestSym (tok, name) ;
+         EndScope ;
+        CheckCanBeImported (init, nextLevel) ;
+        init := nextLevel
+      END ;
+      PushTFQualident (tok, tokstart, init) ;
+      PutIncluded (init)
+   ELSE
+      PushTFQualident (tok, tokstart, init)
+   END
+END CheckModuleQualident ;
+
 % module PCBuild end
 BEGIN
    BlockState := InitState ()
@@ -569,37 +632,11 @@ ImplementationOrProgramModule :=                          
                 % Pus
 
 Number := Integer | Real =:
 
-Qualident :=                                                               % 
VAR name          : Name ;
-                                                                               
  init, ip1,
-                                                                               
  tokstart, tok : CARDINAL ; %
-             Ident
+Qualident := Ident
                                                                            % 
IF IsAutoPushOn()
                                                                              
THEN
-                                                                               
 PopTtok(name, tokstart) ;
-                                                                               
tok := tokstart ;
-                                                                               
 init := RequestSym (tok, name) ;
-                                                                               
 WHILE IsDefImp (init) OR IsModule (init) DO
-                                                                               
    Expect (periodtok, stopset0, stopset1, stopset2 + SetOfStop2{identtok}) ;
-                                                                               
    StartScope (init) ;
-                                                                               
    Ident (stopset0, stopset1, stopset2) ;
-                                                                               
    PopTtok (name, tok) ;
-                                                                               
    ip1 := RequestSym (tok, name) ;
-                                                                               
    PutIncluded(ip1) ;
-                                                                               
    EndScope ;
-                                                                               
    CheckCanBeImported(init, ip1) ;
-                                                                               
    init := ip1
-                                                                               
 END ;
-                                                                               
IF tok#tokstart
-                                                                               
THEN
-                                                                               
   tok := MakeVirtualTok (tokstart, tokstart, tok)
-                                                                               
END ;
-                                                                               
 IF IsProcedure(init) OR IsProcType(init)
-                                                                               
 THEN
-                                                                               
    PushTtok(init, tok)
-                                                                               
 ELSE
-                                                                               
    PushTFtok(init, GetType(init), tok) ;
-                                                                               
 END
-                                                                             
ELSE %
+                                                                               
CheckModuleQualident (stopset0, stopset1, stopset2)
+                                                                             
ELSE (* just parse qualident *) %
              { "." Ident }                                                 % 
END %
            =:
 
diff --git a/gcc/m2/gm2-compiler/PHBuild.bnf b/gcc/m2/gm2-compiler/PHBuild.bnf
index 7bd5bcc2baa7..8153870db8bb 100644
--- a/gcc/m2/gm2-compiler/PHBuild.bnf
+++ b/gcc/m2/gm2-compiler/PHBuild.bnf
@@ -130,12 +130,12 @@ FROM SymbolTable IMPORT MakeGnuAsm, PutGnuAsmVolatile, 
PutGnuAsm, PutGnuAsmInput
                         PutGnuAsmOutput, PutGnuAsmTrash, PutGnuAsmVolatile,
                         MakeRegInterface,
                         PutRegInterface, GetRegInterface,
-                        GetSymName, GetType,
+                        GetSymName, GetType, GetCurrentModule,
                         NulSym,
                         StartScope, EndScope,
                         PutIncluded,
                         IsVarParam, IsProcedure, IsDefImp, IsModule,
-                        IsRecord, IsProcType,
+                        IsRecord, IsProcType, IsInnerModule, IsImported,
                         RequestSym,
                         GetSym, GetLocalSym ;
 
@@ -368,6 +368,68 @@ BEGIN
    Expect(realtok, stopset0, stopset1, stopset2)
 END Real ;
 
+
+(*
+   PushTFQualident - push the result of the Qualident
+                     to the stack.  It checks to see if init
+                    is a procedure or proc type and if so
+                    it does not push the return type.
+*)
+
+PROCEDURE PushTFQualident (tok, tokstart: CARDINAL;
+                           init: CARDINAL) ;
+BEGIN
+   IF tok#tokstart
+   THEN
+      tok := MakeVirtualTok (tokstart, tokstart, tok)
+   END ;
+   IF IsProcedure (init) OR IsProcType (init)
+   THEN
+      PushTtok (init, tok) ;
+      Annotate ("%1s(%1d)||qualident procedure/proctype") ;
+   ELSE
+      Annotate ("%1s(%1d)|%1s(%1d)||qualident|type") ;
+      PushTFtok (init, GetType (init), tok) ;
+   END
+END PushTFQualident ;
+
+
+(*
+   CheckModuleQualident - check to see if the beginning ident of the qualident 
is an
+                          imported module.
+*)
+
+PROCEDURE CheckModuleQualident (stopset0: SetOfStop0;
+                                stopset1: SetOfStop1;
+                               stopset2: SetOfStop2) ;
+VAR
+   name         : Name ;
+   init,
+   nextLevel,
+   tok, tokstart: CARDINAL ;
+BEGIN
+   PopTtok (name, tokstart) ;
+   tok := tokstart ;
+   init := RequestSym (tok, name) ;
+   IF IsImported (GetCurrentModule (), init) AND (IsDefImp (init) OR IsModule 
(init))
+   THEN
+      WHILE IsDefImp (init) OR IsModule (init) DO
+         Expect (periodtok, stopset0, stopset1, stopset2 + 
SetOfStop2{identtok}) ;
+         StartScope (init) ;
+         Ident (stopset0, stopset1, stopset2) ;
+        PopTtok (name, tok) ;
+         nextLevel := RequestSym (tok, name) ;
+         EndScope ;
+        CheckCanBeImported (init, nextLevel) ;
+        init := nextLevel
+      END ;
+      PushTFQualident (tok, tokstart, init) ;
+      PutIncluded (init)
+   ELSE
+      PushTFQualident (tok, tokstart, init)
+   END
+END CheckModuleQualident ;
+
 % module PHBuild end
 END PHBuild.
 % rules
@@ -541,26 +603,10 @@ ImplementationOrProgramModule :=                          
                 % Pus
 Number := Integer | Real =:
 
 
-Qualident :=                                                               % 
VAR name: Name ;
-                                                                               
  Type, Sym, tok: CARDINAL ; %
-             Ident
+Qualident := Ident
                                                                            % 
IF IsAutoPushOn()
                                                                              
THEN
-                                                                               
 PopTtok(name, tok) ;
-                                                                               
 Sym := RequestSym (tok, name) ;
-                                                                               
 IF IsDefImp(Sym) OR IsModule(Sym)
-                                                                               
 THEN
-                                                                               
    Expect(periodtok, stopset0, stopset1, stopset2 + SetOfStop2{identtok}) ;
-                                                                               
    StartScope(Sym) ;
-                                                                               
    Qualident(stopset0, stopset1, stopset2) ;
-                                                                               
    (* should we test for lack of ident? *)
-                                                                               
    PopTFtok(Sym, Type, tok) ;
-                                                                               
    PushTFtok(Sym, Type, tok) ;
-                                                                               
    EndScope ;
-                                                                               
    PutIncluded(Sym)
-                                                                               
 ELSE
-                                                                               
    PushTFtok(Sym, GetType(Sym), tok) ;
-                                                                               
 END
+                                                                               
CheckModuleQualident (stopset0, stopset1, stopset2)
                                                                              
ELSE (* just parse qualident *) %
              { "." Ident }                                                 % 
END %
            =:
diff --git a/gcc/m2/gm2-libs/ARRAYOFCHAR.def b/gcc/m2/gm2-libs/ARRAYOFCHAR.def
new file mode 100644
index 000000000000..451eb56d91ea
--- /dev/null
+++ b/gcc/m2/gm2-libs/ARRAYOFCHAR.def
@@ -0,0 +1,41 @@
+(* ARRAYOFCHAR.def provides output procedures for the ARRAY OF CHAR datatype.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+DEFINITION MODULE ARRAYOFCHAR ;
+
+FROM FIO IMPORT File ;
+
+
+(*
+   Description: provides write and read procedures for
+                ARRAY OF CHAR.
+*)
+
+PROCEDURE Write (f: File; str: ARRAY OF CHAR) ;
+PROCEDURE WriteLn (f: File) ;
+
+
+END ARRAYOFCHAR.
diff --git a/gcc/m2/gm2-libs/ARRAYOFCHAR.mod b/gcc/m2/gm2-libs/ARRAYOFCHAR.mod
new file mode 100644
index 000000000000..f27378a5fc45
--- /dev/null
+++ b/gcc/m2/gm2-libs/ARRAYOFCHAR.mod
@@ -0,0 +1,56 @@
+(* ARRAYOFCHAR.def provides output procedures for the ARRAY OF CHAR datatype.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+IMPLEMENTATION MODULE ARRAYOFCHAR ;
+
+FROM FIO IMPORT WriteChar, WriteLine ;
+IMPORT StrLib ;
+
+
+(*
+   Write - writes a string to file f.
+*)
+
+PROCEDURE Write (f: File; a: ARRAY OF CHAR) ;
+VAR
+   len, i: CARDINAL ;
+BEGIN
+   len := StrLib.StrLen (a) ;
+   i := 0 ;
+   WHILE i < len DO
+      WriteChar (f, a[i]) ;
+      INC (i)
+   END
+END Write ;
+
+
+PROCEDURE WriteLn (f: File) ;
+BEGIN
+   WriteLine (f)
+END WriteLn ;
+
+
+END ARRAYOFCHAR.
diff --git a/gcc/m2/gm2-libs/CFileSysOp.def b/gcc/m2/gm2-libs/CFileSysOp.def
new file mode 100644
index 000000000000..1be213596b77
--- /dev/null
+++ b/gcc/m2/gm2-libs/CFileSysOp.def
@@ -0,0 +1,56 @@
+DEFINITION MODULE CFileSysOp ;
+
+FROM SYSTEM IMPORT ADDRESS ;
+
+
+(*
+   Description: provides access to filesystem operations.
+                The implementation module is written in C
+                and the parameters behave as their C
+                counterparts.
+*)
+
+TYPE
+   AccessMode = SET OF AccessStatus ;
+   AccessStatus = (F_OK, R_OK, W_OK, X_OK, A_FAIL) ;
+
+
+PROCEDURE Unlink (filename: ADDRESS) : INTEGER ;
+
+
+(*
+   Access - test access to a path or file.  The behavior is
+            the same as defined in access(2).  Except that
+            on A_FAIL is only used during the return result
+            indicating the underlying C access has returned
+            -1 (and errno can be checked).
+*)
+
+PROCEDURE Access (pathname: ADDRESS; mode: AccessMode) : AccessMode ;
+
+
+(* Return TRUE if the caller can see the existance of the file or
+   directory on the filesystem.  *)
+
+(*
+   IsDir - return true if filename is a regular directory.
+*)
+
+PROCEDURE IsDir (dirname: ADDRESS) : BOOLEAN ;
+
+
+(*
+   IsFile - return true if filename is a regular file.
+*)
+
+PROCEDURE IsFile (filename: ADDRESS) : BOOLEAN ;
+
+
+(*
+   Exists - return true if pathname exists.
+*)
+
+PROCEDURE Exists (pathname: ADDRESS) : BOOLEAN ;
+
+
+END CFileSysOp.
diff --git a/gcc/m2/gm2-libs/CHAR.def b/gcc/m2/gm2-libs/CHAR.def
new file mode 100644
index 000000000000..71a6791896d5
--- /dev/null
+++ b/gcc/m2/gm2-libs/CHAR.def
@@ -0,0 +1,40 @@
+(* CHAR.def provides output procedures for the CHAR datatype.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+DEFINITION MODULE CHAR ;
+
+FROM FIO IMPORT File ;
+
+
+(*
+   Write a single character ch to file f.
+*)
+
+PROCEDURE Write (f: File; ch: CHAR) ;
+PROCEDURE WriteLn (f: File) ;
+
+
+END CHAR.
diff --git a/gcc/m2/gm2-libs/CHAR.mod b/gcc/m2/gm2-libs/CHAR.mod
new file mode 100644
index 000000000000..9673e25f2d8e
--- /dev/null
+++ b/gcc/m2/gm2-libs/CHAR.mod
@@ -0,0 +1,48 @@
+(* CHAR.mod provides output procedures for the CHAR datatype.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+IMPLEMENTATION MODULE CHAR ;
+
+IMPORT FIO ;
+
+
+(*
+   Write a single character ch to file f.
+*)
+
+PROCEDURE Write (f: File; ch: CHAR) ;
+BEGIN
+   FIO.WriteChar (f, ch)
+END Write ;
+
+
+PROCEDURE WriteLn (f: File) ;
+BEGIN
+   FIO.WriteLine (f)
+END WriteLn ;
+
+
+END CHAR.
diff --git a/gcc/m2/gm2-libs/FileSysOp.def b/gcc/m2/gm2-libs/FileSysOp.def
new file mode 100644
index 000000000000..64ba392bb979
--- /dev/null
+++ b/gcc/m2/gm2-libs/FileSysOp.def
@@ -0,0 +1,44 @@
+(* FileSysOp.def provides procedures to manipulate the file system.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+DEFINITION MODULE FileSysOp ;
+
+FROM CFileSysOp IMPORT AccessMode ;
+
+
+(*
+   Description: provides access to filesystem operations using
+                Modula-2 base types.
+*)
+
+PROCEDURE Exists (filename: ARRAY OF CHAR) : BOOLEAN ;
+PROCEDURE IsDir (dirname: ARRAY OF CHAR) : BOOLEAN ;
+PROCEDURE IsFile (filename: ARRAY OF CHAR) : BOOLEAN ;
+PROCEDURE Unlink (filename: ARRAY OF CHAR) : BOOLEAN ;
+PROCEDURE Access (pathname: ARRAY OF CHAR; mode: AccessMode) : AccessMode ;
+
+
+END FileSysOp.
diff --git a/gcc/m2/gm2-libs/FileSysOp.mod b/gcc/m2/gm2-libs/FileSysOp.mod
new file mode 100644
index 000000000000..c418c22bfe2f
--- /dev/null
+++ b/gcc/m2/gm2-libs/FileSysOp.mod
@@ -0,0 +1,98 @@
+(* FileSysOp.mod provides procedures to manipulate the file system.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+IMPLEMENTATION MODULE FileSysOp ;
+
+IMPORT StringFileSysOp ;
+FROM DynamicStrings IMPORT String, InitString, KillString ;
+
+
+(*
+   Description: provides access to filesystem operations using
+                Modula-2 base types.
+*)
+
+PROCEDURE Exists (filename: ARRAY OF CHAR) : BOOLEAN ;
+VAR
+   fn    : String ;
+   result: BOOLEAN ;
+BEGIN
+   fn := InitString (filename) ;
+   result := StringFileSysOp.Exists (fn) ;
+   fn := KillString (fn) ;
+   RETURN result
+END Exists ;
+
+
+PROCEDURE IsDir (dirname: ARRAY OF CHAR) : BOOLEAN ;
+VAR
+   fn    : String ;
+   result: BOOLEAN ;
+BEGIN
+   fn := InitString (dirname) ;
+   result := StringFileSysOp.IsDir (fn) ;
+   fn := KillString (fn) ;
+   RETURN result
+END IsDir ;
+
+
+PROCEDURE IsFile (filename: ARRAY OF CHAR) : BOOLEAN ;
+VAR
+   fn    : String ;
+   result: BOOLEAN ;
+BEGIN
+   fn := InitString (filename) ;
+   result := StringFileSysOp.IsFile (fn) ;
+   fn := KillString (fn) ;
+   RETURN result
+END IsFile ;
+
+
+PROCEDURE Unlink (filename: ARRAY OF CHAR) : BOOLEAN ;
+VAR
+   fn    : String ;
+   result: BOOLEAN ;
+BEGIN
+   fn := InitString (filename) ;
+   result := StringFileSysOp.Unlink (fn) ;
+   fn := KillString (fn) ;
+   RETURN result
+END Unlink ;
+
+
+PROCEDURE Access (pathname: ARRAY OF CHAR; mode: AccessMode) : AccessMode ;
+VAR
+   pn    : String ;
+   result: AccessMode ;
+BEGIN
+   pn := InitString (pathname) ;
+   result := StringFileSysOp.Access (pn, mode) ;
+   pn := KillString (pn) ;
+   RETURN result
+END Access ;
+
+
+END FileSysOp.
diff --git a/gcc/m2/gm2-libs/String.def b/gcc/m2/gm2-libs/String.def
new file mode 100644
index 000000000000..972232de3741
--- /dev/null
+++ b/gcc/m2/gm2-libs/String.def
@@ -0,0 +1,35 @@
+(* String.def provides output procedures for the String datatype.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+DEFINITION MODULE String ;
+
+FROM DynamicStrings IMPORT String ;
+FROM FIO IMPORT File ;
+
+PROCEDURE Write (f: File; str: String) ;
+PROCEDURE WriteLn (f: File) ;
+
+END String.
diff --git a/gcc/m2/gm2-libs/String.mod b/gcc/m2/gm2-libs/String.mod
new file mode 100644
index 000000000000..5dfbb3f9aa63
--- /dev/null
+++ b/gcc/m2/gm2-libs/String.mod
@@ -0,0 +1,51 @@
+(* String.mod provides output procedures for the String datatype.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+IMPLEMENTATION MODULE String ;
+
+IMPORT DynamicStrings, CHAR ;
+
+
+PROCEDURE Write (f: File; str: String) ;
+VAR
+   i, len: CARDINAL ;
+BEGIN
+   i := 0 ;
+   len := DynamicStrings.Length (str) ;
+   WHILE i < len DO
+      CHAR.Write (f, DynamicStrings.char (str, i)) ;
+      INC (i)
+   END
+END Write ;
+
+
+PROCEDURE WriteLn (f: File) ;
+BEGIN
+   CHAR.WriteLn (f)
+END WriteLn ;
+
+
+END String.
diff --git a/gcc/m2/gm2-libs/StringFileSysOp.def 
b/gcc/m2/gm2-libs/StringFileSysOp.def
new file mode 100644
index 000000000000..ce1d05a5d38b
--- /dev/null
+++ b/gcc/m2/gm2-libs/StringFileSysOp.def
@@ -0,0 +1,40 @@
+(* StringFileSysOp.def provides procedures to manipulate the file system.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+DEFINITION MODULE StringFileSysOp ;
+
+FROM DynamicStrings IMPORT String ;
+FROM CFileSysOp IMPORT AccessMode ;
+
+
+PROCEDURE Exists (filename: String) : BOOLEAN ;
+PROCEDURE IsDir (dirname: String) : BOOLEAN ;
+PROCEDURE IsFile (filename: String) : BOOLEAN ;
+PROCEDURE Unlink (filename: String) : BOOLEAN ;
+PROCEDURE Access (pathname: String; mode: AccessMode) : AccessMode ;
+
+
+END StringFileSysOp.
diff --git a/gcc/m2/gm2-libs/StringFileSysOp.mod 
b/gcc/m2/gm2-libs/StringFileSysOp.mod
new file mode 100644
index 000000000000..3cf9ef9ec8be
--- /dev/null
+++ b/gcc/m2/gm2-libs/StringFileSysOp.mod
@@ -0,0 +1,63 @@
+(* StringFileSysOp.mod provides procedures to manipulate the file system.
+
+Copyright (C) 2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusm...@gmail.com>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  *)
+
+IMPLEMENTATION MODULE StringFileSysOp ;
+
+IMPORT CFileSysOp ;
+FROM DynamicStrings IMPORT string ;
+
+
+PROCEDURE Exists (filename: String) : BOOLEAN ;
+BEGIN
+   RETURN CFileSysOp.Exists (string (filename))
+END Exists ;
+
+
+PROCEDURE IsDir (dirname: String) : BOOLEAN ;
+BEGIN
+  RETURN CFileSysOp.IsDir (string (dirname))
+END IsDir ;
+
+
+PROCEDURE IsFile (filename: String) : BOOLEAN ;
+BEGIN
+   RETURN CFileSysOp.IsFile (string (filename))
+END IsFile ;
+
+
+PROCEDURE Unlink (filename: String) : BOOLEAN ;
+BEGIN
+   RETURN CFileSysOp.Unlink (string (filename)) = 0
+END Unlink ;
+
+
+PROCEDURE Access (pathname: String; mode: AccessMode) : AccessMode ;
+BEGIN
+   RETURN CFileSysOp.Access (string (pathname), mode)
+END Access ;
+
+
+END StringFileSysOp.
diff --git a/gcc/testsuite/gm2/iso/fail/CHAR.mod 
b/gcc/testsuite/gm2/iso/fail/CHAR.mod
new file mode 100644
index 000000000000..0e7d43e24251
--- /dev/null
+++ b/gcc/testsuite/gm2/iso/fail/CHAR.mod
@@ -0,0 +1,7 @@
+MODULE CHAR ;
+
+IMPORT CHAR ;
+
+BEGIN
+   CHAR.Write ("h")
+END CHAR.
diff --git a/gcc/testsuite/gm2/iso/run/pass/CHAR.mod 
b/gcc/testsuite/gm2/iso/run/pass/CHAR.mod
new file mode 100644
index 000000000000..4ca86b8ad326
--- /dev/null
+++ b/gcc/testsuite/gm2/iso/run/pass/CHAR.mod
@@ -0,0 +1,7 @@
+MODULE CHAR ;
+
+FROM libc IMPORT printf ;
+
+BEGIN
+   printf ("hello world\n")
+END CHAR.
diff --git a/gcc/testsuite/gm2/iso/run/pass/importself.mod 
b/gcc/testsuite/gm2/iso/run/pass/importself.mod
new file mode 100644
index 000000000000..06cf7176af59
--- /dev/null
+++ b/gcc/testsuite/gm2/iso/run/pass/importself.mod
@@ -0,0 +1,14 @@
+MODULE importself ;
+
+IMPORT importself ;
+
+
+PROCEDURE foo ;
+BEGIN
+
+END foo ;
+
+BEGIN
+   foo ;
+   importself.foo
+END importself.
diff --git a/gcc/testsuite/gm2/pimlib/run/pass/testwrite.mod 
b/gcc/testsuite/gm2/pimlib/run/pass/testwrite.mod
new file mode 100644
index 000000000000..ce1f0351a051
--- /dev/null
+++ b/gcc/testsuite/gm2/pimlib/run/pass/testwrite.mod
@@ -0,0 +1,8 @@
+MODULE testwrite ;
+
+IMPORT ARRAYOFCHAR ;
+FROM FIO IMPORT StdOut ;
+
+BEGIN
+   ARRAYOFCHAR.Write (StdOut, "hello world") ; ARRAYOFCHAR.WriteLn (StdOut)
+END testwrite.
diff --git a/gcc/testsuite/gm2/pimlib/run/pass/testwritechar.mod 
b/gcc/testsuite/gm2/pimlib/run/pass/testwritechar.mod
new file mode 100644
index 000000000000..c2f739de6449
--- /dev/null
+++ b/gcc/testsuite/gm2/pimlib/run/pass/testwritechar.mod
@@ -0,0 +1,13 @@
+MODULE testwritechar ;
+
+IMPORT CHAR ;
+FROM FIO IMPORT StdOut ;
+
+BEGIN
+   CHAR.Write (StdOut, 'h') ;
+   CHAR.Write (StdOut, 'e') ;
+   CHAR.Write (StdOut, 'l') ;
+   CHAR.Write (StdOut, 'l') ;
+   CHAR.Write (StdOut, 'o') ;
+   CHAR.WriteLn (StdOut)
+END testwritechar.
diff --git a/libgm2/libm2pim/CFileSysOp.cc b/libgm2/libm2pim/CFileSysOp.cc
new file mode 100644
index 000000000000..fc2538c3cb9c
--- /dev/null
+++ b/libgm2/libm2pim/CFileSysOp.cc
@@ -0,0 +1,145 @@
+
+
+/* A C++ implementation for CFileSysOp.def.  This file will use
+   autoconf to test for the presence of operating system facilities.  */
+
+#include <config.h>
+#include <m2rts.h>
+
+#define EXPORT(FUNC) m2pim ## _CFileSysOp_ ## FUNC
+#define M2EXPORT(FUNC) m2pim ## _M2_CFileSysOp_ ## FUNC
+#define M2LIBNAME "m2pim"
+
+#if defined(HAVE_STDLIB_H)
+#include <stdlib.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if defined(HAVE_SYS_STAT_H)
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#if defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+/* Define a generic NULL if one hasn't already been defined.  */
+
+#if !defined(NULL)
+#define NULL 0
+#endif
+
+#define A_FAIL (1<<5)
+
+
+extern "C" int
+EXPORT(Unlink) (char *filename)
+{
+#if defined(HAVE_UNLINK)
+  return unlink (filename);
+#else
+  return -1;
+#endif
+}
+
+
+/* Access test access to a path or file.  The behavior is
+   the same as defined in access(2).  Except that A_FAIL
+   is only used during the return result indicating the
+   underlying C access has returned -1 (and errno can be
+   checked).  */
+
+extern "C" int
+EXPORT(Access) (char *pathname, int mode)
+{
+#if defined(HAVE_ACCESS)
+  int result = access (pathname, mode);
+
+  if (result == -1)
+    return A_FAIL;
+  return result;
+#else
+  return A_FAIL;
+#endif
+}
+
+
+/* Exists return true if pathname exists.  */
+
+extern "C" bool
+EXPORT(Exists) (char *pathname)
+{
+#if defined(HAVE_ACCESS)
+  return (access (pathname, F_OK) == 0);
+#else
+  return false;
+#endif
+}
+
+/* IsDir return true if filename is a regular directory.  */
+
+extern "C" bool
+EXPORT(IsDir) (char *dirname)
+{
+#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT)
+  struct stat dir_stat;
+  int res = stat (dirname, (struct stat *)&dir_stat);
+  if (res == 0)
+    return (dir_stat.st_mode & S_IFMT) == S_IFDIR;
+  return false;
+#else
+  return false;
+#endif
+}
+
+/* IsFile return true if filename is a regular file.  */
+
+extern "C" bool
+EXPORT(IsFile) (char *filename)
+{
+#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT)
+  struct stat file_stat;
+  int res = stat (filename, (struct stat *)&file_stat);
+  if (res == 0)
+    return (file_stat.st_mode & S_IFMT) == S_IFREG;
+  return false;
+#else
+  return false;
+#endif
+}
+
+/* GNU Modula-2 linking hooks.  */
+
+extern "C" void
+M2EXPORT(init) (int, char **, char **)
+{
+}
+
+extern "C" void
+M2EXPORT(fini) (int, char **, char **)
+{
+}
+
+extern "C" void
+M2EXPORT(dep) (void)
+{
+}
+
+extern "C" void __attribute__((__constructor__))
+M2EXPORT(ctor) (void)
+{
+  m2pim_M2RTS_RegisterModule ("CfileSysOp", M2LIBNAME,
+                             M2EXPORT(init), M2EXPORT(fini),
+                             M2EXPORT(dep));
+}
diff --git a/libgm2/libm2pim/Makefile.am b/libgm2/libm2pim/Makefile.am
index 2252f28d6e2f..f8e9aaeafc91 100644
--- a/libgm2/libm2pim/Makefile.am
+++ b/libgm2/libm2pim/Makefile.am
@@ -118,14 +118,20 @@ M2MODS = ASCII.mod IO.mod \
        Indexing.mod \
        LMathLib0.mod LegacyReal.mod \
        MemUtils.mod gdbif.mod \
-       GetOpt.mod OptLib.mod
+       GetOpt.mod OptLib.mod \
+       ARRAYOFCHAR.mod \
+       CHAR.mod \
+       StringFileSysOp.mod \
+       String.mod \
+       FileSysOp.mod
 
 # COROUTINES.mod has been removed as it is implemented in ../libm2iso.
 
 M2DEFS = Args.def   ASCII.def \
          Assertion.def  Break.def \
          Builtins.def  cbuiltin.def \
-         CmdArgs.def COROUTINES.def \
+         CmdArgs.def CFileSysOp.def \
+         COROUTINES.def \
          cxxabi.def  Debug.def \
          dtoa.def  DynamicStrings.def \
          Environment.def  errno.def \
@@ -153,7 +159,12 @@ M2DEFS = Args.def   ASCII.def \
          termios.def  TimeString.def \
          UnixArgs.def  wrapc.def  \
          GetOpt.def OptLib.def \
-         cgetopt.def
+         cgetopt.def \
+         ARRAYOFCHAR.def \
+         CHAR.def \
+         StringFileSysOp.def \
+         String.def \
+         FileSysOp.def
 
 libm2pim_la_SOURCES = $(M2MODS) \
                       UnixArgs.cc \
@@ -161,7 +172,8 @@ libm2pim_la_SOURCES = $(M2MODS) \
                       errno.cc dtoa.cc \
                       ldtoa.cc termios.cc \
                       SysExceptions.cc target.c \
-                      wrapc.cc cgetopt.cc
+                      wrapc.cc cgetopt.cc \
+                      CFileSysOp.cc
 
 libm2pimdir = libm2pim
 libm2pim_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename 
$(libm2pim_la_SOURCES)))
diff --git a/libgm2/libm2pim/Makefile.in b/libgm2/libm2pim/Makefile.in
index f4313e934698..8d101c440525 100644
--- a/libgm2/libm2pim/Makefile.in
+++ b/libgm2/libm2pim/Makefile.in
@@ -169,12 +169,14 @@ libm2pim_la_LIBADD =
 @BUILD_PIMLIB_TRUE@    Builtins.lo MathLib0.lo M2EXCEPTION.lo \
 @BUILD_PIMLIB_TRUE@    RTExceptions.lo SMathLib0.lo RTint.lo \
 @BUILD_PIMLIB_TRUE@    Indexing.lo LMathLib0.lo LegacyReal.lo \
-@BUILD_PIMLIB_TRUE@    MemUtils.lo gdbif.lo GetOpt.lo OptLib.lo
+@BUILD_PIMLIB_TRUE@    MemUtils.lo gdbif.lo GetOpt.lo OptLib.lo \
+@BUILD_PIMLIB_TRUE@    ARRAYOFCHAR.lo CHAR.lo StringFileSysOp.lo \
+@BUILD_PIMLIB_TRUE@    String.lo FileSysOp.lo
 @BUILD_PIMLIB_TRUE@am_libm2pim_la_OBJECTS = $(am__objects_1) \
 @BUILD_PIMLIB_TRUE@    UnixArgs.lo Selective.lo sckt.lo errno.lo \
 @BUILD_PIMLIB_TRUE@    dtoa.lo ldtoa.lo termios.lo \
 @BUILD_PIMLIB_TRUE@    SysExceptions.lo libm2pim_la-target.lo \
-@BUILD_PIMLIB_TRUE@    wrapc.lo cgetopt.lo
+@BUILD_PIMLIB_TRUE@    wrapc.lo cgetopt.lo CFileSysOp.lo
 libm2pim_la_OBJECTS = $(am_libm2pim_la_OBJECTS)
 @BUILD_PIMLIB_TRUE@am_libm2pim_la_rpath = -rpath $(toolexeclibdir)
 AM_V_P = $(am__v_P_@AM_V@)
@@ -495,14 +497,20 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS)
 @BUILD_PIMLIB_TRUE@       Indexing.mod \
 @BUILD_PIMLIB_TRUE@       LMathLib0.mod LegacyReal.mod \
 @BUILD_PIMLIB_TRUE@       MemUtils.mod gdbif.mod \
-@BUILD_PIMLIB_TRUE@       GetOpt.mod OptLib.mod
+@BUILD_PIMLIB_TRUE@       GetOpt.mod OptLib.mod \
+@BUILD_PIMLIB_TRUE@       ARRAYOFCHAR.mod \
+@BUILD_PIMLIB_TRUE@       CHAR.mod \
+@BUILD_PIMLIB_TRUE@       StringFileSysOp.mod \
+@BUILD_PIMLIB_TRUE@       String.mod \
+@BUILD_PIMLIB_TRUE@       FileSysOp.mod
 
 
 # COROUTINES.mod has been removed as it is implemented in ../libm2iso.
 @BUILD_PIMLIB_TRUE@M2DEFS = Args.def   ASCII.def \
 @BUILD_PIMLIB_TRUE@         Assertion.def  Break.def \
 @BUILD_PIMLIB_TRUE@         Builtins.def  cbuiltin.def \
-@BUILD_PIMLIB_TRUE@         CmdArgs.def COROUTINES.def \
+@BUILD_PIMLIB_TRUE@         CmdArgs.def CFileSysOp.def \
+@BUILD_PIMLIB_TRUE@         COROUTINES.def \
 @BUILD_PIMLIB_TRUE@         cxxabi.def  Debug.def \
 @BUILD_PIMLIB_TRUE@         dtoa.def  DynamicStrings.def \
 @BUILD_PIMLIB_TRUE@         Environment.def  errno.def \
@@ -530,7 +538,12 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS)
 @BUILD_PIMLIB_TRUE@         termios.def  TimeString.def \
 @BUILD_PIMLIB_TRUE@         UnixArgs.def  wrapc.def  \
 @BUILD_PIMLIB_TRUE@         GetOpt.def OptLib.def \
-@BUILD_PIMLIB_TRUE@         cgetopt.def
+@BUILD_PIMLIB_TRUE@         cgetopt.def \
+@BUILD_PIMLIB_TRUE@         ARRAYOFCHAR.def \
+@BUILD_PIMLIB_TRUE@         CHAR.def \
+@BUILD_PIMLIB_TRUE@         StringFileSysOp.def \
+@BUILD_PIMLIB_TRUE@         String.def \
+@BUILD_PIMLIB_TRUE@         FileSysOp.def
 
 @BUILD_PIMLIB_TRUE@libm2pim_la_SOURCES = $(M2MODS) \
 @BUILD_PIMLIB_TRUE@                      UnixArgs.cc \
@@ -538,7 +551,8 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS)
 @BUILD_PIMLIB_TRUE@                      errno.cc dtoa.cc \
 @BUILD_PIMLIB_TRUE@                      ldtoa.cc termios.cc \
 @BUILD_PIMLIB_TRUE@                      SysExceptions.cc target.c \
-@BUILD_PIMLIB_TRUE@                      wrapc.cc cgetopt.cc
+@BUILD_PIMLIB_TRUE@                      wrapc.cc cgetopt.cc \
+@BUILD_PIMLIB_TRUE@                      CFileSysOp.cc
 
 @BUILD_PIMLIB_TRUE@libm2pimdir = libm2pim
 @BUILD_PIMLIB_TRUE@libm2pim_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, 
$(basename $(libm2pim_la_SOURCES)))
@@ -639,6 +653,7 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CFileSysOp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Selective.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SysExceptions.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnixArgs.Plo@am__quote@

Reply via email to