mirror of
https://github.com/vishapoberon/compiler.git
synced 2026-10-09 23:17:23 +00:00
oocProgramArgs compatibility library. two examples.
This commit is contained in:
parent
575ea5c236
commit
552eade09d
7 changed files with 310 additions and 1 deletions
2
make.cmd
2
make.cmd
|
|
@ -356,6 +356,8 @@ cd %BUILDDIR%\%MODEL%
|
|||
%ROOTDIR%\%OBECOMP% -Ffs -O%MODEL% ../../../src/library/ooc/oocSysClock.Mod || exit /b
|
||||
%ROOTDIR%\%OBECOMP% -Ffs -O%MODEL% ../../../src/library/ooc/oocTime.Mod || exit /b
|
||||
%ROOTDIR%\%OBECOMP% -Ffs -O%MODEL% ../../../src/library/ooc/oocChannel.Mod || exit /b
|
||||
%ROOTDIR%\%OBECOMP% -Ffs -O%MODEL% ../../../src/library/ooc/oocProgramArgsHost.Mod || exit /b
|
||||
%ROOTDIR%\%OBECOMP% -Ffs -O%MODEL% ../../../src/library/ooc/oocProgramArgs.Mod || exit /b
|
||||
%ROOTDIR%\%OBECOMP% -Ffs -O%MODEL% ../../../src/library/ooc/oocStrings2.Mod || exit /b
|
||||
%ROOTDIR%\%OBECOMP% -Ffs -O%MODEL% ../../../src/library/ooc/oocRts.Mod || exit /b
|
||||
%ROOTDIR%\%OBECOMP% -Ffs -O%MODEL% ../../../src/library/ooc/oocFilenames.Mod || exit /b
|
||||
|
|
|
|||
182
src/library/ooc/oocProgramArgs.Mod
Normal file
182
src/library/ooc/oocProgramArgs.Mod
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
(* oo2c 1.x command-line arguments represented as a read-only channel. *)
|
||||
MODULE oocProgramArgs;
|
||||
|
||||
IMPORT
|
||||
Host := oocProgramArgsHost, Channel0 := oocChannel,
|
||||
CharClass := oocCharClass, Time := oocTime, Msg := oocMsg;
|
||||
|
||||
CONST
|
||||
done* = Channel0.done;
|
||||
outOfRange* = Channel0.outOfRange;
|
||||
readAfterEnd* = Channel0.readAfterEnd;
|
||||
channelClosed* = Channel0.channelClosed;
|
||||
noWriteAccess* = Channel0.noWriteAccess;
|
||||
noModTime* = Channel0.noModTime;
|
||||
|
||||
TYPE
|
||||
Channel* = POINTER TO ChannelDesc;
|
||||
ChannelDesc = RECORD
|
||||
(Channel0.ChannelDesc)
|
||||
END;
|
||||
|
||||
Reader = POINTER TO ReaderDesc;
|
||||
ReaderDesc = RECORD
|
||||
(Channel0.ReaderDesc)
|
||||
argument, offset, position: LONGINT
|
||||
END;
|
||||
|
||||
ErrorContext = POINTER TO ErrorContextDesc;
|
||||
ErrorContextDesc* = RECORD
|
||||
(Channel0.ErrorContextDesc)
|
||||
END;
|
||||
|
||||
VAR
|
||||
args-: Channel;
|
||||
errorContext: ErrorContext;
|
||||
|
||||
PROCEDURE GetError(code: Msg.Code): Msg.Msg;
|
||||
BEGIN
|
||||
RETURN Msg.New(errorContext, code)
|
||||
END GetError;
|
||||
|
||||
PROCEDURE (r: Reader) Pos* (): LONGINT;
|
||||
BEGIN
|
||||
RETURN r.position
|
||||
END Pos;
|
||||
|
||||
PROCEDURE (r: Reader) Available* (): LONGINT;
|
||||
VAR available: LONGINT;
|
||||
BEGIN
|
||||
IF ~r.base.open THEN RETURN -1 END;
|
||||
available := r.base.Length()-r.position;
|
||||
IF available > 0 THEN RETURN available ELSE RETURN 0 END
|
||||
END Available;
|
||||
|
||||
PROCEDURE (r: Reader) SetPos* (newPos: LONGINT);
|
||||
VAR argument, length, remaining: LONGINT;
|
||||
BEGIN
|
||||
IF r.res = done THEN
|
||||
IF newPos < 0 THEN
|
||||
r.res := GetError(outOfRange)
|
||||
ELSIF ~r.base.open THEN
|
||||
r.res := GetError(channelClosed)
|
||||
ELSE
|
||||
argument := 0;
|
||||
remaining := newPos;
|
||||
WHILE (argument < Host.Count()) & (remaining > Host.Length(argument)) DO
|
||||
DEC(remaining, Host.Length(argument)+1);
|
||||
INC(argument)
|
||||
END;
|
||||
IF argument = Host.Count() THEN
|
||||
r.offset := 0
|
||||
ELSE
|
||||
length := Host.Length(argument);
|
||||
IF remaining > length THEN remaining := length END;
|
||||
r.offset := remaining
|
||||
END;
|
||||
r.argument := argument;
|
||||
r.position := newPos
|
||||
END
|
||||
END
|
||||
END SetPos;
|
||||
|
||||
PROCEDURE (r: Reader) ReadByte* (VAR x: Host.Byte);
|
||||
VAR length: LONGINT;
|
||||
BEGIN
|
||||
r.bytesRead := 0;
|
||||
IF r.res = done THEN
|
||||
IF ~r.base.open THEN
|
||||
r.res := GetError(channelClosed)
|
||||
ELSIF r.argument >= Host.Count() THEN
|
||||
r.res := GetError(readAfterEnd)
|
||||
ELSE
|
||||
length := Host.Length(r.argument);
|
||||
IF r.offset = length THEN
|
||||
x := CharClass.eol;
|
||||
INC(r.argument);
|
||||
r.offset := 0
|
||||
ELSE
|
||||
Host.Get(r.argument, r.offset, x);
|
||||
IF Host.IsEol(x) THEN x := " " END;
|
||||
INC(r.offset)
|
||||
END;
|
||||
INC(r.position);
|
||||
r.bytesRead := 1
|
||||
END
|
||||
END
|
||||
END ReadByte;
|
||||
|
||||
PROCEDURE (r: Reader) ReadBytes* (VAR x: ARRAY OF Host.Byte; start, n: LONGINT);
|
||||
VAR count: LONGINT;
|
||||
BEGIN
|
||||
ASSERT((n >= 0) & (start >= 0) & (start+n <= LEN(x)));
|
||||
count := 0;
|
||||
WHILE (count < n) & (r.res = done) DO
|
||||
r.ReadByte(x[start+count]);
|
||||
IF r.res = done THEN INC(count) END
|
||||
END;
|
||||
r.bytesRead := count
|
||||
END ReadBytes;
|
||||
|
||||
PROCEDURE (ch: Channel) Length* (): LONGINT;
|
||||
VAR argument, length: LONGINT;
|
||||
BEGIN
|
||||
argument := 0;
|
||||
length := 0;
|
||||
WHILE argument < Host.Count() DO
|
||||
INC(length, Host.Length(argument)+1);
|
||||
INC(argument)
|
||||
END;
|
||||
RETURN length
|
||||
END Length;
|
||||
|
||||
PROCEDURE (ch: Channel) ArgNumber* (): LONGINT;
|
||||
BEGIN
|
||||
IF Host.Count() > 0 THEN RETURN Host.Count()-1 ELSE RETURN 0 END
|
||||
END ArgNumber;
|
||||
|
||||
PROCEDURE (ch: Channel) GetModTime* (VAR mtime: Time.TimeStamp);
|
||||
BEGIN
|
||||
ch.res := GetError(noModTime)
|
||||
END GetModTime;
|
||||
|
||||
PROCEDURE (ch: Channel) NewReader* (): Channel0.Reader;
|
||||
VAR r: Reader;
|
||||
BEGIN
|
||||
IF ch.open THEN
|
||||
NEW(r);
|
||||
r.base := ch;
|
||||
r.res := done;
|
||||
r.bytesRead := 0;
|
||||
r.positionable := TRUE;
|
||||
r.argument := 0;
|
||||
r.offset := 0;
|
||||
r.position := 0;
|
||||
ch.res := done;
|
||||
RETURN r
|
||||
ELSE
|
||||
ch.res := GetError(channelClosed);
|
||||
RETURN NIL
|
||||
END
|
||||
END NewReader;
|
||||
|
||||
PROCEDURE (ch: Channel) Flush*;
|
||||
BEGIN
|
||||
IF ch.open THEN ch.res := done ELSE ch.res := GetError(channelClosed) END
|
||||
END Flush;
|
||||
|
||||
PROCEDURE (ch: Channel) Close*;
|
||||
BEGIN
|
||||
ch.open := FALSE;
|
||||
ch.res := done
|
||||
END Close;
|
||||
|
||||
BEGIN
|
||||
NEW(errorContext);
|
||||
Msg.InitContext(errorContext, "OOC:Core:ProgramArgs");
|
||||
NEW(args);
|
||||
args.res := done;
|
||||
args.readable := TRUE;
|
||||
args.writable := FALSE;
|
||||
args.open := TRUE
|
||||
END oocProgramArgs.
|
||||
45
src/library/ooc/oocProgramArgsHost.Mod
Normal file
45
src/library/ooc/oocProgramArgsHost.Mod
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
(* Raw command-line access used by oocProgramArgs. *)
|
||||
MODULE oocProgramArgsHost;
|
||||
|
||||
IMPORT SYSTEM, Modules;
|
||||
|
||||
TYPE
|
||||
Byte* = SYSTEM.BYTE;
|
||||
|
||||
PROCEDURE Count* (): LONGINT;
|
||||
BEGIN
|
||||
RETURN Modules.ArgCount
|
||||
END Count;
|
||||
|
||||
PROCEDURE Address(index: LONGINT): SYSTEM.ADDRESS;
|
||||
VAR address: SYSTEM.ADDRESS;
|
||||
BEGIN
|
||||
ASSERT((index >= 0) & (index < Modules.ArgCount));
|
||||
SYSTEM.GET(Modules.ArgVector + index*SIZE(SYSTEM.ADDRESS), address);
|
||||
RETURN address
|
||||
END Address;
|
||||
|
||||
PROCEDURE Length* (index: LONGINT): LONGINT;
|
||||
VAR address: SYSTEM.ADDRESS; ch: Byte; length: LONGINT;
|
||||
BEGIN
|
||||
address := Address(index);
|
||||
length := 0;
|
||||
SYSTEM.GET(address, ch);
|
||||
WHILE SYSTEM.VAL(CHAR, ch) # 0X DO
|
||||
INC(length);
|
||||
SYSTEM.GET(address+length, ch)
|
||||
END;
|
||||
RETURN length
|
||||
END Length;
|
||||
|
||||
PROCEDURE Get* (index, offset: LONGINT; VAR ch: Byte);
|
||||
BEGIN
|
||||
SYSTEM.GET(Address(index)+offset, ch)
|
||||
END Get;
|
||||
|
||||
PROCEDURE IsEol* (ch: Byte): BOOLEAN;
|
||||
BEGIN
|
||||
RETURN SYSTEM.VAL(CHAR, ch) = 0AX
|
||||
END IsEol;
|
||||
|
||||
END oocProgramArgsHost.
|
||||
43
src/test/ooc_compat/testArgs.Mod
Normal file
43
src/test/ooc_compat/testArgs.Mod
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
MODULE testArgs;
|
||||
(**Demonstrates reading command-line arguments via TextRider.
|
||||
|
||||
Each argument is presented as a separate line in the ProgramArgs channel.
|
||||
The first line is always argv[0] (the program name); the actual arguments
|
||||
start from the second line. ConnectReader attaches a TextRider.Reader to
|
||||
that channel so arguments can be read as strings, integers, or reals.
|
||||
|
||||
Usage:
|
||||
bin/testArgs hello 42 3.14
|
||||
*)
|
||||
|
||||
IMPORT
|
||||
Out, ProgramArgs, TextRider;
|
||||
|
||||
PROCEDURE Run;
|
||||
VAR
|
||||
r: TextRider.Reader;
|
||||
arg: ARRAY 1024 OF CHAR;
|
||||
n, i: LONGINT;
|
||||
BEGIN
|
||||
n := ProgramArgs.args.ArgNumber();
|
||||
Out.String("argument count: "); Out.Int(n, 0); Out.Ln;
|
||||
|
||||
r := TextRider.ConnectReader(ProgramArgs.args);
|
||||
|
||||
(* first line is the program name (argv[0]) — skip it *)
|
||||
r.ReadLine(arg);
|
||||
|
||||
i := 0;
|
||||
WHILE r.res = TextRider.done DO
|
||||
r.ReadLine(arg);
|
||||
IF r.res = TextRider.done THEN
|
||||
Out.String("arg "); Out.Int(i, 0);
|
||||
Out.String(": "); Out.String(arg); Out.Ln;
|
||||
INC(i)
|
||||
END
|
||||
END
|
||||
END Run;
|
||||
|
||||
BEGIN
|
||||
Run
|
||||
END testArgs.
|
||||
35
src/test/ooc_compat/testReader.Mod
Normal file
35
src/test/ooc_compat/testReader.Mod
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
MODULE testReader;
|
||||
|
||||
IMPORT oocFiles, oocTextRider, Out;
|
||||
|
||||
VAR f: oocFiles.File;
|
||||
r: oocTextRider.Reader;
|
||||
b: BOOLEAN;
|
||||
ch: CHAR;
|
||||
size: LONGINT;
|
||||
res: oocFiles.Result;
|
||||
BEGIN
|
||||
b := oocFiles.Exists("test.Mod");
|
||||
IF b THEN
|
||||
f := oocFiles.Old("test.Mod", {oocFiles.read}, res);
|
||||
IF res # oocFiles.done THEN
|
||||
Out.String("cannot open file"); Out.Ln
|
||||
ELSE
|
||||
size := f.Length();
|
||||
Out.String("file size: "); Out.Int(size, 0); Out.Ln;
|
||||
r := oocTextRider.ConnectReader(f);
|
||||
IF r = NIL THEN
|
||||
Out.String("connecting reader failed"); Out.Ln
|
||||
ELSE
|
||||
WHILE (r.res = oocTextRider.done) & (r.Pos() < size) DO
|
||||
r.ReadChar(ch);
|
||||
IF r.res = oocTextRider.done THEN Out.Char(ch) END
|
||||
END
|
||||
END;
|
||||
f.Close
|
||||
END
|
||||
ELSE
|
||||
Out.String("file does not exist"); Out.Ln
|
||||
END
|
||||
|
||||
END testReader.
|
||||
|
|
@ -280,6 +280,8 @@ ooc:
|
|||
cd $(BUILDDIR)/$(MODEL); "$(ROOTDIR)/$(OBECOMP)" -Fs -O$(MODEL) ../../../src/library/ooc/oocSysClock.Mod
|
||||
cd $(BUILDDIR)/$(MODEL); "$(ROOTDIR)/$(OBECOMP)" -Fs -O$(MODEL) ../../../src/library/ooc/oocTime.Mod
|
||||
cd $(BUILDDIR)/$(MODEL); "$(ROOTDIR)/$(OBECOMP)" -Fs -O$(MODEL) ../../../src/library/ooc/oocChannel.Mod
|
||||
cd $(BUILDDIR)/$(MODEL); "$(ROOTDIR)/$(OBECOMP)" -Fs -O$(MODEL) ../../../src/library/ooc/oocProgramArgsHost.Mod
|
||||
cd $(BUILDDIR)/$(MODEL); "$(ROOTDIR)/$(OBECOMP)" -Fs -O$(MODEL) ../../../src/library/ooc/oocProgramArgs.Mod
|
||||
cd $(BUILDDIR)/$(MODEL); "$(ROOTDIR)/$(OBECOMP)" -Fs -O$(MODEL) ../../../src/library/ooc/oocStrings2.Mod
|
||||
cd $(BUILDDIR)/$(MODEL); "$(ROOTDIR)/$(OBECOMP)" -Fs -O$(MODEL) ../../../src/library/ooc/oocRts.Mod
|
||||
cd $(BUILDDIR)/$(MODEL); "$(ROOTDIR)/$(OBECOMP)" -Fs -O$(MODEL) ../../../src/library/ooc/oocFilenames.Mod
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ stage6:
|
|||
$(VOCSTATIC) -sPF oocComplexMath.Mod oocLComplexMath.Mod
|
||||
$(VOCSTATIC) -sPF oocLRealConv.Mod oocLRealStr.Mod
|
||||
$(VOCSTATIC) -sPF oocRealConv.Mod oocRealStr.Mod
|
||||
$(VOCSTATIC) -sPF oocMsg.Mod oocChannel.Mod
|
||||
$(VOCSTATIC) -sPF oocMsg.Mod oocChannel.Mod oocProgramArgsHost.Mod oocProgramArgs.Mod
|
||||
$(VOCSTATIC) -sPF oocStrings2.Mod oocRts.Mod oocFilenames.Mod
|
||||
$(VOCSTATIC) -sPF oocTextRider.Mod oocBinaryRider.Mod oocJulianDay.Mod oocFilesHost.Mod oocFiles.Mod
|
||||
$(VOCSTATIC) -sPF oocFilenames.Mod
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue