25 |
26 |
57 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | Contributors
2 | ============
3 |
4 | This is a list of people who have helped out in making Artemis possible.
5 | I apoligize for anyone I have missed.
6 |
7 | - [Oleg-N-Cher](https://github.com/Oleg-N-Cher/)
--------------------------------------------------------------------------------
/INSTALL.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Installation
3 | ---
4 |
5 | Installation
6 | ============
7 |
8 | Installing a released version
9 |
10 | 1. Change into that directory you want to place Artemis
11 | 2. Unzip the release Zip file
12 | 3. Make sure the "Artemis" "bin" sub-directory is in your PATH
13 |
14 | Example
15 | -------
16 |
17 | ```
18 | mkdir -p $HOME/tools
19 | cd $HOME/tools
20 | unzip $HOME/Download/Artemis-0.0.1-Linux-x86_64.zip
21 | export PATH="$HOME/tools/Artimis/bin:$PATH"
22 | ```
23 |
24 | From source
25 | -----------
26 |
27 | Compiling from source requires [OBNC](https://miasap.se/obnc), Git,
28 | GNU Make, a C compiler and linker.
29 |
30 | 1. Clone the Git repository for the project
31 | 2. Change into the repository directory
32 | 3. Run `make`, `make test`, and `sudo make install`
33 |
34 | Example install:
35 |
36 | ```
37 | git clone git@github.com:rsdoiel/Artemis
38 | cd Artemis
39 | make
40 | make full_test
41 | sudo make install
42 | ```
43 |
44 | Example uninstall
45 |
46 | ```
47 | cd Artemis
48 | sudo make uninstall
49 | ```
50 |
51 | The Makefile supports an installation prefix. If
52 | you install with a prefix you need to uninstall with
53 | the same prefix. E.g.
54 |
55 | ```
56 | sudo make install prefix=/opt/local
57 | sudo make uninstall prefix=/opt/local
58 | ```
59 |
60 |
61 |
--------------------------------------------------------------------------------
/JSON.Mod:
--------------------------------------------------------------------------------
1 | MODULE JSON;
2 |
3 | IMPORT Chars;
4 |
5 | CONST
6 | NullType* = 0;
7 | BooleanType* = 1;
8 | NumberType* = 2;
9 | StringType* = 3;
10 | ArrayType* = 4;
11 | ObjectType* = 5;
12 |
13 | TYPE
14 | (* Self services as an interface to JSON types,
15 | all JSON types extend it. *)
16 | Self* = RECORD
17 | type: INTEGER
18 | END;
19 |
20 | Boolean* = POINTER TO BooleanDesc;
21 | BooleanDesc = RECORD (Self)
22 | value: BOOLEAN
23 | END;
24 |
25 | Number* = POINTER TO NumberDesc;
26 | NumberDesc* = RECORD (Self)
27 | value : REAL;
28 | NaN : BOOLEAN
29 | END;
30 |
31 | String* = POINTER TO StringDesc;
32 | StringDesc* = RECORD (Self)
33 | value : CHAR;
34 | next : String
35 | END;
36 |
37 | List* = POINTER TO ListDesc;
38 | ListDesc* = RECORD (Self)
39 | value : Self;
40 | next: List
41 | END;
42 |
43 | Object* = POINTER TO ObjectDesc;
44 | ObjectDesc* = RECORD (Self)
45 | key : String;
46 | value: Self;
47 | next : Object
48 | END;
49 |
50 | (* Base methods available to all JSON types via Self type definition *)
51 | PROCEDURE IsNull*(o : Self) : BOOLEAN;
52 | BEGIN
53 | RETURN (o.type = NullType)
54 | END IsNull;
55 |
56 | (* IsType compares a JSON object agaist a type constant. Returns TRUE
57 | if they match or FALSE otherwise *)
58 | PROCEDURE IsType*(o : Self; checkType : INTEGER) : BOOLEAN;
59 | RETURN (o.type = checkType)
60 | END IsType;
61 |
62 | (* TypeName exams a type setting the value of the typeName array of char *)
63 | PROCEDURE TypeName*(o : Self; VAR typeName : ARRAY OF CHAR);
64 | BEGIN
65 | Chars.Clear(typeName);
66 | IF o.type = NullType THEN
67 | typeName := "null";
68 | ELSIF o.type = BooleanType THEN
69 | typeName := "boolean";
70 | ELSIF o.type = NumberType THEN
71 | typeName := "number";
72 | ELSIF o.type = StringType THEN
73 | typeName := "string";
74 | ELSIF o.type = ArrayType THEN
75 | typeName := "array";
76 | ELSIF o.type = ObjectType THEN
77 | typeName := "object";
78 | ELSE
79 | typeName := "undefined";
80 | END;
81 | END TypeName;
82 |
83 | END JSON.
84 |
--------------------------------------------------------------------------------
/JSONTest.Mod:
--------------------------------------------------------------------------------
1 | MODULE JSONTest;
2 |
3 | IMPORT JSON, Out, T := Tests;
4 |
5 | VAR
6 | ts : T.TestSet;
7 |
8 | PROCEDURE TestSelf() : BOOLEAN;
9 | VAR test : BOOLEAN; self : JSON.Self; str : ARRAY 256 OF CHAR;
10 | BEGIN test := FALSE;
11 | JSON.TypeName(self, str);Out.String(str);Out.Ln; (* DEBUG *)
12 |
13 |
14 | Out.String("DEBUG TestSelf() not implemented");Out.Ln;
15 | RETURN test
16 | END TestSelf;
17 |
18 | BEGIN
19 | (* Initialize our TestSet *)
20 | T.Init(ts, "JSON Test");
21 | T.Add(ts, TestSelf);
22 | (* Run our tests *)
23 | ASSERT(T.Run(ts));
24 | END JSONTest.
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2021, R. S. Doiel
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Simple Makefile for compiling Oberon-7 programs using OBNC.
3 | # Set the list of executables in PROG_NAMES. The rest can probably
4 | # stay as is if all modules are in the same directory.
5 | #
6 | VERSION = $(shell jq .version codemeta.json | cut -d \" -f 2)
7 | BUILD_NAME = Artemis-Modules
8 | PROG_NAMES = #$(shell ls -1 *CmdLn.Mod | sed -E 's/CmdLn\.Mod')
9 | TEST_NAMES = $(shell ls -1 *Test.Mod | sed -E 's/\.Mod//g' )
10 | MODULES = $(shell ls -1 *.Mod)
11 | DOCS= codemeta.json CITATION.cff README.md LICENSE INSTALL.txt
12 | HTML_FILES=$(shell find . -type f | grep -E '.html')
13 |
14 | #OC = env OBNC_IMPORT_PATH="." obnc
15 | # Defaults
16 | OC = obnc
17 | OS = $(shell uname)
18 | ARCH = $(shell uname -m)
19 | PREFIX = /usr/local
20 | LIBDIR = $(PREFIX)/lib
21 | BINDIR = $(PREFIX)/bin
22 |
23 | # Handle Git and commit messages
24 | BRANCH = $(shell git branch | grep '* ' | cut -d\ -f 2)
25 | MSG = Quick Save
26 | ifneq ($(msg),)
27 | MSG = $(msg)
28 | endif
29 |
30 | # Overrides
31 | oc =
32 | ifneq ($(oc),)
33 | OC = $(oc)
34 | endif
35 |
36 | os =
37 | ifneq ($(os),)
38 | OS = $(os)
39 | endif
40 |
41 | EXT =
42 | ifeq ($(OS),Windows)
43 | EXT = .exe
44 | endif
45 |
46 | arch =
47 | ifneq ($(arch),)
48 | ARCH = $(arch)
49 | endif
50 |
51 | prefix =
52 | ifneq ($(prefix),)
53 | PREFIX = $(prefix)
54 | LIBDIR = $(prefix)/lib
55 | BINDIR = $(prefix)/bin
56 | endif
57 |
58 | libdir =
59 | ifneq ($(libdir),)
60 | LIBDIR = $(libdir)
61 | endif
62 |
63 | bindir =
64 | ifneq ($(bindir),)
65 | BINDIR = $(bindir)
66 | endif
67 |
68 | build: $(TEST_NAMES) # $(PROG_NAMES)
69 |
70 | $(PROG_NAMES): $(MODULES)
71 | @mkdir -p bin
72 | $(OC) -o "bin/$@$(EXT)" "$@.Mod"
73 |
74 | $(TEST_NAMES): .FORCE
75 | $(OC) -o "$@$(EXT)" "$@.Mod"
76 |
77 | full_test: .FORCE clean test
78 |
79 | test: Tests.Mod $(TEST_NAMES)
80 | @for FNAME in $(TEST_NAMES); do env OS=$(OS) ARCH=$(ARCH) "./$${FNAME}"; done
81 |
82 | docs: .FORCE
83 | obncdoc
84 |
85 | clean: .FORCE
86 | @if [ -d dist ]; then rm -fR dist; fi
87 | @if [ -d .obnc ]; then rm -fR .obnc; fi
88 | @for FNAME in $(PROG_NAMES); do if [ -f "bin/$${FNAME}$(EXT)" ]; then rm -v "bin/$${FNAME}"; fi; done
89 | @for FNAME in $(TEST_NAMES); do if [ -f "$${FNAME}$(EXT)" ]; then rm -v "$${FNAME}"; fi; done
90 |
91 | web_clean:
92 | @for FNAME in $(HTML_FILES) ; do if [ -f "$${FNAME}" ]; then rm -v "$${FNAME}"; fi; done
93 |
94 | install: $(PROG_NAMES)
95 | @if [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi
96 | @for FNAME in $(PROG_NAMES); do cp -v "bin/$${FNAME}$(EXT)" $(BINDIR)/; done
97 |
98 | uninstall: .FORCE
99 | @for FNAME in $(PROG_NAMES); do if [ -f "$(BINDIR)/$${FNAME}$(EXT)" ]; then rm "$(BINDIR)/$${FNAME}$(EXT)"; fi; done
100 |
101 | dist: $(PROG_NAMES)
102 | @if [ ! -d dist/$(BUILD_NAME) ]; then mkdir -p dist/$(BUILD_NAME); fi
103 | @if [ ! -d dist/$(BUILD_NAME)/bin ]; then mkdir -p dist/$(BUILD_NAME)/bin; fi
104 | @for FNAME in $(PROG_NAMES); do cp -p $$FNAME dist/$(BUILD_NAME)/bin/; done
105 | @for FNAME in $(MODULES) $(DOCS) Makefile; do cp -p $$FNAME dist/$(BUILD_NAME)/;done
106 | @cd dist && zip -r $(BUILD_NAME)-$(OS)-$(ARCH).zip $(BUILD_NAME)/*
107 |
108 |
109 | save:
110 | git commit -am "$(MSG)"
111 | git push origin $(BRANCH)
112 |
113 | status:
114 | git status
115 |
116 | website: web_clean README.md page.tmpl css/site.css
117 | obncdoc
118 | cp -vp css/site.css obncdoc/style.css
119 | ./mk_website.py
120 |
121 | publish: web_clean clean
122 | obncdoc
123 | cp -vp css/site.css obncdoc/style.css
124 | ./mk_website.py
125 | ./publish.bash
126 |
127 |
128 | .FORCE:
129 |
--------------------------------------------------------------------------------
/Obn2.Mod:
--------------------------------------------------------------------------------
1 | (** Obn2.Mod is a module to help port Oberon-2 modules to Oberon-7.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE Obn2;
10 |
11 | (** ASH provides the Oberon-2 built-in ASH functionilty for
12 | Oberon-7. See description of providing ASH in documentation
13 | on Oberon-7 for positive and negative values *)
14 | PROCEDURE ASH*(x, n : INTEGER) : INTEGER;
15 | VAR res : INTEGER;
16 | BEGIN
17 | IF n > 0 THEN
18 | res := LSL(x, n);
19 | ELSE
20 | res := ASR(x, n);
21 | END;
22 | RETURN res
23 | END ASH;
24 |
25 | (** MAX returns the maximum of two integers *)
26 | PROCEDURE MAX*(x, y : INTEGER) : INTEGER;
27 | VAR res : INTEGER;
28 | BEGIN
29 | IF x > y THEN
30 | res := x;
31 | ELSE
32 | res := y;
33 | END;
34 | RETURN res
35 | END MAX;
36 |
37 | (** MIN provides the minimum of two integers *)
38 | PROCEDURE MIN*(x, y : INTEGER) : INTEGER;
39 | VAR res : INTEGER;
40 | BEGIN
41 | IF x < y THEN
42 | res := x;
43 | ELSE
44 | res := y;
45 | END;
46 | RETURN res
47 | END MIN;
48 |
49 | (** ENTIER is a wrapper around FLOOR, you should really just use
50 | FLOOR. *)
51 | PROCEDURE ENTIER*(r : REAL) : INTEGER;
52 | BEGIN
53 | RETURN FLOOR(r)
54 | END ENTIER;
55 |
56 | (** HALT is a wrapper around ASSERT(FALSE), you should just replace
57 | ASSERT(FALSE) *)
58 | PROCEDURE HALT*();
59 | BEGIN
60 | ASSERT(FALSE);
61 | END HALT;
62 |
63 | (** ROT is a wrapper around ROR, you should just replace ROT with ROR *)
64 | PROCEDURE ROT*(x, n : INTEGER) : INTEGER;
65 | BEGIN
66 | RETURN ROR(x, n)
67 | END ROT;
68 |
69 | END Obn2.
70 |
--------------------------------------------------------------------------------
/Obn2Test.Mod:
--------------------------------------------------------------------------------
1 | (** Obn2Test modules provides testing for Obn2 module.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE Obn2Test;
10 |
11 | IMPORT T := Tests, Obn2;
12 |
13 | VAR ts : T.TestSet;
14 |
15 | PROCEDURE TestMinMax() : BOOLEAN;
16 | VAR test : BOOLEAN; x, y, got, expected : INTEGER;
17 | BEGIN test := TRUE;
18 | x := 11; y := 12;
19 | expected := x;
20 | got := Obn2.MIN(x,y);
21 | T.ExpectedInt(expected, got, "Test Min(x,y)", test);
22 | expected := y;
23 | got := Obn2.MAX(x, y);
24 | T.ExpectedInt(expected, got, "Test Mac(x,y)", test);
25 | RETURN test
26 | END TestMinMax;
27 |
28 | PROCEDURE TestShifts() : BOOLEAN;
29 | VAR test : BOOLEAN;
30 | BEGIN test := TRUE;
31 | T.ExpectedBool(TRUE, FALSE, "TestShifts() not implemented.", test);
32 | RETURN test
33 | END TestShifts;
34 |
35 | BEGIN
36 | T.Init(ts, "Obn2");
37 | T.Add(ts, TestMinMax);
38 | T.Add(ts, TestShifts);
39 | ASSERT(T.Run(ts));
40 | END Obn2Test.
41 |
--------------------------------------------------------------------------------
/OfrontPlus.mak:
--------------------------------------------------------------------------------
1 | #
2 | # Simple Makefile for using with Ofront+ compiler.
3 | #
4 |
5 | # FIXME: Need to figure out how to detect the information
6 | # needed to set the flags correctly for Ofront+
7 | # Questions to get sorted:
8 | #
9 | # 1. Set up import paths for modules (e.g. pure Oberon, Ofront specific)
10 | # 2. Where are the standard modules or do I need to write them?
11 | #
12 |
13 | # Defaults
14 | #OC = ofont+
15 | OC=$(shell which ofront+)
16 |
17 | OPT = -7
18 |
19 | MODULES = $(shell ls -1 *.Mod | grep -v -E Test.Mod | sed -E "s/.Mod$$//")
20 |
21 | TEST_NAMES = $(shell ls -1 *.Mod | grep -E Test.Mod | sed -E "s/.Mod$$//")
22 |
23 | PROG_NAMES = #$(shell ls -1 *CmdLn.Mod | sed -E "s/.CmdLn.Mod$$//")
24 |
25 | PLATFORM = $(shell uname -i)
26 |
27 | OS = $(shell uname)
28 |
29 | OPT =
30 |
31 | ifeq ($(PLATFORM), x86_64)
32 | OPT = -7 -88 -s
33 | else ifeq ($(PLATFORM), x86_32)
34 | OPT = -7 -44 -s
35 | else ifeq ($(PLATFORM), arm7)
36 | OPT = -7 -48 -s
37 | endif
38 |
39 | EXT =
40 |
41 | ifeq ($(OS), Windows)
42 | EXT = .exe
43 | OPT = -7 -s -48
44 | endif
45 |
46 |
47 | build: modules test programs
48 |
49 | modules: $(MODULES)
50 |
51 | programs: $(PROG_NAMES)
52 |
53 | $(MODULES):
54 | @mkdir -p bin
55 | $(OC) $(OPT) $@.Mod
56 |
57 | $(PROG_NAMES): $(MODULES)
58 | @mkdir -p bin
59 | $(OC) $(OPT) $@.Mod
60 |
61 | $(TEST_NAMES): .FORCE
62 | $(OC) $(OPT) "$@.Mod" -m
63 |
64 | full_test: .FORCE clean test
65 |
66 | test: ../Tests.Mod $(TEST_NAMES)
67 | @for FNAME in $(TEST_NAMES); do "./$${FNAME}"; done
68 |
69 | clean: .FORCE
70 | @for FNAME in $(PROG_NAMES); do if [ -f "$${FNAME}$(EXT)" ]; then rm -v "$${FNAME}$(EXT)"; fi; done
71 | @for FNAME in $(PROG_NAMES); do if [ -f "$${FNAME}.c" ] || [ -f "$${FNAME}.h" ] || [ -f "$${FNAME}.sym" ]; then rm -v "$${FNAME}.(c|h|sym)"; fi; done
72 | @for FNAME in $(TEST_NAMES); do if [ -f "$${FNAME}$(EXT)" ]; then rm -v "$${FNAME}$(EXT)"; fi; done
73 | @for FNAME in $(TEST_NAMES); do if [ -f "$${FNAME}.c" ] || [ -f "$${FNAME}.h" ] || [ -f "$${FNAME}.sym" ]; then rm -v "$${FNAME}.(c|h|sym)"; fi; done
74 | @for FNAME in $(MODULES); do if [ -f "$${FNAME}.c" ] || [ -f "$${FNAME}.h" ] || [ -f "$${FNAME}.sym" ]; then rm -v "$${FNAME}.(c|h|sym)"; fi; done
75 |
76 | save:
77 | git commit -am "$(MSG)"
78 | git push origin $(BRANCH)
79 |
80 | status:
81 | git status
82 |
83 | .FORCE:
84 |
--------------------------------------------------------------------------------
/PathLists.Mod:
--------------------------------------------------------------------------------
1 | (** PathLists is a module for working with a delimited list of paths. *)
2 | MODULE PathLists;
3 | IMPORT Chars, Path;
4 |
5 | CONST
6 | (** Merge operations *)
7 | PREPEND = 1; (** Insert into path list *)
8 | APPEND = 2; (** Add to end of path list *)
9 | CUT = 3; (** Remove from path from path list *)
10 |
11 | TYPE
12 | PathList* = POINTER TO PathListDesc;
13 | PathListDesc* = RECORD
14 | part : ARRAY Path.MAXLENGTH OF CHAR;
15 | next : PathList
16 | END;
17 |
18 | VAR
19 | delimiter : CHAR;
20 |
21 | (** Length returns the length of the PathList *)
22 | PROCEDURE Length*(pathList : PathList) : INTEGER;
23 | VAR res : INTEGER; cur : PathList;
24 | BEGIN res := 0; cur := pathList;
25 | WHILE cur # NIL DO INC(res); cur := cur.next; END;
26 | RETURN res
27 | END Length;
28 |
29 | (** Find takes a path and searches a path list return -1 if not found
30 | or the position where it was found (zero indexed) *)
31 | PROCEDURE Find*(path : ARRAY OF CHAR; pathList : PathList) : INTEGER;
32 | VAR res, pos : INTEGER; cur : PathList;
33 | BEGIN res := -1; pos := 0; cur := pathList;
34 | WHILE (cur # NIL) & (res = -1) DO
35 | IF Chars.Equal(cur.part, path) THEN
36 | res := pos;
37 | END;
38 | INC(pos); cur := cur.next;
39 | END;
40 | RETURN res
41 | END Find;
42 |
43 | (** Prepend takes a path and a path list and prepends path to path list updating
44 | path list. *)
45 | PROCEDURE Prepend*(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN);
46 | BEGIN
47 | success := FALSE; (* FIXME: Prepend not implemented. *)
48 | END Prepend;
49 |
50 | (** Append takes a path and path list and adds the path to the end of path list *)
51 | PROCEDURE Append*(path: ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN);
52 | BEGIN
53 | success := FALSE; (* FIXME: Append not implemented. *)
54 | END Append;
55 |
56 | (** Cut takes a path and a path list and removes the path element from path list. *)
57 | PROCEDURE Cut*(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN);
58 | BEGIN
59 | success := FALSE; (* FIXME: Cut not implemented *)
60 | END Cut;
61 |
62 | (** SetDelimiter sets the delimiter to be used for encoding and decoding paths *)
63 | PROCEDURE SetDelimiter(c : CHAR);
64 | BEGIN delimiter := c;
65 | END SetDelimiter;
66 |
67 | (** Encode takes a PathList and encodes it into pathListString using the delimiter provided *)
68 | PROCEDURE Encode*(pathList : PathList; delimiter: CHAR; VAR pathListString : ARRAY OF CHAR; VAR success : BOOLEAN);
69 | BEGIN
70 | success := FALSE; (* FIXME: Not implemented *)
71 | END Encode;
72 |
73 | (** Decode takes a path list string and decodes it into a PathList data structure *)
74 | PROCEDURE Decode*(pathListString : ARRAY OF CHAR; VAR pathList : PathList; success : BOOLEAN);
75 | BEGIN
76 | success := FALSE; (* FIXME: Not implemented *)
77 | END Decode;
78 |
79 | (** Apply takes a path, an operation and a path list string. It applies the operation
80 | using the path and pathList updating pathList. Return TRUE of successful,
81 | FALSE otherwise. *)
82 | PROCEDURE Apply*(path: ARRAY OF CHAR; operation: INTEGER; VAR pathListString: ARRAY OF CHAR): BOOLEAN;
83 | VAR success : BOOLEAN; pathList : PathList;
84 | BEGIN
85 | Decode(pathListString, pathList, success);
86 | IF success THEN
87 | IF operation = PREPEND THEN
88 | Prepend(path, pathList, success)
89 | ELSIF operation = APPEND THEN
90 | Append(path, pathList, success)
91 | ELSIF operation = CUT THEN
92 | Cut(path, pathList, success)
93 | END;
94 | END;
95 | RETURN success
96 | END Apply;
97 |
98 | BEGIN
99 | SetDelimiter(":"); (** NOTE: The colon is the default delimiter. *)
100 | END PathLists.
--------------------------------------------------------------------------------
/PathListsTest.Mod:
--------------------------------------------------------------------------------
1 | MODULE PathListsTest;
2 |
3 | IMPORT PathLists, T := Tests;
4 |
5 | VAR ts : T.TestSet;
6 |
7 | PROCEDURE TestEncodeDecode() : BOOLEAN;
8 | VAR test, ok : BOOLEAN; src : ARRAY 1024 OF CHAR;
9 | pl : PathLists.PathList;
10 | BEGIN test := TRUE;
11 | src := "/bin:/usr/bin:/usr/local/bin:/home/jane.doe/bin";
12 | PathLists.Decode(src, pl, ok);
13 | T.ExpectedBool(TRUE, ok, "Expected to decode src", test);
14 | RETURN test
15 | END TestEncodeDecode;
16 |
17 | PROCEDURE TestLengthSetDelimiterFind() : BOOLEAN;
18 | VAR test : BOOLEAN;
19 | BEGIN test := TRUE;
20 | T.ExpectedBool(TRUE, FALSE, "TestLengthSetDelimiterFind() not implemented.", test);
21 | RETURN test
22 | END TestLengthSetDelimiterFind;
23 |
24 | PROCEDURE TestPrepend() : BOOLEAN;
25 | VAR test : BOOLEAN;
26 | BEGIN test := TRUE;
27 | T.ExpectedBool(TRUE, FALSE, "TestPrepend() not implemented.", test);
28 | RETURN test
29 | END TestPrepend;
30 |
31 | PROCEDURE TestAppend() : BOOLEAN;
32 | VAR test : BOOLEAN;
33 | BEGIN test := TRUE;
34 | T.ExpectedBool(TRUE, FALSE, "TestAppend() not implemented. ", test);
35 | RETURN test
36 | END TestAppend;
37 |
38 | PROCEDURE TestCut() : BOOLEAN;
39 | VAR test : BOOLEAN;
40 | BEGIN test := TRUE;
41 | T.ExpectedBool(TRUE, FALSE, "TestCut() not implemented. ", test);
42 | RETURN test
43 | END TestCut;
44 |
45 | PROCEDURE TestApply() : BOOLEAN;
46 | VAR test : BOOLEAN;
47 | BEGIN test := TRUE;
48 | T.ExpectedBool(TRUE,FALSE, "TestApply() not implemented.", test);
49 | RETURN test
50 | END TestApply;
51 |
52 | BEGIN
53 | T.Init(ts, "Test PathLists");
54 | T.Add(ts, TestEncodeDecode);
55 | T.Add(ts, TestLengthSetDelimiterFind);
56 | T.Add(ts, TestPrepend);
57 | T.Add(ts, TestAppend);
58 | T.Add(ts, TestCut);
59 | T.Add(ts, TestApply);
60 | ASSERT(T.Run(ts));
61 | END PathListsTest.
62 |
--------------------------------------------------------------------------------
/PathTest.Mod:
--------------------------------------------------------------------------------
1 | MODULE PathTest;
2 |
3 | IMPORT T := Tests, Path, Chars;
4 |
5 | VAR ts : T.TestSet;
6 |
7 | PROCEDURE TestMaxPath() : BOOLEAN;
8 | VAR test : BOOLEAN;
9 | BEGIN test := TRUE;
10 | T.ExpectedInt(1024, Path.MAXLENGTH, "Current path maximum assumption", test);
11 | RETURN test
12 | END TestMaxPath;
13 |
14 | PROCEDURE TestSetDelimiter() : BOOLEAN;
15 | VAR test : BOOLEAN;
16 | BEGIN test := TRUE;
17 | T.ExpectedChar(Chars.SLASH, Path.delimiter, "Checking default delimiter", test);
18 | Path.SetDelimiter(Chars.BSLASH);
19 | T.ExpectedChar(Chars.BSLASH, Path.delimiter, "Checking set delimiter to ';'", test);
20 | Path.SetDelimiter(Chars.SLASH);
21 | T.ExpectedChar(Chars.SLASH, Path.delimiter, "Checking set delimiter to ':'", test);
22 | RETURN test
23 | END TestSetDelimiter;
24 |
25 | PROCEDURE TestPrepend() : BOOLEAN;
26 | VAR test, ok : BOOLEAN; a : ARRAY Path.MAXLENGTH OF CHAR;
27 | BEGIN test := TRUE;
28 | a[0] := 0X;
29 | Path.Prepend("", a, ok);
30 | T.ExpectedBool(TRUE, ok, "Path.Prepend('', a) ok -> ''", test);
31 | T.ExpectedString("", a, "Path.Prepend('', a)", test);
32 | Path.Prepend("/me", a, ok);
33 | T.ExpectedBool(TRUE, ok, "Path.Prepend('/me', a) ok -> /me", test);
34 | T.ExpectedString("/me", a, "Path.Prepend('/me', a)", test);
35 | Path.Prepend("/home", a, ok);
36 | T.ExpectedBool(TRUE, ok, "Path.Prepend('/home', a) ok -> /home/me", test);
37 | T.ExpectedString("/home/me", a, "Path.Prepend('home', a)", test);
38 | RETURN test
39 | END TestPrepend;
40 |
41 | PROCEDURE TestAppend() : BOOLEAN;
42 | VAR test, ok : BOOLEAN; a : ARRAY Path.MAXLENGTH OF CHAR;
43 | BEGIN test := TRUE;
44 | a := "";
45 | Path.Append("", a, ok);
46 | T.ExpectedBool(TRUE, ok, "Path.Append('', a) ok -> ''", test);
47 | T.ExpectedString("", a, "Path.Append('', a)", test);
48 | Path.Append("/", a, ok);
49 | T.ExpectedBool(TRUE, ok, "Path.Append('/', a) ok -> '/'", test);
50 | T.ExpectedString("/", a, "Path.Append('/', a)", test);
51 | Path.Append("home", a, ok);
52 | T.ExpectedBool(TRUE, ok, "Path.Append('home', a) ok -> /home", test);
53 | T.ExpectedString("/home", a, "Path.Append('home', a)", test);
54 | Path.Append("me", a, ok);
55 | T.ExpectedBool(TRUE, ok, "Path.Append('', a) ok -> /home/me", test);
56 | T.ExpectedString("/home/me", a, "Path.Append('me', a) ok -> /home/me", test);
57 | RETURN test
58 | END TestAppend;
59 |
60 | PROCEDURE TestBasename() : BOOLEAN;
61 | VAR test, ok : BOOLEAN; a, expected, got : ARRAY Path.MAXLENGTH OF CHAR;
62 | BEGIN test := TRUE;
63 | a := "/home/me/.profile";
64 | expected := ".profile";
65 | Path.Basename(a, got, ok);
66 | T.ExpectedBool(TRUE, ok, "Basename(a, got, ok) ok -> ?", test);
67 | T.ExpectedString(expected, got, "Path.Basename(a, got, ok)", test);
68 | RETURN test
69 | END TestBasename;
70 |
71 | PROCEDURE TestDirname() : BOOLEAN;
72 | VAR test, ok : BOOLEAN; a, expected, got : ARRAY Path.MAXLENGTH OF CHAR;
73 | BEGIN test := TRUE;
74 | a := "/home/me/.profile";
75 | expected := "/home/me";
76 | Path.Dirname(a, got, ok);
77 | T.ExpectedBool(TRUE, ok, "Dirname(a, got, ok) ok -> ?", test);
78 | T.ExpectedString(expected, got, "Path.Dirname(a, got, ok)", test);
79 | RETURN test
80 | END TestDirname;
81 |
82 | PROCEDURE TestExt() : BOOLEAN;
83 | VAR test, ok : BOOLEAN; a, expected, got : ARRAY Path.MAXLENGTH OF CHAR;
84 | BEGIN test := TRUE;
85 | a := "/home/me/README.txt";
86 | expected := ".txt";
87 | Path.Ext(a, got, ok);
88 | T.ExpectedBool(TRUE, ok, "Ext(a, got, ok) ok -> ?", test);
89 | T.ExpectedString(expected, got, "Path.Ext(a, got, ok)", test);
90 | RETURN test
91 | END TestExt;
92 |
93 | BEGIN
94 | T.Init(ts, "Test Path");
95 | T.Add(ts, TestMaxPath);
96 | T.Add(ts, TestSetDelimiter);
97 | T.Add(ts, TestPrepend);
98 | T.Add(ts, TestAppend);
99 | T.Add(ts, TestDirname);
100 | T.Add(ts, TestBasename);
101 | T.Add(ts, TestExt);
102 | ASSERT(T.Run(ts));
103 | END PathTest.
104 |
--------------------------------------------------------------------------------
/Scanner.Mod:
--------------------------------------------------------------------------------
1 | MODULE Scanner;
2 |
3 | CONST
4 | (* ERROR in scan, e.g. string start found without end string, position in scan not updated *)
5 | ERROR* = 0;
6 | (* OK scan successful, not at end of text, position in scan updated *)
7 | OK* = 1;
8 | (* EOS, end of scan, scan successful but at end of text, position in scan not updated *)
9 | EOS* = 2;
10 |
11 | (* Common String Delimiters *)
12 | EOT* = 0X; (* end of text *)
13 | TAB* = 9X; (* tab *)
14 | LF* = 10X; (* line feed *)
15 | FF* = 11X; (* form feed *)
16 | CR* = 13X; (* charriage return *)
17 | SPACE* = 32X; (* space *)
18 | DQUOTE* = 34X; (* double quote *)
19 | SQUOTE* = 39X; (* single quote *)
20 | SLASH* = 47X; (* slash or div symbol *)
21 | BSLASH* = 92X; (* backslash *)
22 |
23 | (** Character constants *)
24 | DASH* = "-"; (* dash *)
25 | LODASH* = "_"; (* underscore or low dash *)
26 | CARET* = "^"; (* caret *)
27 | TILDE* = "~"; (* tilde *)
28 |
29 | TYPE
30 | Scanner* = POINTER TO ScannerDesc;
31 | ScannerDesc* = RECORD
32 | delimiter: CHAR;
33 | startString: CHAR;
34 | endString: CHAR;
35 | inString: BOOLEAN;
36 | escape: CHAR;
37 | Pos*: INTEGER
38 | END;
39 |
40 | PROCEDURE Init*(VAR scanner: Scanner; delimiter: CHAR; startString: CHAR; endString: CHAR; Escape: CHAR);
41 | BEGIN
42 | scanner.delimiter := delimiter;
43 | scanner.startString := startString;
44 | scanner.endString := endString;
45 | scanner.escape := Escape;
46 | scanner.inString := FALSE;
47 | scanner.Pos := 0;
48 | END Init;
49 |
50 | PROCEDURE ScanChars*(VAR scanner: Scanner; src : ARRAY OF CHAR; VAR value: ARRAY OF CHAR; VAR OK: BOOLEAN);
51 | BEGIN
52 | END ScanChars;
53 |
54 |
55 | END Scanner.
56 |
57 | Scanner
58 | =======
59 |
60 | Scanner models a simple text scanner like that needed to process Oberon language files or Pascal.
61 |
62 |
63 |
--------------------------------------------------------------------------------
/ScannerTest.Mod:
--------------------------------------------------------------------------------
1 | MODULE ScannerTest;
2 |
3 | IMPORT Scanner, T := Tests;
4 |
5 | VAR ts : T.TestSet;
6 |
7 | PROCEDURE TestScanner() : BOOLEAN;
8 | VAR s : Scanner.Scanner;
9 | txt, token, expected : ARRAY 256 OF CHAR;
10 | test, OK : BOOLEAN;
11 | BEGIN test := FALSE;
12 | txt := "I think pi is about 3.145";
13 | Scanner.Init(s, Scanner.SPACE, Scanner.DQUOTE, Scanner.DQUOTE, Scanner.BSLASH);
14 | expected := "I";
15 | Scanner.ScanChars(s, txt, token, OK);
16 | T.ExpectedBool(TRUE, OK, "Scanner.Chars(s, txt, token, OK) should be true", test);
17 | T.ExpectedString(expected, token, "Expected 'I', got something else", test);
18 |
19 | RETURN test
20 | END TestScanner;
21 |
22 | BEGIN
23 | T.Init(ts, "Test Scanner");
24 | T.Add(ts, TestScanner);
25 | ASSERT(T.Run(ts));
26 | END ScannerTest.
27 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: To do
3 | ---
4 |
5 |
6 | Action Items
7 | ============
8 |
9 | Next
10 | ----
11 |
12 | - [ ] Need a module for working with UTF-8 encoded strings, Scanner need to support UTF-8 encoded files
13 | - [ ] Tests.Mod
14 | - rename ExpectedString to ExpectedChars (for consistency in Artemis)
15 | - Conform the const CHAR descriptions between Scanner.Mod and Chars.Mod
16 | - [ ] Chars.Mod
17 | - QUOTE should be DQUOTE 34X
18 | - Add SQUOTE 39X
19 | - [ ] Add Scanner.Mod implementing a simple text scanner supporting ARRAY OF CHAR and plain text files
20 | - [x] Clock.Mod should wrap host system clock for use by a more general purpose DateTime.Mod.
21 | - [x] Refactor CharsTest.Mod to test Strings compatible procedures
22 | - [x] Tests module for easily writing tests of modules
23 | - [ ] Reals.Mod should provide easy conversion to/from String for Real with exponential or fixed notations without reliance on extConvert.
24 | - [x] Chars should provide a more modern approach to text processing that the Oakwood Strings module
25 | - [x] Chars module should work as a drop in replacement for Oakwood Strings
26 | - [x] DStrings module for dynamic strings, compatible with Chars and Strings where it makes sense, it should include Rider suppport since we lack index notation for working in the string object
27 | - [ ] JSON module for working with JSON data
28 | - [ ] Document coding conventions on when to use snake, camel case in variables and procedure names.
29 | - [ ] Use the `curl --libcurl` option to assemble a C module for handling HTTP/HTTPS and possibly other curl supported protocols
30 |
31 | Requested Ports from Native Oberon
32 | ----------------------------------
33 |
34 |
35 | + [ ] Files.Mod (Confirm Can I use OBNC's implementation, confirm PO 2013 Files.Mod works as replacement)
36 | + [ ] Objects.Mod (Port needed for POSIX, port needed for PO 2013)
37 | + [ ] Display.Mod (Port needed for POSIX, confirm PO 2013 Display.Mod works as replacement)
38 | + [ ] Fonts.Mod (Port needed for POSIX, confirm PO 2013 Fonts.Mod works as replacement)
39 | + [ ] Reals.Mod (Port needed for POSIX and for PO 2013)
40 | + [ ] Texts.Mod, see https://en.wikibooks.org/wiki/Oberon/ETH_Oberon/2003-01-05/Texts.Mod
41 | + Depends on: Files, Objects, Display, Fonts, and Reals
42 | + [ ] Figure out if the other Native Oberon modules like Kernel, Modules, Displays.Display.Mod, etc. need to be ported or we can use PO 2013 modules
43 |
44 | Someday, maybe
45 | --------------
46 |
47 | + [ ] Reals.Mod
48 | + [ ] EBNF.Mod and ebnfc.Mod
49 | + [ ] Scanner.Mod implementing a Texts like Scanner
50 | + [ ] RISC5 emulator (based on Compiler Construction RISC0 emulator)
51 | + [ ] Create a Ofront/V4 like dev environment with direct access to host file system
52 | + [ ] Re-implement Fonts.Mod so Oberon System can use ADA friendly fonts like Open Dyslexia and Atikson Hyperledgable
53 | + [ ] Rename String.Init() to something that both suggests both initialization AND assignment. NOTE: Set/Get/Put are taken by the Rider procedures to remain signature compatible with Files.Rider
54 | + [ ] Refactor StringDesc record for holding CHAR to hold INTEGER to allow support for difference character sets (e.g. UTF-8/UTF-32)
55 | + [ ] Portable Convert module, look at V4 and OBNC implementations as well as Oxford compiler and VOC
56 | + [ ] RegExp module is needed
57 | + [ ] CSV module for working with CSV data
58 | + [ ] XML module for working with XML data
59 | + [ ] HTML review A2 and Native Oberon-7, evaluate a port to Oberon-7
60 | + [ ] OBNC ext modules used need to be re-implemented as pure Oberon-7 to allow Artemis to be Oberon-7 compiler agnostic.
61 | + [ ] Need to test under Oberon Project 2013 in DeWachter's emulator as well as Extended Oberon and IO Core
62 | + [ ] Cli modules (e.g. OCat) need to be clearly marked as non-portable between Oberon Systems and POSIX
63 | + [ ] Makefile needs to handle compile Cli modules to sensible lowercase names based on Oberon-7 compiler used
64 | - [ ] Look at FLTK's Go bindings as well as Fyne's and see if there are some insights for a general purpose set of GUI bindings for Artemis
65 |
66 |
67 |
--------------------------------------------------------------------------------
/clean.bat:
--------------------------------------------------------------------------------
1 | REM A simple batch file to cleanip our compile process and remove any stale exe
2 | del *.exe
3 |
--------------------------------------------------------------------------------
/codemeta.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "https://doi.org/10.5063/schema/codemeta-2.0",
3 | "@type": "SoftwareSourceCode",
4 | "description": "Artemis is a collection of Oberon-07 modules for use on Oberon-07 compilers are available.",
5 | "name": "Artemis",
6 | "codeRepository": "https://github.com/rsdoiel/Artemis",
7 | "issueTracker": "https://github.com/rsdoiel/Artemis/issues",
8 | "license": "https://rsdoiel.github.io/Artemis/license.html",
9 | "version": "0.0.0",
10 | "author": [
11 | {
12 | "@type": "Person",
13 | "givenName": "Robert",
14 | "familyName": "Doiel",
15 | "email": "rsdoiel@gmail.com",
16 | "@id": "https://orcid.org/0000-0003-0900-6903"
17 | }
18 | ],
19 | "developmentStatus": "Concept",
20 | "keywords": [
21 | "Oberon-07",
22 | "portable",
23 | "Oberon-System"
24 | ],
25 | "maintainer": "https://orcid.org/0000-0003-0900-6903",
26 | "programmingLanguage": [
27 | "Oberon-07"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/css/prettify.css:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | /**
5 | * @license
6 | * Copyright (C) 2015 Google Inc.
7 | *
8 | * Licensed under the Apache License, Version 2.0 (the "License");
9 | * you may not use this file except in compliance with the License.
10 | * You may obtain a copy of the License at
11 | *
12 | * http://www.apache.org/licenses/LICENSE-2.0
13 | *
14 | * Unless required by applicable law or agreed to in writing, software
15 | * distributed under the License is distributed on an "AS IS" BASIS,
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | * See the License for the specific language governing permissions and
18 | * limitations under the License.
19 | */
20 |
21 | /* Pretty printing styles. Used with prettify.js. */
22 |
23 |
24 | /* SPAN elements with the classes below are added by prettyprint. */
25 | .pln { color: #000 } /* plain text */
26 |
27 | @media screen {
28 | .str { color: #080 } /* string content */
29 | .kwd { color: #008 } /* a keyword */
30 | .com { color: #800 } /* a comment */
31 | .typ { color: #606 } /* a type name */
32 | .lit { color: #066 } /* a literal value */
33 | /* punctuation, lisp open bracket, lisp close bracket */
34 | .pun, .opn, .clo { color: #660 }
35 | .tag { color: #008 } /* a markup tag name */
36 | .atn { color: #606 } /* a markup attribute name */
37 | .atv { color: #080 } /* a markup attribute value */
38 | .dec, .var { color: #606 } /* a declaration; a variable name */
39 | .fun { color: red } /* a function name */
40 | }
41 |
42 | /* Use higher contrast and text-weight for printable form. */
43 | @media print, projection {
44 | .str { color: #060 }
45 | .kwd { color: #006; font-weight: bold }
46 | .com { color: #600; font-style: italic }
47 | .typ { color: #404; font-weight: bold }
48 | .lit { color: #044 }
49 | .pun, .opn, .clo { color: #440 }
50 | .tag { color: #006; font-weight: bold }
51 | .atn { color: #404 }
52 | .atv { color: #060 }
53 | }
54 |
55 | /* Put a border around prettyprinted code snippets. */
56 | pre.prettyprint { padding: 2px; border: 1px solid #888 }
57 |
58 | /* Specify class=linenums on a pre to get line numbering */
59 | ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */
60 | li.L0,
61 | li.L1,
62 | li.L2,
63 | li.L3,
64 | li.L5,
65 | li.L6,
66 | li.L7,
67 | li.L8 {
68 | list-style-type: decimal !important;
69 | }
70 | /* Alternate shading for lines */
71 | li.L1,
72 | li.L3,
73 | li.L5,
74 | li.L7,
75 | li.L9 { background: #eee }
76 |
--------------------------------------------------------------------------------
/css/site.css:
--------------------------------------------------------------------------------
1 | /* @import 'https://fonts.googleapis.com/css?family=Concert+One|Dosis'; */
2 |
3 | body {
4 | font-family: 'Atkinson-Hyperlegible', 'Open Sans', sans-serif;
5 | font-size: calc(1em+1vw);
6 | padding: 0;
7 | margin: 0;
8 | width: 100%;
9 | height: auto;
10 | color: black;
11 | background-color: white;
12 | }
13 |
14 | a, a:link, a:visited {
15 | color: forestgreen;
16 | text-decoration: none;
17 | }
18 |
19 | a:active, a:focus, a:hover {
20 | color: maroon;
21 | text-decoration: underline;
22 | }
23 |
24 |
25 |
26 | ul {
27 | padding: 0;
28 | margin-left: 1.24em;
29 | /* list-style-type: disc;*/
30 | }
31 |
32 | nav {
33 | position:fixed;
34 | top:0;
35 | display: block;
36 | width: 100%;
37 | height: auto;
38 | padding: 0;
39 | padding: 0.20em;
40 | /* caltech orange, white and black
41 | color: white;
42 | background-color: #FF6E1E;
43 | */
44 | /* white on deep red */
45 | color: white;
46 | background-color: #5f0202;
47 | }
48 |
49 | nav a, nav a:link, nav a:visited {
50 | font-weight: lighter;
51 | color: white;
52 | text-decoration: none;
53 | }
54 |
55 | nav a:active, nav a:focus, nav a:hover {
56 | font-weight: lighter;
57 | color: orange;
58 | text-decoration: none;
59 | text-transform: uppercase;
60 | }
61 |
62 |
63 | nav ul {
64 | display: block;
65 | width: 100%;
66 | height: auto;
67 | list-style: none;
68 | list-style-type: none;
69 | padding: 0;
70 | margin: 0;
71 | }
72 |
73 | nav ul li {
74 | display: inline-block;
75 | text-align: left;
76 | padding-top: 0em;
77 | padding-left: 0.82em;
78 | padding-right: 0.24em;
79 | padding-bottom: 0em;
80 | margin: 0;
81 | }
82 |
83 | section, article {
84 | display: block;
85 | max-width: 90%;
86 | height: auto;
87 | padding: 1.24em;
88 | margin-top: 1.24em;
89 | margin-bottom: 0.24em;
90 | }
91 |
92 |
93 | img.rss-valid {
94 | display: inline;
95 | width: auto;
96 | height: 0.82em;
97 | }
98 |
99 | h1 {
100 | font-size: 200%;
101 | }
102 |
103 | h2 {
104 | font-weight: lighter;
105 | font-size: 170%;
106 | }
107 |
108 | h3 {
109 | font-weight: lighter;
110 | font-size: 120%;
111 | text-transform: uppercase;
112 | }
113 |
114 | h4 {
115 | font-weight: lighter;
116 | font-size: 100%;
117 | text-transform: lowercase;
118 | }
119 |
120 | h1 code, h2 code, h3 code, h4 code {
121 | text-transform:none;
122 | }
123 |
124 |
125 | footer {
126 | position: fixed;
127 | bottom: 0;
128 | font-size: 0.82em;
129 | font-weight: lighter;
130 | padding: 0;
131 | margin: 0;
132 | width: 100%;
133 | height: auto;
134 | color: white;
135 | background-color: black;
136 | }
137 |
138 | /* NOTE: Ingnore a P tag inserted by Markdown when rendering headers */
139 | footer p {
140 | display: block;
141 | width: 100%;
142 | height: auto;
143 | padding: 0;
144 | margin: 0;
145 | font-family: 'Dosis', sans-serif;
146 | font-size: 0.82em;
147 | font-weight: lighter;
148 | margin-top: 0.32em;
149 | margin-left: 0;
150 | margin-right: 0;
151 | margin-bottom: 0;
152 | }
153 |
154 | footer img {
155 | display: block;
156 | float: left;
157 | vertical-align: top;
158 | border: 1px solid black;
159 | border-top-left-radius: 1.2em;
160 | border-top-right-radius: 1.2em;
161 | box-shadow: inset 0.12em 0.12em black;
162 | width: 3.2em;
163 | height: auto;
164 | margin: 0.24em;
165 | }
166 |
167 | footer a, footer a:link, footer a:visited {
168 | font-weight: lighter;
169 | /* caltech orange */
170 | color: #FF6E1E;
171 | }
172 |
173 | footer a:active, footer a:focus, footer a:hover {
174 | font-weight: lighter;
175 | color: lightgreen;
176 | }
177 |
178 | /* color injections for AndOr */
179 | .red {
180 | color: red;
181 | }
182 |
183 | /* Google prittyprint customizaions CSS */
184 | li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9
185 | {
186 | color: #555;
187 | list-style-type: decimal;
188 | }
189 |
190 |
191 | /* Mmark css */
192 | #footnote-section {
193 | font-size: 80%;
194 | display: none;
195 | }
196 |
197 | .footnotes {
198 | font-size: 80%;
199 | }
200 |
201 | /*
202 | * Project Customizations
203 | */
204 | div.project-name {
205 | display: block;
206 | width: 100%;
207 | height: auto;
208 | padding-top: 1.24em;
209 | padding-left: 1.24em;
210 | margin-top: 1.24em;
211 | }
212 |
213 | header blockquote {
214 | display: block;
215 | width: 100%;
216 | height: auto;
217 | padding: 0em;
218 | margin-left: 2.48em;
219 | }
220 |
221 |
--------------------------------------------------------------------------------
/css/tables.css:
--------------------------------------------------------------------------------
1 | table {
2 | table-layout: fixed;
3 | width: 80%;
4 | border-collapse: collapse;
5 | color: white;
6 | background-color: darkblue;
7 | /* border: 3px solid #5f0202; */
8 | caption-side: bottom;
9 | }
10 |
11 | th, td {
12 | font-family: comic, cursive, helvetica;
13 | padding: 0.72em;
14 | }
15 |
16 | tr, td {
17 | font-family: monospace, courier, serif;
18 | }
19 |
20 | tbody tr:nth-child(odd) {
21 | color: blue;
22 | background-color: white;
23 | }
24 |
25 | tbody tr:nth-child(even) {
26 | color: white;
27 | background-color: blue;
28 | }
29 |
30 | caption {
31 | color: black;
32 | background-color: white;
33 | text-align: left;
34 | text-transform: lowercase;
35 | font-size: smaller;
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/development-notes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Project Artemis
5 |
6 |
7 |
8 |
9 |
10 |
11 | Development notes
12 |
13 |
14 |
15 | Development Notes
16 |
17 |
18 | Display & Fonts Modules
19 |
20 |
21 | Two module that are used by Texts.Mod are Display and Fonts. In the Oberon System these are standard modules. In the POSIX environment they are not. The closest is the XYPlane module from the Oakwood Guidelines.
22 |
23 |
24 | There are two approaches for replicating Display and Fonts in a POSIX setting. They could be made headless, meaning they would never attach to a real viewer or they could be integrate into the GUI of the host system. I am currently exploring SDL2 as an option for integrating them into a host environment.
25 |
26 |
27 | It is possible that copilation options could be chosen (e.g. the module search path) to pick which approach was appropriate for compiling in a POSIX environment. As an example a command line tool which is using Texts for compatibility with Oberon Texts but not for displaying them might be better off with a headless implementation. On the otherhand if you wanted to recreate the Oberon Edit command then headless doesn’t do much for you.
28 |
29 |
30 | The primary difference between a headless Texts and a displayable one is how it is hooked in to the actual rendering process. So a Display0.Mod could be the headless one while Display.Mod extended Display0 to provide real GUI rendering via a portable framework like SDL2.
31 |
18 | Copyright (c) 2021, R. S. Doiel All rights reserved.
19 |
20 |
21 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
22 |
23 |
24 |
25 |
26 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
27 |
28 |
29 |
30 |
31 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
32 |
33 |
34 |
35 |
36 | Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
37 |
38 |
39 |
40 |
41 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 |
43 |
44 |
75 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/make.bat:
--------------------------------------------------------------------------------
1 | @REM make.bat is a simple DOS batch file for building Artemis project under Windows 11.
2 |
3 | @echo Removing stale executables.
4 | @del *.exe
5 |
6 | @echo Compiling CharsTest.Mod
7 | call obnc CharsTest.Mod
8 | @echo Compiling DStringsTest.Mod
9 | call obnc DStringsTest.Mod
10 | @echo Compiling JSONTest.Mod
11 | call obnc JSONTest.Mod
12 | @echo Compiling Obn2Test.Mod
13 | call obnc Obn2Test.Mod
14 | @echo Compiling PathListsTest.Mod
15 | call obnc PathListsTest.Mod
16 | @echo Compiling PathTest.Mod
17 | call obnc PathTest.Mod
18 | @echo Compiling ScannerTest.Mod
19 | call obnc ScannerTest.Mod
20 |
21 | @echo Running each test.
22 | CharsTest.exe
23 | DStringsTest.exe
24 | JSONTest.exe
25 | Obn2Test.exe
26 | PathListsTest.exe
27 | PathTest.exe
28 | ScannerTest.exe
29 |
--------------------------------------------------------------------------------
/nav.md:
--------------------------------------------------------------------------------
1 |
2 | + [Home](/)
3 | + [README](./)
4 | + [LICENSE](license.html)
5 | + [INSTALL](install.html)
6 | + [OBNC Modules](./obnc/)
7 | + [Obc-3 Modules](./oxford/)
8 | + [Ofront+ Modules](./ofrontplus/)
9 | + [development notes](./development-notes.html)
10 | + [Github](https://github.com/rsdoiel/Artemis)
11 |
12 |
--------------------------------------------------------------------------------
/note-system.bit-oberon-list.txt:
--------------------------------------------------------------------------------
1 | 2021-06-04, RSD
2 |
3 | Hello everyone,
4 |
5 | This is probably a bit of a novice question and I apologize but
6 | it has me puzzled. In the Oberon-7 language report's
7 | SYSTEM.BIT() is described as using "n" to address a specific bit.
8 | On first reading I assumed "n" zero would be the LSB and "n"
9 | thirty one would be MSB where the compiler deals with the local
10 | implementation of bit ordering. Is that the correct reading
11 | of the report?
12 |
13 | I was planning on implementing a procedure like Native Oberon's
14 | Reals.IntL() but then started having doubts about my reading of the
15 | Oberon-7 report. Have I made too simple a set of assumptions about
16 | how I should expect SYSTEM.BIT() to work under Oberon-7
17 | implementations?
18 |
19 | All the best,
20 |
21 | Robert Doiel
22 |
23 |
24 |
--------------------------------------------------------------------------------
/obnc/C/Clock.GetRtcTime.inc:
--------------------------------------------------------------------------------
1 | static void GetRtcTime_(OBNC_INTEGER *second_, OBNC_INTEGER *minute_, OBNC_INTEGER *hour_, OBNC_INTEGER *day_, OBNC_INTEGER *month_, OBNC_INTEGER *year_, OBNC_INTEGER *wDay_, OBNC_INTEGER *yDay_, OBNC_INTEGER *isDST_, OBNC_INTEGER *utcOffset_, OBNC_INTEGER *seconds_, OBNC_INTEGER *nanoSeconds_, int *ok_)
2 | {
3 | struct timespec now;
4 | struct tm *dt;
5 |
6 | *ok_ = 1; /* Assume clock_gettime() successful */
7 | if (clock_gettime(CLOCK_REALTIME, &now) == -1) {
8 | *ok_ = 0; /* clock_gettime() failed for some reason */
9 | perror("clock_gettime(CLOCK_REALTIME, &now) failed");
10 | } else {
11 | *seconds_ = now.tv_sec;
12 | *nanoSeconds_ = now.tv_nsec;
13 | dt = localtime(&now.tv_sec);
14 | *second_ = dt->tm_sec;
15 | *minute_ = dt->tm_min;
16 | *hour_ = dt->tm_hour;
17 | *day_ = dt->tm_mday;
18 | *month_ = dt->tm_mon + 1; /* We want 1 to 12 rather than 0 to 11 */
19 | *year_ = dt->tm_year + 1900; /* Normalize to current year */
20 | *wDay_ = dt->tm_wday;
21 | *yDay_ = dt->tm_yday;
22 | *isDST_ = dt->tm_isdst;
23 | *utcOffset_ = dt->tm_gmtoff;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/obnc/C/Clock.SetRtcTime.inc:
--------------------------------------------------------------------------------
1 | static void SetRtcTime_(OBNC_INTEGER second_, OBNC_INTEGER minute_, OBNC_INTEGER hour_, OBNC_INTEGER day_, OBNC_INTEGER month_, OBNC_INTEGER year_, OBNC_INTEGER wDay_, OBNC_INTEGER yDay_, OBNC_INTEGER isDST_, OBNC_INTEGER utcOffset_, int *ok_)
2 | {
3 | struct timespec nt;
4 | struct tm dt;
5 |
6 | dt.tm_sec = second_;
7 | dt.tm_min = minute_;
8 | dt.tm_hour = hour_;
9 | dt.tm_mday = day_;
10 | dt.tm_mon = (month_ - 1); /* de-normalize to 0 to 11 from 1 to 12 */
11 | dt.tm_year = (year_ - 1900); /* adjust year to reflect POSIX value */
12 | dt.tm_wday = wDay_;
13 | dt.tm_yday = yDay_;
14 | /* NOTE: tm_idst and tm_gmtoff are not ISO C or POSIX, they come from
15 | BSD and GNU systems. They appear to be available on macOS */
16 | dt.tm_isdst = isDST_;
17 | dt.tm_gmtoff = utcOffset_;
18 | /* NOTE: You must have root permissions for clock_settime() to work */
19 | nt.tv_sec = mktime(&dt);
20 | if (clock_settime(CLOCK_REALTIME, &nt) == -1) {
21 | perror("clock_gettime(CLOCK_REALTIME, &nt) failed");
22 | *ok_ = 0;
23 | } else {
24 | *ok_ = 1;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/obnc/C/Unix.Exit.inc:
--------------------------------------------------------------------------------
1 | void Unix__Exit_(OBNC_INTEGER exitCode_)
2 | {
3 | exit(exitCode_);
4 | }
5 |
6 |
--------------------------------------------------------------------------------
/obnc/C/Unix.includes.inc:
--------------------------------------------------------------------------------
1 | #include ".obnc/Unix.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 |
--------------------------------------------------------------------------------
/obnc/C/Unix.uname.inc:
--------------------------------------------------------------------------------
1 |
2 | static void uname_(char opt_, char dest_[], OBNC_INTEGER dest_len)
3 | {
4 | FILE *in;
5 | char ch;
6 | int i;
7 | char cmd[9];
8 |
9 | /* Setup our POSIX command */
10 | cmd[0] = 'u'; cmd[1] = 'n'; cmd[2] = 'a';
11 | cmd[3] = 'm'; cmd[4] = 'e'; cmd[5] = ' ';
12 | cmd[6] = '-'; cmd[7] = opt_;
13 | cmd[8] = '\x00';
14 | /* open a process and read stdout from a uname call */
15 | in = popen(cmd, "r");
16 | if (!in) return;
17 | /* for each character output by uname copy into our dest string */
18 | i = 0; dest_[i] = '\x00';
19 | while ( ((ch = fgetc(in)) != EOF) && (i < (dest_len - 1) ) ) {
20 | if ((ch == '\n') || (ch == '\r')) {
21 | dest_[i] = '\x00';
22 | break;
23 | } else {
24 | dest_[i] = ch;
25 | }
26 | i = i + 1;
27 | dest_[i] = '\x00'; /* add a trailing NULL CHAR */
28 | }
29 | /* close our pipe and done */
30 | pclose(in);
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/obnc/C/time_example_1.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | /*
5 | NOTES:
6 |
7 | Nano to Milli second 1 milli seconds equals 1000000 nano seconds
8 |
9 | */
10 |
11 | /* In ofront SetClock was skipped due to portability issues. I am
12 | * revisiting that in light of how C evolved.
13 | *
14 | * SetClock takes normalized year and month, i.e. If year
15 | * the year and month at 2021, January the values you pass
16 | * to SetClock for year and month should be 2021 and 1.
17 | **/
18 | void SetClock(int second, int minute, int hour, int day, int month, int year, int is_dst, int utc_offset) {
19 | struct timespec nt;
20 | struct tm tinfo;
21 | /* time_t now;
22 | now = time(NULL);
23 | tinfo = localtime(&now); */
24 |
25 | tinfo.tm_year = year - 1900;
26 | tinfo.tm_mon = month - 1;
27 | tinfo.tm_mday = day;
28 | tinfo.tm_hour = hour;
29 | tinfo.tm_min = minute;
30 | tinfo.tm_sec = second;
31 | tinfo.tm_isdst = is_dst;
32 | tinfo.tm_gmtoff = utc_offset;
33 | /* What goes here? stime is not avialable on macOS */
34 | nt.tv_sec = mktime(&tinfo);
35 | if (clock_settime(CLOCK_REALTIME, &nt) == -1) {
36 | perror("clock_settime(CLOCK_REALTIME, &nt) failed");
37 | }
38 | }
39 |
40 | /* modern way of getting time */
41 | int GetClock() {
42 | int seconds;
43 | struct timespec now;
44 |
45 | seconds = 0;
46 | if (clock_gettime(CLOCK_REALTIME, &now) == -1) {
47 | perror("clock_gettime(CLOCK_REALTIME, now) failed");
48 | } else {
49 | /* now now.tv_sec can be combined with localtime() to
50 | * have a useful conversion of units from EPoch */
51 | seconds = now.tv_sec;
52 | }
53 | return seconds;
54 | }
55 |
56 | /* Let's test out the different approaches */
57 | int main(int argc, char *argv[]) {
58 | int seconds;
59 | struct tm *nt;
60 | struct timespec saved_time;
61 | time_t now;
62 |
63 | seconds = GetClock();
64 | printf("Get clock, in seconds %d\n", seconds);
65 | if (clock_gettime(CLOCK_REALTIME, &saved_time) != -1) {
66 | nt = localtime(&saved_time.tv_sec);
67 | /* Normalize year as SetClock expects */
68 | nt->tm_year = nt->tm_year + 1900;
69 | /* Normalize month as SetClock expects */
70 | nt->tm_mon = nt->tm_mon + 1;
71 | SetClock(nt->tm_sec, nt->tm_min, nt->tm_hour, nt->tm_mday, nt->tm_mon, nt->tm_year + 1, nt->tm_isdst, nt->tm_gmtoff);
72 | now = time(NULL);
73 | nt = localtime(&now);
74 | printf("%04d-%02d-%02d %02d:%02d:%02d\n", nt->tm_year + 1900, nt->tm_mon + 1, nt->tm_mday, nt->tm_hour, nt->tm_min, nt->tm_sec);
75 | if (clock_settime(CLOCK_REALTIME, &saved_time) == -1) {
76 | perror("Could not reset clock after test");
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/obnc/ClockTest.obn:
--------------------------------------------------------------------------------
1 | (** ClockTest.Mod - Tests for Clock.Mod.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE ClockTest;
10 |
11 | IMPORT T := Tests, Env := extEnv, Clock := artClock, Out, Strings;
12 |
13 | VAR ts : T.TestSet;
14 |
15 | PROCEDURE DisplayClock(ct : Clock.Clock);
16 | VAR i, hours, minutes : INTEGER;
17 | BEGIN
18 | Out.Int(ct.year, 4);
19 | Out.String("-");
20 | IF ct.month < 10 THEN
21 | Out.String("0"); Out.Int(ct.month, 1);
22 | ELSE
23 | Out.Int(ct.month, 2);
24 | END;
25 | Out.String("-");
26 | IF ct.day < 10 THEN
27 | Out.String("0"); Out.Int(ct.month, 1);
28 | ELSE
29 | Out.Int(ct.day, 2);
30 | END;
31 | Out.String(" ");
32 | IF ct.hour < 10 THEN
33 | Out.String("0"); Out.Int(ct.hour, 1);
34 | ELSE
35 | Out.Int(ct.hour, 2);
36 | END;
37 | Out.String(":");
38 | IF ct.minute < 10 THEN
39 | Out.String("0"); Out.Int(ct.minute, 1);
40 | ELSE
41 | Out.Int(ct.minute, 2);
42 | END;
43 | Out.String(":");
44 | IF ct.second < 10 THEN
45 | Out.String("0"); Out.Int(ct.second, 1);
46 | ELSE
47 | Out.Int(ct.second, 2);
48 | END;
49 | IF ct.isDST < 0 THEN
50 | Out.String(" "); (* DST info not available *)
51 | ELSIF ct.isDST = 0 THEN
52 | Out.String(" (ST)");
53 | ELSIF ct.isDST = 1 THEN
54 | Out.String(" (DST)");
55 | END;
56 | i := ABS(ct.utcOffset);
57 | IF (i >= 0) & (i <= 86400) THEN
58 | hours := (i DIV 3600) MOD 60;
59 | minutes := (i MOD 3600);
60 | Out.String(" UTC");
61 | IF (ct.utcOffset >= 0) THEN
62 | Out.String("+");
63 | IF hours < 10 THEN
64 | Out.String("0");
65 | END;
66 | Out.Int(hours, 1);
67 | ELSE
68 | Out.String("-");
69 | IF (ABS(hours) < 10) THEN
70 | Out.String("0");
71 | END;
72 | Out.Int(ABS(hours), 1);
73 | END;
74 | IF minutes < 10 THEN
75 | Out.String("0"); Out.Int(minutes, 1);
76 | ELSE
77 | Out.Int(minutes, 2);
78 | END;
79 | END;
80 | Out.Ln();
81 | END DisplayClock;
82 |
83 | PROCEDURE TestClockAndTime*() : BOOLEAN;
84 | VAR test : BOOLEAN; t1 : Clock.Clock;
85 | BEGIN test := TRUE;
86 | NEW(t1);
87 | Clock.Get(t1);
88 | T.ExpectedBool(TRUE, (t1.year > 2020), "Expected t1.year > 2020", test);
89 | T.ExpectedBool(TRUE, ((t1.month >= 1) & (t1.month <= 12)), "Expected (t1.month >= 1) & (t1.mongth <= 12)", test);
90 | T.ExpectedBool(TRUE, (t1.day > 0), "Expected t1.day > 0", test);
91 | T.ExpectedBool(TRUE, (t1.hour > -1), "Expected t1.hour > 0", test);
92 | T.ExpectedBool(TRUE, (t1.minute > -1), "Expected t1.minute > 0", test);
93 | T.ExpectedBool(TRUE, (t1.second > -1), "Expected t1.second > 0", test);
94 |
95 | RETURN test
96 | END TestClockAndTime;
97 |
98 | PROCEDURE TestClockSet*() : BOOLEAN;
99 | VAR test : BOOLEAN; ct, tt, sc : Clock.Clock; ok : BOOLEAN;
100 | uname, os : ARRAY 256 OF CHAR; res : INTEGER;
101 | BEGIN test := TRUE;
102 | Env.Get("OS", os, res);
103 | Env.Get("SUDO_USER", uname, res);
104 | IF os = "Linux" THEN
105 | Out.String("Skipping TestClockSet(), Clock.Set() is not permitted under Linux"); Out.Ln();
106 | ELSIF (Strings.Length(uname) = 0) & (os = "Darwin") THEN
107 | Out.String(" Skipping TestSet(), Clock.Set() requires admin privilleges for Darwin (macOS)");Out.Ln();
108 | Out.String(" You can try rerunning tests with");Out.Ln();
109 | Out.Ln(); Out.String(" sudo make test");Out.Ln();Out.Ln();
110 | ELSE
111 | NEW(ct); NEW(tt); NEW(sc);
112 | Clock.Get(ct);
113 | Out.String(" Current clock: ");DisplayClock(ct);
114 | tt.year := ct.year + 1;
115 | tt.month := ct.month + 1;
116 | IF tt.month > 12 THEN
117 | INC(tt.year);
118 | ct.month := 1;
119 | END;
120 | tt.day := ct.day;
121 | tt.hour := ct.hour;
122 | tt.minute := ct.minute;
123 | tt.second := ct.second;
124 | tt.isDST := ct.isDST;
125 | tt.utcOffset := ct.utcOffset;
126 | Clock.Get(sc); (* Save the time to reset later *)
127 | Clock.Set(tt, ok);
128 | T.ExpectedBool(TRUE, ok, "Clock.Set(tt, ok) failed", test);
129 | IF ok THEN
130 | Out.String(" New clock: ");DisplayClock(tt);
131 |
132 | T.ExpectedBool(TRUE, ok, "Clock.Set(tt, ok) ", test);
133 |
134 | T.ExpectedBool(TRUE, (Clock.clock.year = tt.year), "new time year", test);
135 | T.ExpectedBool(TRUE, (Clock.clock.month = tt.month), "new time month", test);
136 | T.ExpectedBool(TRUE, (Clock.clock.day = tt.day), "new time day", test);
137 | T.ExpectedBool(TRUE, (Clock.clock.hour = tt.hour), "new time hour", test);
138 | T.ExpectedBool(TRUE, (Clock.clock.minute = tt.minute), "new time minute", test);
139 | T.ExpectedBool(TRUE, (Clock.clock.second = tt.second), "new time second", test);
140 | (* Reset the clock *)
141 | Clock.Set(sc, ok);
142 | Clock.Get(ct);
143 | Out.String(" Reset clock: "); DisplayClock(ct);
144 | END;
145 | END;
146 |
147 | RETURN test
148 | END TestClockSet;
149 |
150 | BEGIN
151 | T.Init(ts, "Test Clock");
152 | T.Add(ts, TestClockAndTime);
153 | T.Add(ts, TestClockSet);
154 | ASSERT(T.Run(ts));
155 | END ClockTest.
156 |
157 |
158 |
--------------------------------------------------------------------------------
/obnc/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Simple Makefile for compiling Oberon-7 programs using OBNC.
3 | # Set the list of executables in PROG_NAMES. The rest can probably
4 | # stay as is if all modules are in the same directory.
5 | #
6 | VERSION = $(shell if [ -f VERSION ]; then cat VERSION; else echo "0.0.0"; fi)
7 | BUILD_NAME = Artemis-Modules-NP
8 | PROG_NAMES =
9 | TEST_NAMES = ClockTest UnixTest
10 | MODULES = $(shell ls *.obn)
11 | DOCS= README.md ../LICENSE ../INSTALL.txt
12 |
13 | # Defaults
14 | #OC = obnc
15 | OC = env OBNC_IMPORT_PATH=".:../" obnc
16 | OS = $(shell uname)
17 | ARCH = $(shell uname -m)
18 | PREFIX = /usr/local
19 | LIBDIR = $(PREFIX)/lib
20 | BINDIR = $(PREFIX)/bin
21 |
22 | # Overrides
23 | oc =
24 | ifneq ($(oc), )
25 | OC = $(oc)
26 | endif
27 |
28 | os =
29 | ifneq ($(os), )
30 | OS = $(os)
31 | endif
32 |
33 | arch =
34 | ifneq ($(arch), )
35 | ARCH = $(arch)
36 | endif
37 |
38 | prefix =
39 | ifneq ($(prefix), )
40 | PREFIX = $(prefix)
41 | LIBDIR = $(prefix)/lib
42 | BINDIR = $(prefix)/bin
43 | endif
44 |
45 | libdir =
46 | ifneq ($(libdir), )
47 | LIBDIR = $(libdir)
48 | endif
49 |
50 | bindir =
51 | ifneq ($(bindir), )
52 | BINDIR = $(bindir)
53 | endif
54 |
55 | all: $(PROG_NAMES)
56 |
57 | $(PROG_NAMES): $(MODULES)
58 | $(OC) -o $@ $@.obn
59 |
60 | $(TEST_NAMES): $(MODULE)
61 | $(OC) -o $@ $@.obn
62 |
63 | full_test: .FORCE clean test
64 |
65 | test: $(TEST_NAMES)
66 | @for FNAME in $(TEST_NAMES); do env OS=$(OS) ARCH=$(ARCH) ./$$FNAME; done
67 |
68 | docs: .FORCE
69 | obncdoc
70 |
71 | clean: .FORCE
72 | @if [ -d dist ]; then rm -fR dist; fi
73 | @if [ -d .obnc ]; then rm -fR .obnc; fi
74 | @if [ -d ../ports/po2013/.obnc ]; then rm -fR ../ports/po2013/.obnc; fi
75 | @for FNAME in $(PROG_NAMES); do if [ -f $$FNAME ]; then rm $$FNAME; fi; done
76 | @for FNAME in $(TEST_NAMES); do if [ -f $$FNAME ]; then rm $$FNAME; fi; done
77 |
78 | install: $(PROG_NAMES)
79 | @if [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi
80 | @for FNAME in $(PROG_NAMES); do cp $$FNAME $(BINDIR)/; done
81 |
82 | uninstall: .FORCE
83 | @for FNAME in $(PROG_NAMES); do if [ -f "$(BINDIR)/$$FNAME" ]; then rm "$(BINDIR)/$$FNAME"; fi; done
84 |
85 | dist: $(PROG_NAMES)
86 | @if [ ! -d dist/$(BUILD_NAME) ]; then mkdir -p dist/$(BUILD_NAME); fi
87 | @if [ ! -d dist/$(BUILD_NAME)/bin ]; then mkdir -p dist/$(BUILD_NAME)/bin; fi
88 | @for FNAME in $(PROG_NAMES); do cp -p $$FNAME dist/$(BUILD_NAME)/bin/; done
89 | @for FNAME in $(MODULES) $(DOCS) Makefile; do cp -p $$FNAME dist/$(BUILD_NAME)/;done
90 | @cd dist && zip -r $(BUILD_NAME)-$(OS)-$(ARCH).zip $(BUILD_NAME)/*
91 |
92 | .FORCE:
93 |
--------------------------------------------------------------------------------
/obnc/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: OBNC modules
3 | ---
4 |
5 | OBNC - Not portable
6 | ===================
7 |
8 | This directory contains non-portable Oberon-7 modules intended
9 | for the POSIX environment and compiled with the
10 | [OBNC](http://miasap.se/obnc/) compiler.
11 |
12 | - [artUnix.obn](artUnix.obn), [artUnix.c](artUnix.c), [UnixTest.obn](UnixTest.obn)
13 | - [artClock.obn](artClock.obn), [artClock.c](artClock.c), [ClockTest.obn](ClockTest.obn)
14 |
15 |
16 |
--------------------------------------------------------------------------------
/obnc/UnixTest.obn:
--------------------------------------------------------------------------------
1 | (** UnixTest provided module tests for Unix module.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE UnixTest;
10 |
11 | IMPORT T := Tests, Unix := artUnix, Out, Env := extEnv;
12 |
13 | VAR
14 | ts : T.TestSet;
15 | successes, errors : INTEGER;
16 |
17 | PROCEDURE TestKernelName() : BOOLEAN;
18 | VAR test: BOOLEAN; expected, got : ARRAY 256 OF CHAR; res : INTEGER;
19 | BEGIN test := TRUE;
20 | Env.Get("OS", expected, res);
21 | IF expected[0] = 0X THEN
22 | Out.String("Skipping TestKernelName(), missing environment"); Out.Ln();
23 | Out.String("variable OS (aka kernel name) needed to verify Unix.Kernel()"); Out.Ln();
24 | ELSE
25 | Unix.KernelName(got);
26 | T.ExpectedString(expected, got, "Unix.KernelName(s) should match env. OS", test);
27 | END;
28 | RETURN test
29 | END TestKernelName;
30 |
31 | PROCEDURE TestArchitectureName() : BOOLEAN;
32 | VAR test: BOOLEAN; expected, got : ARRAY 24 OF CHAR; res : INTEGER;
33 | BEGIN test := TRUE;
34 | Env.Get("ARCH", expected, res);
35 | IF expected[0] = 0X THEN
36 | Out.String("Skipping TestArchitectureName(), missing environment"); Out.Ln();
37 | Out.String("variable ARCH needed to verify Unix.Architecture()"); Out.Ln();
38 | ELSE
39 | Unix.Architecture(got);
40 | T.ExpectedString(expected, got, "Unix.Architecture(s) should match env. OS", test);
41 | END;
42 | RETURN test
43 | END TestArchitectureName;
44 |
45 | PROCEDURE TestExit() : BOOLEAN;
46 | BEGIN
47 | Unix.Exit(0);
48 | RETURN FALSE
49 | END TestExit;
50 |
51 | BEGIN
52 | T.Init(ts, "Test Unix");
53 | T.Add(ts, TestKernelName);
54 | T.Add(ts, TestArchitectureName);
55 | ASSERT(T.Run(ts));
56 | (* Testing Unix.Exit(1) is tricky *)
57 | successes := 0; errors := 0;
58 | IF ~ TestExit() THEN
59 | Out.String("Test of Unix.Exit(), failed"); Out.Ln();
60 | ASSERT(FALSE);
61 | END;
62 | END UnixTest.
63 |
--------------------------------------------------------------------------------
/obnc/artUnix.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Unix.c provided an interface to C level libraries needed by Unix.Mod.
3 | *
4 | * Copyright (C) 2021 R. S. Doiel
5 | *
6 | * Released under The 3-Clause BSD License.
7 | * See https://opensource.org/licenses/BSD-3-Clause
8 | *
9 | */
10 |
11 | #include ".obnc/artUnix.h"
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #define OBERON_SOURCE_FILENAME "artUnix.obn"
18 |
19 | static char kernel_[24], architecture_[24];
20 |
21 | static void uname_(char opt_, char dest_[], OBNC_INTEGER dest_len)
22 | {
23 | FILE *in;
24 | char ch;
25 | int i;
26 | char cmd[9];
27 |
28 | /* Setup our POSIX command */
29 | cmd[0] = 'u'; cmd[1] = 'n'; cmd[2] = 'a';
30 | cmd[3] = 'm'; cmd[4] = 'e'; cmd[5] = ' ';
31 | cmd[6] = '-'; cmd[7] = opt_;
32 | cmd[8] = '\x00';
33 | /* open a process and read stdout from a uname call */
34 | in = popen(cmd, "r");
35 | if (!in) return;
36 | /* for each character output by uname copy into our dest string */
37 | i = 0; dest_[i] = '\x00';
38 | while ( ((ch = fgetc(in)) != EOF) && (i < (dest_len - 1) ) ) {
39 | if ((ch == '\n') || (ch == '\r')) {
40 | dest_[i] = '\x00';
41 | break;
42 | } else {
43 | dest_[i] = ch;
44 | }
45 | i = i + 1;
46 | dest_[i] = '\x00'; /* add a trailing NULL CHAR */
47 | }
48 | /* close our pipe and done */
49 | pclose(in);
50 | }
51 |
52 |
53 | void artUnix__Exit_(OBNC_INTEGER exitCode_)
54 | {
55 | exit(exitCode_);
56 | }
57 |
58 |
59 | static OBNC_INTEGER minimum_(OBNC_INTEGER a_, OBNC_INTEGER b_)
60 | {
61 | OBNC_INTEGER res_;
62 |
63 | if (a_ < b_) {
64 | res_ = a_;
65 | }
66 | else {
67 | res_ = b_;
68 | }
69 | return res_;
70 | }
71 |
72 |
73 | static void copyChars_(const char source_[], OBNC_INTEGER source_len, char dest_[], OBNC_INTEGER dest_len)
74 | {
75 | OBNC_INTEGER i_, l_;
76 |
77 | l_ = minimum_(source_len, dest_len) - 2;
78 | if (l_ < 1) {
79 | l_ = 0;
80 | }
81 | i_ = 0;
82 | dest_[OBNC_IT(i_, dest_len, 49)] = '\x00';
83 | while ((i_ < l_) && (source_[OBNC_IT(i_, source_len, 50)] != '\x00')) {
84 | dest_[OBNC_IT(i_, dest_len, 51)] = source_[OBNC_IT(i_, source_len, 51)];
85 | OBNC_INC(i_);
86 | }
87 | dest_[OBNC_IT(i_, dest_len, 54)] = '\x00';
88 | OBNC_DEC(i_);
89 | if ((dest_[OBNC_IT(i_, dest_len, 55)] == '\x10') || (dest_[OBNC_IT(i_, dest_len, 55)] == '\x13')) {
90 | dest_[OBNC_IT(i_, dest_len, 56)] = '\x00';
91 | }
92 | }
93 |
94 |
95 | void artUnix__KernelName_(char dest_[], OBNC_INTEGER dest_len)
96 | {
97 |
98 | if (kernel_[0] == '\x00') {
99 | uname_('s', kernel_, 24);
100 | }
101 | copyChars_(kernel_, 24, dest_, dest_len);
102 | }
103 |
104 |
105 | void artUnix__Architecture_(char dest_[], OBNC_INTEGER dest_len)
106 | {
107 |
108 | if (architecture_[0] == '\x00') {
109 | uname_('m', architecture_, 24);
110 | }
111 | copyChars_(architecture_, 24, dest_, dest_len);
112 | }
113 |
114 |
115 | void artUnix__Init(void)
116 | {
117 | static int initialized = 0;
118 |
119 | if (! initialized) {
120 | kernel_[0] = '\x00';
121 | architecture_[0] = '\x00';
122 | initialized = 1;
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/obnc/artUnix.obn:
--------------------------------------------------------------------------------
1 | (** Unix provides asscess to some POSIX C based libraries and services.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE artUnix;
10 |
11 | VAR
12 | kernel, architecture : ARRAY 24 OF CHAR;
13 |
14 |
15 | (*
16 | * C implemented procedures
17 | * ------------------------
18 | *)
19 |
20 | (* uname does a popen call to `uname` *)
21 | PROCEDURE uname(opt : CHAR; VAR dest : ARRAY OF CHAR);
22 | BEGIN
23 | END uname;
24 |
25 | (** Exit performs a system exit with error number *)
26 | PROCEDURE Exit*(exitCode : INTEGER);
27 | BEGIN
28 | END Exit;
29 |
30 | (*
31 | * Oberon-7 implemented procedures
32 | * -------------------------------
33 | *)
34 |
35 | (* mininum returns the lesser of two integer *)
36 | PROCEDURE minimum(a, b : INTEGER) : INTEGER;
37 | VAR res : INTEGER;
38 | BEGIN
39 | IF a < b THEN res := a; ELSE res := b; END;
40 | RETURN res
41 | END minimum;
42 |
43 | (* copy an array of chars, truncate dest if needed *)
44 | PROCEDURE copyChars(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR);
45 | VAR i, l : INTEGER;
46 | BEGIN
47 | l := minimum(LEN(source), LEN(dest)) - 2; (* leave room of 0X *)
48 | IF l < 1 THEN l := 0 END;
49 | i := 0; dest[i] := 0X;
50 | WHILE (i < l) & (source[i] # 0X) DO
51 | dest[i] := source[i];
52 | INC(i);
53 | END;
54 | dest[i] := 0X; DEC(i);
55 | IF (dest[i] = 10X) OR (dest[i] = 13X) THEN
56 | dest[i] := 0X;
57 | END;
58 | END copyChars;
59 |
60 |
61 | (** KernelName attempts a system exec call to `uname -s` to determine the
62 | Kernel name, e.g. Linux, Darwin, Windows *)
63 | PROCEDURE KernelName*(VAR dest : ARRAY OF CHAR);
64 | BEGIN
65 | IF kernel[0] = 0X THEN
66 | uname("s", kernel);
67 | END;
68 | copyChars(kernel, dest);
69 | END KernelName;
70 |
71 | (** Architecture attempts a system exec call to `uname -m` to determine
72 | the machine archtecture, e.g. i386, x86_64 *)
73 | PROCEDURE Architecture*(VAR dest : ARRAY OF CHAR);
74 | BEGIN
75 | IF architecture[0] = 0X THEN
76 | uname("m", architecture);
77 | END;
78 | copyChars(architecture, dest);
79 | END Architecture;
80 |
81 |
82 | BEGIN kernel[0] := 0X; architecture[0] := 0X;
83 | END artUnix.
84 |
--------------------------------------------------------------------------------
/obnc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Project Artemis
5 |
6 |
7 |
8 |
9 |
10 |
11 | OBNC modules
12 |
13 |
14 |
15 | OBNC - Not portable
16 |
17 |
18 | This directory contains non-portable Oberon-7 modules intended for the POSIX environment and compiled with the OBNC compiler.
19 |
28 |
29 |
60 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/obnc/nav.md:
--------------------------------------------------------------------------------
1 |
2 | + [Home](/)
3 | + [README](../)
4 | + [LICENSE](../license.html)
5 | + [INSTALL](../install.html)
6 | + [OBNC Modules](./)
7 | + [Obc-3 Modules](../oxford/)
8 | + [Ofront+ Modules](../ofrontplus/)
9 | + [development notes](../development-notes.html)
10 | + [Github](https://github.com/rsdoiel/Artemis)
11 |
12 |
--------------------------------------------------------------------------------
/obnc/ocat.obn:
--------------------------------------------------------------------------------
1 | (** ocat.Mod is inspired by ocat command found in Joseph Templ's in Ofront.
2 |
3 | Copyright (C) 2021 R. S. Doiel This Source Code Form is subject to the terms of the Mozilla PublicLicense, v. 2.0. If a copy of the MPL was not distributed with thisfile, You can obtain one at http://mozilla.org/MPL/2.0/. *)
4 | MODULE ocat;
5 |
6 | (** NOTE: OCat is a POSIX command line program. *)
7 |
8 | IMPORT Args := extArgs, Out, Files, Texts := artTextsCmdLn, Chars, Convert := extConvert, Err := extErr;
9 |
10 | CONST
11 | TAB = 9X;
12 | LF = 10X;
13 | CR = 13X;
14 | SPACE = 20X;
15 | TILDE = "~";
16 |
17 | VAR
18 | tabs : ARRAY 128 OF CHAR;
19 |
20 | (* Usage displays a help screen *)
21 | PROCEDURE Usage();
22 | BEGIN
23 | Out.String("USAGE OCat [OPTION] FILENAME [[OPTION] FILENAME ...]"); Out.Ln();
24 | Out.Ln();
25 | Out.String("Read Oberon Texts and write them to standard out");Out.Ln();
26 | Out.Ln();
27 | Out.String("OPTIONS"); Out.Ln();
28 | Out.Ln();
29 | Out.String(" -h, --help"); Out.Char(Chars.TAB); Out.String("this help document"); Out.Ln();Out.Ln();
30 | Out.String(" -t, --tabs"); Out.Char(Chars.TAB); Out.String("Allow tab characters"); Out.Ln();
31 | Out.String(" --spaces"); Out.Char(Chars.TAB); Out.String("Convert tab characters to four spaces"); Out.Ln();
32 | Out.String(" --spaces=X"); Out.Char(Chars.TAB); Out.String("Convert tab characters to X number of spaces"); Out.Ln();
33 | Out.Ln();
34 | END Usage;
35 |
36 | (* Convert Oberon texts to POSIX friendly standard out *)
37 | PROCEDURE Cat(filename : ARRAY OF CHAR);
38 | VAR T : Texts.Text; R : Texts.Reader; ch : CHAR; skipLF : BOOLEAN;
39 | BEGIN
40 | IF Files.Old(filename) # NIL THEN
41 | Texts.Open(T, filename);
42 | Texts.OpenReader(R, T, 0);
43 | (* FIXME: Need to handle case where this is an Oberon file
44 | and skip beyond the font settings to start of Text *)
45 | Texts.Read(R, ch);
46 | WHILE ~ R.eot DO
47 | IF (ch >= SPACE) & (ch <= TILDE) THEN
48 | Out.Char(ch);
49 | skipLF := FALSE;
50 | ELSIF ch = TAB THEN
51 | Out.String(tabs);
52 | skipLF := FALSE;
53 | ELSIF ch = LF THEN
54 | IF skipLF = TRUE THEN
55 | skipLF := FALSE;
56 | ELSE
57 | Out.Ln();
58 | END;
59 | ELSIF ch = CR THEN
60 | Out.Ln();
61 | skipLF := TRUE;
62 | END;
63 | Texts.Read(R, ch);
64 | END;
65 | Out.Ln();
66 | ELSE
67 | Err.String("Can't open ");Err.String(filename);Err.Ln();
68 | END;
69 | END Cat;
70 |
71 | (* Apply process POSIX command line parameters and envoke Cat.*)
72 | PROCEDURE Apply();
73 | VAR i, j, k, res : INTEGER; arg : ARRAY 1024 OF CHAR; ok : BOOLEAN;
74 | BEGIN
75 | IF Args.count = 0 THEN
76 | Out.String("Try OCat --help for explanation of how this works"); Out.Ln();
77 | ELSE
78 | i := 0;
79 | WHILE i < Args.count DO
80 | Args.Get(i, arg, res);
81 | IF Chars.Equal("-h", arg) OR Chars.Equal("--help", arg) THEN
82 | Usage();
83 | ELSIF Chars.Equal("-t", arg) OR Chars.StartsWith("--tab", arg) THEN
84 | tabs[0] := Chars.TAB; tabs[1] := 0X;
85 | ELSIF Chars.StartsWith("--spaces=", arg) THEN
86 | Chars.TrimPrefix("--spaces=", arg);
87 | Convert.StringToInt(arg, k, ok);
88 | Chars.Clear(tabs);
89 | j := 0;
90 | WHILE j < k DO tabs[j] := " "; INC(j) END;
91 | tabs[j] := 0X; (* Terminate the tabs array of char *)
92 | ELSIF Chars.Equal("--spaces", arg) THEN
93 | Chars.Clear(tabs);
94 | tabs := " ";
95 | ELSE
96 | Cat(arg);
97 | END;
98 | INC(i);
99 | END;
100 | END;
101 | END Apply;
102 |
103 | BEGIN tabs[0] := Chars.TAB; tabs[1] := 0X; Apply();
104 | END ocat.
105 |
106 | The POSIX command line version is built with
107 |
108 | obnc -o ocat ocat.Mod
109 |
110 |
--------------------------------------------------------------------------------
/obncdoc/CharsTest.def:
--------------------------------------------------------------------------------
1 | (* CharsTest.Mod - test procedure the Chars.Mod.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 | *)
8 | DEFINITION CharsTest;
9 | END CharsTest.
10 |
--------------------------------------------------------------------------------
/obncdoc/DStringsTest.def:
--------------------------------------------------------------------------------
1 | (* DStringTest.Mod implements tests for the DStrings Module.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 | *)
8 | DEFINITION DStringsTest;
9 | END DStringsTest.
10 |
--------------------------------------------------------------------------------
/obncdoc/JSON.def:
--------------------------------------------------------------------------------
1 | DEFINITION JSON;
2 |
3 | CONST
4 | NullType = 0;
5 | BooleanType = 1;
6 | NumberType = 2;
7 | StringType = 3;
8 | ArrayType = 4;
9 | ObjectType = 5;
10 |
11 | TYPE
12 | Self = RECORD END;
13 |
14 | Boolean = POINTER TO BooleanDesc;
15 |
16 | Number = POINTER TO NumberDesc;
17 | NumberDesc = RECORD (Self) END;
18 |
19 | String = POINTER TO StringDesc;
20 | StringDesc = RECORD (Self) END;
21 |
22 | List = POINTER TO ListDesc;
23 | ListDesc = RECORD (Self) END;
24 |
25 | Object = POINTER TO ObjectDesc;
26 | ObjectDesc = RECORD (Self) END;
27 |
28 | PROCEDURE IsNull(o : Self) : BOOLEAN;
29 |
30 | PROCEDURE IsType(o : Self; checkType : INTEGER) : BOOLEAN;
31 |
32 | PROCEDURE TypeName(o : Self; VAR typeName : ARRAY OF CHAR);
33 |
34 | END JSON.
35 |
--------------------------------------------------------------------------------
/obncdoc/JSONTest.def:
--------------------------------------------------------------------------------
1 | DEFINITION JSONTest;
2 | END JSONTest.
3 |
--------------------------------------------------------------------------------
/obncdoc/Obn2.def:
--------------------------------------------------------------------------------
1 | (* Obn2.Mod is a module to help port Oberon-2 modules to Oberon-7.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | DEFINITION Obn2;
10 |
11 | (* ASH provides the Oberon-2 built-in ASH functionilty for
12 | Oberon-7. See description of providing ASH in documentation
13 | on Oberon-7 for positive and negative values *)
14 | PROCEDURE ASH(x, n : INTEGER) : INTEGER;
15 |
16 | (* MAX returns the maximum of two integers *)
17 | PROCEDURE MAX(x, y : INTEGER) : INTEGER;
18 |
19 | (* MIN provides the minimum of two integers *)
20 | PROCEDURE MIN(x, y : INTEGER) : INTEGER;
21 |
22 | (* ENTIER is a wrapper around FLOOR, you should really just use
23 | FLOOR. *)
24 | PROCEDURE ENTIER(r : REAL) : INTEGER;
25 |
26 | (* HALT is a wrapper around ASSERT(FALSE), you should just replace
27 | ASSERT(FALSE) *)
28 | PROCEDURE HALT();
29 |
30 | (* ROT is a wrapper around ROR, you should just replace ROT with ROR *)
31 | PROCEDURE ROT(x, n : INTEGER) : INTEGER;
32 |
33 | END Obn2.
34 |
--------------------------------------------------------------------------------
/obncdoc/Obn2Test.def:
--------------------------------------------------------------------------------
1 | (* Obn2Test modules provides testing for Obn2 module.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | DEFINITION Obn2Test;
10 | END Obn2Test.
11 |
--------------------------------------------------------------------------------
/obncdoc/Path.def:
--------------------------------------------------------------------------------
1 | DEFINITION Path;
2 |
3 | CONST
4 | (* Maximum path length *)
5 | MAXLENGTH = 1024;
6 |
7 | VAR
8 | delimiter : CHAR;
9 | extDelimiter : CHAR;
10 |
11 | (* SetDelimiter used for parsing paths *)
12 | PROCEDURE SetDelimiter(c : CHAR);
13 |
14 | (* SetExtDelimiter used for delimiting a filename extension, e.g. .txt *)
15 | PROCEDURE SetExtDelimiter(c : CHAR);
16 |
17 | (* Prepend insert the path fragement into the path adding
18 | the delimiter appropriately.
19 |
20 | NOTE: Prepend is limited by the temporary path used in assembling data.
21 | If the length of the prefix and path is too long then success will be
22 | set to FALSE and path will remain unchanged. *)
23 | PROCEDURE Prepend(prefix : ARRAY OF CHAR; VAR path : ARRAY OF CHAR; VAR success : BOOLEAN);
24 |
25 | (* Append appends the path fragment onto the path adding a delimiter appropriately.
26 |
27 | NOTE: The size of path limits how long the suffix can be. If it is too long then
28 | path remains unchanged and success is set to FALSE. *)
29 | PROCEDURE Append(suffix : ARRAY OF CHAR; VAR path : ARRAY OF CHAR; VAR success : BOOLEAN);
30 |
31 | (* Basename scans source and writes the last path segment to dest based on the path delimiter set *)
32 | PROCEDURE Basename(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR; success : BOOLEAN);
33 |
34 | (* Dirname scans source and writes the all but the last path segment to dest based on the path delimiter set *)
35 | PROCEDURE Dirname(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR; success : BOOLEAN);
36 |
37 | (* Ext scans source and writes the file extension to dest based on the extDelimiter set *)
38 | PROCEDURE Ext(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR; success : BOOLEAN);
39 |
40 | END Path.
41 |
--------------------------------------------------------------------------------
/obncdoc/PathLists.def:
--------------------------------------------------------------------------------
1 | (* PathLists is a module for working with a delimited list of paths. *)
2 | DEFINITION PathLists;
3 | (* Merge operations *)
4 | TYPE
5 | PathList = POINTER TO PathListDesc;
6 | PathListDesc = RECORD END;
7 |
8 | (* Length returns the length of the PathList *)
9 | PROCEDURE Length(pathList : PathList) : INTEGER;
10 |
11 | (* Find takes a path and searches a path list return -1 if not found
12 | or the position where it was found (zero indexed) *)
13 | PROCEDURE Find(path : ARRAY OF CHAR; pathList : PathList) : INTEGER;
14 |
15 | (* Prepend takes a path and a path list and prepends path to path list updating
16 | path list. *)
17 | PROCEDURE Prepend(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN);
18 |
19 | (* Append takes a path and path list and adds the path to the end of path list *)
20 | PROCEDURE Append(path: ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN);
21 |
22 | (* Cut takes a path and a path list and removes the path element from path list. *)
23 | PROCEDURE Cut(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN);
24 |
25 | (* SetDelimiter sets the delimiter to be used for encoding and decoding paths *)
26 |
27 | (* Encode takes a PathList and encodes it into pathListString using the delimiter provided *)
28 | PROCEDURE Encode(pathList : PathList; delimiter: CHAR; VAR pathListString : ARRAY OF CHAR; VAR success : BOOLEAN);
29 |
30 | (* Decode takes a path list string and decodes it into a PathList data structure *)
31 | PROCEDURE Decode(pathListString : ARRAY OF CHAR; VAR pathList : PathList; success : BOOLEAN);
32 |
33 | (* Apply takes a path, an operation and a path list string. It applies the operation
34 | using the path and pathList updating pathList. Return TRUE of successful,
35 | FALSE otherwise. *)
36 | PROCEDURE Apply(path: ARRAY OF CHAR; operation: INTEGER; VAR pathListString: ARRAY OF CHAR): BOOLEAN;
37 |
38 | END PathLists.
39 |
--------------------------------------------------------------------------------
/obncdoc/PathListsTest.def:
--------------------------------------------------------------------------------
1 | DEFINITION PathListsTest;
2 | END PathListsTest.
3 |
--------------------------------------------------------------------------------
/obncdoc/PathTest.def:
--------------------------------------------------------------------------------
1 | DEFINITION PathTest;
2 | END PathTest.
3 |
--------------------------------------------------------------------------------
/obncdoc/Scanner.def:
--------------------------------------------------------------------------------
1 | DEFINITION Scanner;
2 |
3 | CONST
4 | ERROR = 0;
5 | OK = 1;
6 | EOS = 2;
7 |
8 | EOT = 0X;
9 | TAB = 9X;
10 | LF = 10X;
11 | FF = 11X;
12 | CR = 13X;
13 | SPACE = 32X;
14 | DQUOTE = 34X;
15 | SQUOTE = 39X;
16 | SLASH = 47X;
17 | BSLASH = 92X;
18 |
19 | (* Character constants *)
20 | DASH = "-";
21 | LODASH = "_";
22 | CARET = "^";
23 | TILDE = "~";
24 |
25 | TYPE
26 | Scanner = POINTER TO ScannerDesc;
27 | ScannerDesc = RECORD
28 | Pos: INTEGER
29 | END;
30 |
31 | PROCEDURE Init(VAR scanner: Scanner; delimiter: CHAR; startString: CHAR; endString: CHAR; Escape: CHAR);
32 |
33 | PROCEDURE ScanChars(VAR scanner: Scanner; src : ARRAY OF CHAR; VAR value: ARRAY OF CHAR; VAR OK: BOOLEAN);
34 |
35 | END Scanner.
36 |
--------------------------------------------------------------------------------
/obncdoc/ScannerTest.def:
--------------------------------------------------------------------------------
1 | DEFINITION ScannerTest;
2 | END ScannerTest.
3 |
--------------------------------------------------------------------------------
/obncdoc/Tests.def:
--------------------------------------------------------------------------------
1 | (* Tests.Mod - A module providing simple test support for Oberon-7.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | DEFINITION Tests; (* portable *)
10 | CONST
11 | MAXSTR = 1024;
12 |
13 | TYPE
14 | (* TestProc is the signature of a test procedure. It is simple.
15 | if a test successeds it returns true, otherwise it returns false.
16 | The procedure Test counts the number of test run and results
17 | updating variable parameters of success and errors. In turn
18 | these are passed to Summarize to return a summary report. *)
19 | TestProc = PROCEDURE () : BOOLEAN;
20 |
21 | TestSet = POINTER TO TestSetDesc;
22 | TestSetDesc = RECORD
23 | title : ARRAY MAXSTR OF CHAR;
24 | fn : TestProc;
25 | next : TestSet
26 | END;
27 |
28 | (* DisplayString display quoted ARRAY OF CHAR with prefixed by msg *)
29 | PROCEDURE DisplayString(msg: ARRAY OF CHAR; source : ARRAY OF CHAR);
30 |
31 | (* ExpectedInt compares to int display msg on error and updates test to
32 | FALSE if they don'y match *)
33 | PROCEDURE ExpectedInt(expected, got : INTEGER; msg : ARRAY OF CHAR; VAR test : BOOLEAN);
34 |
35 | (* ExpectedReal compares to REAL display msg on error and updates test to
36 | FALSE if they don'y match *)
37 | PROCEDURE ExpectedReal(expected, got : REAL; msg : ARRAY OF CHAR; VAR test : BOOLEAN);
38 |
39 | (* ExpectedString compare two ARRAY OF CHAR, set test to FALSE
40 | if they don't match and display msg *)
41 | PROCEDURE ExpectedString(s1, s2, msg : ARRAY OF CHAR; VAR test : BOOLEAN);
42 |
43 | (* ExpectedChar compare two CHAR, set test to FALSE if they don't
44 | match and display msg *)
45 | PROCEDURE ExpectedChar(expected, got : CHAR; msg : ARRAY OF CHAR; VAR test : BOOLEAN);
46 |
47 | (* ExpectedBool compare to BOOLEAN values, set test to FALSE if they
48 | don't match and display message *)
49 | PROCEDURE ExpectedBool(expected, got : BOOLEAN; msg : ARRAY OF CHAR; VAR test : BOOLEAN);
50 |
51 | (* ExpectedBytes compares the first N values to two array of byte *)
52 | PROCEDURE ExpectedBytes(expected, got : ARRAY OF BYTE; n : INTEGER; msg : ARRAY OF CHAR; VAR test: BOOLEAN);
53 |
54 | (*ExpectedSet compares two sets, display message if they don't match and
55 | set the value of test to FALSE *)
56 | PROCEDURE ExpectedSet(expected, got : SET; msg : ARRAY OF CHAR; VAR test : BOOLEAN);
57 |
58 | (* ShowTitle displays the title in standard out and underlined with '=' *)
59 | PROCEDURE ShowTitle(s : ARRAY OF CHAR);
60 |
61 | (* Test -- run the test method and update the success and error variables
62 | provided. *)
63 | PROCEDURE Test(fn : TestProc; VAR success : INTEGER; VAR errors : INTEGER);
64 |
65 | (* Summarize -- sumarize the results using the test title, success
66 | and error counts. *)
67 | PROCEDURE Summarize(title : ARRAY OF CHAR; successes, errors : INTEGER);
68 |
69 | (* New initializes a new TestSet with a title *)
70 | PROCEDURE Init(VAR ts: TestSet; title : ARRAY OF CHAR);
71 |
72 | PROCEDURE Add(VAR ts : TestSet; fn : TestProc);
73 |
74 | PROCEDURE Run(ts : TestSet) : BOOLEAN;
75 |
76 | END Tests.
77 |
--------------------------------------------------------------------------------
/obncdoc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Index of Artemis
7 |
8 |
9 |
10 |
22 | Learn Ofront+ command line options and how to handle pathing
23 |
24 |
25 | See “OBERON” environment variable
26 |
27 |
28 |
29 |
30 | Create a general purpose Makefile for compiling Artemis/Ofront+ projects
31 |
32 |
33 |
34 |
65 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/ofrontplus/TODO.md:
--------------------------------------------------------------------------------
1 | To do
2 | =====
3 |
4 | Next
5 | ----
6 |
7 | - [ ] Learn Ofront+ command line options and how to handle pathing
8 | - See "OBERON" environment variable
9 | - [ ] Create a general purpose Makefile for compiling Artemis/Ofront+ projects
10 |
11 |
--------------------------------------------------------------------------------
/ofrontplus/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Project Artemis
5 |
6 |
7 |
8 |
9 |
10 |
11 | Ofront+ modules
12 |
13 |
14 |
15 | Ofront+ - Not portable
16 |
17 |
18 | In this directory are Artemis modules for Ofront+. This is currently a placeholder but will become populated as the non-portable Artemis modules are completed. The non-portable modules use C code integration. It is a counter part to the obnc and oxford directories.
19 |
20 |
21 | Modules naming
22 |
23 |
24 | Where modules are not canonical to Artemis the modules names have a prefix of “art” (e.g. the Clock module is named artClock.Mod). Where they are canonical to Artemis (e.g. Chars.Mod in the project root) they do not have a prefix.
25 |
26 |
27 |
58 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/ofrontplus/nav.md:
--------------------------------------------------------------------------------
1 |
2 | + [Home](/)
3 | + [README](../)
4 | + [LICENSE](../license.html)
5 | + [INSTALL](../install.html)
6 | + [OBNC Modules](../obnc/)
7 | + [Obc-3 Modules](../oxford/)
8 | + [Ofront+ Modules](./)
9 | + [development notes](../development-notes.html)
10 | + [Github](https://github.com/rsdoiel/Artemis)
11 |
12 |
--------------------------------------------------------------------------------
/oxford/ArgsTest.m:
--------------------------------------------------------------------------------
1 | (** ArgsTest.m modules provides test coverage for artArgs.m
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE ArgsTest;
10 |
11 | IMPORT T := Tests, Args := artArgs, Out;
12 |
13 | VAR ts : T.TestSet;
14 |
15 | PROCEDURE TestOneTwoThree() : BOOLEAN;
16 | VAR test : BOOLEAN; one, two, three : ARRAY 12 OF CHAR;
17 | res : INTEGER;
18 | BEGIN test := TRUE;
19 | T.ExpectedInt(3, Args.count, "Args.count for 'argtest one two three'", test);
20 | IF Args.count = 3 THEN
21 | Args.Get(0, one, res);
22 | Args.Get(1, two, res);
23 | Args.Get(2, three, res);
24 |
25 | T.ExpectedString("one", one, "Args.Get(0, one, res) for 'argtest one two three'", test);
26 | T.ExpectedString("two", two, "Args.Get(1, two, res) for 'argtest one two three'", test);
27 | T.ExpectedString("three", three, "Args.Get(2, three, res) for 'argtest one two three'", test);
28 | END;
29 | RETURN test
30 | END TestOneTwoThree;
31 |
32 | BEGIN
33 | Out.String("NOTE: run `argtest one two three`"); Out.Ln;
34 | T.Init(ts, "ArgsTest");
35 | T.Add(ts, TestOneTwoThree);
36 | ASSERT(T.Run(ts));
37 | END ArgsTest.
38 |
39 |
--------------------------------------------------------------------------------
/oxford/ClockTest.m:
--------------------------------------------------------------------------------
1 | (** ClockTest.m provide module Tests for Clock.mo.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE ClockTest;
10 |
11 | IMPORT T := Tests, Clock := artClock, Env := artEnv, Out, Strings;
12 |
13 | VAR ts : T.TestSet;
14 |
15 | PROCEDURE DisplayClock(ct : Clock.Clock);
16 | VAR i, hours, minutes : INTEGER;
17 | BEGIN
18 | Out.Int(ct.year, 4);
19 | Out.String("-");
20 | IF ct.month < 10 THEN
21 | Out.String("0"); Out.Int(ct.month, 1);
22 | ELSE
23 | Out.Int(ct.month, 2);
24 | END;
25 | Out.String("-");
26 | IF ct.day < 10 THEN
27 | Out.String("0"); Out.Int(ct.month, 1);
28 | ELSE
29 | Out.Int(ct.day, 2);
30 | END;
31 | Out.String(" ");
32 | IF ct.hour < 10 THEN
33 | Out.String("0"); Out.Int(ct.hour, 1);
34 | ELSE
35 | Out.Int(ct.hour, 2);
36 | END;
37 | Out.String(":");
38 | IF ct.minute < 10 THEN
39 | Out.String("0"); Out.Int(ct.minute, 1);
40 | ELSE
41 | Out.Int(ct.minute, 2);
42 | END;
43 | Out.String(":");
44 | IF ct.second < 10 THEN
45 | Out.String("0"); Out.Int(ct.second, 1);
46 | ELSE
47 | Out.Int(ct.second, 2);
48 | END;
49 | IF ct.isDST < 0 THEN
50 | Out.String(" "); (* DST info not available *)
51 | ELSIF ct.isDST = 0 THEN
52 | Out.String(" (ST)");
53 | ELSIF ct.isDST = 1 THEN
54 | Out.String(" (DST)");
55 | END;
56 | i := ABS(ct.utcOffset);
57 | IF (i >= 0) & (i <= 86400) THEN
58 | hours := (i DIV 3600) MOD 60;
59 | minutes := (i MOD 3600);
60 | Out.String(" UTC");
61 | IF (ct.utcOffset >= 0) THEN
62 | Out.String("+");
63 | IF hours < 10 THEN
64 | Out.String("0");
65 | END;
66 | Out.Int(hours, 1);
67 | ELSE
68 | Out.String("-");
69 | IF (ABS(hours) < 10) THEN
70 | Out.String("0");
71 | END;
72 | Out.Int(ABS(hours), 1);
73 | END;
74 | IF minutes < 10 THEN
75 | Out.String("0"); Out.Int(minutes, 1);
76 | ELSE
77 | Out.Int(minutes, 2);
78 | END;
79 | END;
80 | Out.Ln();
81 | END DisplayClock;
82 |
83 | PROCEDURE TestClockAndTime*() : BOOLEAN;
84 | VAR test : BOOLEAN; t1 : Clock.Clock;
85 | BEGIN test := TRUE;
86 | NEW(t1);
87 | Clock.Get(t1);
88 | T.ExpectedBool(TRUE, (t1.year > 2020), "Expected t1.year > 2020", test);
89 | T.ExpectedBool(TRUE, ((t1.month >= 1) & (t1.month <= 12)), "Expected (t1.month >= 1) & (t1.mongth <= 12)", test);
90 | T.ExpectedBool(TRUE, (t1.day > 0), "Expected t1.day > 0", test);
91 | T.ExpectedBool(TRUE, (t1.hour > -1), "Expected t1.hour > 0", test);
92 | T.ExpectedBool(TRUE, (t1.minute > -1), "Expected t1.minute > 0", test);
93 | T.ExpectedBool(TRUE, (t1.second > -1), "Expected t1.second > 0", test);
94 |
95 | RETURN test
96 | END TestClockAndTime;
97 |
98 | PROCEDURE TestClockSet*() : BOOLEAN;
99 | VAR test : BOOLEAN; ct, tt, sc : Clock.Clock; ok : BOOLEAN;
100 | uname, os : ARRAY 256 OF CHAR; res : INTEGER;
101 | BEGIN test := TRUE;
102 | res := 0;
103 | Env.Get("OS", os, res);
104 | Env.Get("SUDO_USER", uname, res);
105 | IF os = "Linux" THEN
106 | Out.String("Skipping TestClockSet(), Clock.Set() is not permitted under Linux"); Out.Ln();
107 | ELSIF (Strings.Length(uname) = 0) & (os = "Darwin") THEN
108 | Out.String(" Skipping TestSet(), Clock.Set() requires admin privilleges for Darwin (macOS)");Out.Ln();
109 | Out.String(" You can try rerunning tests with");Out.Ln();
110 | Out.Ln(); Out.String(" sudo make test");Out.Ln();Out.Ln();
111 | ELSE
112 | NEW(ct); NEW(tt); NEW(sc);
113 | Clock.Get(ct);
114 | Out.String(" Current clock: ");DisplayClock(ct);
115 | tt.year := ct.year + 1;
116 | tt.month := ct.month + 1;
117 | IF tt.month > 12 THEN
118 | INC(tt.year);
119 | ct.month := 1;
120 | END;
121 | tt.day := ct.day;
122 | tt.hour := ct.hour;
123 | tt.minute := ct.minute;
124 | tt.second := ct.second;
125 | tt.isDST := ct.isDST;
126 | tt.utcOffset := ct.utcOffset;
127 | Clock.Get(sc); (* Save the time to reset later *)
128 | Clock.Set(tt, ok);
129 | T.ExpectedBool(TRUE, ok, "Clock.Set(tt, ok) failed", test);
130 | IF ok THEN
131 | Out.String(" New clock: ");DisplayClock(tt);
132 |
133 | T.ExpectedBool(TRUE, ok, "Clock.Set(tt, ok) ", test);
134 |
135 | T.ExpectedBool(TRUE, (Clock.clock.year = tt.year), "new time year", test);
136 | T.ExpectedBool(TRUE, (Clock.clock.month = tt.month), "new time month", test);
137 | T.ExpectedBool(TRUE, (Clock.clock.day = tt.day), "new time day", test);
138 | T.ExpectedBool(TRUE, (Clock.clock.hour = tt.hour), "new time hour", test);
139 | T.ExpectedBool(TRUE, (Clock.clock.minute = tt.minute), "new time minute", test);
140 | T.ExpectedBool(TRUE, (Clock.clock.second = tt.second), "new time second", test);
141 | (* Reset the clock *)
142 | Clock.Set(sc, ok);
143 | Clock.Get(ct);
144 | Out.String(" Reset clock: "); DisplayClock(ct);
145 | END;
146 | END;
147 |
148 | RETURN test
149 | END TestClockSet;
150 |
151 | BEGIN
152 | T.Init(ts, "Test Clock");
153 | T.Add(ts, TestClockAndTime);
154 | T.Add(ts, TestClockSet);
155 | ASSERT(T.Run(ts));
156 | END ClockTest.
157 |
158 |
159 |
--------------------------------------------------------------------------------
/oxford/ConvertTest.m:
--------------------------------------------------------------------------------
1 | (** ConvertTest.m provides module tests for Convert.m.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE ConvertTest;
10 |
11 | IMPORT T := Tests, Convert := artConvert;
12 |
13 | VAR ts : T.TestSet;
14 |
15 | PROCEDURE TestIntConvs() : BOOLEAN;
16 | VAR test, ok : BOOLEAN;
17 | expectI, gotI : INTEGER;
18 | expectS, gotS : ARRAY 128 OF CHAR;
19 | BEGIN test := TRUE;
20 | gotS[0] := 0X; gotI := 0;
21 | expectI := 101;
22 | expectS := "101";
23 |
24 | Convert.StringToInt(expectS, gotI, ok);
25 | T.ExpectedBool(TRUE, ok, "StringToInt('101', gotI, ok) true", test);
26 | T.ExpectedInt(expectI, gotI, "StringToInt('101', gotI, ok)", test);
27 |
28 | Convert.IntToString(expectI, gotS, ok);
29 | T.ExpectedBool(TRUE, ok, "IntToString(101, gotS, ok) true", test);
30 | T.ExpectedString(expectS, gotS, "IntToString(101, gotS, ok)", test);
31 |
32 | RETURN test
33 | END TestIntConvs;
34 |
35 | PROCEDURE TestRealConvs() : BOOLEAN;
36 | VAR test, ok : BOOLEAN;
37 | expectR, gotR : REAL;
38 | expectS, gotS : ARRAY 128 OF CHAR;
39 | BEGIN test := TRUE;
40 | gotR := 0.0; gotS[0] := 0X;
41 | expectR := 3.1459;
42 | expectS := "3.145900";
43 |
44 | Convert.StringToReal(expectS, gotR, ok);
45 | T.ExpectedBool(TRUE, ok, "StringToReal('3.1459', gotR, ok) true", test);
46 | T.ExpectedReal(expectR, gotR, "StringToReal('3.1459', gotR, ok)", test);
47 |
48 | Convert.RealToString(expectR, gotS, ok);
49 | T.ExpectedBool(TRUE, ok, "RealToString(3.1459, gotS; ok) true", test);
50 | T.ExpectedString(expectS, gotS, "RealToString(3.1459, gotS, ok)", test);
51 |
52 | RETURN test
53 | END TestRealConvs;
54 |
55 | BEGIN
56 | T.Init(ts, "artConvert");
57 | T.Add(ts, TestIntConvs);
58 | T.Add(ts, TestRealConvs);
59 | ASSERT(T.Run(ts));
60 | END ConvertTest.
61 |
--------------------------------------------------------------------------------
/oxford/EnvTest.m:
--------------------------------------------------------------------------------
1 | (** EvnTest.m provide module tests for Env.m
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE EnvTest;
10 |
11 | IMPORT T := Tests, Env := artEnv, Out;
12 |
13 | VAR ts : T.TestSet;
14 |
15 | PROCEDURE TestEnv() : BOOLEAN;
16 | VAR test : BOOLEAN; value : ARRAY 256 OF CHAR;
17 | res : INTEGER;
18 | BEGIN test := TRUE;
19 | Env.Get("GOOD_NIGHT", value, res);
20 | T.ExpectedString("Irine", value, "Env.Get('GOOD_NIGHT', value, res') for 'env GOOD_NIGHT=Irine envtest'", test);
21 | RETURN test
22 | END TestEnv;
23 |
24 | BEGIN
25 | Out.String("NOTE: run `env GOOD_NIGHT=Irine envtest`"); Out.Ln;
26 | T.Init(ts, "EnvTest");
27 | T.Add(ts, TestEnv);
28 | ASSERT(T.Run(ts));
29 | END EnvTest.
30 |
31 |
--------------------------------------------------------------------------------
/oxford/Makefile:
--------------------------------------------------------------------------------
1 |
2 | OS = $(shell uname)
3 |
4 | SUDO_USER = $$SUDO_USER
5 |
6 | SHARE_LIBS =
7 |
8 | #FIXME: Compiling under macOS is failing right now. This is true for
9 | # both static and dynamic compilations.
10 | #
11 | # Per https://spivey.oriel.ox.ac.uk/corner/How_to_add_primitives_to_OBC
12 | #GCC_SO_OPT = -m32 -fPIC -shared -I /usr/local/lib/obc
13 | #ifeq ($(OS),Darwin)
14 | # GCC_SO_OPT = -m32 -fPIC -bundle -undefined dynamic_lookup -I /usr/local/lib/obc
15 | #endif
16 |
17 | PROGRAMS = helloworld clocktest converttest argstest envtest
18 |
19 | build: $(SHARE_LIBS) $(PROGRAMS) ../Tests.m
20 |
21 | #../Tests.m: ../Tests.Mod
22 | # echo '(** Copied from ../Tests.Mod, DO NOT edit *)' >../Tests.m
23 | # #cat ../Tests.Mod >>../Tests.m
24 |
25 | clocktest: ../Tests.m artEnv.m artClock.m ClockTest.m
26 | obc -07 -c ../Tests.m
27 | obc -07 -c artClock.m
28 | obc -07 -c artClock.c
29 | obc -07 -c artEnv.m
30 | obc -07 -c ClockTest.m
31 | obc -07 -C -o clocktest ../Tests.m artClock.m artClock.o artEnv.m ClockTest.m
32 |
33 | converttest: ../Tests.m ConvertTest.m artConvert.m
34 | obc -07 -c ../Tests.m
35 | obc -07 -c artConvert.m
36 | obc -07 -c artConvert.c
37 | obc -07 -c ConvertTest.m
38 | obc -07 -C -o converttest artConvert.m artConvert.o ../Tests.m ConvertTest.m
39 |
40 | argstest: ../Tests.m artArgs.m ArgsTest.m
41 | obc -07 -o argstest artArgs.m ../Tests.m ArgsTest.m
42 |
43 | envtest: ../Tests.m artEnv.m EnvTest.m
44 | obc -07 -o envtest artEnv.m ../Tests.m EnvTest.m
45 |
46 | helloworld: helloworld.m
47 | obc -07 -o helloworld helloworld.m
48 |
49 |
50 | test: $(PROGRAMS)
51 | ./helloworld
52 | env OS=$(OS) SUDO_USER=$(SUDO_USER) ./clocktest
53 | ./argstest one two three
54 | env GOOD_NIGHT=Irine ./envtest
55 | ./converttest
56 |
57 | clean: .FORCE
58 | @for FNAME in $(shell ls -1 *.bak *~ *.o a.out 2>/dev/null); do rm $$FNAME; done
59 | @for FNAME in $(PROGRAMS); do if [ -f $$FNAME ]; then rm $$FNAME; fi; done
60 | @for FNAME in $(SHARED_LIBS); do if [ -f $$FNAME ]; then rm $$FNAME; fi; done
61 | @for FNAME in $(shell ls -1 *.k 2>/dev/null); do rm $$FNAME; done
62 | @for FNAME in $(shell ls -1 *.so 2>/dev/null); do rm $$FNAME; done
63 |
64 | full_test: clean test
65 |
66 |
67 | .FORCE:
68 |
--------------------------------------------------------------------------------
/oxford/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Obc-3 modules
3 | ---
4 |
5 | Oxford - Not portable
6 | =====================
7 |
8 | DRAFT: sketch of untested code.
9 |
10 | FIXME: I have not gotten the current Obc-3 to compile under Darwin (macOS).
11 |
12 | Modules in this directory are being ported to the Obc-3 compiler
13 | and should be compiled with the `-07` option.
14 |
15 | - [Obc-3 compiler](https://spivey.oriel.ox.ac.uk/corner/Oxford_Oberon-2_compiler)
16 | - [How to add primitives to Obc-3](https://spivey.oriel.ox.ac.uk/corner/How_to_add_primitives_to_OBC)
17 |
18 | Pre-requisites
19 | --------------
20 |
21 | **Debian systems**
22 |
23 | ~~~bash
24 | sudo apt install build-essential autotools automake autoconf git
25 | sudo apt install ocaml
26 | sudo apt install libgtksourceview2.0-dev
27 | git clone git@github.com:Spivoxity/obc-3
28 | ~~~
29 |
30 | NOTE: Unresolved issues on macOS
31 | --------------------------------
32 |
33 | I am currently running into issues compiling these modules on macOS.
34 | Not sure if this is specific to my Mac (it is rather vintage) or due
35 | to problems with compiler flags. I suspect my Makefile is not calling
36 | the right options for macOS compilation.
37 |
38 |
--------------------------------------------------------------------------------
/oxford/UnixTest.m:
--------------------------------------------------------------------------------
1 | (** UnixTest.m provide module tests for Unix.m
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE UnixTest;
10 |
11 | IMPORT T := Tests, Unix, Out, Env := artEnv;
12 |
13 | VAR
14 | ts : T.TestSet;
15 | successes, errors : INTEGER;
16 |
17 | PROCEDURE TestKernelName() : BOOLEAN;
18 | VAR test: BOOLEAN; expected, got : ARRAY 256 OF CHAR; res : INTEGER;
19 | BEGIN test := TRUE;
20 | Env.Get("OS", expected, res);
21 | IF expected[0] = 0X THEN
22 | Out.String("Skipping TestKernelName(), missing environment"); Out.Ln();
23 | Out.String("variable OS (aka kernel name) needed to verify Unix.Kernel()"); Out.Ln();
24 | ELSE
25 | Unix.KernelName(got);
26 | T.ExpectedString(expected, got, "Unix.KernelName(s) should match env. OS", test);
27 | END;
28 | RETURN test
29 | END TestKernelName;
30 |
31 | PROCEDURE TestArchitectureName() : BOOLEAN;
32 | VAR test: BOOLEAN; expected, got : ARRAY 24 OF CHAR; res : INTEGER;
33 | BEGIN test := TRUE;
34 | Env.Get("ARCH", expected, res);
35 | IF expected[0] = 0X THEN
36 | Out.String("Skipping TestArchitectureName(), missing environment"); Out.Ln();
37 | Out.String("variable ARCH needed to verify Unix.Architecture()"); Out.Ln();
38 | ELSE
39 | Unix.Architecture(got);
40 | T.ExpectedString(expected, got, "Unix.Architecture(s) should match env. OS", test);
41 | END;
42 | RETURN test
43 | END TestArchitectureName;
44 |
45 | PROCEDURE TestExit() : BOOLEAN;
46 | BEGIN
47 | Unix.Exit(0);
48 | RETURN FALSE
49 | END TestExit;
50 |
51 | BEGIN
52 | T.Init(ts, "Test Unix");
53 | T.Add(ts, TestKernelName);
54 | T.Add(ts, TestArchitectureName);
55 | ASSERT(T.Run(ts));
56 | (* Testing Unix.Exit(1) is tricky *)
57 | successes := 0; errors := 0;
58 | IF ~ TestExit() THEN
59 | Out.String("Test of Unix.Exit(), failed"); Out.Ln();
60 | ASSERT(FALSE);
61 | END;
62 | END UnixTest.
63 |
--------------------------------------------------------------------------------
/oxford/artArgs.m:
--------------------------------------------------------------------------------
1 | (** artArgs.m provides access to POSIX system arguments. It is based
2 | on the definition found in OBNC's extended library extArgs.Mod.
3 |
4 | Copyright (C) 2021 R. S. Doiel
5 |
6 | Released under The 3-Clause BSD License.
7 | See https://opensource.org/licenses/BSD-3-Clause
8 |
9 | *)
10 | MODULE artArgs;
11 |
12 | IMPORT Args;
13 |
14 | VAR
15 | count*: INTEGER; (*number of arguments*)
16 |
17 | (** Get provides access to the parameters passed one the command line.
18 | The parameters are n:th command line argument (0 <= n < count).
19 |
20 | The parameter res is provided for compatibilty with OBNC
21 | artArgs. It is ignored. *)
22 | PROCEDURE Get*(n: INTEGER; VAR arg: ARRAY OF CHAR; VAR res: INTEGER);
23 | BEGIN
24 | (* The zero's arg need to be the first parameter from the command line *)
25 | Args.GetArg(n + 1, arg); res := 0;
26 | END Get;
27 |
28 | BEGIN
29 | count := Args.argc - 1;
30 | END artArgs.
31 |
32 |
--------------------------------------------------------------------------------
/oxford/artClock.c:
--------------------------------------------------------------------------------
1 | /*
2 | * artClock.c provides an interface to C libraries used to implement artClock.m.
3 | *
4 | * Copyright (C) 2021 R. S. Doiel
5 | *
6 | * Released under The 3-Clause BSD License.
7 | * See https://opensource.org/licenses/BSD-3-Clause
8 | *
9 | */
10 | #include
11 | #include
12 |
13 | void get_rtc_time(int *second_, int *minute_, int *hour_, int *day_, int *month_, int *year_, int *wDay_, int *yDay_, int *isDST_, int *utcOffset_, int *seconds_, int *nanoSeconds_, int *ok_)
14 | {
15 | struct timespec now;
16 | struct tm *dt;
17 |
18 | *ok_ = 1; /* Assume clock_gettime() successful */
19 | if (clock_gettime(CLOCK_REALTIME, &now) == -1) {
20 | perror("clock_gettime(CLOCK_REALTIME, &now) failed");
21 | *ok_ = 0; /* clock_gettime() failed for some reason */
22 | } else {
23 | *seconds_ = now.tv_sec;
24 | *nanoSeconds_ = now.tv_nsec;
25 | dt = localtime(&now.tv_sec);
26 | *second_ = dt->tm_sec;
27 | *minute_ = dt->tm_min;
28 | *hour_ = dt->tm_hour;
29 | *day_ = dt->tm_mday;
30 | *month_ = dt->tm_mon + 1; /* We want 1 to 12 rather than 0 to 11 */
31 | *year_ = dt->tm_year + 1900; /* Normalize to current year */
32 | *wDay_ = dt->tm_wday;
33 | *yDay_ = dt->tm_yday;
34 | *isDST_ = dt->tm_isdst;
35 | *utcOffset_ = dt->tm_gmtoff;
36 | }
37 | }
38 |
39 |
40 |
41 | void set_rtc_time(int second_, int minute_, int hour_, int day_, int month_, int year_, int wDay_, int yDay_, int isDST_, int utcOffset_, int *ok_)
42 | {
43 | struct timespec nt;
44 | struct tm dt;
45 |
46 | dt.tm_sec = second_;
47 | dt.tm_min = minute_;
48 | dt.tm_hour = hour_;
49 | dt.tm_mday = day_;
50 | dt.tm_mon = (month_ - 1); /* de-normalize to 0 to 11 from 1 to 12 */
51 | dt.tm_year = (year_ - 1900); /* adjust year to reflect POSIX value */
52 | dt.tm_wday = wDay_;
53 | dt.tm_yday = yDay_;
54 | /* NOTE: tm_idst and tm_gmtoff are not ISO C or POSIX, they come from
55 | BSD and GNU systems. They appear to be available on macOS */
56 | dt.tm_isdst = isDST_;
57 | dt.tm_gmtoff = utcOffset_;
58 | /* NOTE: You must have root permissions for clock_settime() to work */
59 | nt.tv_sec = mktime(&dt);
60 | if (clock_settime(CLOCK_REALTIME, &nt) == -1) {
61 | perror("clock_settime(CLOCK_REALTIME, &nt) failed");
62 | *ok_ = 0;
63 | } else {
64 | *ok_ = 1;
65 | }
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/oxford/artConvert.c:
--------------------------------------------------------------------------------
1 | /**
2 | * extConvert.c provides the C implementation used in extConvert.m
3 | *
4 | * Copyright (C) 2021 R. S. Doiel
5 | *
6 | * Released under The 3-Clause BSD License.
7 | * See https://opensource.org/licenses/BSD-3-Clause
8 | *
9 | */
10 | #include
11 | #include
12 |
13 | void conv_int_to_string(int i, char *s, int l) {
14 | snprintf(s, l, "%d", i);
15 | }
16 |
17 | void conv_real_to_string(float r, char *s, int l) {
18 | snprintf(s, l, "%f", r);
19 | }
20 |
21 | void conv_real_to_exp_string(float r, char *s, int l) {
22 | snprintf(s, l, "%e", r);
23 | }
24 |
25 | void conv_string_to_int(char *s, int *i) {
26 | *i = atoi(s);
27 | }
28 |
29 | void conv_string_to_real(char *s, float *r) {
30 | *r = atof(s);
31 | }
32 |
--------------------------------------------------------------------------------
/oxford/artConvert.m:
--------------------------------------------------------------------------------
1 | (** artConvert.m provides procedures to convert between numbers and
2 | strings. It is based on the definition found in OBNC's
3 | extended library extConvert.Mod.
4 |
5 | Copyright (C) 2021 R. S. Doiel
6 |
7 | Released under The 3-Clause BSD License.
8 | See https://opensource.org/licenses/BSD-3-Clause
9 |
10 | *)
11 | MODULE artConvert;
12 |
13 | (* IMPORT SYSTEM; *)
14 |
15 | (** Conversions between numbers and strings
16 |
17 | All conversions from a string skips over preceeding whitespace. *)
18 |
19 | (** IntToString(i, s, d) returns in s the decimal representation of i.
20 | The done parameters is for compatibility, it is alwasy TRUE. *)
21 | PROCEDURE IntToString*(i: INTEGER; VAR s: ARRAY OF CHAR; VAR done: BOOLEAN);
22 | VAR l : INTEGER;
23 | BEGIN
24 | l := LEN(s); done := TRUE;
25 | IntToString0(i, s, l);
26 | END IntToString;
27 |
28 | PROCEDURE IntToString0(i : INTEGER; VAR s : ARRAY OF CHAR; l : INTEGER) IS "conv_int_to_string";
29 |
30 | (** RealToString(x, s, d) returns in s a string representation of x. If s is large enough to hold the result, d is set to TRUE. Otherwise d is set to FALSE.*)
31 | PROCEDURE RealToString*(x: REAL; VAR s: ARRAY OF CHAR; VAR done: BOOLEAN);
32 | VAR l : INTEGER;
33 | BEGIN
34 | l := LEN(s);
35 | RealToString0(x, s, l);
36 | END RealToString;
37 |
38 | PROCEDURE RealToString0(x: REAL; VAR s: ARRAY OF CHAR; l : INTEGER) IS "conv_real_to_string";
39 |
40 |
41 | (** StringToInt(s, i, d) returns in i the integer constant in s according to the format
42 |
43 | integer = digit {digit} | digit {hexDigit} "H".
44 | hexDigit = digit | "A" | "B" | "C" | "D" | "E" | "F".
45 |
46 | d indicates the success of the operation.*)
47 | PROCEDURE StringToInt*(s: ARRAY OF CHAR; VAR i: INTEGER; VAR done: BOOLEAN);
48 | BEGIN
49 | done := TRUE;
50 | StringToInt0(s, i);
51 | END StringToInt;
52 |
53 | PROCEDURE StringToInt0(s : ARRAY OF CHAR; VAR i : INTEGER) IS "conv_string_to_int";
54 |
55 | (** StringToReal(s, x, d) returns in x the real number in s according to the format
56 |
57 | real = digit {digit} "." {digit} [ScaleFactor].
58 | ScaleFactor = "E" ["+" | "-"] digit {digit}.
59 |
60 | d indicates the success of the operation. *)
61 | PROCEDURE StringToReal*(s: ARRAY OF CHAR; VAR x: REAL; VAR done: BOOLEAN);
62 | BEGIN
63 | done := TRUE;
64 | StringToReal0(s, x);
65 | END StringToReal;
66 |
67 | PROCEDURE StringToReal0(s: ARRAY OF CHAR; VAR x : REAL) IS "conv_string_to_real";
68 |
69 | BEGIN
70 | (* SYSTEM.LOADLIB("./artConvert.so"); *)
71 | END artConvert.
72 |
73 |
--------------------------------------------------------------------------------
/oxford/artEnv.m:
--------------------------------------------------------------------------------
1 | (**artEnv.m is a compatible module for code written for OBNC but compiler with Obc-3
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE artEnv;
10 |
11 | IMPORT Args, Strings;
12 |
13 | PROCEDURE Get*(name : ARRAY OF CHAR; VAR value : ARRAY OF CHAR; VAR res : INTEGER);
14 | VAR i, l1, l2 : INTEGER; val : ARRAY 512 OF CHAR;
15 | BEGIN
16 | l1 := LEN(value) - 1; (* Allow for trailing 0X *)
17 | Args.GetEnv(name, val);
18 | l2 := Strings.Length(val);
19 | IF l2 <= l1 THEN
20 | res := 0;
21 | ELSE
22 | res := l2 - l1;
23 | END;
24 | i := 0;
25 | WHILE (i < l2) & (val[i] # 0X) DO
26 | value[i] := val[i];
27 | INC(i);
28 | END;
29 | value[i] := 0X;
30 | END Get;
31 |
32 | END artEnv.
33 |
--------------------------------------------------------------------------------
/oxford/artUnix.m:
--------------------------------------------------------------------------------
1 | (** artUnix.m provides an interface to some POSIX services.
2 |
3 | Copyright (C) 2021 R. S. Doiel
4 |
5 | Released under The 3-Clause BSD License.
6 | See https://opensource.org/licenses/BSD-3-Clause
7 |
8 | *)
9 | MODULE artUnix;
10 |
11 | VAR
12 | kernel, architecture : ARRAY 24 OF CHAR;
13 |
14 |
15 | (*
16 | * C implemented procedures
17 | * ------------------------
18 | *)
19 |
20 | (* uname does a popen call to `uname` *)
21 | PROCEDURE uname(opt : CHAR; VAR dest : ARRAY OF CHAR);
22 | BEGIN
23 | END uname;
24 |
25 | (** Exit performs a system exit with error number *)
26 | PROCEDURE Exit*(exitCode : INTEGER);
27 | BEGIN
28 | END Exit;
29 |
30 | (*
31 | * Oberon-7 implemented procedures
32 | * -------------------------------
33 | *)
34 |
35 | (* mininum returns the lesser of two integer *)
36 | PROCEDURE minimum(a, b : INTEGER) : INTEGER;
37 | VAR res : INTEGER;
38 | BEGIN
39 | IF a < b THEN res := a; ELSE res := b; END;
40 | RETURN res
41 | END minimum;
42 |
43 | (* copy an array of chars, truncate dest if needed *)
44 | PROCEDURE copyChars(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR);
45 | VAR i, l : INTEGER;
46 | BEGIN
47 | l := minimum(LEN(source), LEN(dest)) - 2; (* leave room of 0X *)
48 | IF l < 1 THEN l := 0 END;
49 | i := 0; dest[i] := 0X;
50 | WHILE (i < l) & (source[i] # 0X) DO
51 | dest[i] := source[i];
52 | INC(i);
53 | END;
54 | dest[i] := 0X; DEC(i);
55 | IF (dest[i] = 10X) OR (dest[i] = 13X) THEN
56 | dest[i] := 0X;
57 | END;
58 | END copyChars;
59 |
60 |
61 | (** KernelName attempts a system exec call to `uname -s` to determine the
62 | Kernel name, e.g. Linux, Darwin, Windows *)
63 | PROCEDURE KernelName*(VAR dest : ARRAY OF CHAR);
64 | BEGIN
65 | IF kernel[0] = 0X THEN
66 | uname("s", kernel);
67 | END;
68 | copyChars(kernel, dest);
69 | END KernelName;
70 |
71 | (** Architecture attempts a system exec call to `uname -m` to determine
72 | the machine archtecture, e.g. i386, x86_64 *)
73 | PROCEDURE Architecture*(VAR dest : ARRAY OF CHAR);
74 | BEGIN
75 | IF architecture[0] = 0X THEN
76 | uname("m", architecture);
77 | END;
78 | copyChars(architecture, dest);
79 | END Architecture;
80 |
81 |
82 | BEGIN kernel[0] := 0X; architecture[0] := 0X;
83 | END artUnix.
84 |
--------------------------------------------------------------------------------
/oxford/helloworld.m:
--------------------------------------------------------------------------------
1 | (** helloworld.m is intended to test the Obc-3 compiler installation. *)
2 | MODULE helloworld;
3 |
4 | IMPORT Args, Strings, Out;
5 | (* NOTE: Args provide GetEnv() for obc-3 *)
6 | VAR
7 | name : ARRAY 256 OF CHAR;
8 |
9 | BEGIN
10 | Args.GetEnv("USER", name);
11 | IF Strings.Length(name) > 0 THEN
12 | Out.String("Hello ");Out.String(name); Out.Ln;
13 | ELSE
14 | Out.String("Hello World!"); Out.Ln;
15 | END;
16 | END helloworld.
17 |
--------------------------------------------------------------------------------
/oxford/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Project Artemis
5 |
6 |
7 |
8 |
9 |
10 |
11 | Obc-3 modules
12 |
13 |
14 |
15 | Oxford - Not portable
16 |
17 |
18 | DRAFT: sketch of untested code.
19 |
20 |
21 | FIXME: I have not gotten the current Obc-3 to compile under Darwin (macOS).
22 |
23 |
24 | Modules in this directory are being ported to the Obc-3 compiler and should be compiled with the -07 option.
25 |
50 | I am currently running into issues compiling these modules on macOS. Not sure if this is specific to my Mac (it is rather vintage) or due to problems with compiler flags. I suspect my Makefile is not calling the right options for macOS compilation.
51 |
52 |
53 |
84 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/oxford/nav.md:
--------------------------------------------------------------------------------
1 |
2 | + [Home](/)
3 | + [README](../)
4 | + [LICENSE](../license.html)
5 | + [INSTALL](../install.html)
6 | + [OBNC Modules](../obnc/)
7 | + [Obc-3 Modules](./)
8 | + [Ofront+ Modules](../ofrontplus/)
9 | + [development notes](../development-notes.html)
10 | + [Github](https://github.com/rsdoiel/Artemis)
11 |
12 |
--------------------------------------------------------------------------------
/oxford/ocat.m:
--------------------------------------------------------------------------------
1 | (** ocat.Mod is inspired by ocat command found in Joseph Templ's in Ofront.
2 |
3 | Copyright (C) 2021 R. S. Doiel This Source Code Form is subject to the terms of the Mozilla PublicLicense, v. 2.0. If a copy of the MPL was not distributed with thisfile, You can obtain one at http://mozilla.org/MPL/2.0/. *)
4 | MODULE ocat;
5 |
6 | (** NOTE: OCat is a POSIX command line program. *)
7 |
8 | IMPORT Args := extArgs, Out, Files, Texts := TextsCmdLn, Chars, Convert := extConvert, Err := extErr;
9 |
10 | CONST
11 | TAB = 9X;
12 | LF = 10X;
13 | CR = 13X;
14 | SPACE = 20X;
15 | TILDE = "~";
16 |
17 | VAR
18 | tabs : ARRAY 128 OF CHAR;
19 |
20 | (* Usage displays a help screen *)
21 | PROCEDURE Usage();
22 | BEGIN
23 | Out.String("USAGE OCat [OPTION] FILENAME [[OPTION] FILENAME ...]"); Out.Ln();
24 | Out.Ln();
25 | Out.String("Read Oberon Texts and write them to standard out");Out.Ln();
26 | Out.Ln();
27 | Out.String("OPTIONS"); Out.Ln();
28 | Out.Ln();
29 | Out.String(" -h, --help"); Out.Char(Chars.TAB); Out.String("this help document"); Out.Ln();Out.Ln();
30 | Out.String(" -t, --tabs"); Out.Char(Chars.TAB); Out.String("Allow tab characters"); Out.Ln();
31 | Out.String(" --spaces"); Out.Char(Chars.TAB); Out.String("Convert tab characters to four spaces"); Out.Ln();
32 | Out.String(" --spaces=X"); Out.Char(Chars.TAB); Out.String("Convert tab characters to X number of spaces"); Out.Ln();
33 | Out.Ln();
34 | END Usage;
35 |
36 | (* Convert Oberon texts to POSIX friendly standard out *)
37 | PROCEDURE Cat(filename : ARRAY OF CHAR);
38 | VAR T : Texts.Text; R : Texts.Reader; ch : CHAR; skipLF : BOOLEAN;
39 | BEGIN
40 | IF Files.Old(filename) # NIL THEN
41 | Texts.Open(T, filename);
42 | Texts.OpenReader(R, T, 0);
43 | (* FIXME: Need to handle case where this is an Oberon file
44 | and skip beyond the font settings to start of Text *)
45 | Texts.Read(R, ch);
46 | WHILE ~ R.eot DO
47 | IF (ch >= SPACE) & (ch <= TILDE) THEN
48 | Out.Char(ch);
49 | skipLF := FALSE;
50 | ELSIF ch = TAB THEN
51 | Out.String(tabs);
52 | skipLF := FALSE;
53 | ELSIF ch = LF THEN
54 | IF skipLF = TRUE THEN
55 | skipLF := FALSE;
56 | ELSE
57 | Out.Ln();
58 | END;
59 | ELSIF ch = CR THEN
60 | Out.Ln();
61 | skipLF := TRUE;
62 | END;
63 | Texts.Read(R, ch);
64 | END;
65 | Out.Ln();
66 | ELSE
67 | Err.String("Can't open ");Err.String(filename);Err.Ln();
68 | END;
69 | END Cat;
70 |
71 | (* Apply process POSIX command line parameters and envoke Cat.*)
72 | PROCEDURE Apply();
73 | VAR i, j, k, res : INTEGER; arg : ARRAY 1024 OF CHAR; ok : BOOLEAN;
74 | BEGIN
75 | IF Args.count = 0 THEN
76 | Out.String("Try OCat --help for explanation of how this works"); Out.Ln();
77 | ELSE
78 | i := 0;
79 | WHILE i < Args.count DO
80 | Args.Get(i, arg, res);
81 | IF Chars.Equal("-h", arg) OR Chars.Equal("--help", arg) THEN
82 | Usage();
83 | ELSIF Chars.Equal("-t", arg) OR Chars.StartsWith("--tab", arg) THEN
84 | tabs[0] := Chars.TAB; tabs[1] := 0X;
85 | ELSIF Chars.StartsWith("--spaces=", arg) THEN
86 | Chars.TrimPrefix("--spaces=", arg);
87 | Convert.StringToInt(arg, k, ok);
88 | Chars.Clear(tabs);
89 | j := 0;
90 | WHILE j < k DO tabs[j] := " "; INC(j) END;
91 | tabs[j] := 0X; (* Terminate the tabs array of char *)
92 | ELSIF Chars.Equal("--spaces", arg) THEN
93 | Chars.Clear(tabs);
94 | tabs := " ";
95 | ELSE
96 | Cat(arg);
97 | END;
98 | INC(i);
99 | END;
100 | END;
101 | END Apply;
102 |
103 | BEGIN tabs[0] := Chars.TAB; tabs[1] := 0X; Apply();
104 | END ocat.
105 |
106 | The POSIX command line version is built with
107 |
108 | obnc -o ocat ocat.Mod
109 |
110 |
--------------------------------------------------------------------------------
/page.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ${if(fontmatter)}${if(title)}${title}{else}Project Artemis${endif}
5 | ${else}Project Artemis${endif}
6 |
7 |
8 |
9 |
10 |
11 | ${if(front_matter)}
12 |
13 | ${title}
14 |
15 | ${endif}
16 |
17 | ${content}
18 |
19 |
22 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/ports/Oberon-2_to_Oberon-07.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Project Artemis
5 |
6 |
7 |
8 |
9 |
10 |
11 | Ports, from Oberon-2 to Oberon-07
12 |
13 |
14 |
15 | Oberon-2 to Oberon-07
16 |
17 |
18 | In approaching bringing the full range of historic Oberon-2 modules to Oberon-07 I found it useful to have a rather systematic approach.
19 |
20 |
21 | Steps
22 |
23 |
24 |
25 | Review Oberon-2 code and flag (via comments)
26 |
27 |
67 | Oberon-07 does away with LOOP while it does allow a WHILE with an ELSE. REPEAT/UNTIL and FOR are also available.
68 |
69 |
70 | Refactor CASE
71 |
72 |
73 | Refactor RETURN
74 |
75 |
76 | Refactor forward references
77 |
78 |
79 | Update IMPORT
80 |
81 |
82 | Add Obn2 to IMPORT line. Replace missing Oberon-2 built-ins with the Obn2 equivallent.
83 |
84 |
85 | Update SHORTINT, LONGINT, LONGREAL
86 |
87 |
88 |
119 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/ports/Oberon-2_to_Oberon-07.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Ports, from Oberon-2 to Oberon-07
3 | ---
4 |
5 | Oberon-2 to Oberon-07
6 | =====================
7 |
8 | In approaching bringing the full range of historic Oberon-2 modules
9 | to Oberon-07 I found it useful to have a rather systematic approach.
10 |
11 | Steps
12 | -----
13 |
14 | 1. Review Oberon-2 code and flag (via comments)
15 | a. LOOP/EXIT replaced with WHILE, WHILE/ELSE, REPEAT/UNTIL, FOR/DO
16 | b. Convert RETURN to a single RETURN at end of functional procedure
17 | c. Refactor CASE is not used as a type guard
18 | d. Refactor any forward references
19 | 2. Refactor LOOP
20 | 3. Refactor CASE statement
21 | 4. Refactor RETURN clauses
22 | 5. Refactor any forward references
23 | 6. Review and replace use of LONGINT, SHORTINT, LONGREAL
24 | 7. Update IMPORT, replace missing built-in with Obn2 equivalent
25 |
26 |
27 | Review code and flag issues
28 | ---------------------------
29 |
30 | Refactor LOOPS
31 | --------------
32 |
33 | Oberon-07 does away with LOOP while it does allow a WHILE with
34 | an ELSE. REPEAT/UNTIL and FOR are also available.
35 |
36 | Refactor CASE
37 | -------------
38 |
39 | Refactor RETURN
40 | ---------------
41 |
42 | Refactor forward references
43 | ---------------------------
44 |
45 | Update IMPORT
46 | -------------
47 |
48 | Add `Obn2` to IMPORT line. Replace missing Oberon-2 built-ins with
49 | the `Obn2` equivallent.
50 |
51 | Update SHORTINT, LONGINT, LONGREAL
52 | ----------------------------------
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/ports/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Ports, from Oberon-2 to Oberon-07
3 | ---
4 |
5 | README Ports
6 | ============
7 |
8 |
9 | The ports directory contains modules that were ported to a
10 | POSIX environment from previous Oberon Systems written in
11 | Oberon-2. The ported code is written in Oberon-7. Where necessary
12 | compatibility modules have been created to minimize the changes
13 | to the ported code.
14 |
15 | - [s3](s3/) contains ports from Native Oberon to Oberon-7
16 | - [v4](v4/) contains ports of Linz V4 code to Oberon-7
17 |
18 | NOTE: Authorship of the modules in this sub directory vary.
19 | They included "ported" code. The "ports" retain their original
20 | authorship, copyright, license, etc.
21 |
22 | Porting Strategy
23 | ----------------
24 |
25 | 1. [Porting the Oberon Compiler from Oberon to Oberon-07](https://people.inf.ethz.ch/wirth/Oberon/PortingOberon.pdf), Niklaus Wirth, 2007-08-15.
26 | 2. [Differences between Revised Oberon and Oberon](https://people.inf.ethz.ch/wirth/Oberon/Oberon07.pdf), Niklaus Wirth, 2008-03-22 / 2011-07-05
27 | 3. [The Programming Language Oberon](https://people.inf.ethz.ch/wirth/Oberon/Oberon07.Report.pdf), Niklaus Wirth, Revision 2013-10-01 / 2016-05-03
28 | - aka "The Programming Language Oberon-07 (Revised Oberon)"
29 | - Karl Landström provides an [HTML version](http://miasap.se/obnc/oberon-report.html)
30 |
31 | What follows are my notes which might be helpful to others (YMMV).
32 |
33 | The basic data types in Oberon-7 are more limitted. In some cases the
34 | data types could simply be mapped to the newer version of the language.
35 | The built-in procedures and functions are different from Oberon-2 to
36 | Oberon-7. The [Obn2.Mod](Obn2.Mod) provides a small collection of
37 | formerly build-in Oberon-2 function for use in Oberon-7.
38 |
39 |
40 | | Oberon-2 | Oberon-7 | Compatibility |
41 | |:---------|:--------------|:---------------|
42 | | LONGINT | INTEGER | |
43 | | LONGREAL | REAL | |
44 | | SHORTINT | BYTE | |
45 | | ASH | | Obn2.ASH |
46 | | MAX | | Obn2.MAX |
47 | | MIN | | Obn2.MIN |
48 | | ENTIER | FLOOR | Obn2.ENTIER |
49 | | HALT | ASSERT(FALSE) | Obn2.HALT |
50 | | ROT | ROR | Obn2.ROT |
51 |
52 |
53 | POSIX compilers
54 | ---------------
55 |
56 | Artemis and these ports have been developed with two Oberon-7
57 | POSIX based compilers in mind
58 |
59 | - [OBNC](https://)
60 | - [Obc-3](https://github.com/Spivoxity/Obc-3 "aka Oxford Oberon Compiler")
61 |
62 | OBNC advantage is it is realatively easy to port between POSIX systems.
63 | It only requires a good C compiler and optionally SDL 1.2. Obc-3 has the
64 | advantage of also being able to compile both Oberon-2 and Oberon-7
65 | code selectable with a command line flag. This has been used to help
66 | compare behaviors in the language.
67 |
68 |
69 | OBNC
70 | ----
71 |
72 | Standard compiler envocation, `obnc MODULE_NAME`
73 |
74 | Haven't noticed deviation from Oakwood except Out has some
75 | additional output formats.
76 |
77 |
78 | Oxford Oberon Compiler (obc-3)
79 | ------------------------------
80 |
81 | Standard compiler envocation, `obc -07 DEP_MODULE_LIST PROG_MODULE -m`
82 |
83 | The latest version on GitHub includes a more Oakwood-ish
84 | implementation of Out and Math modules.
85 |
86 |
87 |
--------------------------------------------------------------------------------
/ports/nav.md:
--------------------------------------------------------------------------------
1 |
2 | + [Home](/)
3 | + [README](../)
4 | + [LICENSE](../license.html)
5 | + [INSTALL](../install.html)
6 | + [OBNC Modules](../obnc/)
7 | + [Obc-3 Modules](../oxford/)
8 | + [Ofront+ Modules](../ofrontplus/)
9 | + [development notes](../development-notes.html)
10 | + [Github](https://github.com/rsdoiel/Artemis)
11 |
12 |
--------------------------------------------------------------------------------
/ports/s3/Conversions.Mod:
--------------------------------------------------------------------------------
1 | (* ETH Oberon, Copyright 1990-2003 Computer Systems Institute, ETH Zurich, CH-8092 Zurich.
2 | Refer to the license.txt file provided with this distribution. *)
3 | (* Port to Oberon-7 started RSD / 2021.06.04 *)
4 | MODULE Conversions; (** portable *) (** PRK / 20.01.97**)
5 |
6 | (*
7 | This module performs useful conversions between the different formats
8 |
9 | History
10 |
11 | 1.0 / 20.01.96
12 | o IntToStr, StrToInt, RealToStr
13 | o leading zeros removed in base2 conversion to Str
14 |
15 | *)
16 |
17 | IMPORT
18 | Reals, Strings, BIT;
19 |
20 | TYPE
21 | String = ARRAY 34 OF CHAR;
22 |
23 | VAR
24 | Min: ARRAY 16 OF String;
25 | Digit: ARRAY 17 OF CHAR;
26 |
27 |
28 | PROCEDURE BitPatternToStr (val: INTEGER; VAR str: ARRAY OF CHAR; base: INTEGER);
29 | VAR i, j, shift, size: BYTE;
30 | BEGIN
31 | ASSERT ((base=2) OR (base=8) OR (base=16));
32 | IF base = 2 THEN shift := 1; size := 32
33 | ELSIF base = 8 THEN shift := 3; size := 11
34 | ELSIF base = 16 THEN shift := 4; size := 8
35 | END;
36 | IF LEN(str) < size+1 THEN COPY ("str to short", str); RETURN END;
37 | i := 0; j := 0;
38 | WHILE i < size DO
39 | str[j] := Digit[BIT.LAND(BIT.LLSH(val, (i+1)*shift - 32), base-1)];
40 | INC (i);
41 | IF (j#0) OR (base#2) OR (str[0]#"0") THEN INC (j) END (* ejz proposal *)
42 | END;
43 | IF j=0 THEN str[0] := "0"; INC (j) END; (* ejz proposal *)
44 | str[j] := 0X;
45 | END BitPatternToStr;
46 |
47 | (** IntToStr -- convert a longint to a representation in a given base (2..16) *)
48 | PROCEDURE IntToStr* (val: LONGINT; VAR str: ARRAY OF CHAR; base: LONGINT);
49 | VAR i, j: LONGINT; digits: ARRAY 32 OF LONGINT;
50 | BEGIN
51 | IF (base <= 1) OR (base > 16) THEN COPY("???", str); RETURN END;
52 | IF (base = 2) OR (base = 16) THEN BitPatternToStr (val, str, base); RETURN END;
53 | IF val = MIN(LONGINT) THEN
54 | COPY (Min[base-1], str); RETURN
55 | END;
56 | IF val < 0 THEN val := -val; str[0] := "-"; j := 1 ELSE j := 0 END;
57 | i := 0;
58 | REPEAT
59 | digits[i] := val MOD base; INC (i); val := val DIV base
60 | UNTIL val = 0;
61 | DEC(i);
62 | WHILE i >= 0 DO
63 | str[j] := Digit[digits[i]]; INC (j); DEC (i)
64 | END;
65 | str[j] := 0X
66 | END IntToStr;
67 |
68 |
69 | (** RealToStr -- convert a longreal to a representation in a given base (2..16) *)
70 | PROCEDURE RealToStr*(x: LONGREAL; VAR s: ARRAY OF CHAR; base: LONGINT);
71 | VAR h, l: LONGINT; d: ARRAY 16 OF CHAR;
72 |
73 | BEGIN
74 | IF (base # 2) & (base # 10) & (base # 16) THEN COPY("???", s); RETURN END;
75 | IF base # 10 THEN
76 | Reals.IntL (x, h, l);
77 | IntToStr (h, s, base); IntToStr (l, d, base);
78 | Strings.Append (s, d);
79 | RETURN
80 | END;
81 | Strings.RealToStr (x, s)
82 | END RealToStr;
83 |
84 | (* ============================================================= *)
85 | PROCEDURE StrToInt* (s: ARRAY OF CHAR; VAR val: LONGINT; base: LONGINT);
86 | VAR j: LONGINT; neg: BOOLEAN;
87 |
88 | PROCEDURE IsOK (ch: CHAR; base: LONGINT): BOOLEAN;
89 | BEGIN
90 | IF Strings.UpperCh(ch) >= "A" THEN
91 | base := base - ORD(Strings.UpperCh(ch)) + ORD ("A") + 10
92 | ELSE
93 | base := base - ORD(ch) + ORD ("0")
94 | END;
95 | RETURN (ch >= "0") & (base > 0)
96 | END IsOK;
97 |
98 | BEGIN
99 | val := 0; j := 0;
100 | IF (base < 2) OR (base > 16) THEN RETURN END;
101 | IF s[j] = "-" THEN neg := TRUE; INC (j) END;
102 | WHILE IsOK(s[j], base) DO
103 | val := val * base;
104 | IF s[j] <= "9" THEN val := val+ ORD(s[j])-ORD("0")
105 | ELSE val := val + ORD(s[j])-ORD("7")
106 | END;
107 | INC (j)
108 | END;
109 | IF neg THEN val := -val END
110 | END StrToInt;
111 |
112 |
113 | BEGIN
114 | Min[0] := "???";
115 | Min[1] := "10000000000000000000000000000000";
116 | Min[2] := "???";
117 | Min[3] := "???";
118 | Min[4] := "???";
119 | Min[5] := "???";
120 | Min[6] := "???";
121 | Min[7] := "???";
122 | Min[8] := "???";
123 | Min[9] := "-2147483648";
124 | Min[10] := "???";
125 | Min[11] := "???";
126 | Min[12] := "???";
127 | Min[13] := "???";
128 | Min[14] := "???";
129 | Min[15] := "80000000";
130 | Digit := "0123456789ABCDEF";
131 | END Conversions.
132 |
133 |
134 |
--------------------------------------------------------------------------------
/ports/s3/README.md:
--------------------------------------------------------------------------------
1 | S3, Native Oberon ports
2 | =======================
3 |
4 | This directory is for modules ported (or being ported) from
5 | Native Oberon 2.3.7. The original was Oberon-2 and is
6 | being ported to the Oberon-7.
7 |
8 | NOTE: Be mindful of information such as author, copyright and licenses
9 | maintained in the comments at the start of each module.
10 |
11 |
--------------------------------------------------------------------------------
/ports/s3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Project Artemis
5 |
6 |
7 |
8 |
9 |
10 |
11 | …
12 |
13 |
14 |
15 | S3, Native Oberon ports
16 |
17 |
18 | This directory is for modules ported (or being ported) from Native Oberon 2.3.7. The original was Oberon-2 and is being ported to the Oberon-7.
19 |
20 |
21 | NOTE: Be mindful of information such as author, copyright and licenses maintained in the comments at the start of each module.
22 |
23 |
24 |
27 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ports/v4/README.md:
--------------------------------------------------------------------------------
1 |
2 | V4, Linz Oberon
3 | ===============
4 |
5 | This directory is for modules ported (or being ported) from
6 | Linz Oberon also known as V4. The original was Oberon-2 and is
7 | being ported to the Oberon-7.
8 |
9 | NOTE: Be mindful of information such as author, copyright and licenses
10 | maintained in the comments at the start of each module.
11 |
12 |
--------------------------------------------------------------------------------
/ports/v4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Project Artemis
5 |
6 |
7 |
8 |
9 |
10 |
11 | …
12 |
13 |
14 |
15 | V4, Linz Oberon
16 |
17 |
18 | This directory is for modules ported (or being ported) from Linz Oberon also known as V4. The original was Oberon-2 and is being ported to the Oberon-7.
19 |
20 |
21 | NOTE: Be mindful of information such as author, copyright and licenses maintained in the comments at the start of each module.
22 |
23 |
24 |
27 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/posix/Display.Mod:
--------------------------------------------------------------------------------
1 | (** Display.Mod impements a minimal set of procedures and
2 | exported variables to support porting the Native Oberon 2.3.6
3 | codebase envolved with Texts.Mod *)
4 | MODULE Display;
5 |
6 | END Display.
7 |
--------------------------------------------------------------------------------
/posix/Kernel.Mod:
--------------------------------------------------------------------------------
1 | (** Kernel.Mod this is a compatibility module to
2 | allow us to port modules requiring specific Kernel
3 | functionality in a POSIX environment *)
4 | MODULE Kernel
5 |
6 | (*------------------- Miscellaneous Procedures from PO 2013 ------------*)
7 |
8 | (** Time exposes the Unix time value *)
9 | PROCEDURE Time*() : INTEGER;
10 | BEGIN
11 | END Time;
12 |
13 | (** Exposes returns the Unix time (epoch) *)
14 | PROCEDURE Clock*() : INTEGER;
15 | BEGIN
16 | END Clock;
17 |
18 | (** SetClock sets the clock given an INTEGER prepresentation
19 | of the date and time. NOTE: Most Linux will not allow you
20 | to set the clock from regular userspace. *)
21 | PROCEDURE SetClock*(dt: INTEGER);
22 | BEGIN
23 | END SetClock;
24 |
25 | (** Initialize the Kernel space *)
26 | PROCEDURE Init*;
27 | BEGIN
28 | END Init;
29 |
30 | END Kernel.
31 |
--------------------------------------------------------------------------------
/publish.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 |
4 | WORKING_BRANCH=$(git branch | grep '* ' | cut -d \ -f 2)
5 | if [ "$WORKING_BRANCH" = "gh-pages" ]; then
6 | git commit -am "publishing to gh-pages branch"
7 | git push origin gh-pages
8 | else
9 | echo "You're in $WORKING_BANCH branch"
10 | echo "You need to pull in changes to the gh-pages branch to publish"
11 | read -p "Pull into gh-pages and publish? Y/N " YES_NO
12 | if [ "$YES_NO" = "Y" ] || [ "$YES_NO" = "y" ]; then
13 | echo "Committing and pushing to $WORKING_BRANCH"
14 | git commit -am "commiting to $WORKING_BANCH";
15 | git push origin "$WORKING_BRANCH";
16 | echo "Changing branchs from $WORKING_BRANCH to gh-pages";
17 | git checkout gh-pages
18 | echo "Merging changes from origin gh-pages"
19 | git pull origin gh-pages
20 | git commit -am "merging origin gh-pages"
21 | echo "Pulling changes from $WORKING_BRANCH info gh-pages"
22 | git pull origin "$WORKING_BRANCH"
23 | echo "Merging changes from $WORKING_BRANCH"
24 | git commit -am "merging $WORKING_BRANCH with gh-pages"
25 | echo "Pushing changes up and publishing"
26 | git push origin gh-pages
27 | echo "Changing back to your working branch $WORKING_BRANCH"
28 | git checkout "$WORKING_BRANCH"
29 | fi
30 | fi
31 |
--------------------------------------------------------------------------------
/setup.bat:
--------------------------------------------------------------------------------
1 | SET PATH=%PATH%;C:\Program Files (x86)\OBNC
2 |
--------------------------------------------------------------------------------